搭建网络顺序:
1.定义网络,网络Net的class,class Net(nn.Module):
2.定义一个优化器(目前用到adam优化器 替代传统随机梯度下降过程的一阶优化算法,它能基于训练数据迭代地更新神经网络权重)
3.定义损失函数
4.定义完成后进入循环
(1)清空优化器梯度信息 optimizer.zero_grad();
(2)input传入,正向传播 output=net(input)
(3)用损失函数计算损失 loss=compute_loss(target,output),target是期望值,output是网络输出值。
(4)反向传播 loss.backward()
(5)更新参数 optimizer.step()
参考https://blog.csdn.net/zkk9527/article/details/88399176
反向传播的解释
参考https://zhuanlan.zhihu.com/p/261710847
pytorch的网络搭建格式
先定义class
class Net(nn.Module):
Class里面主要写两个函数,一个是初始化的__init__函数,另一个是forward函数,比如:
import torch.nn.functional as F
import torch.nn as nn
class Net(nn.Module): # 任何层或神经网络都是module的子类。Net是module的子类
def __init__(self):
super().__init__() #调用他的父类module.init的参数,把需要的初始化参数设置好
self.conv1=nn.conv2d(1,6,5)
self.conv2=nn.conv2d(6,16,5)
def forward(self,x):
x=F.max_pool2d(F.relu(self.conv1(x)),2)
return x
__init__里面就是定义卷积层,super()一下,给父类nn.Module初始化。第一个卷积层输入是1通道,输出为6通道,卷积核
5
×
5
5\times5
5×5,后面接一个池化层,第二个卷积层输入是6通道,输出是16通道,卷积核
5
×
5
5\times5
5×5,输出是自己定义的,输入是上一层的输出,如果是全连接层输入为上一层每个单元都拉直,如
16
×
5
×
5
16\times5\times5
16×5×5。
forward里面就是真正执行数据的流动。比如上面的代码,输入的x先经过定义的conv1(这个名字是你自己起的),再经过激活函数F.relu()(这个就不是自己起的名字了,最开始应该先import torch.nn.functional as F,F.relu()是官方提供的函数。当然如果你在__init__里面把relu定义成了我上面说的myrelu,那你这里直接第一句话就成了x=F.max_pool2d(myrelu(self.conv1(x)),2)。下一步的F.max_pool2d池化也是一样的。在一系列流动以后,最后把x返回到外面去。
通过下述方式实现对权重W的更新:
【1】 先算loss对于输入x的偏导,(当然网络好几层,这个x指的是每一层的输入,而不是最开始的输入input)
【2】 对【1】的结果再乘以一个步长(这样就相当于是得到一个对参数W的修改量)
【3】 用W减掉这个修改量,完成一次对参数W的修改。