web-dev-qa-db-ja.com

Keras CNNモデルでトレーニングと損失が変化しない

左と右の靴型分類のためにCNNを実行しています。私は190,000のトレーニング画像を所有しており、その10%を検証に使用しています。モデルは以下のように設定されています。すべての画像のパスを取得し、読み込み、サイズを変更します。画像を正規化し、モデルに合わせます。私の問題は、62.5%のトレーニング精度と約0.6615-0.6619の損失で動かなくなったことです。私がやっていることに何か問題がありますか?これを防ぐにはどうすればよいですか?

注意すべきいくつかの興味深い点:

1)私は最初に同じ問題を抱えていた10個の画像でこれをテストしましたが、オプティマイザをadamに変更し、バッチサイズを4に変更しました。

2)その後、より多くの画像でテストしましたが、精度と損失を改善するために、毎回バッチサイズを変更する必要があります。 10,000枚の画像では、バッチサイズ500とオプティマイザrmspropを使用する必要がありました。ただし、精度と損失は、エポック10以降にのみ実際に変化し始めました。

3)190,000枚の画像でトレーニングを行っていますが、GPUが最大なのでバッチサイズを増やすことができません。

imageWidth = 50
imageHeight = 150

def get_filepaths(directory):
file_paths = []
for filename in files:
filepath = os.path.join(root, filename)
file_paths.append(filepath) # Add it to the list.
return file_paths

def cleanUpPaths(fullFilePaths):
cleanPaths = []
for f in fullFilePaths:
if f.endswith(".png"):
cleanPaths.append(f)
return cleanPaths

def getTrainData(paths):
trainData = []
for i in xrange(1,190000,2):
im = image.imread(paths[i])
im = image.imresize(im, (150,50))
im = (im-255)/float(255)
trainData.append(im)
trainData = np.asarray(trainData)
right = np.zeros(47500)
left = np.ones(47500)
trainLabels = np.concatenate((left, right))
trainLabels = np_utils.to_categorical(trainLabels)
return (trainData, trainLabels)

#create the convnet
model = Sequential()

model.add(Conv2D(32, (3, 3), activation='relu', input_shape=(imageWidth,imageHeight,1),strides=1))#32
model.add(Conv2D(32, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3), activation='relu',strides=1))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(1, 3)))
model.add(Dropout(0.25))

model.add(Conv2D(64, (1, 2), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 1)))
model.add(Dropout(0.25))

model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(2, activation='softmax'))

sgd = SGD(lr=0.01)
model.compile(loss='categorical_crossentropy', optimizer='rmsprop',metrics=['accuracy'])

#prepare the training data*/

trainPaths = get_filepaths("better1/train")
trainPaths = cleanUpPaths(trainPaths)
(trainData, trainLabels) = getTrainData(trainPaths)
trainData = np.reshape(trainData,(95000,imageWidth,imageHeight,1)).astype('float32')
trainData = (trainData-255)/float(255)

#train the convnet***
model.fit(trainData, trainLabels, batch_size=500, epochs=50, validation_split=0.2)

#/save the model and weights*/
model.save('myConvnet_model5.h5');
model.save_weights('myConvnet_weights5.h5');
8
TriniPhantom

これまで何度もこの問題に遭遇したので、少し要約して将来の人々を助けるための可能な解決策などを考えます。

問題:モデルは、表示するすべてのデータについて、2つ(またはそれ以上)の可能なクラスの1つを予測します*

問題が発生していることを確認しています方法1:モデルの精度は、トレーニング中に約0.5のままです(または1/n(nは数値))クラスの)。 方法2:予測の各クラスの数を取得し、それがすべての1つのクラスを予測していることを確認します。

修正/チェック(ある程度の順序で):

  • モデルアーキテクチャのダブルチェックmodel.summary()を使用して、モデルを検査します。
  • データラベルの確認:前処理などでトレインデータのラベル付けがどこかで混同されていないことを確認してください(発生します!)
  • 列車データのフィードがランダムにチェックされる:一度に1つのクラスでモデルに列車データをフィードしていないことを確認します。たとえば、ImageDataGenerator().flow_from_directory(PATH)を使用している場合は、そのパラメータshuffle=Trueとそのbatch_sizeは1より大きい。
  • 事前トレーニング済みレイヤーがトレーニング可能でないことを確認:**事前トレーニング済みモデルを使用している場合、事前トレーニング済みの重みを使用するレイヤーが最初はでないことを確認してくださいトレーニング可能。最初のエポックでは、新しく追加された(ランダムに初期化された)レイヤーのみがトレーニング可能である必要があります。 for layer in pretrained_model.layers: layer.trainable = Falseはコードのどこかにあるはずです。
  • ランプダウン学習率:学習率を10分の1に減らし、再試行します。新しい学習率を試すたびに、トレーニングしようとしているレイヤーを完全に再初期化する必要があることに注意してください。 (たとえば、私はこの問題を抱えていましたが、lr=1e-6、続けてください!)

モデルトレーニングを適切に取得できる可能性のある修正やチェックについて知っている人がいれば、投稿してください。リストを更新します。

**新しいレイヤーが最初に「十分」にトレーニングされたら、トレーニング済みモデルをさらにトレーニング可能にするのが一般的です。

*検索がここに到達するのを助けるための問題のその他の名前... keras tensorflow theano CNN畳み込みニューラルネットワーク悪いトレーニングが動かない固定されていない壊れていないバグが詰まっている詰まったトレーニング最適化最適化のみ0.5の変化は変化しないエポックケラスCNNの同じ出力間で自身をリセットするクラスモデル

15
DBCerigo

私はいくつかのことを試してみました。より低い学習率はより多くのデータに役立ちます。一般に、オプティマイザを適合させると役立ちます。さらに、ネットワークは非常に小さいようです。レイヤーを追加するか、レイヤー内のフィルターの数を増やすことで、モデルの容量を増やすことができます。

ディープラーニングを実際に適用する方法についてのより良い説明がここにあります:( http://www.deeplearningbook.org/contents/guidelines.html )。

2
Thomas Pinetz

BatchNornmalization()の後にMaxPooling2D()レイヤーを追加してみてください。それは私にはうまくいきます。

2
tangerine

私は、DBCerigoのすばらしいリストにさらに2つ追加する必要があります。

  • アクティベーション関数を確認する:一部のレイヤーにはデフォルトでlinearアクティベーション関数があります。モデルに非線形性を挿入しないと、一般化できなくなり、ネットが学習しようとします。線形ではない特徴空間を線形に分離する方法。非線形性のセットがあることを確認することは良いチェックポイントです。
  • モデルの複雑度をチェック:比較的単純なモデルがあり、1番目または2番目のエポックまでしか学習せず、その後停止する場合は、複雑すぎるものを学習しようとしている可能性があります。モデルをさらに深くしてみてください。これは通常、1つまたは2つのレイヤーのみがフリーズされていないフリーズモデルで作業しているときに発生します。

2番目は明白かもしれませんが、私は彼の問題に一度遭遇し、理解する前にすべて(データ、バッチ、LR ...)をチェックする多くの時間を失いました。

お役に立てれば

0
JVGD