2

我是Chainer的新手。我正在按照指南做。但是,我发现了一些我认为很奇怪的东西。在 Docs » Guides » Variable 章节中,我编写了 blow 代码:

x = Variable(np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float32))
y = 2.0 * x
# y.grad = np.zeros((2, 3), dtype=np.float32)
y.backward()
print(x.grad)
print(y.data)

然后,有一个错误,错误信息是:

TypeError: unsupported operand type(s) for *: 'float' and 'NoneType'

当我们删除带注释的符号时,代码是:

x = Variable(np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float32))
y = 2.0 * x
y.grad = np.zeros((2, 3), dtype=np.float32)
y.backward()
print(x.grad)
print(y.data)

然后一切正常。

所以似乎必须将初始grad分配给y的变量。我觉得这很奇怪。它应该是一个作为默认值吗?

我正在寻找你的解释,非常感谢你!

4

1 回答 1

2

当输出y不是标量时,Chainer 不会自动填充初始梯度,因为在这种情况下,反向传播会计算需要向量(由输出梯度给出)的雅可比向量积。ones只是向量的一个例子,它并不特殊,因此 Chainer 强制用户明确指定它。

当输出是标量(形状为 的数组())时,Chainer 会自动将输出填充一(参见参考资料)。这意味着反向传播默认计算标量值函数的梯度,这是自然的。

于 2018-06-22T00:42:13.087 回答