【问题标题】:Flag for training and test for custom layer in KerasKeras 中自定义层的训练和测试标志
【发布时间】:2019-08-09 21:25:57
【问题描述】:

我想创建一个自定义的 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

有谁知道如何解决这个问题?

【问题讨论】:

    标签: tensorflow keras


    【解决方案1】:

    这里存在一些问题和误解。首先,您在 kerastf.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)]
    

    这表明该层在训练和推理/测试期间具有不同的行为。

    【讨论】:

    • 谢谢!实际上,现在打印效果很好。只需要确保一切都是tf.keras
    • @bettercallsomeone 我尝试过使用 keras 和 tf.print,但并没有真正奏效。
    • 您确定是tf.keras 而不是keras
    【解决方案2】:

    所以,我刚刚弄清楚出了什么问题。我混合了两种不同类型的课程:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-16
      • 2019-02-28
      • 2023-03-19
      • 2021-09-30
      • 2023-03-13
      • 1970-01-01
      相关资源
      最近更新 更多