一、描述
神经网络如何通过简单的形式将一群数据用一条线在表示。找到数据之间的关系,然后通过神经网络模型来建立一个可以表示他们关系的曲线。
二、步骤
1.创建数据集:
创建一些假数据来模拟。令,给y加上一些噪声。
import torch
import matplotlib.pyplot as plt
from torch.autograd import Variable
#建立数据集
x=torch.unsqueeze(torch.linspace(-1,1,100),dim=1)#x data(tensor,shape=(100,1) unsqueeze将1维数据转换为2维数据,因为torch只能处理2D数据
y=x.pow(2)+0.2*torch.rand(x.size()) #给y加上一点噪声
- 注1:unsqueeze函数中的参数dim的取值为-2,-1,0,1。取值为-2和0的结果一样,取值为-1和1的结果一样:
x1=torch.unsqueeze(torch.linspace(-1,1,5),dim=-1)
x2=torch.unsqueeze(torch.linspace(-1,1,5),dim=-2)
print('dim=-1 or dim=1:\n',x1)
print('dim=-2 or dim=0:\n',x2)
#运行结果:
dim=-1 or dim=1:
tensor([[-1.0000],
[-0.5000],
[ 0.0000],
[ 0.5000],
[ 1.0000]])
dim=-2 or dim=0:
tensor([[-1.0000, -0.5000, 0.0000, 0.5000, 1.0000]])
- 注2:torch.rand(size):返回一个张量,包含了从区间[0,1)的均匀分布中抽取的一组随机数,张量的形状有参数size定义。pytorch生成随机数的函数还有torch.randn():标准正太分布;torch.normal():离散正太分布;torch.linspace():线性间距向量。
举例:
import torch
x=torch.unsqueeze(torch.linspace(-1,1,5),dim=1)
noisy=torch.rand(x.size())
print('x:\n',x)
print('noisy:\n',noisy)
运行结果:
x:
tensor([[-1.0000],
[-0.5000],
[ 0.0000],
[ 0.5000],
[ 1.0000]])
noisy:
tensor([[0.1946],
[0.9093],
[0.8763],
[0.2535],
[0.9164]])
2.创建神经网络:
用torch中的module来建立一个神经网络。先定义所有的层属性(__init__()),然后再一层层搭建(forward(x))搭建层与层之间的关系。建立关系的时候,要用到激活函数,每一层隐藏层的输出值需要用激活函数进行加工才能作为下一层的输入值。
x=Variable(x)#因为神经网络只能输入Varible
y=Variable(y)
#创建神经网络
class Net(torch.nn.Module): #继承torch的Module,Net的主模块,很多神经网络的功能都包含在这个模块中
def __init__(self,n_feature,n_hidden,n_output): #定义层属性
super(Net,self).__init__() #继承__init__功能
#定义每一层用什么样的形式
self.hidden=torch.nn.Linear(n_feature,n_hidden) #隐藏层,隐藏层包含的内容就是有n_feature个输入he n_hidden个输出
self.predict=torch.nn.Linear(n_hidden,n_output) #输出层,n_hidden个输入和n_output个输出
def forward(self,x): #前向传播,搭建层与层的关系,x为输入信息
#搭建神经网络: 前向传播输入值,神经网络分析输出值
a_i=torch.relu(self.hidden(x)) #输入值用激活函数处理。在激活之前要加工一下输入的x(隐藏层的线性值)
h_x=self.predict(a_i) #输出值
return h_x
注:torch.nn.Linear():
class torch.nn.linear(in_features,out_features,bias=True) 对传入的数据做线性变换:y=ax+b
in_features:输入数据的大小;out_features:输出数据的大小
bias:默认为True,表示图层会学习附加偏差
举例:
import torch.nn
from torch.autograd import Variable
h_x=torch.nn.Linear(in_features=2,out_features=4)
in_features=Variable(torch.rand(3,2)) #在[0,1)区间随机生成3*2大小的随机数矩阵
out_features=h_x(in_features)
print(out_features)
print(out_features.size()) #out_features.size()=(3*2)*(2*4)=3*4
运行结果:
tensor([[-0.5179, -0.4531, 0.2644, -0.1680],
[-1.1484, -0.8473, 0.2247, -0.1441],
[-0.7792, -0.6470, 0.2994, -0.1619]], grad_fn=<AddmmBackward>)
torch.Size([3, 4])
3.训练网络并将其可视化:
net=Net(1,10,1)
#训练网络
#optimizer,优化神经网络
optimizer=torch.optim.SGD(net.parameters(),lr=0.2) #SGD是随机梯度下降算法。用优化器优化神经网络中的参数。传入net的所有参数,学习率。学习率越大表示学习的越快。
loss_func=torch.nn.MSELoss() #计算误差。预测值和真实值的误差计算公式(均方差)
for i in range(100): #开始训练
prediction=net.forward(x) #给net训练数据x,输出预测值
loss=loss_func(prediction,y) #计算误差,注意参数的顺序
#优化步骤:
optimizer.zero_grad() #step1:优化神经网络中的所有参数之前把参数的梯度都将为0,因为每一次计算loss以后,梯度都会保留在optimizer里面。清空上一步的残余更新参数值
loss.backward() #step2:误差反向传播,为每一个节点计算梯度,
optimizer.step() #step3:用optimizer优化梯度。将参数更新值施加到net的parameters上
if i%5==0: #每5步打印一次
plt.cla()
plt.scatter(x.data.numpy(),y.data.numpy())
plt.plot(x.data.numpy(),prediction.data.numpy(),color='red',linewidth='4')
plt.text(0.5,0,'Loss=%.4f'%loss.data.numpy())
plt.pause(0.1)
plt.show()