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

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

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

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

Python

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

Q&A

解決済

1回答

4930閲覧

kerasによる2クラス分類から3クラス分類への変更

kusaaaaaaaaa

総合スコア15

Jupyter

Jupyter (旧IPython notebook)は、Notebook形式でドキュメント作成し、プログラムの記述・実行、その実行結果を記録するツールです。メモの作成や保存、共有、確認などもブラウザ上で行うことができます。

Keras

Kerasは、TheanoやTensorFlow/CNTK対応のラッパーライブラリです。DeepLearningの数学的部分を短いコードでネットワークとして表現することが可能。DeepLearningの最新手法を迅速に試すことができます。

Python

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

0グッド

1クリップ

投稿2018/10/18 03:03

前提・実現したいこと

機械学習初心者で勉強がてらkerasによる分類問題の実装を試みています。
自前のデータを準備し以下のサイトのコード(fruit.py)利用し、2クラスの分類の実装に成功しました。

https://qiita.com/hiroeorz@github/items/ecb39ed4042ebdc0a957

私の目的は多クラス分類だったため、3クラスへの分類を試みたのですが、エラーばかりでうまくできませんでした。
最後のdenseを2から3に変更してみたりと、初心者なりにいじったのですがうまくできませんでした。
先ほどの2クラスに分類するコードを3クラスに分類にするコードに変換したものを頂けないでしょうか?また、それ以上のクラスに分類できるコードに変換する際にも、どこを変更すれば良いのかを教えていただきたいです。
初歩的な質問かもしれませんが、よろしくお願いします。jupyterを使用しています。

該当のソースコード

from keras.models import Sequential from keras.layers import Activation, Dense, Dropout from keras.utils.np_utils import to_categorical from keras.optimizers import Adagrad from keras.optimizers import Adam import numpy as np from PIL import Image import os # 学習用のデータを作る. image_list = [] label_list = [] # ./data/train 以下のorange,appleディレクトリ以下の画像を読み込む。 for dir in os.listdir("data/train"): if dir == ".DS_Store": continue dir1 = "data/train/" + dir label = 0 if dir == "apple": # appleはラベル0 label = 0 elif dir == "orange": # orangeはラベル1 label = 1 for file in os.listdir(dir1): if file != ".DS_Store": # 配列label_listに正解ラベルを追加(りんご:0 オレンジ:1) label_list.append(label) filepath = dir1 + "/" + file # 画像を25x25pixelに変換し、1要素が[R,G,B]3要素を含む配列の25x25の2次元配列として読み込む。 # [R,G,B]はそれぞれが0-255の配列。 image = np.array(Image.open(filepath).resize((25, 25))) print(filepath) # 配列を変換し、[[Redの配列],[Greenの配列],[Blueの配列]] のような形にする。 image = image.transpose(2, 0, 1) # さらにフラットな1次元配列に変換。最初の1/3はRed、次がGreenの、最後がBlueの要素がフラットに並ぶ。 image = image.reshape(1, image.shape[0] * image.shape[1] * image.shape[2]).astype("float32")[0] # 出来上がった配列をimage_listに追加。 image_list.append(image / 255.) # kerasに渡すためにnumpy配列に変換。 image_list = np.array(image_list) # ラベルの配列を1と0からなるラベル配列に変更 # 0 -> [1,0], 1 -> [0,1] という感じ。 Y = to_categorical(label_list) # モデルを生成してニューラルネットを構築 model = Sequential() model.add(Dense(200, input_dim=1875)) model.add(Activation("relu")) model.add(Dropout(0.2)) model.add(Dense(200)) model.add(Activation("relu")) model.add(Dropout(0.2)) model.add(Dense(2)) model.add(Activation("softmax")) # オプティマイザにAdamを使用 opt = Adam(lr=0.001) # モデルをコンパイル model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"]) # 学習を実行。10%はテストに使用。 model.fit(image_list, Y, nb_epoch=1500, batch_size=100, validation_split=0.1) # テスト用ディレクトリ(./data/train/)の画像でチェック。正解率を表示する。 total = 0. ok_count = 0. for dir in os.listdir("data/train"): if dir == ".DS_Store": continue dir1 = "data/test/" + dir label = 0 if dir == "apple": label = 0 elif dir == "orange": label = 1 for file in os.listdir(dir1): if file != ".DS_Store": label_list.append(label) filepath = dir1 + "/" + file image = np.array(Image.open(filepath).resize((25, 25))) print(filepath) image = image.transpose(2, 0, 1) image = image.reshape(1, image.shape[0] * image.shape[1] * image.shape[2]).astype("float32")[0] result = model.predict_classes(np.array([image / 255.])) print("label:", label, "result:", result[0]) total += 1. if label == result[0]: ok_count += 1. print("seikai: ", ok_count / total * 100, "%")

