Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/359.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,Keras:如何在具有停止梯度的Keras层中设置附加损耗? 问题1_Python_Tensorflow_Keras - Fatal编程技术网

Python Tensorflow,Keras:如何在具有停止梯度的Keras层中设置附加损耗? 问题1

Python Tensorflow,Keras:如何在具有停止梯度的Keras层中设置附加损耗? 问题1,python,tensorflow,keras,Python,Tensorflow,Keras,我们知道我们可以使用tf.stop\u梯度(B)来防止变量B在反向传播中被训练。但是我不知道如何在一定的损失中阻止B 简单来说,假设我们的损失是: loss = categorical_crossentropy + my_loss B = tf.stop_gradient(B) 其中分类交叉熵和我的损失都取决于B。因此,如果我们为B设置停止梯度,它们都将B作为常数 但是我如何只设置my_lossstop gradient w.r.tB,保持categorical_crossentropy不变?

我们知道我们可以使用
tf.stop\u梯度(B)
来防止变量
B
在反向传播中被训练。但是我不知道如何在一定的损失中阻止
B

简单来说,假设我们的损失是:

loss = categorical_crossentropy + my_loss
B = tf.stop_gradient(B)
其中分类交叉熵和
我的损失都取决于
B
。因此,如果我们为
B
设置停止梯度,它们都将
B
作为常数

但是我如何只设置
my_loss
stop gradient w.r.t
B
,保持
categorical_crossentropy
不变?类似于
B=tf.stop\u梯度(B,myloss)

我的代码是:

这样行吗?或者,如何使其工作


问题2 好的,伙计们,如果Q1可以解决,我最后的任务是如何在自定义层中做到这一点

具体来说,假设我们有一个自定义层,该层仅具有可训练权重
a
B
和自损耗
my_loss

class My_层(keras.layers.Layer):
定义初始(自我,**kwargs):
超级(我的图层,自我)。\uuuuu初始化(**kwargs)
def构建(自我,输入_形状):
self.w=self.add_重量(name='w',trainable=True)
self.B=self.add_weight(name='B',trainable=True)
我的损失=w*B
#tf.停止梯度(w)
添加损失(我的损失)
如何使
w
仅可用于模型损耗(MSE、交叉熵等)的培训,以及
B
仅可用于
my_损耗的培训


如果我添加了
tf.stop\u gradient(w)
,那么它是只为
my\u损失
而停止,还是为模型的最终损失而停止?

问题1

运行
y=tf.stop\u gradient(x)
时,创建一个
StopGradient
操作,其输入为
x
,输出为
y
。此操作的行为类似于标识,即
x
的值与
y
的值相同,只是梯度不会从
y
流向
x

如果您想让渐变仅从某些损失流向
B
,只需执行以下操作:

B_no_grad = tf.stop_gradient(B)
loss1 = get_loss(B)  # B will be updated because of loss1
loss2 = get_loss(B_no_grad)   # B will not be updated because of loss2 
当您考虑正在构建的计算图时,事情应该变得清楚
stop_gradient
允许您为任何不允许渐变通过的张量(不仅仅是变量)创建“标识”节点

问题2


我不知道在使用您使用字符串指定的模型丢失时如何执行此操作(例如,
model.compile(loss='classifical\u crossentropy',…)
因为你不能控制它的构造。但是,你可以通过使用
添加损耗
或使用模型输出自己构建模型级损耗来实现。对于前者,只需使用普通变量创建一些损耗,使用
*\u no\u grad
版本创建一些损耗,然后使用
添加损耗()
,然后用
loss=None

编译你的模型,不过这里说你可以传递一个函数到
compile
,而不仅仅是一个字符串,比如
model.compile(loss=loss.mean\u squared\u error,optimizer='sgd')
而不是
model.compile(loss='mean\u squared\u error',optimizer='sgd'))
如果我想让loss1的梯度只影响第1-2层(而不是第3-4层)的权重,让Loss2的梯度只影响第3-4层(而不是第1-2层),该怎么办。这正是您想要的。例如,当您试图向变分自动编码器添加两个不同的自定义正则化项时,一个仅用于编码器,另一个仅用于解码器,而它们必须进行联合训练。@Kristof您有没有想过这一点?如何让loss1仅影响层1-2,而loss2仅影响层1-2第3-4层?
B_no_grad = tf.stop_gradient(B)
loss1 = get_loss(B)  # B will be updated because of loss1
loss2 = get_loss(B_no_grad)   # B will not be updated because of loss2