为什么需要在Chainer中分配y的等级?

时间:2018-06-21 12:49:58

标签: chainer

我是Chainer的新手。我正在按照指南进行操作。但是,我发现一些我认为很奇怪的东西。 在文档»指南»可变章节中,编写了打击代码:

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变量。我觉得这很奇怪。它应该是默认值吗?

我正在寻找您对此的解释,非常感谢!

1 个答案:

答案 0 :(得分:2)

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

当输出为标量(形状为()的数组)时,Chainer会自动将输出填充1(请参见the reference)。这意味着默认情况下,反向传播会计算标量值函数的梯度,这很自然。