我想计算所有网络参数的损耗梯度。当我尝试重塑每个权重矩阵以使其成为1维时,就会出现问题(这对于以后使用梯度进行计算非常有用)。
这时Tensorflow输出一个None
列表(这意味着从损失到这些张量没有路径,而应该有重塑模型参数的路径)。
代码如下:
all_tensors = list()
for dir in ["fw", "bw"]:
for mtype in ["kernel"]:
t = tf.get_default_graph().get_tensor_by_name("encoder/bidirectional_rnn/%s/lstm_cell/%s:0" % (dir, mtype))
all_tensors.append(t)
# classifier tensors:
for mtype in ["kernel", "bias"]:
t = tf.get_default_graph().get_tensor_by_name("encoder/dense/%s:0" % (mtype))
all_tensors.append(t)
all_tensors = [tf.reshape(x, [-1]) for x in all_tensors]
tf.gradients(self.loss, all_tensors)
for循环末尾的 all_tensor
是4个组件的列表,这些组件具有不同形状的矩阵。这段代码输出[None, None, None, None]
。
如果删除重塑线all_tensors = [tf.reshape(x, [-1]) for x in all_tensors]
该代码可以正常工作,并返回4个张量,每个张量均包含渐变。
为什么会发生?我很确定,重塑不会破坏图中的任何依赖关系,否则根本无法在任何网络中使用。
答案 0 :(得分:1)
嗯,事实是,从张量到损失没有任何途径。如果您想到TensorFlow中的计算图,则self.loss
是通过一系列操作定义的,这些操作有时使用您感兴趣的张量。但是,当您这样做时:
all_tensors = [tf.reshape(x, [-1]) for x in all_tensors]
您正在图形中创建新节点以及任何人都没有使用的新张量。是的,这些张量与损失值之间存在关系,但是从TensorFlow的角度来看,重塑是独立的计算。
如果要执行类似的操作,则必须先进行重塑,然后使用重整的张量计算损耗。或者,您也可以只计算相对于原始张量的梯度,然后对结果进行整形。