簡體   English   中英

良好的訓練/驗證准確度,但測試准確度差

[英]Good training/validation accuracy but poor test accuracy

我訓練了一個 model 使用 VGG16 預訓練的 model 對 4 種眼部疾病進行分類。 我對機器學習還很陌生,所以不知道如何從結果中得出結論。 在 90,000 張圖像上訓練了大約 6 個小時后:

  • 訓練准確率和損失不斷增加(從大約 2 到 0.8 以 88% 的准確率結束)

  • 驗證損失在每個 epoch 1-2 之間波動(准確度確實提高到 85%)(我不小心重新運行了單元,所以看不到輸出)

查看混淆矩陣后,我的測試似乎表現不佳

Image_height = 196
Image_width = 300
val_split = 0.2
batches_size = 10
lr = 0.0001
spe = 512
vs = 32
epoch = 10

#Creating batches
#Creating batches
train_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input,validation_split=val_split) \
    .flow_from_directory(directory=train_folder, target_size=(Image_height,Image_width), classes=['CNV','DME','DRUSEN','NORMAL'], batch_size=batches_size,class_mode="categorical",
                              subset="training")
validation_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input,validation_split=val_split) \
    .flow_from_directory(directory=train_folder, target_size=(Image_height,Image_width), classes=['CNV','DME','DRUSEN','NORMAL'], batch_size=batches_size,class_mode="categorical",
                              subset="validation")
test_batches = ImageDataGenerator(preprocessing_function=tf.keras.applications.vgg16.preprocess_input) \
                       .flow_from_directory(test_folder, target_size=(Image_height,Image_width), 
                         classes=['CNV','DME','DRUSEN','NORMAL'], batch_size=batches_size,class_mode="categorical")

#Function to create model. We will be using a pretrained model
def create():
  vgg16_model = keras.applications.vgg16.VGG16(input_tensor=Input(shape=(Image_height, Image_width, 3)),input_shape=(Image_height,Image_width,3), include_top = False)
  model = Sequential()
  model.add(vgg16_model)
  for layer in model.layers:
    layer.trainable = False
  model.add(Flatten())
  model.add(Dense(4, activation='softmax'))
  return model

model = create()
model.compile(Adam(lr=lr),loss="categorical_crossentropy",metrics=['accuracy'])

model.fit(train_batches, steps_per_epoch=spe,
                    validation_data=validation_batches,validation_steps=vs, epochs=epoch)

在此處輸入圖像描述

關於我可以改進的任何建議,以便混淆矩陣做得不那么差? 如果可能的話,我還保存了 model,只需用更多層重新訓練它。

除了最后一層,您不訓練任何層。 您需要將訓練能力設置為最后幾層或添加更多層。

添加

tf.keras.applications.VGG16(... weights='imagenet'... )

在您的代碼中,權重沒有在任何集合上進行預訓練。

此處解釋了可用的選項:

https://www.tensorflow.org/api_docs/python/tf/keras/applications/VGG16

一些問題和建議。 您正在使用 VGG16 model。 model 有超過 4000 萬個可訓練參數。 在包含 90,000 張圖像的數據集上,您的訓練時間將非常長。 所以我建議你考慮使用 MobileNet model。 它只有 400 萬個可訓練參數,基本上和 VGG16 一樣准確。 文檔在 [這里][1] 接下來,無論您使用哪個 model,您都應該將初始權重設置為 imagenet 權重。 您的 model 將開始對圖像進行訓練。我發現通過使 model 中的所有層都可訓練可以得到更好的結果。 現在你說你的 model 達到了 88% 的准確度。 我不認為這很好。 我相信你至少需要達到 95%。 您可以通過使用可調整的學習率來做到這一點。 keras 回調 ReduceLROnPlateau 使這變得容易。 文檔在 [here.][2] 設置它以監控驗證損失並在連續時期未能降低學習率時降低學習率。 接下來,您要保存具有最低驗證損失的 model 並使用它來進行預測。 可以設置 Keras 回調 ModelCheckpoint 來監控驗證損失,並保存損失最低的 model。 文檔在[這里][3]。 下面的代碼顯示了如何針對您的問題實施 MobileNet model 並定義回調。 您還必須更改生成器以使用 Mobilenet 預處理並將目標大小設置為 (224,224)。 另外我相信你在預處理 function 周圍缺少 () 希望這有幫助..

mobile = tf.keras.applications.mobilenet.MobileNet( include_top=False,
                                                           input_shape=(224, 224,3),
                                                           pooling='max', weights='imagenet',
                                                           alpha=1, depth_multiplier=1,dropout=.5)                                                          
x=mobile.layers[-1].output
x=keras.layers.BatchNormalization(axis=-1, momentum=0.99, epsilon=0.001 )(x)
predictions=Dense (4, activation='softmax')(x)
model = Model(inputs=mobile.input, outputs=predictions)    
for layer in model.layers:
    layer.trainable=True
model.compile(Adamax(lr=lr), loss='categorical_crossentropy', metrics=['accuracy'])
checkpoint=tf.keras.callbacks.ModelCheckpoint(filepath=save_loc, monitor='val_loss', verbose=0, save_best_only=True,
    save_weights_only=False, mode='auto', save_freq='epoch', options=None)
lr_adjust=tf.keras.callbacks.ReduceLROnPlateau( monitor="val_loss", factor=0.5, patience=1, verbose=0, mode="auto",
    min_delta=0.00001,  cooldown=0,  min_lr=0) 
callbacks=[checkpoint, lr_adjust]


  [1]: http://httphttps://keras.io/api/applications/mobilenet/s://
  [2]: https://keras.io/api/callbacks/reduce_lr_on_plateau/
  [3]: https://keras.io/api/callbacks/model_checkpoint/

在向 model 添加層時,您必須刪除 model 的最后一個密集層,因為您的 model 有四個類,但 vgg16 有 1000 個密集層然后刪除最后一個密集層,所以您有:

def create():
    vgg16_model = keras.applications.vgg16.VGG16(input_tensor=Input(shape=(Image_height, Image_width, 3)),input_shape=(Image_height,Image_width,3), include_top = False)

    model = Sequential()
    for layer in vgg16_model.layers[:-1]:
        model.add(layer)
    model.summary()

    for layer in model.layers:
        layer.trainable = False
    model.add(Flatten())
    model.add(Dense(4, activation='softmax'))

    return model

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM