我想创建一个自定义的keras层,该层在训练过程中执行其他操作,以进行验证或测试。
from tensorflow import keras
K = keras.backend
from keras.layers import Layer
import tensorflow as tf
class MyCustomLayer(Layer):
def __init__(self, ratio=0.5, **kwargs):
self.ratio = ratio
super(MyCustomLayer, self).__init__(**kwargs)
@tf.function
def call(self, x, is_training=None):
is_training = K.learning_phase()
tf.print("training: ", is_training)
if is_training is 1 or is_training is True:
xs = x * 4
return xs
else:
xs = x*0
return xs
model = Sequential()
model.add(Dense(16, input_dim=input_dim))
model.add(MyCustomLayer(0.5))
model.add(ReLU())
model.add(Dense(32, activation='relu'))
model.add(Dense(16, activation='relu'))
model.add(Dense(output_dim, activation='softmax', kernel_regularizer=l2(0.01)))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X_train, y_train, validation_split=0.05, epochs=5)
在输出中,我总是得到:
training: 0
training: 0
training: 0
training: 0
training: 0
training: 0
training: 0
training: 0
有人知道如何解决此问题吗?
答案 0 :(得分:0)
这里存在一些问题和误解。首先,您在keras
和tf.keras
导入之间混合了导入,您应该只使用其中一个。其次,call
的参数称为training
,而不是is_training
。
我认为问题在于tf.print
并没有真正打印training
变量的值作为其张量流符号变量,并且可能间接更改值。还有其他方法可以检查图层在推理和训练期间的行为是否不同,例如:
class MyCustomLayer(Layer):
def __init__(self, ratio=0.5, **kwargs):
super(MyCustomLayer, self).__init__(**kwargs)
def call(self, inputs, training=None):
train_x = inputs * 4
test_x = inputs * 0
return K.in_train_phase(train_x,
test_x,
training=training)
然后使用此模型:
model = Sequential()
model.add(Dense(1, input_dim=10))
model.add(MyCustomLayer(0.5))
model.compile(loss='mse', optimizer='adam')
并创建一个明确接收K.learning_phase()
变量的函数实例:
fun = K.function([model.input, K.learning_phase()], [model.output])
如果您将Klearning_phase()
设置为1或0进行调用,则会看到不同的输出:
d = np.random.random(size=(2,10))
print(fun([d, 1]))
print(fun([d, 0]))
结果:
[array([[4.1759257], [3.9988194]], dtype=float32)]
[array([[0.], [0.]], dtype=float32)]
这表明该层在训练和推理/测试期间具有不同的行为。
答案 1 :(得分:0)
所以,我只是弄清楚出了什么问题。我正在混合两种不同类型的类:
from keras import Sequential
from tensorflow import keras
K = keras.backend
因此,模型正在使用keras
,而我正在从tensorflow.keras
调用该标志。因此,K.learning_phase()
不能按预期工作。
要修复它,我用过
from tensorflow.keras import Sequential
from tensorflow import keras
K = keras.backend