第一个pytorch
昨晚学习了一下如何搭建一个简易神经网络,现在来讲述一下
一、首先需要在anaconda安装一个pytorch库
到这个网址https://www.lfd.uci.edu/~gohlke/pythonlibs/#pytorch下载符合你电脑python版本的库文件
比如说我的python是3.5版本的电脑是64位,就选择cp35m-win_amd64(一定要下正确!!)
下载好后就打开anaconda prompt
打开anaconda prompt之后默认路径是c盘的user文件,若你下载的库文件没存在默认路径,存在了d盘,则输入以下操作就可以到达你文存的位置:
路径对了后,输入命令:pip install 文件名,然后就会开始下载了
如果你下载出现错误,那可能是numpy的版本不匹配的问题了
这时你还要下载一个符合你电脑python版本的numpy库,
https://www.lfd.uci.edu/~gohlke/pythonlibs/#numpy
下载步骤一样
二、开始搭建简易神经网络
1、导入torch,定义变量
import torch batch_n = 100 #输入的数据量是100 hidden_layer = 100 #隐藏层是一层 input_data = 1000 #每个数据有1000个特征 output_data = 10 #输出值为10个
变量定义:batch_n是在一个批次中输入数据的数量,值是100,这意味着我们在一个批次中输入100个数据,同时,每个数据包含的数据特征有input_data个,因为input_data的值是1000,所以每个数据的特征就是1000个,hidden_layer用于定义经过隐藏层后保留的数据特征的个数,这里有100个,因为我们的模型只考虑一层隐藏层,所以在代码中仅仅定义了一个隐藏层的参数;output_data是输出的数据,值是10,我们可以将输出的数据看作一个分类结果值得数量,个数10表示我们最后要得到10个分类结果值。
2.初始化权重
x = torch.randn(batch_n, input_data) #随机选取100个数据,每个数据都有1000个特征,形成100*1000的矩阵,每行代表一个数据。 y = torch.randn(batch_n, output_data) #随机形成一个100*10的矩阵,y是真实值 w1 = torch.randn(input_data, hidden_layer) #w1是输入层到隐藏层的权重参数 w2 = torch.randn(hidden_layer, output_data) #w2是隐藏层到输出层的权重参数
3、定义训练次数和学习效率
epoch_n = 20 #训练次数是20次 learning_rate = 1e-6 #学习效率是1e-6
4、梯度下降优化神经网络的参数
for epoch in range(epoch_n): #前向传播 h = x.mm(w1) # 100*1000 #h=x*w1 h1 = h.clamp(min=0) #h1=ReLu(h) y_pred = h1.mm(w2) # 100*10 #y_pred是预测值,y_pred=h1*w2 # print(y_pred) #后向传播 loss = (y_pred - y).pow(2).sum() #loss是损失函数 print("Epoch:{} , Loss:{:.4f}".format(epoch, loss)) gray_y_pred = 2 * (y_pred - y) #y_pred的梯度=∂loss/∂y_pred gray_w2 = h1.t().mm(gray_y_pred) #w2的梯度=(∂loss/∂y_pred)*(∂y_pred/∂w2) grad_h = gray_y_pred.clone() #返回一个张量的副本,其与原张量的尺寸和数据类型相同。即给gray_y_pred另一个别名 grad_h = grad_h.mm(w2.t()) grad_h.clamp_(min=0) grad_w1 = x.t().mm(grad_h) w1 -= learning_rate * grad_w1 w2 -= learning_rate * gray_w2
前向传播和后向传播的就算过程图:
要想深入理解后向传播,可以看看这个博主的https://www.cnblogs.com/wj-1314/p/9830950.html
完整代码:
import torch batch_n = 100 #输入的数据量是100 hidden_layer = 100 #隐藏层是一层 input_data = 1000 #每个数据有1000个特征 output_data = 10 #输出值为10个 x = torch.randn(batch_n, input_data) #随机选取100个数据,每个数据都有1000个特征,形成100*1000的矩阵,每行代表一个数据。 y = torch.randn(batch_n, output_data) #随机形成一个100*10的矩阵,y是真实值 w1 = torch.randn(input_data, hidden_layer) #w1是输入层到隐藏层的权重参数 w2 = torch.randn(hidden_layer, output_data) #w2是隐藏层到输出层的权重参数 epoch_n = 20 #训练次数是20次 learning_rate = 1e-6 #学习效率是1e-6 for epoch in range(epoch_n): #前向传播 h = x.mm(w1) # 100*1000 #h=x*w1 h1 = h.clamp(min=0) #h1=ReLu(h) y_pred = h1.mm(w2) # 100*10 #y_pred是预测值,y_pred=h1*w2 # print(y_pred) #后向传播 loss = (y_pred - y).pow(2).sum() #loss是损失函数 print("Epoch:{} , Loss:{:.4f}".format(epoch, loss)) gray_y_pred = 2 * (y_pred - y) #y_pred的梯度=∂loss/∂y_pred gray_w2 = h1.t().mm(gray_y_pred) #w2的梯度=(∂loss/∂y_pred)*(∂y_pred/∂w2) grad_h = gray_y_pred.clone() #返回一个张量的副本,其与原张量的尺寸和数据类型相同。即给gray_y_pred另一个别名 grad_h = grad_h.mm(w2.t()) grad_h.clamp_(min=0) grad_w1 = x.t().mm(grad_h) w1 -= learning_rate * grad_w1 w2 -= learning_rate * gray_w2
结果:
Epoch:0 , Loss:43615284.0000 Epoch:1 , Loss:91471992.0000 Epoch:2 , Loss:330298272.0000 Epoch:3 , Loss:683488832.0000 Epoch:4 , Loss:122780872.0000 Epoch:5 , Loss:20005414.0000 Epoch:6 , Loss:9135615.0000 Epoch:7 , Loss:5064396.5000 Epoch:8 , Loss:3213300.2500 Epoch:9 , Loss:2285546.5000 Epoch:10 , Loss:1784441.1250 Epoch:11 , Loss:1492424.2500 Epoch:12 , Loss:1307289.6250 Epoch:13 , Loss:1179117.7500 Epoch:14 , Loss:1082826.7500 Epoch:15 , Loss:1005753.7500 Epoch:16 , Loss:940913.1250 Epoch:17 , Loss:884514.8750 Epoch:18 , Loss:834361.0000 Epoch:19 , Loss:789175.0625