人工智能编程:神经收集的快速搭建模块以及收集模型参数的获取_神经收集_参数
为方便用户利用,PyTorch实现了神经网络中绝大多数的layer,这些layer都继续于nn.Module,封装了可学习参数parameter,并实现了forward函数,且很多都专门针对GPU运算进行了CuDNN优化,其速率和性能都十分精良。
如nn.Linear(in_features, out_features, bias),需关注这三个参数的浸染。
如nn.Linear中有weight和bias两个可学习参数输入输出的形状,如nn.linear的输入形状是(N, input_features),输出为(N,output_features),N是batch_size。
在PyTorch里面编写神经网络,所有的层构造和丢失函数都来自于torch.nn,所有的模型构建都是从这个基类 nn.Module 继续的,于是有了下面这个模板。
class net_name(nn.Moudle) :
def __init__ (self,other_ments) :
super(net_name,self). __init__()
self.conv1=nn.Conv2d(in_channels, out_channels, kernel_size)
# other network l ayer 其它网络层
def forward(self, x):
x=self.conv1(x)
return x
这样就建立了一个打算图 ,并且这个构造可以复用多次,每次调用就相称于用该打算图定义的相同参数做一次前向传播,这得益于 PyTorch 的自动求导功能,以是我们不须要自己编写反向传播,而所有的网络层都是由 nn 这个包得到的,比如线性层nn.Linear,等之后利用的时候我们可以详细地先容每一种网络对应的构造,以及如何调用。
定义完模型之后 ,我们须要通过nn这个包来定义丢失函数。 常见的丢失函数都已经定义在了nn巾,比如均方偏差 、多分类的交叉熵,以及二分类的交叉熵,等等,调用这些已经定义好的丢失函数也很大略:
criterion = nn.CrossEntropyLoss( )
loss = criterion(output, target)
这样就能求得我们的输出和真实目标之间的丢失函数了
常见的神经网络层:卷积层conv = nn.Conv2d(1, 1, (3, 3), 1, bias=False)
池化层pool = nn.AvgPool2d(2,2)
Linear:全连接层linear = nn.Linear(3, 4)
BatchNorm:批规范化层bn = nn.BatchNorm1d(4)
Dropout:dropout层dropout = nn.Dropout(0.5)#0.5的概率舍弃
激活函数relu = nn.ReLU(True)
# Embedding层,有4个词,每个词用5维的向量表示
embedding = nn.Embedding(4, 5)
搭建网络的两种办法我们在搭建神经网络的时候,可以将多个神经网络层组合在一起,我们可以利用Sequential和ModuleList这两种办法。
我们先来看一下Sequential,它我们可以看作是一个module
# Sequential的三种写法
写法一:为每一个神经网络层添加一个名字
net1 = nn.Sequential()
net1.add_module('conv', nn.Conv2d(3, 3, 3))
net1.add_module('batchnorm', nn.BatchNorm2d(3))
net1.add_module('activation_layer', nn.ReLU())
由于有名字,以是我们可以根据名字来取出神经网络的每一层
net1.conv
net1.batchnorm
前向传播out=net1(input)
写法二:
net2 = nn.Sequential(
nn.Conv2d(3, 3, 3),
nn.BatchNorm2d(3),
nn.ReLU()
)
这个没有名字,我们可以通过索引取出Sequential中神经网路的每一层
net2[0]
前向传播out=net2(input)
写法三:利用OrderedDict将神经网络层封装为一个字典,然后通报到Sequential中
from collections import OrderedDict
net3= nn.Sequential(OrderedDict([
('conv1', nn.Conv2d(3, 3, 3)),
('bn1', nn.BatchNorm2d(3)),
('relu1', nn.ReLU())
]))
可以根据名字取出神经网络的每一层
net3.conv1
前向传播
办法一:output = net3(input)
办法二:output = net3.relu1(net1.batchnorm(net1.conv(input)))
ModuleList的利用办法,把稳ModuleList在Module中利用它的时候(在实现nn.Module的__init__()方法中利用的时候),才能自动识别为子module。
class Net4(nn.Module):
def __init__(self):
super(Net4, self).__init__()
self.module_list = nn.ModuleList([nn.Conv2d(3, 3, 3), nn.ReLU()])
def forward(self):
model = MyModule()
ModuleList实在便是一个List,只不过在Module中它会自动识别为module,识别为module的好处便是它会作为全体module的一个整体,在反向传播中跟新其参数。
除ModuleList之外还有ParameterList,其是一个可以包含多个parameter的类list工具。我们如果假如在init中用到list,我们该当用ModuleList或ParameterList,而不是利用list。
class MyLinear(nn.Module):
def __init__(self, inp, outp):
super(MyLinear, self).__init__()
# requires_grad = True
self.w = nn.Parameter(torch.randn(outp, inp))
self.b = nn.Parameter(torch.randn(outp))
def forward(self, x):
x = x @ self.w.t() + self.b
return x
这个表示建立一个全连接层,w和b便是全连接层的权重参数,个中w的维度是(输出,输入)
nn.Parameter中会自带梯度求梯度功能
获取参数
Net.parameters()表示获取net的所有参数
List表示转换为列脸色势,此时这个列表该当是[w0,b0,w1,b1]
遍历所有的模型的参数,个中name表示模型的参数,把稳这个名字中没有net.1,这是由于nn.ReLU是模型的第二层,但是这里并没有参数,以是net.0之后没有net.1,而直接是net.2
Named——children表示获取net的网络的孩子结点
获取所有结点,从子结点开始逐渐到孙子结点
自定义展开层class Flatten(nn.Module):
def __init__(self):
super(Flatten, self).__init__()
def forward(self, input):
return input.view(input.size(0), -1)
class TestNet(nn.Module):
def __init__(self):
super(TestNet, self).__init__()
self.net = nn.Sequential(nn.Conv2d(1, 16, stride=1, padding=1),
nn.MaxPool2d(2, 2),
Flatten(),
nn.Linear(11414, 10))
def forward(self, x):
return self.net(x)
本文系作者个人观点,不代表本站立场,转载请注明出处!