質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

1回答

13558閲覧

【Python/SVM】画像の分類を行いたい

nnahito

総合スコア2004

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2016/12/12 18:20

編集2016/12/13 02:08

前提

機械学習初心者です。
サポートベクターマシーン(SVM)の使い方を勉強中です。

質問概要

サポートベクターマシーン(SVM)とPythonを用いて、
膨大な量の画像を「好き」or「嫌い」に分けたいが、以下のエラーが出てしまう。
なぜでしょうか?

ValueError: Found array with dim 3. Estimator expected <= 2.

質問詳細

サポートベクターマシーン(SVM)とPythonを用いて、
膨大な量の画像を「好き」or「嫌い」に分けたいが、以下のエラーが出てしまいます。

ValueError: Found array with dim 3. Estimator expected <= 2.

これの意味がよく分かりませんが、調べてみたところ、入力値に問題があると……
……それは調べなくとも何となくわかりますが、その整形の仕方が分かりません。

以下、私が書いたコードと、フォルダ構成です。

フォルダ構成

イメージ説明

  • img:分類したい画像データ
  • ng:嫌いな画像の教師群
  • ok:好きな画像の教師群
  • out:グレースケール、エッジ抽出、ダウンサイジングを行った後の画像を出力するフォルダ

コード

python

1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4import sys 5import os 6from PIL import Image 7import ImageFilter 8import numpy as np 9from sklearn import svm 10 11 12# 定数定義場 13STANDARD_SIZE = (300, 167) 14CONST_NUM = 50100 15 16 17# 変数定義場 18Images = [] # 教師画像 19Labels = [] # ラベル(ok = 0, ng = 1とする) 20 21 22# 学習用画像データ(OK)を読み込む 23for f in os.listdir("./ok/"): 24 # 画像を読み込む 25 img = Image.open("./ok/" + f) 26 27 # グレースケール化 28 img = img.convert('L') 29 30 # エッジ抽出 31 img = img.filter(ImageFilter.FIND_EDGES) 32 33 # ダウンサイジング 34 img = img.resize(STANDARD_SIZE) 35 36 # データを追加 37 Images.append(np.asarray(img)) 38 39 # ラベルを設定 40 Labels.append(0) 41 42 print "Images, Labels = " + str(len(Images)) + ", " + str(len(Labels)) 43 44 #print "0, " + f 45 46 img.save('./out/ok_' + f) 47 48 49 50# 学習用画像データ(NG)を読み込む 51for f in os.listdir("./ng/"): 52 # 画像を読み込む 53 img = Image.open("./ng/" + f) 54 55 # グレースケール化 56 img = img.convert('L') 57 58 # エッジ抽出 59 img = img.filter(ImageFilter.FIND_EDGES) 60 61 # ダウンサイジング 62 img = img.resize(STANDARD_SIZE) 63 64 # データを追加 65 Images.append(np.asarray(img)) 66 67 img.save('./out/ng_' + f) 68 69 # ラベルを設定 70 Labels.append(1) 71 #print "1, " + f 72 print "Images, Labels = " + str(len(Images)) + ", " + str(len(Labels)) 73 74print Images 75 76# ガウシアンカーネルによる SVM インスタンス生成 77clf = svm.SVC(C=100, kernel="rbf") 78 79# 教師データで学習 (データに対するフィッティング) 80print "----------------" 81print "TRAINING NOW..." 82print "----------------" 83 84print "画像数:" + str(len(Images)) 85print "ラベル数:" + str(len(Labels)) 86 87# トレーニング 88clf.fit(Images, Labels) 89 90 91# 分類する画像データを入れる変数 92studentImages = [] 93 94# 分類する画像を読み込む 95for f in os.listdir("./img/"): 96 print "filename: " + f 97 98 # 画像を読み込む 99 img = Image.open("./img/" + f) 100 101 # グレースケール化 102 img = img.convert('L') 103 104 # エッジ抽出 105 img = img.filter(ImageFilter.FIND_EDGES) 106 107 # ダウンサイジング 108 img = img.resize(STANDARD_SIZE) 109 110 # データを追加 111 studentImages.append(np.asarray(img)) 112 113 img.save('./out/student_' + f) 114 115 116print "-------------------" 117print "CLUSTERING NOW..." 118print "-------------------" 119 120# 画像データを分類する 121results = clf.predict(studentImages) 122 123for r in results: 124 if r == 0: 125 print "ok" 126 elif r == 1: 127 print "ng" 128 else: 129 print "error" 130

このやり方であっているのでしょうか?
画像の読み込み方や、配列の指定方法はあっていますでしょうか?

何かお気づきの点などございましたら、ご教示頂けますと幸いです。
よろしくお願いいたします。

参考サイト様

環境

  • MacOSX Yosemite 10.10.5
  • Python 2.7.10

追記1

ベクトルの1次元変換は、このような感じでは無いでしょうか?

python

1# 次元を1次元に変換 2 img_np = np.asarray(img) 3 img_np = img_np.shape[0] * img_np.shape[1]

以下、全文

python

