实现一个简单的全来凝结网络,完成的工作是:
然后损失函数就是经典的L2损失:
代码如下,这里我们将偏执设置为0:
class network(nn.Module):
def __init__(self):
super().__init__()
self.w = torch.Tensor([1.0])
self.w.requires_grad = True
def forward(self, x):
output = self.w * x
return output
def gradient(x, y, w):
return 2*x*(x*w - y)
if __name__ == '__main__':
model = network()
x_data = torch.Tensor([1.0,2.0,3.0])
y_data = torch.Tensor([2.0,4.0,6.0])
output = model(x_data)
loss = (output-y_data).pow(2).mean()
loss.backward()
grads = gradient(x_data, y_data, model.w).mean()#手动实现 反向传播
print(model.w.grad.data) #
print(grads)
运行的结果是一致的,都为-8.3333
具体推导一下:
下面修改一下loss的形式,相当于每个样本的权重不一样,增加最后一个样本的权重,可以看到两个样本的权重为1/4,最后一个样本的权重为1/2。从这个角度来看,实际上上面按照标准的loss反向传播,实际就是每个样本等权重。
model = network()
x_data = torch.Tensor([1.0,2.0,3.0])
y_data = torch.Tensor([2.0,4.0,6.0])
output = model(x_data)
loss = (output-y_data).pow(2)
loss = (loss[0:2].mean() + loss[2])/2 #修改loss
loss.backward()
# grads = gradient(x_data, y_data, model.w).mean()#手动实现 反向传播
print(model.w.grad.data) #
计算结果是-11.5,下面手动计算下: