私のトレーニングと損失曲線は以下のようになります。はい、同様のグラフに「古典的なオーバーフィッティング」などのコメントが寄せられています。
私のモデルは以下のようになります
input_shape_0 = keras.Input(shape=(3,100, 100, 1), name="img3")
model = tf.keras.layers.TimeDistributed(Conv2D(8, 3, activation="relu"))(input_shape_0)
model = tf.keras.layers.TimeDistributed(Dropout(0.3))(model)
model = tf.keras.layers.TimeDistributed(MaxPooling2D(2))(model)
model = tf.keras.layers.TimeDistributed(Conv2D(16, 3, activation="relu"))(model)
model = tf.keras.layers.TimeDistributed(MaxPooling2D(2))(model)
model = tf.keras.layers.TimeDistributed(Conv2D(32, 3, activation="relu"))(model)
model = tf.keras.layers.TimeDistributed(MaxPooling2D(2))(model)
model = tf.keras.layers.TimeDistributed(Dropout(0.3))(model)
model = tf.keras.layers.TimeDistributed(Flatten())(model)
model = tf.keras.layers.TimeDistributed(Dropout(0.4))(model)
model = LSTM(16, kernel_regularizer=tf.keras.regularizers.l2(0.007))(model)
# model = Dense(100, activation="relu")(model)
# model = Dense(200, activation="relu",kernel_regularizer=tf.keras.regularizers.l2(0.001))(model)
model = Dense(60, activation="relu")(model)
# model = Flatten()(model)
model = Dropout(0.15)(model)
out = Dense(30, activation='softmax')(model)
model = keras.Model(inputs=input_shape_0, outputs = out, name="mergedModel")
def get_lr_metric(optimizer):
def lr(y_true, y_pred):
return optimizer.lr
return lr
opt = tf.keras.optimizers.RMSprop()
lr_metric = get_lr_metric(opt)
# merged.compile(loss='sparse_categorical_crossentropy',
optimizer='adam', metrics=['accuracy'])
model.compile(loss='sparse_categorical_crossentropy',
optimizer=opt, metrics=['accuracy',lr_metric])
model.summary()
上記のモデル構築コードで、コメント行をこれまでに試したアプローチの一部と考えてください。
この種の質問に対する回答とコメントとして与えられた提案に従いましたが、どれもうまくいかないようです。たぶん私は本当に重要なものを見逃していますか?
私が試したこと:
- さまざまな場所でさまざまな量のドロップアウト。
- 高密度レイヤーの包含と排除とそのユニット数で遊んだ。
- LSTM レイヤーのユニット数をさまざまな値で試しました (1 から始めて、現在は 16 で、最高のパフォーマンスが得られています)。
- 重みの正則化手法に出くわし、上記のコードに示すようにそれらを実装しようとしたため、さまざまなレイヤーに配置しようとしました(単純な試行錯誤の代わりに、それを使用する必要がある手法を知る必要があります-これは私がしたこととそれは間違っているようです)
- 一定数のエポックの後にエポックが進行するにつれて学習率を下げる学習率スケジューラーを実装しました。
- return_sequences = true を持つ最初のレイヤーで 2 つの LSTM レイヤーを試しました。
これらすべての後、私はまだオーバーフィッティングの問題を克服できません。私のデータセットは適切にシャッフルされ、80/20 のトレイン/ヴァル比率で分割されます。
データ拡張は、私がまだ試していない一般的に示唆されているもう 1 つのことですが、これまでに間違いを犯していないかどうかを確認し、それを修正して、今のところデータ拡張の手順に飛び込むことを避けたいと考えています。私のデータセットのサイズは次のとおりです。
Training images: 6780
Validation images: 1484
表示されている数字はサンプルで、各サンプルには 3 つの画像があります。基本的にCNN
、モデルの説明に示されているように、3 つのメイジを一度に 1 つのサンプルとして時間分散に入力し、その後に他のレイヤーを入力します。それに続いて、トレーニング画像は 6780 * 3 で、検証画像は 1484 * 3 です。各画像は 100 * 100 で、チャネル 1 にあります。
RMS prop
テストよりも優れたパフォーマンスのオプティマイザーとして使用してadam
います
アップデート
いくつかの異なるアーキテクチャといくつかの再正規化とドロップアウトをさまざまな場所で試しましたが、新しいモデルである 59% 以下の val_acc を達成できるようになりました。
# kernel_regularizer=tf.keras.regularizers.l2(0.004)
# kernel_constraint=max_norm(3)
model = tf.keras.layers.TimeDistributed(Conv2D(32, 3, activation="relu"))(input_shape_0)
model = tf.keras.layers.TimeDistributed(Dropout(0.3))(model)
model = tf.keras.layers.TimeDistributed(MaxPooling2D(2))(model)
model = tf.keras.layers.TimeDistributed(Conv2D(64, 3, activation="relu"))(model)
model = tf.keras.layers.TimeDistributed(MaxPooling2D(2))(model)
model = tf.keras.layers.TimeDistributed(Conv2D(128, 3, activation="relu"))(model)
model = tf.keras.layers.TimeDistributed(MaxPooling2D(2))(model)
model = tf.keras.layers.TimeDistributed(Dropout(0.3))(model)
model = tf.keras.layers.TimeDistributed(GlobalAveragePooling2D())(model)
model = LSTM(128, return_sequences=True,kernel_regularizer=tf.keras.regularizers.l2(0.040))(model)
model = Dropout(0.60)(model)
model = LSTM(128, return_sequences=False)(model)
model = Dropout(0.50)(model)
out = Dense(30, activation='softmax')(model)