如何在Keras中微调功能模型?

时间:2018-12-23 22:37:43

标签: python tensorflow keras

在Keras中使用预训练模型并替换顶层分类层以将网络重新训练为新任务,其中有几个在Keras中使用顺序模型的示例。顺序模型具有方法model.pop()model.add(),这使这相当容易。

但是,使用功能模型如何实现?该框架没有方法model.add()

如何在Keras中加载经过预训练的功能模型,裁剪最后一层并替换为新层?

到目前为止的当前方法:

model.load_weights('/my_model_weights.h5')

def pop_layer(model):
    if not model.outputs:
    raise Exception('Sequential model cannot be popped: model is empty.')

    model.layers.pop()
    if not model.layers:
        model.outputs = []
        model.inbound_nodes = []
        model.outbound_nodes = []
    else:
        model.layers[-1].outbound_nodes = []
        model.outputs = [model.layers[-1].output]
    model.built = False

# Remove last layer with custom function (from another post)
pop_layer(model)

# Now add a new layer to the model ???

model.add(Dense(2, activation='softmax', name='fc2'))
model.compile(loss='sparse_categorical_crossentropy', optimizer='sgd',
              metrics=['accuracy'])
  

AttributeError:“模型”对象没有属性“添加”

1 个答案:

答案 0 :(得分:2)

您可以使用预先训练的功能模型,并删除最后一层作为图层。您可能会认为模型是“更大的层”。然后重新定义一个包含“更大的图层”和新图层的新模型。

一个例子:

import tensorflow as tf
from keras.layers import Dense,Input
from keras.models import Sequential,Model

input_tensor = Input(shape=(64,))
x = Dense(32, activation='relu')(input_tensor)
x = Dense(32, activation='relu')(x)
output_tensor = Dense(10, activation=tf.nn.softmax)(x)
model = Model(input_tensor, output_tensor)
model.compile(loss='sparse_categorical_crossentropy', optimizer='sgd',
              metrics=['accuracy'])
print(model.summary())
model.save_weights('my_model_weights.h5')
# 
model.load_weights('my_model_weights.h5')

def pop_layer(model):
    if not model.outputs:
        raise Exception('Sequential model cannot be popped: model is empty.')
    model.layers.pop()
    if not model.layers:
        model.outputs = []
        model.inbound_nodes = []
        model.outbound_nodes = []
    else:
        model.layers[-1].outbound_nodes = []
        model.outputs = [model.layers[-1].output]
    return model

# Remove last layer with custom function (from another post)
model_old = pop_layer(model)
# Now add a new layer to the model
model_new = Sequential()
model_new.add(model_old)
model_new.add(Dense(2, activation=tf.nn.softmax, name='fc2'))
model_new.compile(loss='sparse_categorical_crossentropy', optimizer='sgd',
              metrics=['accuracy'])
print(model_new.summary())

结果,您会看到缺少预训练功能模型的最后一层的参数。

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 64)                0         
_________________________________________________________________
dense_1 (Dense)              (None, 32)                2080      
_________________________________________________________________
dense_2 (Dense)              (None, 32)                1056      
_________________________________________________________________
dense_3 (Dense)              (None, 10)                330       
=================================================================
Total params: 3,466
Trainable params: 3,466
Non-trainable params: 0
_________________________________________________________________
None

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
model_1 (Model)              multiple                  3136      
_________________________________________________________________
fc2 (Dense)                  (None, 2)                 66        
=================================================================
Total params: 3,202
Trainable params: 3,202
Non-trainable params: 0
_________________________________________________________________
None