我正在尝试使用Keras和MNIST数据集在预测模型中冻结特定层的权重,但它不起作用。代码如下所示:
from keras.layers import Dense, Flattenfrom keras.utils import to_categoricalfrom keras.models import Sequential, load_modelfrom keras.datasets import mnistfrom keras.losses import categorical_crossentropyimport numpy as npdef load_data(): (x_train, y_train), (x_test, y_test) = mnist.load_data() x_train = x_train.astype('float32') x_test = x_test.astype('float32') x_train /= 255 x_test /= 255 y_train = to_categorical(y_train, num_classes=10) y_test = to_categorical(y_test, num_classes=10) return x_train, y_train, x_test, y_testdef run(): x_train, y_train, x_test, y_test = load_data() model = Sequential([Flatten(input_shape=(28, 28)), Dense(300, name='dense1', activation='relu'), Dense(100, name='dense2', activation='relu'), Dense(10, name='dense3', activation='softmax')]) model.trainable = True model.compile(optimizer='Adam', metrics=['accuracy'], loss=categorical_crossentropy) print(model.summary()) model.fit(x_train, y_train, epochs=5, verbose=2) print(model.evaluate(x_test, y_test)) return modeldef freeze(model): x_train, y_train, x_test, y_test = load_data() name = 'dense1' weightsAndBias = model.get_layer(name=name).get_weights() # 冻结这一层的权重 model.get_layer(name=name).trainable = False # 记录重新训练前的权重 weights_before = weightsAndBias[0] # 重新训练 model.fit(x_train, y_train, verbose=2, epochs=1) weights_after = model.get_layer(name=name).get_weights()[0] if (weights_before == weights_after).all(): print('权重没有变化!!!') else: print('权重变化了!!!!')if __name__ == '__main__': model = run() freeze(model)
程序输出的是’权重变化了!!!!’。我无法理解为什么在设置model.get_layer(name=name).trainable = False
之后,名为’dense1’的层的权重仍然会发生变化。
回答:
你可以使用以下方式来实现:
model=Sequential()layer=Dense(64,init='glorot_uniform',input_shape=(784,))layer.trainable=Falsemodel.add(layer)layer2=Dense(784, activation='sigmoid',init='glorot_uniform')layer2.trainable=Truemodel.add(layer2)model.compile(loss='relu', optimizer=sgd,metrics = ['mae'])