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

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

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

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

Google Colaboratory

Google Colaboratoryとは、無償のJupyterノートブック環境。教育や研究機関の機械学習の普及のためのGoogleの研究プロジェクトです。PythonやNumpyといった機械学習で要する大方の環境がすでに構築されており、コードの記述・実行、解析の保存・共有などが可能です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

6427閲覧

CNNで学習が進まない

gakusyusuruzo

総合スコア11

Keras

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

Google Colaboratory

Google Colaboratoryとは、無償のJupyterノートブック環境。教育や研究機関の機械学習の普及のためのGoogleの研究プロジェクトです。PythonやNumpyといった機械学習で要する大方の環境がすでに構築されており、コードの記述・実行、解析の保存・共有などが可能です。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

1クリップ

投稿2019/05/07 12:54

編集2019/05/08 11:43

acc,val_accを上げたい、loss,val_lossを下げたいです。

Python、機械学習および画像認識超初心者です。
自分で用意した2クラスの画像を、CNNで学習をして分類をするプログラムを書きたいと思いました。

1クラスにつき、訓練用に130枚ずつ、評価用に40枚ずつ、写真を撮って用意しました。下が用意した写真です。(2クラスなので合計260枚、80枚です)

イメージ説明
イメージ説明
それをgoogle drive に入れ、colaboratoryでマウントし、読み込んでいます。

見よう見まねでコードを書いて実行してみたのですが、acc,val_accが上がらず、loss,val_lossも下がりません。それらの値の変化をプロットしたグラフも振れ幅が大きく正しく学習を行えていると思えません。学習回数を増やしても同様の結果でした。
イメージ説明
イメージ説明

1.学習がうまくいかない原因
2.バッチサイズ、およびステップ数の決め方(今は決め方が分からなくて適当な値を入れています)
3.学習させるにはどうしたらよいのか

この3点について、ご教授お願いします。そのほかコードに変なところがあれば指摘いただきたいです。

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

from google.colab import drive drive.mount('/content/drive') from keras.models import Sequential, Model from keras.layers import Dense, Dropout, Activation, Flatten from keras.layers import Conv2D, MaxPooling2D, BatchNormalization num_classes = 2 img_height, img_width =64, 64 #モデルを定義 model = Sequential() model.add(Conv2D(32, (3, 3), padding='same', activation='relu', input_shape=(img_height, img_width, 3))) model.add(Conv2D(32, (3, 3), padding='same', activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.5)) model.add(Conv2D(64, (3, 3), padding='same', activation='relu')) model.add(Conv2D(64, (3, 3), padding='same', activation='relu')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Dropout(0.5)) model.add(Flatten()) model.add(Dense(512, activation='relu')) model.add(Dropout(0.25)) model.add(Dense(num_classes)) model.add(Activation('softmax')) #ここなに? for layer in model.layers: layer.trainable = True from keras import optimizers model.compile(loss='categorical_crossentropy', optimizer=optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True), metrics=['accuracy']) from keras.preprocessing.image import ImageDataGenerator train_datagen = ImageDataGenerator( rescale=1. / 255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True, featurewise_center=True, featurewise_std_normalization=True, zca_whitening=True ) test_datagen = ImageDataGenerator( rescale=1. / 255, featurewise_center=True, featurewise_std_normalization=True, zca_whitening=True ) #訓練用データを作る train_generator = train_datagen.flow_from_directory( '/content/drive/My Drive/takekino/train', target_size=(img_height, img_width), batch_size= 26, #バッチサイズ分かりません class_mode='categorical') #検証用データ validation_generator = test_datagen.flow_from_directory( '/content/drive/My Drive/takekino/val', target_size=(img_height, img_width), batch_size= 8, #バッチサイズ分かりません class_mode='categorical') #学習 history = model.fit_generator( train_generator, steps_per_epoch=10, #これも適当です (訓練データサイズ)/(訓練バッチサイズ)? epochs=50, validation_data=validation_generator, validation_steps=10 #これも適当です (評価データサイズ)/(評価バッチサイズ)? ) # モデルを保存 print("Model saving... at ./drive/My Drive/model.json") from keras.utils import plot_model model_json = model.to_json() with open("./drive/My Drive/takekino_model.json", mode='w') as f: f.write(model_json) # 学習済みの重みを保存 print("Weight saving... at ./drive/My Drive/weights.hdf5") model.save_weights("./drive/My Drive/takekino_weights.hdf5") import matplotlib.pyplot as plt print("plotting...") plt.plot(history.history['acc']) plt.plot(history.history['val_acc']) plt.title('model accuracy') plt.xlabel('epoch') plt.ylabel('accuracy') plt.legend(['acc', 'val_acc'], loc='lower right') plt.show() print("plotting...") plt.plot(history.history['loss']) plt.plot(history.history['val_loss']) plt.title('model loss') plt.xlabel('epoch') plt.ylabel('loss') plt.legend(['loss', 'val_loss'], loc='upper right') plt.show()

