如何处理维度大小为 None 的渐变

How to process gradients with a Dimension size of None

使用 AdamOptimizer,当我获得二维变量的梯度时,第二维的大小最终为 None,而第一维与变量的第一维大小相同。这使得处理渐变变得困难,因为 None 的大小与大多数函数的其他大小不兼容。当我得到一维变量的梯度时,梯度的维度大小与变量的维度大小相同。我没有尝试过超过 2 个维度的变量。

这是一个错误吗?有没有办法通过 compute_gradients 函数来指定渐变的大小应该是多少?有没有办法处理大小 None 问题附近的渐变?

TL;DR: 没关系,您可以正常使用 tf.train.AdamOptimizer 处理渐变。如果您看到 shape-related 错误,这很可能是由于已知维度之一不匹配造成的。

梯度张量 shapeNone 的存在仅仅意味着无法静态推断该维度的大小。这不一定是错误:许多运算符的形状取决于它们的数据输入,而 TensorFlow Python front-end 使用简单的启发式算法(即只计算一组有限的具有恒定输入的运算符)来决定评估哪些数据输入。几乎所有 TensorFlow 操作(不包括一些图像处理操作)都将处理形状未知(或仅部分已知)的输入,并在运行时执行检查。

处理渐变的主要方法是使用 Optimizer.apply_gradients(), which defers shape checking to the shape function for the ApplyAdam operator. This shape function asserts that the variable and gradient have the same shape, but the TensorShape.merge_with() 方法允许在任一形状中出现 None 时出现误报。

最后,如果您需要在图形构造时处理梯度,并且您的处理在某种程度上取决于具有已知形状的梯度,您始终可以使用 Tensor.set_shape() 方法将变量的形状复制到渐变的形状,因为它们必须等价:

var = tf.Variable(...)
loss = ...
grad = tf.gradients(loss, [var])[0]

# `grad` and `var` must have the same shape.
grad.set_shape(var.get_shape())