加载权重后如何在keras中添加和删除新层?
How to add and remove new layers in keras after loading weights?
我正在尝试进行迁移学习;为此,我想删除神经网络的最后两层并添加另外两层。这是一个示例代码,它也输出相同的错误。
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' object has no attribute 'add'
我知道错误最可能的原因是 model.add()
使用不当。我应该使用什么其他语法?
编辑:
我尝试在 keras 中 remove/add 层,但它不允许在加载外部权重后添加它。
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: []
您可以使用上一个模型的 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()
勾选
编辑更新:
新错误是因为您试图在全局 in_img
上创建新模型,而这在之前的模型创建中实际上并未使用。您实际上是在定义局部 in_img
。所以全局in_img
在符号图中显然没有连接到上层。并且与加载权重无关
为了更好地解决这个问题,您应该使用 model.input
来引用输入。
model3 = Model(input=model2.input, output=[o])
另一种方法
from keras.models import Model
layer_name = 'relu_conv2'
model2= Model(inputs=model1.input, outputs=model1.get_layer(layer_name).output)
从 Keras 2.3.1 和 TensorFlow 2.0 开始,model.layers.pop()
未按预期工作(请参阅问题 here)。他们提出了两种选择。
一种选择是重新创建模型并复制图层。例如,如果你想删除最后一层并添加另一层,你可以这样做:
model = Sequential()
for layer in source_model.layers[:-1]: # go through until last layer
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.
Wesam Na 答案的替代方案,如果您不知道图层名称,您可以通过以下方式简单地切断最后一层:
from keras.models import Model
model2= Model(inputs=model1.input, outputs=model1.layers[-2].output)
我正在尝试进行迁移学习;为此,我想删除神经网络的最后两层并添加另外两层。这是一个示例代码,它也输出相同的错误。
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' object has no attribute 'add'
我知道错误最可能的原因是 model.add()
使用不当。我应该使用什么其他语法?
编辑:
我尝试在 keras 中 remove/add 层,但它不允许在加载外部权重后添加它。
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: []
您可以使用上一个模型的 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()
勾选
编辑更新:
新错误是因为您试图在全局 in_img
上创建新模型,而这在之前的模型创建中实际上并未使用。您实际上是在定义局部 in_img
。所以全局in_img
在符号图中显然没有连接到上层。并且与加载权重无关
为了更好地解决这个问题,您应该使用 model.input
来引用输入。
model3 = Model(input=model2.input, output=[o])
另一种方法
from keras.models import Model
layer_name = 'relu_conv2'
model2= Model(inputs=model1.input, outputs=model1.get_layer(layer_name).output)
从 Keras 2.3.1 和 TensorFlow 2.0 开始,model.layers.pop()
未按预期工作(请参阅问题 here)。他们提出了两种选择。
一种选择是重新创建模型并复制图层。例如,如果你想删除最后一层并添加另一层,你可以这样做:
model = Sequential()
for layer in source_model.layers[:-1]: # go through until last layer
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.
Wesam Na 答案的替代方案,如果您不知道图层名称,您可以通过以下方式简单地切断最后一层:
from keras.models import Model
model2= Model(inputs=model1.input, outputs=model1.layers[-2].output)