编译keras模型后如何防止反向传播?
How to prevent backpropagation after compiling a keras model?
我有一个像这样的多输出模型
input
|
hidden
|
/ \
/ \
output1 output2
我可以通过 model.train_on_batch(input=input,output=[output1,output2])
训练这个模型,但是在我训练的某个特定阶段,我只想训练这个模型的一个分支(输出 2)并防止输出 1 的反向传播。我最初尝试在模型 model.train_on_batch(input=input,output=[None,output2])
中传递一个 None
值,但它显示
AttributeError: 'NoneType' object has no attribute 'shape'
然后我尝试传递一个 output1 形状 model.train_on_batch(input=input,output=[Nan_array,output2])
的 NaN 数组,然后损失变为 NaN
。如何在多输出 keras 模型中只训练一个分支并防止另一个分支中的反向传播?
编辑
我试图找到这个问题的解决方案,并遇到了 K.stop_gradient
函数。我试图在这样的单输出模型中停止反向传播
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout
import keras.backend as K
def loss(y_true, y_pred):
return K.stop_gradient(y_pred)
# Generate dummy data
x_train = np.random.random((10, 20))
y_train = np.random.randint(2, size=(10, 1))
x_test = np.random.random((10, 20))
y_test = np.random.randint(2, size=(10, 1))
model = Sequential()
model.add(Dense(64, input_dim=20, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss=loss,
optimizer='rmsprop',
metrics=['accuracy'])
model.fit(x_train, y_train,
epochs=1,
batch_size=128)
score = model.evaluate(x_test, y_test, batch_size=128)
但是得到这个错误
ValueError: Tried to convert 'x' to a tensor and failed. Error: None values not supported.
您可以创建两个共享权重的 Model
对象。第一个模型在 output=[output1, output2]
上优化,而第二个模型只包含 output2
的分支。如果您在第二个模型上调用 train_on_batch
,分支 1 中的权重将不会更新。
例如,
x = Input(shape=(32,))
hidden = Dense(32)(x)
output1 = Dense(1)(hidden)
output2 = Dense(1)(hidden)
model = Model(x, [output1, output2])
model.compile(loss='mse', optimizer='adam')
model_only2 = Model(x, output2)
model_only2.compile(loss='mse', optimizer='adam')
X = np.random.rand(2, 32)
y1 = np.random.rand(2)
y2 = np.random.rand(2)
# verify: all the weights will change if we train on `model`
w0 = model.get_weights()
model.train_on_batch(X, [y1, y2])
w1 = model.get_weights()
print([np.allclose(x, y) for x, y in zip(w0, w1)])
# => [False, False, False, False, False, False]
# verify: branch 1 will not change if we train on `model_only2`
model_only2.train_on_batch(X, y2)
w2 = model.get_weights()
print([np.allclose(x, y) for x, y in zip(w1, w2)])
# => [False, False, True, True, False, False]
像
一样设置图层
layer.trainable = False
所以在训练过程中这一层不改变权重。
https://keras.io/getting-started/faq/#how-can-i-freeze-keras-layers
您是否试过通过 None
来编译您的模型:
model.compile(loss=loss,
optimizer='rmsprop',
metrics=[None, 'accuracy'])
?
我有一个像这样的多输出模型
input
|
hidden
|
/ \
/ \
output1 output2
我可以通过 model.train_on_batch(input=input,output=[output1,output2])
训练这个模型,但是在我训练的某个特定阶段,我只想训练这个模型的一个分支(输出 2)并防止输出 1 的反向传播。我最初尝试在模型 model.train_on_batch(input=input,output=[None,output2])
中传递一个 None
值,但它显示
AttributeError: 'NoneType' object has no attribute 'shape'
然后我尝试传递一个 output1 形状 model.train_on_batch(input=input,output=[Nan_array,output2])
的 NaN 数组,然后损失变为 NaN
。如何在多输出 keras 模型中只训练一个分支并防止另一个分支中的反向传播?
编辑
我试图找到这个问题的解决方案,并遇到了 K.stop_gradient
函数。我试图在这样的单输出模型中停止反向传播
import numpy as np
from keras.models import Sequential
from keras.layers import Dense, Dropout
import keras.backend as K
def loss(y_true, y_pred):
return K.stop_gradient(y_pred)
# Generate dummy data
x_train = np.random.random((10, 20))
y_train = np.random.randint(2, size=(10, 1))
x_test = np.random.random((10, 20))
y_test = np.random.randint(2, size=(10, 1))
model = Sequential()
model.add(Dense(64, input_dim=20, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(64, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(1, activation='sigmoid'))
model.compile(loss=loss,
optimizer='rmsprop',
metrics=['accuracy'])
model.fit(x_train, y_train,
epochs=1,
batch_size=128)
score = model.evaluate(x_test, y_test, batch_size=128)
但是得到这个错误
ValueError: Tried to convert 'x' to a tensor and failed. Error: None values not supported.
您可以创建两个共享权重的 Model
对象。第一个模型在 output=[output1, output2]
上优化,而第二个模型只包含 output2
的分支。如果您在第二个模型上调用 train_on_batch
,分支 1 中的权重将不会更新。
例如,
x = Input(shape=(32,))
hidden = Dense(32)(x)
output1 = Dense(1)(hidden)
output2 = Dense(1)(hidden)
model = Model(x, [output1, output2])
model.compile(loss='mse', optimizer='adam')
model_only2 = Model(x, output2)
model_only2.compile(loss='mse', optimizer='adam')
X = np.random.rand(2, 32)
y1 = np.random.rand(2)
y2 = np.random.rand(2)
# verify: all the weights will change if we train on `model`
w0 = model.get_weights()
model.train_on_batch(X, [y1, y2])
w1 = model.get_weights()
print([np.allclose(x, y) for x, y in zip(w0, w1)])
# => [False, False, False, False, False, False]
# verify: branch 1 will not change if we train on `model_only2`
model_only2.train_on_batch(X, y2)
w2 = model.get_weights()
print([np.allclose(x, y) for x, y in zip(w1, w2)])
# => [False, False, True, True, False, False]
像
一样设置图层layer.trainable = False
所以在训练过程中这一层不改变权重。
https://keras.io/getting-started/faq/#how-can-i-freeze-keras-layers
您是否试过通过 None
来编译您的模型:
model.compile(loss=loss,
optimizer='rmsprop',
metrics=[None, 'accuracy'])
?