基础神经网络构建
线性回归
引入相关的模块
import torch #torch模块
from torch.autograd import Variable #Variable模块,因为神经网络只能输入Variable
import torch.nn.functional as F #神经网络模块
import matplotlib.pyplot as plt #画图模块
随机制造一些数据来训练
#假的数据
x = torch.unsqueeze(torch.linspace(-1, 1, 100), dim=1) # x data (tensor), shape=(100, 1),torch的数据是有维度的,torch只会处理二维的数据
y = x.pow(2) + 0.2*torch.rand(x.size()) # noisy y data (tensor), shape=(100, 1),x的平方加上一些噪声(干扰数据)
x,y = Variable(x),Variable(y)#神经网络只能输入Variable
#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): #n_features输入数据(特征)的个数,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) #预测层,接收的神经元从隐藏层过来的神经元,1为预测的输出,因为这里只预测1个y值,所以为1
#这个函数用来搭建神经网络
def forward(self,x): #前向传播,x为输入信息
x = F.relu(self.hidden(x)) #激励函数激活一下这个信息,在这之前先用隐藏层来加工x的信息
x = self.predict(x) #output的输入就是x,就是预测层接收x,然后再输出
return x #为什么predict的时候不用激励函数?因为大多数回归问题预测的值的分布是无穷区间,如果用了激励函数则范围会缩小
net = Net(1,10,1) #输入为1个特征,隐藏层有10个神经元,输出为1个值
print(net) #神经网络的样子,可以打印出每一层的结构信息
plt.ion() #可视化的过程,实时打印
plt.show()
优化神经网络,计算误差
optimizer = torch.optim.SGD(net.parameters(),lr=0.5) #用于优化神经网络,需要传入我们神经网络的参数,给定学习率(这里可以看看是不是梯度下降来优化)
loss_func = torch.nn.MSELoss() #计算误差的手段,均方差,应该是计算代价函数
训练神经网络
for t in range(100): #训练一百次
prediction = net(x) #直接放入输入信息
loss = loss_func(prediction,y) #计算预测值与真实值y的误差
#这三步是优化的步骤
optimizer.zero_grad() #梯度设为0?,有可能梯度下降或者梯度上升,每次计算loss以后,梯度都会保留在optimizer里面,都会保留在net里面
loss.backward() #反向传播,loss是一个Variable
optimizer.step() #优化梯度,每次移动0.5
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)
plt.ioff()
plt.show()