試したこと

回答を受けてまずデータサンプル数を1クラスにつき訓練用200枚、評価用100枚(2クラスで400枚、200枚)に増やしました。
そのうえで、ImageDataGeneratorでの操作を色々変えてみました。

変更1.サンプル数を増やし、ImageDataGeneratorの操作はそのままにしたもの
変更1

変更2.サンプル数を増やしImageDataGeneratorの操作を次のように変更したもの
train_datagen = ImageDataGenerator(
rescale=1. / 255,
horizontal_flip=True
)
test_datagen = ImageDataGenerator(
rescale=1. / 255,
)
変更2

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

ここにより詳細な情報を記載してください。

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

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

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

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

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

guest

回答2

0

読み込みの際に1/255してさらにImageDataGeneratorで
rescale=1. / 255 してないでしょうか。

他のものも効くやつと効かないやつがあるかもしれません。

投稿2019/05/08 03:03

daesaka

総合スコア136

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

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

gakusyusuruzo

2019/05/08 03:56

daesakaさん、回答ありがとうございます。 rescale しているのは ImageDataGeneratorの部分のみだと思っていましたが、私自身コードの意味がまだよくわかっていないので調べてみます。 「他のものも効くやつと効かないやつがあるかもしれない」について、ImageDataGeneratorによるデータ拡張が効かない場合、あるいは学習を妨げるような場合があるのでしょうか?
daesaka

2019/05/08 04:33

> あるいは学習を妨げるような場合があるのでしょうか? 多少学習の妨げになった経験があります。rescaleが原因じゃなかったら1つ1つ確認してみても良いかもしれません。
gakusyusuruzo

2019/05/08 11:52

>多少学習の妨げになった経験があります。 そうなんですね。一つ一つ確認してみたところ、違いはあまりありませんでした。 ただ、有効性はデータにもよるらしいと知ったので、今回の画像に対しては適切な操作ではなかったのかもしれません。
guest

0

ベストアンサー

1.学習がうまくいかない原因

1から学習するにはデータ枚数が少なすぎるかもしれません。
例えば、サンプルとしてよく使われる MNIST は1クラス5000枚ぐらいあります。

2.バッチサイズ、およびステップ数の決め方(今は決め方が分からなくて適当な値を入れています)

バッチサイズは 1 ~ 100 ぐらいの間で適当に決めてください。
GPU は一度に大量の計算をしたほうが効率がよいので、バッチサイズが大きくするほど学習時間が早くなります。(とはいえ、大きくしすぎると GPU メモリに乗り切らなくなるかもしれない)
しかし、バッチサイズを大きくすると局所解に陥りやすくなるので、結局どの値がいいかは問題によります。
いくつかの値を試して良い値を採用しましょう。

ステップ数はサンプル数 / バッチサイズで決めます。

3.学習させるにはどうしたらよいのか

今回のように学習データのサンプル数が少ない場合は、フルスクラッチで学習するのではなく、学習済みのモデルを使って転移学習をしたほうが精度がでるかもしれません。

