要点
这次会来见证神经网络是如何通过简单的形式将一群数据用一条线条来表示. 或者说, 是如何在数据当中找到他们的关系, 然后用神经网络模型来建立一个可以代表他们关系的线条.
建立数据集
我们创建一些假数据来模拟真实的情况. 比如一个一元二次函数:
, 我们给 y 数据加上一点噪声来更加真实的展示它
import torch
import matplotlib.pyplot as plt
import torch.nn.functional as F # 激励函数都在这
#torch.unsqueeze,torch.squeeze,torch.linspace我的之前文章有讲解
#在torch中,只会处理2维的数据,
x=torch.unsqueeze(torch.linspace(-1,1,100),dim=1)
#x.pow(2)的意思是x的平方
y=x.pow(2)+0.2*torch.rand(x.size())
#画图
plt.scatter(x.data.numpy(),y.data.numpy())
plt.show()
pytorch学习 中 torch.squeeze() 和torch.unsqueeze()的用法:CSDN-专业IT技术社区-登录blog.csdn.net
建立神经网络
建立一个神经网络我们可以直接运用 torch 中的体系. 先定义所有的层属性( __init__() ), 然后再一层层搭建(forward(x))层于层的关系链接. 建立关系的时候, 我们会用到激励函数.
class Net(torch.nn.Module):#继承torch的module
def __init__(self,n_feature,n_hidden,n_output):
super(Net,self).__init__() #继承__init__功能
#定义每一层用什么样的样式
self.hidden = torch.nn.Linear(n_feature,n_hidden) #隐藏层线性输出
self.predict = torch.nn.Linear(n_hidden,n_output) #输出层线性输出
def forward(self,x):
# 激励函数(隐藏层的线性值)
x=F.relu(self.hidden(x))
x=self.predict(x) #输出值
return x
我们定义一个1->10->1的网络结构
net = Net(1,10,1)
print(net)
print(net.parameters())
结果:
Net(
(hidden): Linear(in_features=1, out_features=10, bias=True)
(predict): Linear(in_features=10, out_features=1, bias=True)
)
可以看到Net的内部结构,net.parameters()是表示net模块里的参数,但是这样print看不到内容,我们在net.parameters()外面加上list,就可以打印出里面的内容了
para = list(net.parameters())
print(para)
结果:
[Parameter containing:
tensor([[-0.8071],
[-0.0896],
[-0.2232],
[-0.0489],
[-0.0234],
[ 0.7099],
[ 0.0146],
[-0.3764],
[-0.4424],
[ 0.0315]], requires_grad=True), Parameter containing:
tensor([ 0.2949, 0.8472, -0.2594, -0.8014, -0.9749, 0.2688, -0.0868, -0.8369,
0.7273, -0.9676], requires_grad=True), Parameter containing:
tensor([[-0.1560, 0.2062, 0.1508, 0.1066, 0.2852, 0.0929, 0.0903, 0.2248,
0.0319, -0.2936]], requires_grad=True), Parameter containing:
tensor([0.2569], requires_grad=True)]
关于parameters可以看我之前写的博客:CSDN-专业IT技术社区-登录blog.csdn.net
训练网络
训练的步骤很简单, 如下:
#optimizer是训练的工具
#传入net的所有参数和学习率
optimizer = torch.optim.SGD(net.parameters(),lr=0.2)
print(optimizer)
#预测值和真实值的误差计算公式(均方差)
loss_func = torch.nn.MSELoss()
for t in range(100):
#喂给net训练数据x,输出预测值
prediction = net(x)
#计算两者的误差
loss = loss_func(prediction,y)
#先把梯度全部降为0,防止梯度爆炸
#梯度清0
optimizer.zero_grad()
#误差反向传播,计算参数更新
loss.backward()
#更新权重参数
optimizer.step()
SGD (
Parameter Group 0
dampening: 0
lr: 0.2
momentum: 0
nesterov: False
weight_decay: 0
)
这里的内容有点多,先解释optimizer = torch.optim.SGD,这是一个优化器,在我之前的文章有讲解
optimizer.zero_grad():
由于pytorch的动态计算图,当我们使用loss.backward()和opimizer.step()进行梯度下降更新参数的时候,梯度并不会自动清零,所以需要optimizer.zero_grad()把梯度归0。并且这两个操作是独立操作
optimizer.zero_grad()
loss.backward()
optimizer.step()
这三步是搭建神经网络经常会用到的CSDN-专业IT技术社区-登录blog.csdn.net
可视化训练过程
plt.ion() # 画图
plt.show()
for t in range(100):
print(x.shape)
#喂给net训练数据x,输出预测值
prediction = net(x)
#计算两者的误差
loss = loss_func(prediction,y)
#先把梯度全部降为0,防止梯度爆炸
#梯度清0
optimizer.zero_grad()
#误差反向传播,计算参数更新
loss.backward()
#更新权重参数
optimizer.step()
if t % 5 == 0:
# plot and show learning process
plt.cla()
plt.scatter(x.data.numpy(), y.data.numpy())
plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5)
plt.text(0.5, 0, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color': 'red'})
plt.pause(0.1)
完整代码
import torch
import matplotlib.pyplot as plt
import torch.nn.functional as F
#torch.unsqueeze,torch.squeeze,torch.linspace有文章讲解
#在torch中,只会处理2维的数据
x=torch.unsqueeze(torch.linspace(-1,1,100),dim=1)
#x.pow(2)的意思是x的平方
y=x.pow(2)+0.2*torch.rand(x.size())
#画图
plt.scatter(x.data.numpy(),y.data.numpy())
plt.show()
class Net(torch.nn.Module):#继承torch的module
def __init__(self,n_feature,n_hidden,n_output):
super(Net,self).__init__() #继承__init__功能
#定义每一层用什么样的样式
self.hidden = torch.nn.Linear(n_feature,n_hidden) #隐藏层线性输出
self.predict = torch.nn.Linear(n_hidden,n_output) #输出层线性输出
def forward(self,x):
# 激励函数(隐藏层的线性值)
x=F.relu(self.hidden(x))
# x=F.relu(self.hidden(x))
x=self.predict(x) #输出值
return x
net = Net(1,10,1)
para = list(net.parameters())
#optimizer是训练的工具
#传入net的所有参数和学习率
optimizer = torch.optim.SGD(net.parameters(),lr=0.2)
#预测值和真实值的误差计算公式(均方差)
loss_func = torch.nn.MSELoss()
plt.ion() # 画图
plt.show()
for t in range(100):
print(x.shape)
#喂给net训练数据x,输出预测值
prediction = net(x)
#计算两者的误差
loss = loss_func(prediction,y)
#先把梯度全部降为0,防止梯度爆炸
#梯度清0
optimizer.zero_grad()
#误差反向传播,计算参数更新
loss.backward()
#更新权重参数
optimizer.step()
if t % 5 == 0:
# plot and show learning process
plt.cla()
plt.scatter(x.data.numpy(), y.data.numpy())
plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-', lw=5)
plt.text(0.5, 0, 'Loss=%.4f' % loss.data.numpy(), fontdict={'size': 20, 'color': 'red'})
plt.pause(0.1)