Tensorflow 如何使用tf.keras编写自定义标准化层

Tensorflow 如何使用tf.keras编写自定义标准化层,tensorflow,keras,neural-network,keras-layer,tf.keras,Tensorflow,Keras,Neural Network,Keras Layer,Tf.keras,目前,我正在用tensorflow和KerasAPI构建我的第一个神经网络。 我想为输入的标准化编写一个层,因为在预处理中这样做可能会导致在训练后使用模型时出错。 因此,我希望将我的训练数据集传递给该层的init函数,并计算平均值和标准偏差 问题是我还想在训练后保存和加载模型。但是如果我调用load_model(modelname),我会得到一个错误,因为init函数期望将训练数据作为参数。此外,我不确定将平均值和标准值指定为tf.变量是否正确,或者是否有更好的方法,例如在使用load_模型/l

目前,我正在用tensorflow和KerasAPI构建我的第一个神经网络。 我想为输入的标准化编写一个层,因为在预处理中这样做可能会导致在训练后使用模型时出错。 因此,我希望将我的训练数据集传递给该层的init函数,并计算平均值和标准偏差

问题是我还想在训练后保存和加载模型。但是如果我调用load_model(modelname),我会得到一个错误,因为init函数期望将训练数据作为参数。此外,我不确定将平均值和标准值指定为tf.变量是否正确,或者是否有更好的方法,例如在使用load_模型/load_权重时加载这些值

我为每一个答案感到高兴

下面的代码表示这样一个层的基本思想

class stdLayer(tf.keras.layers.Layer):
    def __init__(self, train_x, trainable=False,**kwargs):
        super(stdLayer, self).__init__(trainable=trainable,**kwargs)
        means=np.mean(train_x,axis=0)
        stds=np.std(train_x,axis=0)
        self.means = tf.Variable(means,
                                dtype=tf.float32,
                                name="means",
                                trainable=False)
        self.stds = tf.Variable(stds,
                                dtype=tf.float32,
                                name="stds",
                                trainable=False)


    def call(self, input):
        input_st = (input-self.means)/self.stds
        return input_st

也许您可以在模型的开头有一个
BatchNormalization

不过,在所有情况下,您都需要生产数据的格式与培训数据的格式相同


或者,不要传递训练数据,只传递
意味着
性病

class StdLayer(tf.keras.layers.Layer):
    def __init__(self, means, stds, trainable=False,**kwargs):
        ...
        self.means_init = means
        self.stds_init = stds
        ...

    def build(self, input_shape):
        self.means = self.add_weight(name='means', 
                                      shape=self.means_init.shape,
                                      initializer='zeros',
                                      trainable=True) 
                                       #if you put false here, they will never be trainable
        self.stds =  self.add_weight(name='stds', 
                                      shape=self.stds_init.shape,
                                      initializer='ones',
                                      trainable=True)
                                      #if you put false here, they will never be trainable

        keras.backend.set_value(self.means, self.means_init)
        keras.backend.set_value(self.stds, self.stds)

        self.built = True

    def call(self, inputs):
        ...

    def compute_output_shape(self, input_shape):
        ...

    def get_config(self):
        config = {
            'means_init': self.means_init,
            'stds_init': self.stds_init,
        }
        base_config = super(StdLayer, self).get_config()
        return dict(list(base_config.items()) + list(config.items()))
老实说,我不确定numpy数组是否可以传递到
config


您可以使用
\uu init__(self,means=None,stds=None,…
,在
build
中放入
if
,用于
set\u值
。在
add\u weight
中找到另一种方法来计算形状,你可以摆脱
配置
变量。

这可能是最简单的方法,但从如果我已经知道它们,那么开始是什么?你能告诉我,当我执行model.save()或model.save_weights()时,tf.Variable类型的所有图层属性的值是否会自动保存吗?不,你必须遵循Keras文档,并在
build
中使用
add_weight