補足情報(FW/ツールのバージョンなど)

window 10
python 3.6.6
jupyter notebook

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

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

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

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

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

guest

回答1

0

ベストアンサー

必要な変更

1. ラベルを3クラスにする。

elif dir == "pineapple": # pineappleはラベル3 label = 3

2. 出力層の出力数を3クラスにする。

model.add(Dense(2))

model.add(Dense(3))

投稿2018/10/18 03:09

tiitoi

総合スコア21956

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

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

kusaaaaaaaaa

2018/10/18 03:20

回答ありがとうございます。 既に回答の様に実装を試みていたのですが、 ValueError Traceback (most recent call last) <ipython-input-21-ea24b2a33620> in <module> 69 model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"]) 70 # 学習を実行。10%はテストに使用。 ---> 71 model.fit(image_list, Y, nb_epoch=1500, batch_size=100, validation_split=0.1) 72 73 # テスト用ディレクトリ(./data/train/)の画像でチェック。正解率を表示する。 ~\Miniconda3\envs\mykeras\lib\site-packages\keras\engine\training.py in fit(self, x, y, batch_size, epochs, verbose, callbacks, validation_split, validation_data, shuffle, class_weight, sample_weight, initial_epoch, steps_per_epoch, validation_steps, **kwargs) 950 sample_weight=sample_weight, 951 class_weight=class_weight, --> 952 batch_size=batch_size) 953 # Prepare validation data. 954 do_validation = False ~\Miniconda3\envs\mykeras\lib\site-packages\keras\engine\training.py in _standardize_user_data(self, x, y, sample_weight, class_weight, check_array_lengths, batch_size) 749 feed_input_shapes, 750 check_batch_axis=False, # Don't enforce the batch size. --> 751 exception_prefix='input') 752 753 if y is not None: ~\Miniconda3\envs\mykeras\lib\site-packages\keras\engine\training_utils.py in standardize_input_data(data, names, shapes, check_batch_axis, exception_prefix) 136 ': expected ' + names[i] + ' to have shape ' + 137 str(shape) + ' but got array with shape ' + --> 138 str(data_shape)) 139 return data 140 ValueError: Error when checking input: expected dense_58_input to have shape (1875,) but got array with shape (1,) とエラーが出てしまいました。 対処法があったら教えて頂きたいです。よろしくお願いします。 ちなみに、2クラス分類の際にもこの様なエラーが出たのですが、その際はjpgの他にpngも使っておりそれが良くないと判断した為、jpgのみにした結果うまく実装できました。 今回はその経験を元に全ての画像はjpgにしているので、うまく対処できずに困っています。
tiitoi

2018/10/18 03:23

モデルに渡してるラベルデータがおかしいエラーのように見えるので、`Y = to_categorical(label_list)` の直後に print(Y.shape) とするとどうなりますか?
kusaaaaaaaaa

2018/10/18 03:29

(46, 3) と出力されました。 よろしくお願いします。
tiitoi

2018/10/18 03:35

であれば、ラベルのほうは大丈夫そうです。 すいません。1875 はラベルではなく、画像のほうですね。 モデルの入力の image_list は image_list.shape の値が (N, 1875) になっていないと駄目なので、そうなっていなければ、それより前のデータセットを作る部分に問題があります。
kusaaaaaaaaa

2018/10/18 03:52

データセットを作る部分に問題があるということで、3つめのデータセットを削除し1つめのデータセットをコピペし3つめのデータセットとし、実行してみた結果うまく実装することができました。 本当にありがとうございます。 今回は、3つめデータセットの画像に何かしらの問題があったと言えるのですが、いまいち原因が把握できていません。(サイズ等バラバラな画像を適当に集めていたことが原因?) もしよろしければ、今後データセットの画像を集めて作成する際に、何に注意をすれば良いのか教えていただきたいです。
tiitoi

2018/10/18 04:00

リサイズは行っているのでそこは大丈夫そうですが、画像の中にグレースケール画像が混じっていたりして、サイズがおかしくなってしまったのではないでしょうか? image = np.array(Image.open(filepath).resize((25, 25))) のあとに image.shape してみて (25, 25, 3) になっていない画像があった場合、その画像が原因です。
kusaaaaaaaaa

2018/10/18 04:18

問題の画像が見つかりました!笑 おそらく、1つだけ深さが32ビットの透明度の情報が乗った画像を使ったせいでがエラーが発生していたようです。 無事に解決しました。素早い回答、お返事、本当にありがとうございます。
kusaaaaaaaaa

