Introduction to Neural Network
在人工神经网络里,没有产生新连接,网络固定不变
反向传播: 对比预测答案和真实答案的差别,再将差别去 反向传播 调整参数,提高正确率
详细的训练: 每个神经元都有一个自己的activate function, 刺激行为
神经网络: 梯度下降公式-》 优化问题optimization
求导求微分,Gradient Descent
沿着梯度去下降,得到最小的W值 -> 优化问题
迁移学习: 拆掉输出层,保留分辨能力,添加其他层,进行另外的功能
Pytorch PyTorch 是 Torch 在 Python 上的衍生. 因为 PyTorch 是一个使用 PyTorch 语言的神经网络库, Torch 很好用, 但是 Lua 又不是特别流行, 所有开发团队将 Lua 的 Torch 移植到了更流行的语言 Python 上. 是的 PyTorch 一出生就引来了剧烈的反响. 为什么呢?
而且如果你知道 Numpy , PyTorch 说他就是在神经网络领域可以用来替换 numpy 的模块.
神经网络在做什么 神经网络在学习拟合线条(回归):
PyTorch 和 Tensorflow 据 PyTorch 自己介绍, 他们家的最大优点就是建立的神经网络是动态的 , 对比静态的 Tensorflow, 他能更有效地处理一些问题, 比如说 RNN 变化时间长度的输出 . 而我认为, 各家有各家的优势和劣势, 所以我们要以中立的态度. 两者都是大公司, Tensorflow 自己说自己在分布式训练上下了很大的功夫, 那我就默认 Tensorflow 在这一点上要超出 PyTorch, 但是 Tensorflow 的静态计算图使得他在 RNN 上有一点点被动 (虽然它用其他途径解决了), 不过用 PyTorch 的时候, 你会对这种动态的 RNN 有更好的理解.
Torch 或 Numpy Torch 自称为神经网络界的 Numpy, 因为他能将 torch 产生的 tensor 放在 GPU 中加速运算 (前提是你有合适的 GPU), 就像 Numpy 会把 array 放在 CPU 中加速运算. 所以神经网络的话, 当然是用 Torch 的 tensor 形式数据 最好咯. 就像 Tensorflow 当中的 tensor 一样.
1 2 3 4 5 6 7 import torchimport numpy as npnp_data = np.arange(6 ).reshape((2 , 3 )) torch_data = torch.from_numpy(np_data) tensor2array = torch_data.numpy() np.sin(data) == torch.sin(data)
除了简单的计算, 矩阵运算 才是神经网络中最重要的部分. 所以我们展示下矩阵的乘法. 注意一下包含了一个 numpy 中可行, 但是 torch 中不可行的方式.
variable就是存放神经网络参数的东西,并且神经网络优化一般都是优化类型为variable的节点
1 2 3 4 5 6 7 8 9 data = [[1 , 2 ], [3 , 4 ]] tensor = torch.FloatTensor(data) print( "\nmatrix multiplication (matmul)" , "\nnumpy" , np.matmul(data, data), "\ntorch" , torch.mm(tensor, tensor) )
变量 (Variable) 在 Torch 中的 Variable 就是一个存放会变化的值的地理位置. 里面的值会不停的变化. 就像一个裝鸡蛋的篮子, 鸡蛋数会不停变动. 那谁是里面的鸡蛋呢, 自然就是 Torch 的 Tensor 咯. 如果用一个 Variable 进行计算, 那返回的也是一个同类型的 Variable.
我们定义一个 Variable:
1 2 3 4 5 6 7 8 9 10 import torchfrom torch.autograd import Variable tensor = torch.FloatTensor([[1 , 2 ], [3 , 4 ]]) variable = Variable(tensor, requires_grad = True ) print( tensor )
Variable 计算, 梯度 我们再对比下Tensor的计算和variable的计算
1 2 3 4 5 6 7 import torchfrom torch.autograd import Variabletensor = torch.FloatTensor([[1 , 2 ], [3 , 4 ]]) t_out = torch.mean(tensor*tensor) v_out = torch.mean(variable*variable) print(t_out) print(v_out)
到目前为止, 我们看不出什么不同, 但是时刻记住, Variable 计算时, 它在背景幕布后面一步步默默地搭建着一个庞大的系统, 叫做计算图, computational graph. 这个图是用来干嘛的? 原来是将所有的计算步骤 (节点) 都连接起来, 最后进行误差反向传递的时候, 一次性将所有 variable 里面的修改幅度 (梯度) 都计算出来, 而 tensor 就没有这个能力啦.
v_out = torch.mean(variable*variable)
就是在计算图中添加的一个计算步骤, 计算误差反向传递的时候有他一份功劳, 我们就来举个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import torch from torch.autograd import Variable tensor = torch.FloatTensor([[1 , 2 ], [3 , 4 ]]) variable = Variable(tensor, requires_grad = True ) t_out = torch.mean(tensor*tensor) v_out = torch.mean(variable*variable) print(t_out) print(v_out) v_out.backward() print( "variable.grad: " ,variable.grad )
获取Variable 里面的数据 直接print(variable)
只会输出Variable 形式的数据,很多时候用不了(plt画图),转化成Tensor
1 2 3 print(variable) print(Variable.data) print(variable.data.numpy())
激励函数 Activation Function 为什么需要?解决 日常生活总不能用 线性方程解决的问题
Linear; NonLinear; y = Wx
=> y = AF(Wx)
; W 就是我们要求的参数, y 是预测值, x 是输入值.
激励函数
AF 就是指的激励函数(本身就是非线性的,必须可微分). 激励函数拿出自己最擅长的”掰弯利器”, 套在了原函数上 用力一扭, 原来的 Wx 结果就被扭弯了。
你甚至可以创造自己的激励函数来处理自己的问题, 不过要确保的是这些激励函数必须是可以微分的, 因为在 backpropagation 误差反向传递的时候, 只有这些可微分的激励函数才能把误差传递回去。当你使用特别多层的神经网络, 在掰弯的时候, 玩玩不得随意选择利器. 因为这会涉及到梯度爆炸, 梯度消失的问题。卷积神经网络 Convolutional neural networks 的卷积层中, 推荐的激励函数是 relu. 在循环神经网络中 recurrent neural networks, 推荐的是 tanh 或者是 relu
pytorch activation function
神经网络中的每一层出来都是线性的函数关系,而在日常生活许多都是非线性关系。因此我们需要用激活函数将线性网络转成非线性结果。就是让神经网络可以描述非线性问题的步骤, 是神经网络变得更强大.
Torch中的激励函数 Torch中的激励函数: relu, sigmoid, tanh, softplus
1 2 3 4 5 6 import torchimport torch.nn.funcational as F from torch.autograd import Variablex = torch.linespace(-5 , 5 , 200 ) x = Variable(x)
接着就是做生成不同的激励函数数据:
1 2 3 4 5 6 7 x_np = x.data.numpy() y_relu = F.relu(x).data.numpy() y_sigmoid = F.sigmoid(x).data.numpy() y_tanh = F.tanh(x).data.numpy() y_softplus = F.softplus(x).data.numpy()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 import matplotlib.pyplot as plt plt.figure(1 , figsize = (8 , 6 )) plt.subplot(221 ) plt.plot(x_np, y_relu, c='red' , label="relu" ) plt.ylim((-1 , 5 )) plt.legend(loc="best" ) plt.subplot(223 ) plt.plot(x_np, y_sigmoid, c="blue" , label="sigmoid" ) plt.ylim((-0.1 , 1.2 )) plt.legend(loc="best" ) plt.subplot(222 ) plt.plot(x_np, y_tanh, c="orange" , label="tanh" ) plt.ylim((-1.1 , 1.1 )) plt.legend(loc="best" ) plt.subplot(224 ) plt.plot(x_np, y_softplus, c="yellow" , label="softplus" ) plt.ylim((-1 , 5 )) plt.legend(loc="best" ) plt.show()
神经网络 神经网络分为两类: 回归和分类;
回归,就是结果为一些系列连续的值,如f(房价) = W(大小,地点等);
分类,就是判断结果的类别, 如图像中判断 是 猫还是狗
关系拟合(回归) 来见证神经网络是如何通过简单的形式将一群数据用一条线条来表示. 或者说, 是如何在数据当中找到他们的关系, 然后用神经网络模型来建立一个可以代表他们关系的线条 .
建立数据集 我们创建一些假数据来模拟真实的情况. 比如一个一元二次函数: y = a * x^2 + b
, 我们给 y
数据加上一点噪声来更加真实的展示它.
1 2 3 4 5 6 7 8 9 import torchimport matplotlib.pyplot as pltx = torch.unsqueeze(torch.linspace(-1 , 1 , 100 ), dim=1 ) y = x.pow(2 ) + 0.2 *torch.rand(x.size()) plt.scatter(x.data.numpy(), y.data.numpy()) plt.show()
建立神经网络 建立一个神经网络我们可以直接运用 torch 中的体系. 先定义所有的层属性 (__init__()
), 然后再一层层搭建(forward(x)
)层与层的关系链接 . 建立关系的时候, 我们会用到激励函数,
1 2 3 4 5 6 7 8 9 10 import torchimport torch.nn.funcational as Fclass Net (torch.nn.Module) : def __init__ (self) : super(Net, self).__init__() pass def forward (self, x) : pass
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 import torchimport torch.nn.funcational as Fclass Net (torch.nn.Module) : def __init__ (self, n_features, n_hidden, n_output) : super(Net, self).__init__() self.hidden = torch.nn.Linear(n_features, n_hidden) self.predict = torch.nn.Linear(n_hidden, n_output) pass def forward (self, x) : x = F.relu(self.hidden(x)) x = self.predict(x) return x net = Net(n_features=1 , n_hidden=10 , n_output=1 ) print(net) """ Net ( (hidden): Linear (1 -> 10) (predict): Linear (10 -> 1) ) """
训练网络 训练步骤很简单:
1 2 3 4 5 6 7 8 9 10 11 optimizer = torch.optim.SGD(net.parameters(), lr=0.2 ) loss_func = torch.nn.MSELoss() for t in range(100 ): prediction = net(x) loss = loss_func(prediction, y) optimizer.zero_grad() loss.backward() optimizer.step()
可视化训练过程 理解如何训练
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import matplotlib.pyplot as pltplt.ion() plt.show() optimizer = torch.optim.SGD(net.parameters(), lr=0.2 ) loss_func = torch.nn.MSELoss() for t in range(200 ): prediction = net(x) loss = loss_func(prediction, y) optimizer.zero_grad() loss.backward() optimizer.step() if t%5 == 0 : 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 )
区分类型(分类) Classification 分类; x 是32bit FloatTensor, y 64bit FloatTensor
建立数据集 创建一些假数据来模拟真实的情况. 比如两个二次分布的数据, 不过他们的均值都不一样.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import torchimport matplotlib.pyplot as pltn_data = torch.ones((100 , 2 )) x0 = torch.normal(2 *n_data, 1 ) y0 = torch.zeros((100 ,)) x1 = torch.normal(-2 *n_data, 1 ) y1 = torch.ones((100 ,)) x = torch.cat((x0, x1), 0 ).type(torch.FloatTensor) y = torch.cat((y0, y1),).type(torch.LongTensor) plt.scatter(x.data.numpy()[:, 0 ], x.data.numpy()[:, 1 ], c=y.data.numpy(), s=100 , lw=0 , cmap='RdYlGn' ) plt.show()
建立神经网络 建立一个神经网络我们可以直接运用 torch 中的体系:
先定义所有的层属性(__init__()
) , 定义神经元个数
再一层层搭建(forward(x)
)层于层的关系链接.建立关系的时候, 我们会用到激励函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import torchimport torch.nn.functional as F class Net (torch.nn.Module) : def __init__ (self, n_feature, n_hidden, n_output) : super(Net, self).__init__() self.hidden = torch.nn.Linear(n_feature, n_hidden) self.predict = torch.nn.Linear(n_hidden, n_output) pass def forward (self, x) : x = F.relu(self.hidden(x)) x = self.predict(x) return x net = Net(n_feature=2 , n_hidden=10 , n_output=2 ) print(net)
训练网络 用优化器 训练 网络参数;loss 反向传播
1 2 3 4 5 6 7 8 9 10 11 optimizer = torch.optim.SGD(net.parameters(), lr=0.02 ) loss_func = torch.nn.CrossEntropyLoss() for t in range(100 ): out = net(x) loss = loss_func(out, y) optimizer.zero_grad() loss.backward() optimizer.step()
可视化训练过程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import matplotlib.pyplot as pltplt.ion() plt.show() optimizer = torch.optim.SGD(net.parameters(), lr=0.02 ) loss_func = torch.nn.CrossEntropyLoss() for t in range(100 ): out = net(x) loss = loss_func(out, y) optimizer.zero_grad() loss.backward() optimizer.step() if t%2 == 0 : plt.cla() prediction = torch.max(F.softmax(out), 1 )[1 ] pred_y = prediction.data.numpy().squeeze() target_y = y.data.numpy() plt.scatter(x.data.numpy()[:,0 ], x.data.numpy()[:,1 ], c=pred_y, s=100 , lw=0 , cmap='RdYlGn' ) accuracy = sum(pred_y == target_y) /200 plt.text(1.5 , -4 , 'Accuracy=%.2f' %accuracy, fontdict={'size' :20 , 'color' :'red' }) plt.pause(0.1 ) plt.ioff() plt.show()
快速搭建 之前的搭法
1 2 3 4 5 6 7 8 9 10 11 12 13 import torchclass Net (torch.nn.Module) : def __init__ (self, n_feature, n_hidden, n_output) : super(Net, self).__init__() self.hidden = torch.nn.Linear(n_feature, n_hidden) self.output = torch.nn.Linear(n_hidden, n_output) pass def forward (self, x) : x = F.relu(self.hidden(x)) x = self.output(x) return x net1 = Net(1 , 10 , 1 ) print(net)
我们用 class 继承了一个 torch 中的神经网络结构, 然后对其进行了修改 , 不过还有更快的一招, 用一句话就概括了上面所有的内容!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 net2 = torch.nn.Sequential( torch.nn.Linear(1 , 10 ), torch.nn.ReLU(), torch.mm.Linear(10 , 1 ) ) print(net1) """ Net ( (hidden): Linear (1 -> 10) (predict): Linear (10 -> 1) ) """ print(net2) """ Sequential ( (0): Linear (1 -> 10) (1): ReLU () (2): Linear (10 -> 1) ) """
我们会发现 net2
多显示了一些内容, 这是为什么呢? 原来他把激励函数也一同纳入进去了, 但是 net1
中, 激励函数实际上是在 forward()
功能中才被调用的. 这也就说明了, 相比 net2
, net1
的好处就是, 你可以根据你的个人需要更加个性化你自己的前向传播过程, 比如(RNN). 不过如果你不需要七七八八的过程, 相信 net2
这种形式更适合你.
保存提取 训练好了一个模型, 我们当然想要保存它, 留到下次要用的时候直接提取直接用
保存 我们快速建造数据,搭建神经网络
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import torchtorch.manual_seed(1 ) x = torch.unsqueeze(torch.linspace(-1 , 1 , 100 ), dim=1 ) y = x.pow(2 )+0.2 *torch.rand(x.size()) def save () : net1 = torch.nn.Sequential( torch.nn.Linear(1 , 10 ), torch.nn.ReLu(), torch.nn.Linear(10 , 1 ) ) optimizer = torch.optim.SGD(net1.parameters(), lr=0.02 ) loss_func = torch.nn.MSELoss() for t in range(2000 ): prediction = net1(x) loss = loss_func(prediction, y) optimizer.zero_grad() loss.backkward() optimizer.step() torch.save(net1, 'net.pkl' ) torch.save(net1.state_dict(), 'net_params.pkl' ) prediction = net1(x) plt.figure(1 , figsize=(10 , 3 )) plt.subplot(131 ) plt.title('Net1' ) plt.scatter(x.data.numpy(), y.data.numpy()) plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-' , lw=5 )
提取网络 提取整个神经网络, 网络大的时候可能会比较慢.
1 2 3 4 5 6 7 8 def restore_net () : net2 = torch.load('net.pkl' ) prediction = net2(x) plt.subplot(132 ) plt.title('Net2' ) plt.scatter(x.data.numpy(), y.data.numpy()) plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-' , lw=5 )
只提取网络参数 提取所有的参数, 然后再放到你的新建网络中.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 def restore_params () : net3 = torch.nn.Sequential( torch.nn.Linear(1 , 10 ) torch.nn.ReLU() torch.nn.Linear(10 , 1 ) ) net3.load_state_dict(torch.load('net_params.pkl' )) prediction = net3(x) plt.subplot(133 ) plt.title('Net3' ) plt.scatter(x.data.numpy(), y.data.numpy()) plt.plot(x.data.numpy(), prediction.data.numpy(), 'r-' , lw=5 )
显示结果 1 2 3 4 5 6 7 save() restore_net() restore_params() plt.show()
批训练 Torch中有个帮助整理数据结构,DataLoader
,用来包装自己的数据,进行批训练,批训练途径:
DataLoader DataLoader
是 torch 给你用来包装你的数据的工具 . 所以你要讲自己的 (numpy array 或其他) 数据形式装换成 Tensor , 然后再放进这个包装器 中. 使用 DataLoader
有什么好处呢? 就是他们帮你有效地迭代数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 , ximport torch import torch.utils.data as Datatorch.manual_seed(1 ) BATCH_SIZE = 5 x = torch.linspace(1 , 10 , 10 ) y = torch.linspace(10 , 1 , 10 ) torch_dataset = Data.TensorDataset(data_tensor=x, target_tensor=y) loader = Data.DataLoader( dataset=torch_dataset, batch_size = BATCH_SIZE, shuffle=True , num_workers=2 , ) for epoch in range(3 ): for step, (batch_x, batch_y) in enumerate(loader): print('Epoch: ' , epoch, '| Step: ' , step, '| batch x: ' , batch_x.numpy(), '| batch y: ' , batch_y.numpy())
可以看出, 每步都导出了5个数据进行学习. 然后每个 epoch 的导出数据都是先打乱了以后再导出.
真正方便的还不是这点. 如果我们改变一下 BATCH_SIZE = 8
, 这样我们就知道, step=0
会导出8个数据, 但是, step=1
时数据库中的数据不够 8个, 这时怎么办呢:
这时, 在 step=1
就只给你返回这个 epoch 中剩下的数据就好了.
加速神经网络训练 (Speed Up Training) 包括以下几种模式:
Stochastic Gradient Descent (SGD)
Momentum
AdaGrad
RMSProp
Adam
Stochastic Gradient Descent (SGD)
最基础的方法就是 SGD 啦, 想像红色方块是我们要训练的 data, 如果用普通的训练方法, 就需要重复不断的把整套数据放入神经网络 NN训练, 这样消耗的计算资源会很大.
我们换一种思路, 如果把这些数据拆分成小批小批的, 然后再分批不断放入 NN 中计算, 这就是我们常说的 SGD 的正确打开方式了. 每次使用批数据, 虽然不能反映整体数据的情况, 不过却很大程度上加速了 NN 的训练过程, 而且也不会丢失太多准确率.如果运用上了 SGD, 你还是嫌训练速度慢, 那怎么办?
事实证明, SGD 并不是最快速的训练方法, 红色的线是 SGD, 但它到达学习目标的时间是在这些方法中最长的一种. 我们还有很多其他的途径来加速训练.
Momentum 更新方法
大多数其他途径是在更新神经网络参数那一步上动动手脚. 传统的参数 W 的更新是把原始的 W 累加上一个负的学习率(learning rate) 乘以校正值 (dx).这种方法可能会让学习过程曲折无比, 看起来像 喝醉的人回家时, 摇摇晃晃走了很多弯路.
所以我们把这个人从平地上放到了一个斜坡上, 只要他往下坡的方向走一点点, 由于向下的惯性, 他不自觉地就一直往下走, 走的弯路也变少了. 这就是 Momentum 参数更新. 另外一种加速方法叫AdaGrad.
AdaGrad 更新方法
这种方法是在学习率上面动手脚, 使得每一个参数更新都会有自己与众不同的学习率 , 他的作用和 momentum 类似, 不过不是给喝醉酒的人安排另一个下坡, 而是给他一双不好走路的鞋子, 使得他一摇晃着走路就脚疼, 鞋子成为了走弯路的阻力, 逼着他往前直着走. 他的数学形式是这样的. 接下来又有什么方法呢? 如果把下坡和不好走路的鞋子合并起来, 是不是更好呢? 没错, 这样我们就有了 RMSProp 更新方法.
RMSProp 更新方法
有了 momentum 的惯性原则 , 加上 adagrad 的对错误方向的阻力, 我们就能合并成这样. 让 RMSProp同时具备他们两种方法的优势. 不过细心的同学们肯定看出来了, 似乎在 RMSProp 中少了些什么. 原来是我们还没把 Momentum合并完全, RMSProp 还缺少了 momentum 中的 这一部分. 所以, 我们在 Adam 方法中补上了这种想法.
Adam 更新方法
计算m 时有 momentum 下坡的属性, 计算 v 时有 adagrad 阻力的属性, 然后再更新参数时 把 m 和 V 都考虑进去. 实验证明, 大多数时候, 使用 adam 都能又快又好的达到目标, 迅速收敛. 所以说, 在加速神经网络训练的时候, 一个下坡, 一双破鞋子, 功不可没.
Optimizer 优化器 伪数据 为了对比各种优化器的效果, 我们需要有一些数据, 今天我们还是自己编一些伪数据, 这批数据是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import torchimport torch.utils.data as Dataimport torch.nn.functional as Fimport matplotlib.pyplot as plttorch.manual_seed(1 ) LR = 0.01 BATCH_SIZE = 32 EPOCH = 12 x = torch.unsqueeze(torch.linpsace(-1 , 1 , 1000 ), dim=1 ) y = x.pow(2 ) + 0.1 *torch.normal(torch.zeros(*x.size())) plt.scatter(x.numpy(), y.numpy()) plt.show() torch_dataset = Data.TensorDataset(x, y) loader = Data.DataLoader(dataset=torch_dataset, batch_size=BATCH_SIZE, shuffle=True , num_workers=2 )
每个优化器优化一个神经网络 为了对比每一种优化器, 我们给他们各自创建一个神经网络, 但这个神经网络都来自同一个 Net
形式.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Net (torch.nn.Module) : def __init__ (self) : super(Net, self).__init__() self.hidden = torch.nn.Linear(1 , 20 ) self.predict = torch.nn.Linear(20 , 1 ) def forward (self, x) : x = F.relu(self.hidden(x)) x = self.predict(x) return x net_SGD = Net() net_Momentum = Net() net_RMSprop = Net() net_Adam = Net() nets = [net_SGD, net_Momentum, net_RMSprop, net_Adam]
优化器 Optimizer 接下来在创建不同的优化器, 用来训练不同的网络. 并创建一个 loss_func
用来计算误差. 我们用几种常见的优化器, SGD
, Momentum
, RMSprop
, Adam
.
1 2 3 4 5 6 7 8 opt_SGD = torch.optim.SGD(net_SGD.parameters(), lr=LR) opt_Momentum = torch.optim.SGD(net_Momentum.parameters(), lr=LR, momentum=0.8 ) opt_RMSprop = torch.optim.RMSprop(net_RMSprop.parameters(), lr=LR, alpha=0.9 ) opt_Adam = torch.optim.Adam(net.net_Adam.parameters(), lr=LR, betas=(0.9 , 0.99 )) optimizers = [opt_SGD, opt_Momentum, opt_RMSprop, opt_Adam] loss_func = torch.nn.MSELoss() loss_his = [[], [], [], []]
训练/出图 1 2 3 4 5 6 7 8 9 10 11 for epoch in range(EPOCH): print(epoch) for step, (b_x, b_y) in enumerate(loader): for net, opt, l_his in zip(nets, optimizers, loss_his): output = net(b_x) loss = loss_func(output, b_y) opt.zero_grad() loss.backward() opt.step() l_his.append(loss.data.numpy())