首页 文章

加载vgg16_weights.h5时如何使用vgg-net?

提问于
浏览
4

我使用keras的VGG-16网络 . 这是detail

我的问题是如何使用这个网进行微调,我必须使用这个网络的224 * 224的图像大小?我使用这个网时必须使用1000个课程?如果我不使用1000个类,则会导致错误

例外:层形状(4096L,10L)与重量形状(4096,1000)不兼容 .

求助,谢谢!

1 回答

  • 5

    如果你想看看,我发布了详细的答案in this issue . 以下代码段将帮助您了解最后一个图层的尺寸:

    from keras.models import Sequential, Graph
    from keras.layers import Convolution2D, ZeroPadding2D, MaxPooling2D
    import keras.backend as K
    
    img_width, img_height = 128, 128
    
    # build the VGG16 network with our input_img as input
    first_layer = ZeroPadding2D((1, 1), input_shape=(3, img_width, img_height))
    
    model = Sequential()
    model.add(first_layer)
    model.add(Convolution2D(64, 3, 3, activation='relu', name='conv1_1'))
    model.add(ZeroPadding2D((1, 1)))
    model.add(Convolution2D(64, 3, 3, activation='relu', name='conv1_2'))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    model.add(ZeroPadding2D((1, 1)))
    model.add(Convolution2D(128, 3, 3, activation='relu', name='conv2_1'))
    model.add(ZeroPadding2D((1, 1)))
    model.add(Convolution2D(128, 3, 3, activation='relu', name='conv2_2'))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    model.add(ZeroPadding2D((1, 1)))
    model.add(Convolution2D(256, 3, 3, activation='relu', name='conv3_1'))
    model.add(ZeroPadding2D((1, 1)))
    model.add(Convolution2D(256, 3, 3, activation='relu', name='conv3_2'))
    model.add(ZeroPadding2D((1, 1)))
    model.add(Convolution2D(256, 3, 3, activation='relu', name='conv3_3'))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    model.add(ZeroPadding2D((1, 1)))
    model.add(Convolution2D(512, 3, 3, activation='relu', name='conv4_1'))
    model.add(ZeroPadding2D((1, 1)))
    model.add(Convolution2D(512, 3, 3, activation='relu', name='conv4_2'))
    model.add(ZeroPadding2D((1, 1)))
    model.add(Convolution2D(512, 3, 3, activation='relu', name='conv4_3'))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    model.add(ZeroPadding2D((1, 1)))
    model.add(Convolution2D(512, 3, 3, activation='relu', name='conv5_1'))
    model.add(ZeroPadding2D((1, 1)))
    model.add(Convolution2D(512, 3, 3, activation='relu', name='conv5_2'))
    model.add(ZeroPadding2D((1, 1)))
    model.add(Convolution2D(512, 3, 3, activation='relu', name='conv5_3'))
    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
    
    # get the symbolic outputs of each "key" layer (we gave them unique names).
    layer_dict = dict([(layer.name, layer) for layer in model.layers])
    
    # load the weights
    
    import h5py
    
    weights_path = 'vgg16_weights.h5'
    
    f = h5py.File(weights_path)
    for k in range(f.attrs['nb_layers']):
        if k >= len(model.layers):
            # we don't look at the last (fully-connected) layers in the savefile
            break
        g = f['layer_{}'.format(k)]
        weights = [g['param_{}'.format(p)] for p in range(g.attrs['nb_params'])]
        model.layers[k].set_weights(weights)
    f.close()
    print('Model loaded.')
    
    # Here is what you want:
    
    graph_m = Graph()
    graph_m.add_input('my_inp', input_shape=(3, img_width, img_height))
    graph_m.add_node(model, name='your_model', input='my_inp')
    graph_m.add_node(Flatten(), name='Flatten', input='your_model')
    graph_m.add_node(Dense(4096, activation='relu'), name='Dense1',      input='Flatten')
    graph_m.add_node(Dropout(0.5), name='Dropout1', input='Dense1')
    graph_m.add_node(Dense(4096, activation='relu'), name='Dense2',  input='Dropout1')
    graph_m.add_node(Dropout(0.5), name='Dropout2', input='Dense2')
    graph_m.add_node(Dense(10, activation='softmax'), name='Final', input='Dropout2')
    graph_m.add_output(name='out1', input='Final')
    sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
    graph_m.compile(optimizer=sgd, loss={'out1': 'categorical_crossentropy'})
    

    请注意,您可以冻结特征提取图层的训练,并仅微调最后完全连接的图层 . 从doc开始,您只需添加 trainable = False 即可冻结图层的训练 . 前冻结:

    ...
    model.add(Convolution2D(512, 3, 3, activation='relu', name='conv5_1', trainable=False))
    ...
    

    可训练:

    ...
    model.add(Convolution2D(512, 3, 3, activation='relu', name='conv5_1',     trainable=True))
    ...
    

    trainable 默认为 True ,以便在您不了解该功能时发生某些事情......

相关问题