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

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

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

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

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

機械学習

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

Python

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

Q&A

解決済

2回答

4689閲覧

CNNを用いた2値分類でのパラメータ設定について

---stax---

総合スコア148

Keras

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

深層学習

深層学習は、多数のレイヤのニューラルネットワークによる機械学習手法。人工知能研究の一つでディープラーニングとも呼ばれています。コンピューター自体がデータの潜在的な特徴を汲み取り、効率的で的確な判断を実現することができます。

機械学習

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

Python

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

0グッド

0クリップ

投稿2019/03/11 00:44

編集2019/03/11 00:46

表題の件で質問させてください。
CNNを用いて画像の2値(正常/異常)分類を行っています。
いくつかモデルを作成したのですがその結果を受けてつぎはどのようなアプローチをすればよいのか分からず悩んでいます

使用しているフレームワークはkerasです。
データ数は以下の通りです。

正常画像 100枚
異常画像 100枚

訓練データ:120枚(正常:60枚、異常:60枚)
検証データ:40枚(正常:20枚、異常:20枚)
テストデータ:40枚(正常:20枚、異常:20枚)

精度指標:正解率(acc)

試した方法としては以下の3パターンです
①CNNでの分類
loss=0.14226582273840904
accuracy=0.9249999821186066
イメージ説明
![イメージ説明]

②データを水増ししたモデル
loss=0.22634971141815186
accuracy=0.9749999940395355
イメージ説明
イメージ説明

③水増し+バッチ正規化をしたモデル
loss=0.18287870474159718
accuracy=0.9249999821186066
イメージ説明
イメージ説明

精度やロスに関しては各エポック毎で一番良い結果(今回は検証データに対するロス)のモデルをスナップショットで保存したもので結果を出しています。
結果を見ると①と②のモデルはaccもlossも良さそうなのですがグラフの結果とは整合性が取れていないように感じます(まぐれで精度が良かっただけかも)
③に関してはaccもlossも訓練データ、検証データ共に良い結果が出せている箇所が見られます。

上記の結果から③に関しては他に比べるとマシなのかなとも感じるのですが、どのモデルも結果が収束している傾向が見られません(収束しているべきとの認識がすでに間違っていたらすいません)
これはパラメータの指定などで収束させることが出来る部分なのでしょうか?
また収束していない原因と考えられる部分はどこでしょうか?

↓収束しているイメージ
イメージ説明

データ数やエポック数で変わる部分もありますし、何を持ってこれは良いモデルだとするかはビジネスケースにもよるとは思うのですが、スナップショットで一番いいところを保存したモデルでも、他のエポックでは精度が出ていない場合はそれは良いモデルと判断しても良いのでしょうか?

以下レイヤー定義、コンパイル、学習部分になります
一部のみ抜粋しているのであまり役に立たないかもしれません・・・

python

1from keras import layers 2from keras import models 3from keras import optimizers 4 5model = models.Sequential() 6#input_shape = CNNの入力テンソルが(image_height, image_width, image_channels)(バッチ次元を含まない)の形状 7model.add(layers.Conv2D(32, (3, 3), activation='relu', input_shape=(300, 300, 3))) 8model.add(layers.BatchNormalization()) 9model.add(layers.MaxPooling2D((2, 2))) 10 11model.add(layers.Conv2D(64, (3, 3), activation='relu')) 12model.add(layers.BatchNormalization()) 13model.add(layers.MaxPooling2D((2, 2))) 14 15model.add(layers.Conv2D(128, (3, 3), activation='relu')) 16model.add(layers.BatchNormalization()) 17model.add(layers.MaxPooling2D((2, 2))) 18 19model.add(layers.Conv2D(128, (3, 3), activation='relu')) 20model.add(layers.BatchNormalization()) 21model.add(layers.MaxPooling2D((2, 2))) 22 23model.add(layers.Conv2D(128, (3, 3), activation='relu')) 24model.add(layers.BatchNormalization()) 25model.add(layers.MaxPooling2D((2, 2))) 26 27model.add(layers.Flatten()) 28model.add(layers.Dense(512, activation='relu')) 29model.add(layers.BatchNormalization()) 30model.add(layers.Dense(1, activation='sigmoid')) 31 32model.compile(loss='binary_crossentropy', 33 optimizer=optimizers.RMSprop(lr=1e-4), 34 metrics=['acc']) 35 36history = model.fit_generator(train_generator, 37 steps_per_epoch = 6, 38 epochs = 30, 39 validation_data = validation_generator, 40 validation_steps = 5, 41 callbacks=[check_point])

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

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

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

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

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

guest

回答2

0

単純にデータが少ないので、結果の出方が大きくばらつく(分散が大きい)ということかと。40件の検証データで正解する数が1つ変わると正解率が0.025ぶれます。

