Deep learning 使用预先训练的VGG16模型时无法保存权重

Deep learning 使用预先训练的VGG16模型时无法保存权重,deep-learning,keras,Deep Learning,Keras,使用预先训练过的VGG16模型时,我无法保存最佳模型的权重。我使用以下代码: checkpointer = [ # Stop if the accuracy is not improving after 7 iterations EarlyStopping(monitor='val_loss', patience=3, verbose=1), # Saving the best model and r

使用预先训练过的VGG16模型时,我无法保存最佳模型的权重。我使用以下代码:

checkpointer = [
                # Stop if the accuracy is not improving after 7 iterations
                EarlyStopping(monitor='val_loss', patience=3, verbose=1),
                # Saving the best model and re-use it while prediction 
                ModelCheckpoint(filepath="C:/Users/skumarravindran/Documents/keras_save_model/vgg16_v1.hdf5", verbose=1, monitor='val_acc', save_best_only=True),
                #            
]
我得到以下错误:

C:\Users\skumarravindran\AppData\Local\Continuum\Anaconda2\envs\py35gpu1\lib\site packages\keras\callbacks.py:405:RuntimeWarning:只能在val\u acc可用的情况下保存最佳模型,跳过。 “正在跳过”。%(self.monitor),运行时警告)


通过使用以下代码,您将能够根据精度保存最佳模型

请使用以下代码:

model.compile(loss='categorical_crossentropy', optimizer= 'adam',
          metrics=['accuracy'])

history = model.fit_generator(
    train_datagen.flow(x_train, y_train, batch_size=batch_size),
    steps_per_epoch=x_train.shape[0] // batch_size,
    epochs=epochs,
    callbacks=[ModelCheckpoint('VGG16-transferlearning.model', monitor='val_acc', save_best_only=True)]
)

我经历了两种出现此错误的情况:

  • 引入自定义度量
  • 使用多个输出
  • 在这两种情况下,
    acc
    val_acc
    都不计算。奇怪的是,Keras确实计算了总体
    损失
    valu损失

    您可以通过在度量中添加
    准确性
    来纠正第一种情况,但我不确定这可能会有副作用。但是,在这两种情况下,您都可以在回调中自己添加
    acc
    val_acc
    。我为多输出案例添加了一个示例,其中我创建了一个自定义回调,通过对输出层的所有val和val_acc进行平均,计算我自己的
    acc
    val_acc
    结果

    我有一个模型,末尾有5个密集的输出层,标记为D0..D4。一个历元的输出如下:

    3540/3540 [==============================] - 21s 6ms/step - loss: 14.1437 - 
    D0_loss: 3.0446 - D1_loss: 2.6544 - D2_loss: 3.0808 - D3_loss: 2.7751 -
    D4_loss: 2.5889 - D0_acc: 0.2362 - D1_acc: 0.3681 - D2_acc: 0.1542 - D3_acc: 0.1161 - 
    D4_acc: 0.3994 - val_loss: 8.7598 - val_D0_loss: 2.0797 - val_D1_loss: 1.4088 - 
    val_D2_loss: 2.0711 - val_D3_loss: 1.9064 - val_D4_loss: 1.2938 - 
    val_D0_acc: 0.2661 - val_D1_acc: 0.3924 - val_D2_acc: 0.1763 - 
    val_D3_acc: 0.1695 - val_D4_acc: 0.4627
    
    如您所见,它输出整体
    损耗
    val_损耗
    ,并且对于每个输出层:Di_损耗、Di_acc、val_Di_损耗和val_Di_acc,对于0..4中的i。所有这些都是
    日志
    字典的内容,它作为参数在回调的
    on\u epoch\u begin
    on\u epoch\u end
    中传输。回调有更多的事件处理程序,但就我们的目的而言,这两个是最相关的。当您有5个输出(如我的情况)时,字典的大小是5乘以4(acc,loss,val_acc,val_loss)+2(loss+val_loss)

    我所做的是计算所有精度和验证精度的平均值,将两项添加到
    日志中

    logs['acc'] = som_acc / n_accs
    logs['val_acc'] = som_val_acc / n_accs
    
    确保在检查点回调之前添加此回调,否则您提供的额外信息将不会被“看到”。如果所有这些都正确实现,错误消息将不再出现,并且模型正在检查点。 下面提供了我针对多输出情况的回调代码

        class ExtraLogInfo(keras.callbacks.Callback):
            def on_epoch_begin(self, epoch, logs):
                self.timed = time.time()
    
                return
    
            def on_epoch_end(self, epoch, logs):
                print(logs.keys())
                som_acc = 0.0
                som_val_acc = 0.0
                n_accs = (len(logs) - 2) // 4
                for i in range(n_accs):
                    acc_ptn = 'D{:d}_acc'.format(i)
                    val_acc_ptn = 'val_D{:d}_acc'.format(i)
                    som_acc += logs[acc_ptn]
                    som_val_acc += logs[val_acc_ptn]
    
                logs['acc'] = som_acc / n_accs
                logs['val_acc'] = som_val_acc / n_accs
                logs['time'] = time.time() - self.timed
    
                return
    

    您的
    模型.compile()
    行中是否有
    metrics=['acc']
    ?在使用自定义度量或多输出模型时没有。