在下面的简单代码中,我对一个1的输入张量执行一个简单的线性运算,并计算它的二进制交叉熵损失,考虑到一个零向量作为期望输出。当计算相对于w的损失梯度时,行与相对于b的梯度相等。这是违反直觉的,因为w和b有随机值.原因何在?
n_input, n_output = 5, 3
x = torch.ones(n_input)
y = torch.zeros(n_output) # expected output
w = torch.randn(n_input, n_output, requires_grad=True)
b = torch.randn(n_output, requires_grad=True)
z = torch.matmul(x,w) + b
loss = torch.nn.functional.binary_cross_entropy_with_logits(z, y)
loss.backward()
print(w.grad)
print(b.grad)输出:
tensor([[0.2179, 0.4337, 0.1959],
[0.2179, 0.4337, 0.1959],
[0.2179, 0.4337, 0.1959],
[0.2179, 0.4337, 0.1959],
[0.2179, 0.4337, 0.1959]])
tensor([0.2179, 0.4337, 0.1959])发布于 2021-08-26 15:49:53
这是因为您的输入是对称。
从感知器的角度来想象这个问题(在您的设置中有3个):每个输入都是1.0,因此特定神经元的权重并不重要(因为到处都有1.0 )。
如果你将投入多样化,那么一切都会很好:
n_input, n_output = 5, 3
x = torch.randn(n_input)
y = torch.ones(n_output)/2. # expected output
w = torch.randn(n_input, n_output, requires_grad=True)
b = torch.randn(n_output, requires_grad=True)
z = torch.matmul(x, w) + b
loss = torch.nn.functional.binary_cross_entropy_with_logits(z, y)
loss.backward()
print(w.grad)
print(b.grad) tensor([[-0.1939, 0.1657, -0.2501],
[ 0.0561, -0.0480, 0.0724],
[-0.3162, 0.2703, -0.4079],
[ 0.0947, -0.0809, 0.1221],
[-0.0140, 0.0120, -0.0181]])
tensor([-0.1263, 0.1080, -0.1630])发布于 2021-08-26 15:30:06
只有一个数据点,输入特性大小为5。如果您查看所执行的操作您有z = x@w + b,那么您有一个二进制交叉熵从日志对空标签。二进制交叉熵的定义如下:
bce = -[y_true*log(σ(y_pred)) + (1 - y_true)*log(1 - σ(y_pred))]z的梯度被写成偏导数dL/dz,它由三个元素组成(与z相同大小),比方说[dz1, dz2, dz3]。
为了计算权重参数w和偏置参数b的梯度,我们有以下内容:
dL/dw = x.T @ dL/dz
dL/db = dL/dz (with a shape change)因此,b.grad是简单的
[dz1, dz2, dz3]而且,由于x是由它们组成的,所以x.T @ dL/dz最终也是一个矩阵,其中的行也等于dL/dz,即有五行:
[[dz1, dz2, dz3],
[dz1, dz2, dz3],
[dz1, dz2, dz3],
[dz1, dz2, dz3],
[dz1, dz2, dz3]]https://stackoverflow.com/questions/68941009
复制相似问题