如何在加载权重后在keras中添加和删除新图层?

时间:2017-01-16 02:56:47

标签: python theano keras keras-layer

我正在尝试进行转学习;为此我想删除神经网络的最后两层并添加另外两层。这是一个示例代码,它也输出相同的错误。

from keras.models import Sequential
from keras.layers import Input,Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.layers.core import Dropout, Activation
from keras.layers.pooling import GlobalAveragePooling2D
from keras.models import Model

in_img = Input(shape=(3, 32, 32))
x = Convolution2D(12, 3, 3, subsample=(2, 2), border_mode='valid', name='conv1')(in_img)
x = Activation('relu', name='relu_conv1')(x)
x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool1')(x)
x = Convolution2D(3, 1, 1, border_mode='valid', name='conv2')(x)
x = Activation('relu', name='relu_conv2')(x)
x = GlobalAveragePooling2D()(x)
o = Activation('softmax', name='loss')(x)
model = Model(input=in_img, output=[o])
model.compile(loss="categorical_crossentropy", optimizer="adam")
#model.load_weights('model_weights.h5', by_name=True)
model.summary()

model.layers.pop()
model.layers.pop()
model.summary()
model.add(MaxPooling2D())
model.add(Activation('sigmoid', name='loss'))

我使用pop()删除了图层,但当我尝试添加其输出此错误时

  

AttributeError:'Model'对象没有属性'add'

我知道错误的最可能原因是model.add()的使用不当。我应该使用哪种其他语法?

修改

我尝试在keras中删除/添加图层但是在加载外部权重后不允许添加图层。

from keras.models import Sequential
from keras.layers import Input,Flatten
from keras.layers.convolutional import Convolution2D, MaxPooling2D
from keras.layers.core import Dropout, Activation
from keras.layers.pooling import GlobalAveragePooling2D
from keras.models import Model
in_img = Input(shape=(3, 32, 32))

def gen_model():
    in_img = Input(shape=(3, 32, 32))
    x = Convolution2D(12, 3, 3, subsample=(2, 2), border_mode='valid', name='conv1')(in_img)
    x = Activation('relu', name='relu_conv1')(x)
    x = MaxPooling2D(pool_size=(3, 3), strides=(2, 2), name='pool1')(x)
    x = Convolution2D(3, 1, 1, border_mode='valid', name='conv2')(x)
    x = Activation('relu', name='relu_conv2')(x)
    x = GlobalAveragePooling2D()(x)
    o = Activation('softmax', name='loss')(x)
    model = Model(input=in_img, output=[o])
    return model

#parent model
model=gen_model()
model.compile(loss="categorical_crossentropy", optimizer="adam")
model.summary()

#saving model weights
model.save('model_weights.h5')

#loading weights to second model
model2=gen_model()
model2.compile(loss="categorical_crossentropy", optimizer="adam")
model2.load_weights('model_weights.h5', by_name=True)

model2.layers.pop()
model2.layers.pop()
model2.summary()

#editing layers in the second model and saving as third model
x = MaxPooling2D()(model2.layers[-1].output)
o = Activation('sigmoid', name='loss')(x)
model3 = Model(input=in_img, output=[o])

显示此错误

RuntimeError: Graph disconnected: cannot obtain value for tensor input_4 at layer "input_4". The following previous layers were accessed without issue: []

5 个答案:

答案 0 :(得分:41)

您可以使用最后一个模型的output并创建一个新模型。较低的层保持不变。

model.summary()
model.layers.pop()
model.layers.pop()
model.summary()

x = MaxPooling2D()(model.layers[-1].output)
o = Activation('sigmoid', name='loss')(x)

model2 = Model(input=in_img, output=[o])
model2.summary()

检查How to use models from keras.applications for transfer learnig?

更新编辑:

新错误是因为您正在尝试在全局in_img上创建新模型,而该模型实际上并未在之前的模型创建中使用过..您实际上是在定义本地in_img。因此,全局in_img显然没有连接到符号图中的上层。它与加载重量无关。

为了更好地解决此问题,您应该使用model.input来引用输入。

model3 = Model(input=model2.input, output=[o])

答案 1 :(得分:6)

另一种方法

from keras.models import Model

layer_name = 'relu_conv2'
model2= Model(inputs=model1.input, outputs=model1.get_layer(layer_name).output)

答案 2 :(得分:6)

作为Wesam Na答案的替代方法,如果您不知道图层名称,则可以通过以下方法简单地切断最后一层:

from keras.models import Model

model2= Model(inputs=model1.input, outputs=model1.layers[-2].output)

答案 3 :(得分:2)

从Keras 2.3.1和TensorFlow 2.0开始,model.layers.pop()不能按预期运行(请参阅问题here)。他们提出了两种选择方法。

一个选项是重新创建模型并复制图层。例如,如果要删除最后一层并添加另一层,可以执行以下操作:

model = Sequential()
for layer in source_model.layers[-1]:
    model.add(layer)
model.add(Dense(3, activation='softmax'))
model.summary()
model.compile(optimizer='adam', loss='categorical_crossentropy')

另一种选择是使用功能模型:

predictions = Dense(3, activation='softmax')(source_model.layers[-2].output)
model = Model(inputs=inputs, outputs=predictions)
model.compile(optimizer='adam', loss='categorical_crossentropy')

model.layers[-1].output表示最后一层的输出即最终输出,因此在您的代码中,您实际上并未删除任何层,而是添加了另一个head / path。

答案 4 :(得分:0)

以上所有方法都适用于保存在 keras 函数式 api 中的模型,但不适用于顺序。
这是当您保存顺序模型然后加载它并想要更改其结构时的代码

from keras.models import load_model
from keras import layers
model = load_model('my_model.h5')
model.pop() # removes the last layer
# again if you want to add after removing the last layer ,then
model.add(layers.Dense(5,activation = 'softmax'))