左と右の靴型分類のために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');
これまで何度もこの問題に遭遇したので、少し要約して将来の人々を助けるための可能な解決策などを考えます。
問題:モデルは、表示するすべてのデータについて、2つ(またはそれ以上)の可能なクラスの1つを予測します*
問題が発生していることを確認しています:方法1:モデルの精度は、トレーニング中に約0.5のままです(または1/n(nは数値))クラスの)。 方法2:予測の各クラスの数を取得し、それがすべての1つのクラスを予測していることを確認します。
修正/チェック(ある程度の順序で):
model.summary()
を使用して、モデルを検査します。ImageDataGenerator().flow_from_directory(PATH)
を使用している場合は、そのパラメータshuffle=True
とそのbatch_size
は1より大きい。for layer in pretrained_model.layers: layer.trainable = False
はコードのどこかにあるはずです。lr=1e-6
、続けてください!)モデルトレーニングを適切に取得できる可能性のある修正やチェックについて知っている人がいれば、投稿してください。リストを更新します。
**新しいレイヤーが最初に「十分」にトレーニングされたら、トレーニング済みモデルをさらにトレーニング可能にするのが一般的です。
*検索がここに到達するのを助けるための問題のその他の名前... keras tensorflow theano CNN畳み込みニューラルネットワーク悪いトレーニングが動かない固定されていない壊れていないバグが詰まっている詰まったトレーニング最適化最適化のみ0.5の変化は変化しないエポックケラスCNNの同じ出力間で自身をリセットするクラスモデル
私はいくつかのことを試してみました。より低い学習率はより多くのデータに役立ちます。一般に、オプティマイザを適合させると役立ちます。さらに、ネットワークは非常に小さいようです。レイヤーを追加するか、レイヤー内のフィルターの数を増やすことで、モデルの容量を増やすことができます。
ディープラーニングを実際に適用する方法についてのより良い説明がここにあります:( http://www.deeplearningbook.org/contents/guidelines.html )。
BatchNornmalization()
の後にMaxPooling2D()
レイヤーを追加してみてください。それは私にはうまくいきます。
私は、DBCerigoのすばらしいリストにさらに2つ追加する必要があります。
linear
アクティベーション関数があります。モデルに非線形性を挿入しないと、一般化できなくなり、ネットが学習しようとします。線形ではない特徴空間を線形に分離する方法。非線形性のセットがあることを確認することは良いチェックポイントです。2番目は明白かもしれませんが、私は彼の問題に一度遭遇し、理解する前にすべて(データ、バッチ、LR ...)をチェックする多くの時間を失いました。
お役に立てれば