双层神经网络
Pytorch 里的Tensor
用法:torch.Tensor([data]),对张量的操作,想象成建立计算图的过程。
Tensor中重要的两个成员:
- .data: 用于保存权重本身的值w,本身也是个张量。
- .grad: 保存loss对权重w的偏导,本身也是个张量。
(笼统一点,梯度就是loss对权重的导)
如果想直接要张量里的值(标量),用 张量.item()
反向传播思想(手动推导)
先算损失,再回过头来跑bp,用梯度不断进行更新。
反向传播实现
代码(含解析)
# -*- coding:utf-8 -*-
# Abstract: 反向传播算法
import torch
x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]
w = torch.Tensor([1]) #权重初始值,比较随机
#print(w,type(w)) #tensor([1.]) <class 'torch.Tensor'>
w.requires_grad = True # 如果不写,后续 w.data就不会存权值(第30行)
def forward(x):
return w*x # Tensor 与 Tensor 的数乘;对于Tensor的运算,相当于构建计算图
def loss(x,y):
y_pred = forward(x)
return (y_pred - y) **2
print("训练前(w=1),预测 x=4 时的 y_pred:", forward(4).item())
for epoch in range(50):
for x,y in zip(x_data, y_data):
l = loss(x,y) # l是个Tensor
l.backward() # 调用Trnsor的成员函数
# 会自动计算链路中的各个梯度,梯度存到w里,backward后计算图即被释放
print("\tx={0} y={1} grad={2}".format(x, y, w.grad.item()), end = ' ') #.item()相当于直接把梯度里的标量值拿出来
w.data = w.data - 0.01 * w.grad.data #注意:w.grad是张量,所以需要用.data做运算
w.grad.data.zero_() #注意:一定要清零,防止下次的结果在上次的结果上累加,此时w.grad.item()=0
print("权值:", w.data.item()) #这里之所以会显示是因为第10行设置了True
# 总结:构建计算图时直接用张量进行运算如求forward,loss,backward,权重更新时用data而不是张量
print("epoch:{0} loss:{1}".format(epoch, l.item() ))
print("训练后,预测 x=4 时的 y_pred:", forward(4).item())
输出结果
代码纯享版
# -*- coding:utf-8 -*-
import torch
x_data = [1.0, 2.0, 3.0]
y_data = [2.0, 4.0, 6.0]
w = torch.Tensor([1])
w.requires_grad = True
def forward(x):
return w*x
def loss(x,y):
y_pred = forward(x)
return (y_pred - y) **2
print("训练前(w=1),预测 x=4 时的 y_pred:", forward(4).item())
for epoch in range(50):
for x,y in zip(x_data, y_data):
l = loss(x,y)
l.backward()
print("\tx={0} y={1} grad={2}".format(x, y, w.grad.item()), end = ' ')
w.data = w.data - 0.01 * w.grad.data
w.grad.data.zero_()
print("权值:", w.data.item())
print("epoch:{0} loss:{1}".format(epoch, l.item() ))
print("训练后,预测 x=4 时的 y_pred:", forward(4).item())