もう少し変動がなくなるまで回しても良いかもしれませんが、だいたい使えるレベルまで収束していそうな気はします。

投稿2019/03/11 06:17

hayataka2049

総合スコア30933

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

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

---stax---

2019/03/11 07:16

回答ありがとうございます。 >>40件の検証データで正解する数が1つ変わると正解率が0.025ぶれます。 こういう考え方はしていませんでした・・・。 確かに数個間違えただけでも波形として目立つようになってしまいます。 100エポックまでは回したことがあるのですが良い方への変化が見られませんでした。
guest

0

ベストアンサー

これはパラメータの指定などで収束させることが出来る部分なのでしょうか?

バッチサイズや最適化手法を変更する。SGD なら学習率をいくつか試す。
学習に時間がかからないようであれば、それらのハイパーパラメータをグリッドサーチする。

他のエポックでは精度が出ていない場合はそれは良いモデルと判断しても良いのでしょうか?

学習でやっていることは非線形関数を確率的勾配法で最適化しているだけなので、LOSS が少ないところは関数でより値が小さい部分が見つかったということです。
テストデータが実際に運用する際のデータを十分に表現できており、かつそのテストデータに対する精度に満足できるのであれば、それでいいのではないでしょうか。

投稿2019/03/11 02:29

tiitoi

総合スコア21956

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

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

---stax---

2019/03/11 03:10

回答ありがとうございます。 RMSpropを使っているので学習率を変更してみます 最初は大きくして徐々に小さくする方が良さそうなのでLearningRateSchedulerも使ってみます。 収束に関しては収束しているかしていないかは、テストデータに対して満足できる結果が出ていればあまり意識する必要はないという理解でよいでしょうか?(ケースバイケースとは思いますが基本的な考え方として) また評価指標については今回はテスト的に行っているのでaccを使っていますが、F値やAUCが一般的かと思います。 ドキュメントを見たところkerasでAUCなどを出す機能は標準ではないように感じたのですが、scikit-learnなどに渡して出すのが一般的なのでしょうか?
tiitoi

2019/03/11 05:33 編集

> 収束に関しては収束しているかしていないかは、 validation loss がまだ下がる傾向があるならエポックはもっと回してください。validation loss が頭打ち、もしくは上昇していくようであれば、これ以上 epoch 回しても改善しないので止めてしまってよいです。 > ドキュメントを見たところkerasでAUCなどを出す機能は標準ではないように感じたのですが、scikit-learnなどに渡して出すのが一般的なのでしょうか? もしそのような指標がほしければ、sklearn に渡してください。 あとハイパーパラメータはバッチサイズもいくつか試したほうがよいですよ。大きいほど局所解にハマりやすくなるので。
---stax---

2019/03/11 07:09

回答ありがとうございます。 100エポックほど回したことがあるのですが③水増し+バッチ正規化をしたモデルのvalidation accのようにギザギザが続いたり突然大きくlossが上がるだけで収束する気配がありませんでした・・・ バッチサイズはずっと固定だったので数を減らして変化を見てみます AUCの出力に関してですが、探してみたもののscikit-learnを使う場合にdecision_functionやpredict_probaの結果をkerasで学習中のものからどのように抜き出すのか分からなかったのでもう少し調べてみます。 参考書などで勉強していると分類問題の精度指標はaccuracyではなく、AUCなどを用いるべきとの認識なのですが上記のやり方をしらべる中で「AUCはあまり使うことはない。あくまで見せる用」との記事を見かけたのですが一般的に目標にすべき指標ではないのでしょうか? 初歩的な質問で申し訳ありません。
tiitoi

2019/03/11 07:26

今回の (正常/異常)分類の場合は ROC 曲線を書いてみてると、閾値を決めるのに便利かもしれませんね。その指標がモデルの性能を理解する上で役に立つのであれば計算すればいいのではないでしょうか。
---stax---

2019/03/11 07:51

回答ありがとうございます。 まだ精度指標についてどのような場合にどのような指標を使うべきかいまいちよく分かっていないのでもう一度復習してきます。 初歩的な質問にもかかわらず丁寧に対応して頂きありがとうございます。
tiitoi

2019/03/11 08:02 編集

正常/異常2値分類の場合はネットワークの出力として異常度の確率が出てくると思うので、何% 以上なら異常と見なすのかみたいな閾値を決める必要があります。そのようなケースで ROC 曲線を見ながら、異常であることを正常と判断する未検出がないことを重視するのか、正常を異常と判断してしまう誤検出がないことを重視するのかを考え、閾値を決めることができます。 http://www.randpy.tokyo/entry/roc_auc
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問