Applications - Keras Documentation

Keras では VGG 等の学習済みモデルが提供されているので、これを使うのがよいでしょう。

投稿2019/05/07 21:33

tiitoi

総合スコア21956

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

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

gakusyusuruzo

2019/05/08 02:39

tiitoiさん回答ありがとうございます。 1.について データ数が少ないことが主な原因なのかとは私も思いました。 しかし、始めはImageDataGeneratorを使わずに学習を行っていたのですが、そのときはepoch数とともにacc,val_accが上がり、loss,val_lossが下がっていました。 データ拡張のためにImageDataGeneratorを組み込んだプログラムを実行したところ、なんともうまくいかなくなってしまいました。その辺に原因はないでしょうか。 2.について ありがとうございます。ImageDataGeneratorを使う場合はサンプル数が増えるのではないかとおもうのですが、その場合のステップ数はどのように指定すればよいのでしょうか。 3.について 転移学習ですね。さっそく試してみます。
tiitoi

2019/05/08 04:46

> そのときはepoch数とともにacc,val_accが上がり、loss,val_lossが下がっていました。 それは過学習です。サンプル数に対して学習対象のパラメータ数が多すぎるとそのような現象になります。 > ImageDataGeneratorを組み込んだプログラムを実行したところ、なんともうまくいかなくなってしまいました。 Data Argumentation は確かに精度向上に効果はあるのですが、パラメータをたくさん指定して闇雲に増やせばいいというわけではありません。 以下のリンク先にパラメータの意味の説明があります。 http://pynote.hatenablog.com/entry/keras-image-data-generator 例えば、zoom_range や shear_range は、画像に変換した際に存在しない画素値が出てきてしまい、それを適当な値で人工的に埋めるということが行われます。このような画素は実際のデータにはないため、過学習の原因になる可能性もあります。また正規化 featurewise_center, featurewise_std_normalization や白色化 zca_whitening も有用かどうかというとケースバイケースで、1 / 255 で [0, 1] に正規化するだけで十分だったりします。 まずは rescale=1. / 255 とhorizontal_flip=True だけで試されてはどうでしょうか。 > 。ImageDataGeneratorを使う場合はサンプル数が増えるのではないかとおもうのですが ImageDataGenerator は予め n 倍に増やしたりするわけではなく、ミニバッチに対してリアルタイムに変換を行い、モデルにわたすようになっています。 なので、steps_per_epoch はサンプル数 // バッチサイズでよいです。
gakusyusuruzo

2019/05/08 12:03

>それは過学習です。 そうなんですね。「学習ができている」と判断していました… >Data Argumentation は確かに精度向上に効果はあるのですが、パラメータをたくさん指定して闇雲に増やせばいいというわけではありません 穴埋めによっていらない情報が増えたことでAugmentationを行う前よりおかしな挙動をするようになったのかもしれないと思いました。気を付けて使う必要があるようですね。 >まずは rescale=1. / 255 とhorizontal_flip=True だけで試されてはどうでしょうか。 サンプル数を増やし、この条件で実行してみたところ、追記画像のような結果になりました。 とりあえずサンプル数が増えたことでハチャメチャなグラフがでることはなくなりました。ありがとうございます。 >ImageDataGenerator は予め n 倍に増やしたりするわけではなく、ミニバッチに対してリアルタイムに変換を行い、モデルにわたすようになっています。 そうだったんですね。
tiitoi

2019/05/09 02:18 編集

追記された画像を拝見しましたが、バリデーションの精度も80%は超えていおり、グラフの推移を見ても学習できているように思えます。 ここからさらに精度を上げるためには、サンプル増やす、フルスクラッチでなく、転移学習をする等いろいろ試されるとよいと思います。 もし質問内容が解決されたようでしたら、お手数ですが、質問をクローズしていただけますか。
gakusyusuruzo

2019/05/09 11:07

転移学習も試してみたところ、val_acc = 0.9550 と、より精度を上げることができました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問