我是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变量。我觉得这很奇怪。它应该是默认值吗?
我正在寻找您对此的解释,非常感谢!
答案 0 :(得分:2)
当输出y
不是标量时,Chainer不会自动填充初始梯度,因为在这种情况下,反向传播会计算需要矢量(由输出等级给出)的雅可比矢量积。 ones
只是向量的一个示例,并不特殊,因此Chainer强制用户明确指定它。
当输出为标量(形状为()
的数组)时,Chainer会自动将输出填充1(请参见the reference)。这意味着默认情况下,反向传播会计算标量值函数的梯度,这很自然。