1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3 4import sys 5import os 6from PIL import Image 7import ImageFilter 8import numpy as np 9from sklearn import svm 10 11 12# 定数定義場 13STANDARD_SIZE = (300, 167) 14CONST_NUM = 50100 15 16 17# 変数定義場 18Images = [] # 教師画像 19Labels = [] # ラベル(ok = 0, ng = 1とする) 20 21 22# 学習用画像データ(OK)を読み込む 23for f in os.listdir("./ok/"): 24 # 画像を読み込む 25 img = Image.open("./ok/" + f) 26 27 # グレースケール化 28 img = img.convert('L') 29 30 # エッジ抽出 31 img = img.filter(ImageFilter.FIND_EDGES) 32 33 # ダウンサイジング 34 img = img.resize(STANDARD_SIZE) 35 36 # 次元を1次元に変換 37 img_np = np.asarray(img) 38 img_np = img_np.shape[0] * img_np.shape[1] 39 40 # データを追加 41 Images.append(img_np) 42 43 # ラベルを設定 44 Labels.append(0) 45 46 print "Images, Labels = " + str(len(Images)) + ", " + str(len(Labels)) 47 48 img.save('./out/ok_' + f) 49 50 51 52# 学習用画像データ(NG)を読み込む 53for f in os.listdir("./ng/"): 54 # 画像を読み込む 55 img = Image.open("./ng/" + f) 56 57 # グレースケール化 58 img = img.convert('L') 59 60 # エッジ抽出 61 img = img.filter(ImageFilter.FIND_EDGES) 62 63 # ダウンサイジング 64 img = img.resize(STANDARD_SIZE) 65 66 # 次元を1次元に変換 67 img_np = np.asarray(img) 68 img_np = img_np.shape[0] * img_np.shape[1] 69 70 # データを追加 71 Images.append(img_np) 72 73 img.save('./out/ng_' + f) 74 75 print "Images, Labels = " + str(len(Images)) + ", " + str(len(Labels)) 76 77 # ラベルを設定 78 Labels.append(1) 79 80 81 82# ガウシアンカーネルによる SVM インスタンス生成 83clf = svm.SVC(C=100, kernel="rbf") 84 85# 教師データで学習 (データに対するフィッティング) 86print "----------------" 87print "TRAINING NOW..." 88print "----------------" 89 90print "画像数:" + str(len(Images)) 91print "ラベル数:" + str(len(Labels)) 92 93# トレーニング 94clf.fit(Images, Labels) 95 96 97# 分類する画像データを入れる変数 98studentImages = [] 99 100# 分類する画像を読み込む 101for f in os.listdir("./img/"): 102 print "filename: " + f 103 104 # 画像を読み込む 105 img = Image.open("./img/" + f) 106 107 # グレースケール化 108 img = img.convert('L') 109 110 # エッジ抽出 111 img = img.filter(ImageFilter.FIND_EDGES) 112 113 # ダウンサイジング 114 img = img.resize(STANDARD_SIZE) 115 116 # 次元を1次元に変換 117 img_np = np.asarray(img) 118 img_np = img_np.shape[0] * img_np.shape[1] 119 120 # データを追加 121 studentImages.append(img_np) 122 123 img.save('./out/student_' + f) 124 125 126print "-------------------" 127print "CLUSTERING NOW..." 128print "-------------------" 129 130# 画像データを分類する 131results = clf.predict(studentImages) 132 133for r in results: 134 if r == 0: 135 print "ok" 136 elif r == 1: 137 print "ng" 138 else: 139 print "error" 140

追記2

/Library/Python/2.7/site-packages/sklearn/utils/validation.py:386: DeprecationWarning: Passing 1d arrays as data is deprecated in 0.17 and willraise ValueError in 0.19. Reshape your data either using X.reshape(-1, 1) if your data has a single feature or X.reshape(1, -1) if it contains a single sample. ValueError: X and y have incompatible shapes. X has 1 samples, but y has 170.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

2次元画像をスタックして、3次元配列を作成しているようです。

># データを追加 >Images.append(np.asarray(img))

svmで画像を分類するには、画像を1次元のベクトルに変換する必要があります。それらを画像の枚数だけ並べて
行列を作り、それをsvmに渡します。

投稿2016/12/12 19:32

編集2016/12/12 20:04
WathMorks

総合スコア1582

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nnahito

2016/12/13 02:04

ご回答ありがとうございます。 ベクトルの変換が必要ということなのですが、どのように行うのでしょうか。 一応調べて見たところ、「追記1」のようにすればいいと載っているサイト様があったのですが、 「追記2」のようなエラーが出ます。 お手数をおかけいたしますが、もう少し詳しく教えて頂けませんでしょうか。
WathMorks

2016/12/14 22:54

>> # 次元を1次元に変換 >> img_np = np.asarray(img) >> img_np = img_np.shape[0] * img_np.shape[1] img_npガスカラーになっています。 svmに渡すデータの構造を知るには、例えば from sklearn import datasets digits = datasets.load_digits() print(digits.data) を実行してみてください。何をどのようにならべればよいかわかるはずです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問