在 TF1 中以图形模式运行时,我相信我在使用函数式 API 时需要通过 feeddicts 连接 training=Truetraining=False。在 TF2 中执行此操作的正确方法是什么?

我相信这是在使用 tf.keras.Sequential 时自动处理的。例如,我不需要在以下 docs 示例中指定 training :

model = tf.keras.Sequential([
    tf.keras.layers.Conv2D(32, 3, activation='relu',
                           kernel_regularizer=tf.keras.regularizers.l2(0.02),
                           input_shape=(28, 28, 1)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dropout(0.1),
    tf.keras.layers.Dense(64, activation='relu'),
    tf.keras.layers.BatchNormalization(),
    tf.keras.layers.Dense(10, activation='softmax')
])

# Model is the full model w/o custom layers
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model.fit(train_data, epochs=NUM_EPOCHS)
loss, acc = model.evaluate(test_data)
print("Loss {:0.4f}, Accuracy {:0.4f}".format(loss, acc))

我还可以假设 keras 在使用功能性 api 进行训练时会自动处理这个问题吗?这是相同的模型,使用函数 api 重写:
inputs = tf.keras.Input(shape=((28,28,1)), name="input_image")
hid = tf.keras.layers.Conv2D(32, 3, activation='relu',
                           kernel_regularizer=tf.keras.regularizers.l2(0.02),
                           input_shape=(28, 28, 1))(inputs)
hid = tf.keras.layers.MaxPooling2D()(hid)
hid = tf.keras.layers.Flatten()(hid)
hid = tf.keras.layers.Dropout(0.1)(hid)
hid = tf.keras.layers.Dense(64, activation='relu')(hid)
hid = tf.keras.layers.BatchNormalization()(hid)
outputs = tf.keras.layers.Dense(10, activation='softmax')(hid)
model_fn = tf.keras.Model(inputs=inputs, outputs=outputs)

# Model is the full model w/o custom layers
model_fn.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

model_fn.fit(train_data, epochs=NUM_EPOCHS)
loss, acc = model_fn.evaluate(test_data)
print("Loss {:0.4f}, Accuracy {:0.4f}".format(loss, acc))

我不确定 hid = tf.keras.layers.BatchNormalization()(hid) 是否需要是 hid = tf.keras.layers.BatchNormalization()(hid, training)

可以找到这些模型的 colab here

最佳答案

我意识到 BatchNormalization 文档 [1] 中存在一个错误,其中 {{TRAINABLE_ATTRIBUTE_NOTE}} 实际上并未替换为预期的注释 [2]:

关于在 layer.trainable = False 层上设置 BatchNormalization:
设置layer.trainable = False的意思是卡住图层,
即它的内部状态在训练期间不会改变:
它的可训练权重不会更新
fit()train_on_batch() 期间,不会运行其状态更新。
通常,这并不一定意味着该层在推理中运行
模式(通常由 training 参数控制,可以
调用层时传递)。 “卡住状态”和“推理模式”
是两个不同的概念。

但是,在 BatchNormalization 层的情况下, 设置
层上的 trainable = False 表示该层将
随后以推理模式
运行(意味着它将使用
移动均值和移动方差以归一化当前批次,
而不是使用当前批次的均值和方差)。
此行为已在 TensorFlow 2.0 中引入,以便
使 layer.trainable = False 能够产生最常见的
convnet 微调用例中的预期行为。
注意:

  • 此行为仅在 TensorFlow 2.0 后出现。在 1.* 中,
    设置 layer.trainable = False 会卡住层,但会
    不要将其切换到推理模式。
  • 在包含其他层的模型上设置 trainable
    递归设置所有内层的 trainable 值。
  • 如果 trainable 的值
    在模型上调用 compile() 后属性发生更改,
    新值对此模型无效
    直到 compile() 再次被调用。

  • [1] https://www.tensorflow.org/api_docs/python/tf/keras/layers/BatchNormalization?version=stable

    [2] https://github.com/tensorflow/tensorflow/blob/r2.0/tensorflow/python/keras/layers/normalization_v2.py#L26-L65

    关于python - 使用 Tensorflow 2 的 Keras Functional API 时传递 `training=true`,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/58728086/

    10-12 23:51