Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何在tensorflow自定义训练循环中考虑l1和l2正则化器?_Python_Tensorflow_Keras_Deep Learning - Fatal编程技术网

Python 如何在tensorflow自定义训练循环中考虑l1和l2正则化器?

Python 如何在tensorflow自定义训练循环中考虑l1和l2正则化器?,python,tensorflow,keras,deep-learning,Python,Tensorflow,Keras,Deep Learning,在使用model.fit_on_batch方法时,我意识到在自定义训练循环代码中,损失和梯度不考虑任何l1-l2正则化器,因此optimizer.apply_梯度方法不考虑正则化器。下面您可以找到显示这一点的代码,但是想法非常简单。所以我的问题是,是否有一种方法可以以优化器细节不可知的方式使用所有这些优化器来考虑正则化器。它是如何在Keras中实施的?在一个相关的注释中,model.fit_On_batch返回一个值,该值不是损失(如docstring中所声明的),而是其他值。我想知道这里是否有

在使用model.fit_on_batch方法时,我意识到在自定义训练循环代码中,损失和梯度不考虑任何l1-l2正则化器,因此optimizer.apply_梯度方法不考虑正则化器。下面您可以找到显示这一点的代码,但是想法非常简单。所以我的问题是,是否有一种方法可以以优化器细节不可知的方式使用所有这些优化器来考虑正则化器。它是如何在Keras中实施的?在一个相关的注释中,model.fit_On_batch返回一个值,该值不是损失(如docstring中所声明的),而是其他值。我想知道这里是否有人知道它的回报

代码

要查看此效果,请先创建一些数据

x=tf.constant([[1]])
y=tf.constant([[1]])
并创建一个函数来创建一个可复制的模型

def make_model(l1=.01,l2=.01):
    tf.random.set_seed(42)
    np.random.seed(42)
    model=tf.keras.models.Sequential([
        tf.keras.layers.Dense(2,'softmax',
                              use_bias=False,
                              kernel_regularizer=tf.keras.regularizers.l1_l2(l1=l1,l2=l2),
                              input_shape=(1,))
    ])
    return model
现在在批上运行Keras列车

model=make_model()
loss_object=tf.keras.losses.SparseCategoricalCrossentropy()
optimizer=tf.keras.optimizers.RMSprop()
model.compile(loss=loss_object,optimizer=optimizer)
model.train_on_batch(x,y)
并将输出与上述链接中解释的自定义训练循环进行比较,以及


除非l1==0和l2==0,否则您将看到这两个结果是不同的。

事实上,我在Aurelian Geron的书中找到了答案

事实上,在我实现了下面的代码之后,我发现这已经包含在了中(我不知道为什么在问题中提到的教程中没有,因为这是一个重要的观点)。这里的解决方案比这里提到的更一般,但我保留它,因为它更能说明发生了什么

因此,只需将自定义训练循环修改为

def add_model_regularizer_loss(model):
    loss=0
    for l in model.layers:
        if hasattr(l,'layers') and l.layers: # the layer itself is a model
            loss+=add_model_loss(l)
        if hasattr(l,'kernel_regularizer') and l.kernel_regularizer:
            loss+=l.kernel_regularizer(l.kernel)
        if hasattr(l,'bias_regularizer') and l.bias_regularizer:
            loss+=l.bias_regularizer(l.bias)
    return loss

def train_step(x,y):

    with tf.GradientTape() as tape:
        predictions  = model(x)
        loss = loss_object(y, predictions)
        loss += add_model_regularizer_loss(model)

    gradients = tape.gradient(loss, model.trainable_variables)    
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))
    return loss
为了回答我问题的第二部分,keras的模型拟合方法返回的就是这个损失值

def add_model_regularizer_loss(model):
    loss=0
    for l in model.layers:
        if hasattr(l,'layers') and l.layers: # the layer itself is a model
            loss+=add_model_loss(l)
        if hasattr(l,'kernel_regularizer') and l.kernel_regularizer:
            loss+=l.kernel_regularizer(l.kernel)
        if hasattr(l,'bias_regularizer') and l.bias_regularizer:
            loss+=l.bias_regularizer(l.bias)
    return loss

def train_step(x,y):

    with tf.GradientTape() as tape:
        predictions  = model(x)
        loss = loss_object(y, predictions)
        loss += add_model_regularizer_loss(model)

    gradients = tape.gradient(loss, model.trainable_variables)    
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))
    return loss