2018/10/18 06:26

引き続きですみません。 先ほど実装したもののニューラルネット構築をLenetに変えてみようと思い、 モデルを一通り変えました。また、conv2Dのimportや画像のサイズをlenetに合わせるため28×に変更しました。 しかし、下記のようなエラーが出てしまい、うまくいきませんでした。 ValueError: Error when checking input: expected conv2d_11_input to have 4 dimensions, but got array with shape (43, 2352) 今回は画像に問題はなく配列の部分に問題があると思うのですが、いまいち変更の仕方がわかりません。 下記のコードをどのように変更すればlenetでも実装できるのか教えて頂けないでしょうか? ----------------------------------------------------------------------------------- from keras.models import Sequential from keras.layers import Activation, Dense, Dropout from keras.utils.np_utils import to_categorical from keras.optimizers import Adagrad from keras.optimizers import Adam import numpy as np from PIL import Image import os from keras.layers.convolutional import Conv2D, MaxPooling2D from keras.layers.core import Activation, Flatten, Dense # 学習用のデータを作る. image_list = [] label_list = [] # ./data/train 以下のorange,appleディレクトリ以下の画像を読み込む。 for dir in os.listdir("data/train"): if dir == ".DS_Store": continue dir1 = "data/train/" + dir label = 0 if dir == "dora": # doraはラベル0 label = 0 elif dir == "pika": # pikaはラベル1 label = 1 elif dir == "shin": # shinはラベル2 label = 2 for file in os.listdir(dir1): if file != ".DS_Store": # 配列label_listに正解ラベルを追加(どら:0 ぴか:1しん2) label_list.append(label) filepath = dir1 + "/" + file # 画像を28x28pixelに変換し、1要素が[R,G,B]3要素を含む配列の25x25の2次元配列として読み込む。 # [R,G,B]はそれぞれが0-255の配列。 image = np.array(Image.open(filepath).resize((28, 28))) image.shape print(filepath) # 配列を変換し、[[Redの配列],[Greenの配列],[Blueの配列]] のような形にする。 image = image.transpose(2, 0, 1) # さらにフラットな1次元配列に変換。最初の1/3はRed、次がGreenの、最後がBlueの要素がフラットに並ぶ。 image = image.reshape(1, image.shape[0] * image.shape[1] * image.shape[2]).astype("float32")[0] # 出来上がった配列をimage_listに追加。 image_list.append(image / 255.) # kerasに渡すためにnumpy配列に変換。 image_list = np.array(image_list) # ラベルの配列を1と0からなるラベル配列に変更 # 0 -> [1,0], 1 -> [0,1] という感じ。 Y = to_categorical(label_list) print(Y.shape) # モデルを生成してニューラルネットを構築 model = Sequential() model.add(Conv2D(20, kernel_size=5, padding="same", input_shape=(1,28,28))) model.add(Activation("relu")) model.add(MaxPooling2D()) model.add(Conv2D(50, kernel_size=5, border_mode="same")) model.add(Activation("relu")) model.add(MaxPooling2D()) model.add(Flatten()) model.add(Dense(500)) model.add(Activation("relu")) model.add(Dense(3)) model.add(Activation("softmax")) # オプティマイザにAdamを使用 opt = Adam(lr=0.001) # モデルをコンパイル model.compile(loss="categorical_crossentropy", optimizer=opt, metrics=["accuracy"]) # 学習を実行。10%はテストに使用。 model.fit(image_list, Y, nb_epoch=1500, batch_size=100, validation_split=0.1) # テスト用ディレクトリ(./data/train/)の画像でチェック。正解率を表示する。 total = 0. ok_count = 0. for dir in os.listdir("data/train"): if dir == ".DS_Store": continue dir1 = "data/test/" + dir label = 0 if dir == "dora": label = 0 elif dir == "pika": label = 1 elif dir == "shin": label = 2 for file in os.listdir(dir1): if file != ".DS_Store": label_list.append(label) filepath = dir1 + "/" + file image = np.array(Image.open(filepath).resize((28, 28))) print(filepath) image = image.transpose(2, 0, 1) image = image.reshape(1, image.shape[0] * image.shape[1] * image.shape[2]).astype("float32")[0] result = model.predict_classes(np.array([image / 255.])) print("label:", label, "result:", result[0]) total += 1. if label == result[0]: ok_count += 1. print("seikai: ", ok_count / total * 100, "%") --------------------------------------------------------------------------- Lenetのモデルは以下のサイトを参照しました。 https://10001ideas.com/2017/08/30 こちらのサイトではmnistのようなものを使用しているので、配列辺りで違いが生じているとは思います。 どうかよろしくお願いします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問