代码之家  ›  专栏  ›  技术社区  ›  geometrikal

在Keras中用迁移学习训练CNN-图像输入不起作用,但向量输入起作用

  •  1
  • geometrikal  · 技术社区  · 7 年前

    我想在Keras做迁移学习。我设置了一个ResNet50网络,设置为不可训练,带有一些额外的层:

    # Image input
    model = Sequential()
    model.add(ResNet50(include_top=False, pooling='avg')) # output is 2048
    model.add(Dropout(0.05))
    model.add(Dense(512, activation='relu'))
    model.add(Dropout(0.15))
    model.add(Dense(512, activation='relu'))
    model.add(Dense(7, activation='softmax'))
    model.layers[0].trainable = False
    model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
    model.summary()
    

    然后我创建输入数据: x_batch 使用ResNet50 preprocess_input y_batch 并按如下方式安装:

    model.fit(x_batch,
              y_batch,
              epochs=nb_epochs,
              batch_size=64,
              shuffle=True,
              validation_split=0.2,
              callbacks=[lrate])
    

    经过10个周期左右的训练,训练准确率接近100%,但随着验证损失的不断增加,验证准确率实际上从50%左右下降到30%。

    但是,如果我创建一个仅包含最后几层的网络:

    # Vector input
    model2 = Sequential()
    model2.add(Dropout(0.05, input_shape=(2048,)))
    model2.add(Dense(512, activation='relu'))
    model2.add(Dropout(0.15))
    model2.add(Dense(512, activation='relu'))
    model2.add(Dense(7, activation='softmax'))
    model2.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
    model2.summary()
    

    并输入ResNet50预测的输出:

    resnet = ResNet50(include_top=False, pooling='avg')
    x_batch = resnet.predict(x_batch)
    

    更新:

    这个问题真奇怪。如果我把ResNet50改成VGG19,它看起来可以工作。

    1 回复  |  直到 7 年前
        1
  •  1
  •   geometrikal    7 年前

    在Keras中有一个pull请求来修复此问题 here ,更详细地解释了:

    这意味着BN层正在根据训练数据进行调整,但是在执行验证时,使用BN层的原始参数。据我所知,修复方法是允许冻结的BN层使用训练中更新的均值和方差。

    解决方法是预先计算ResNet输出。事实上,这大大减少了训练时间,因为我们不会重复这部分计算。

        2
  •  0
  •   Amara Miloudi    7 年前

    您可以尝试:

    Res = keras.applications.resnet.ResNet50(include_top=False, 
                  weights='imagenet',  input_shape=(IMG_SIZE , IMG_SIZE , 3 ) )
    
    
        # Freeze the layers except the last 4 layers
    for layer in vgg_conv.layers  :
       layer.trainable = False
    
    # Check the trainable status of the individual layers
    for layer in vgg_conv.layers:
        print(layer, layer.trainable)
    
    # Vector input
    model2 = Sequential()
    model2.add(Res)
    model2.add(Flatten())
    model2.add(Dropout(0.05 ))
    model2.add(Dense(512, activation='relu'))
    model2.add(Dropout(0.15))
    model2.add(Dense(512, activation='relu'))
    model2.add(Dense(7, activation='softmax'))
    model2.compile(optimizer='adam', loss='categorical_crossentropy', metrics =(['accuracy'])
    model2.summary()
    
    推荐文章