Tensorflow Keras自定义批处理规范化层,具有可在运行时更改的额外变量
我通过添加Tensorflow Keras自定义批处理规范化层,具有可在运行时更改的额外变量,tensorflow,keras,keras-layer,batch-normalization,Tensorflow,Keras,Keras Layer,Batch Normalization,我通过添加self.skip变量实现了批量规范化的自定义版本,该变量以某种方式充当可训练的。以下是最低限度的代码: from tensorflow.keras.layers import BatchNormalization import tensorflow as tf # class CustomBN(tf.keras.layers.Layer): class CustomBN(BatchNormalization): def __init__(self, **kwargs):
self.skip
变量实现了批量规范化的自定义版本,该变量以某种方式充当可训练的
。以下是最低限度的代码:
from tensorflow.keras.layers import BatchNormalization
import tensorflow as tf
# class CustomBN(tf.keras.layers.Layer):
class CustomBN(BatchNormalization):
def __init__(self, **kwargs):
super(CustomBN, self).__init__(**kwargs)
self.skip = False
def call(self, inputs, training=None):
if self.skip:
tf.print("I'm skipping")
else:
tf.print("I'm not skipping")
return super(CustomBN, self).call(inputs, training)
def build(self, input_shape):
super(CustomBN, self).build(input_shape)
说得非常清楚,我迄今为止所做的一切是:
BatchNormalization
:我应该子分类tf.keras.layers.Layer
self.skip
以更改运行时CustomBN
层的行为call
方法中的self.skip
的状态以进行相应操作self.model.layers[ind].skip = state
其中,state
为True
或False
,ind
为模型中自定义BN
层的索引号。
明显的问题是,self.skip
的值永远不会改变。
如果您注意到任何错误,请通知我。默认情况下,构建图形时将调用您所在层中的调用函数。不是以每批为基础。Keras modelcompile
方法作为一个run\u急切地
选项,该选项将导致模型在急切模式下运行(较慢),该模式将调用调用函数而无需构建图形。然而,这很可能不是您想要做的
理想情况下,您希望更改行为的标志成为调用方法的输入。。。例如,您可以向图形中添加一个额外的输入,它就是这个状态
标志,并将其传递给图层
下面的示例说明了如何在额外参数上创建条件图
import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
class MyLayerWithFlag(keras.layers.Layer):
def call(self, inputs, flag=None):
c_one = tf.constant([1], dtype=tf.float32)
if flag is not None:
x = tf.cond(
flag, lambda: tf.math.add(inputs, c_one),
lambda: inputs)
return x
return inputs
inputs = layers.Input(shape=(2,))
state = layers.Input(shape=(1,), dtype=tf.bool)
x = MyLayerWithFlag()(inputs, flag=state)
out = layers.Lambda(tf.reduce_sum)(x)
model = keras.Model([inputs, state], out)
data = np.array([[1., 2.]])
state = np.array([[True]])
model.predict((data, state))
默认情况下,构建图形时将调用层中的调用函数。不是以每批为基础。Keras modelcompile
方法作为一个run\u急切地
选项,该选项将导致模型在急切模式下运行(较慢),该模式将调用调用函数而无需构建图形。然而,这很可能不是您想要做的
理想情况下,您希望更改行为的标志成为调用方法的输入。。。例如,您可以向图形中添加一个额外的输入,它就是这个状态
标志,并将其传递给图层
下面的示例说明了如何在额外参数上创建条件图
import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
class MyLayerWithFlag(keras.layers.Layer):
def call(self, inputs, flag=None):
c_one = tf.constant([1], dtype=tf.float32)
if flag is not None:
x = tf.cond(
flag, lambda: tf.math.add(inputs, c_one),
lambda: inputs)
return x
return inputs
inputs = layers.Input(shape=(2,))
state = layers.Input(shape=(1,), dtype=tf.bool)
x = MyLayerWithFlag()(inputs, flag=state)
out = layers.Lambda(tf.reduce_sum)(x)
model = keras.Model([inputs, state], out)
data = np.array([[1., 2.]])
state = np.array([[True]])
model.predict((data, state))
我使用Sequential
和model
kerasapi实现了model
,这不会改变结果。在设置model.layers[ind].skip=state
之后,我也编译了模型,这同样没有什么区别!我使用Sequential
和model
kerasapi实现了model
,这不会改变结果。在设置model.layers[ind].skip=state
之后,我也编译了模型,这同样没有什么区别!