00-1010以下栏目限时优惠,欢迎订阅。
人工智能专栏限时打折中
为了方便用户,PyTorch实现了神经网络中的大部分层,这些层都是从神经网络继承而来的。模块,封装了可学习的参数参数并实现了前向功能,其中很多都是CuDNN专门针对GPU操作进行优化的,速度和性能都很出色。
比如nn。线性(in _ features,out _ features,bias),我们要注意这三个参数的作用。
例如,在神经网络中有两种可学习的权重和偏差参数的输入和输出形式。线性,例如,nn.linear的输入形状为(N,input_features),输出为(N,output_features),N为batch_size。
把神经网络写在PyTorch里。所有的层结构和损失函数都来自torch.nn,所有的模型构建都继承自这个基类nn。模块,所以我们有以下模板。
类net_name(nn。Moudle) :
def _ _ init _ _ :(自身,其他)
super(net_name,self)。__init__()
self.conv1=nn。Conv2d(输入通道、输出通道、内核大小)
#其他网络层其他网络层
向前延迟(自我,x):
x=self.conv1(x)
返回x
这样就建立了一个计算图,这种结构可以多次重用,每次调用都相当于一次前向传播,参数和计算图定义的一样,这得益于PyTorch的自动推导功能,所以我们不需要自己写反向传播,所有的网络层都是通过nn包得到的,比如线性层nn。线性当我们以后使用它时,我们可以详细介绍每个网络的相应结构以及如何调用它。
在定义了模型之后,我们需要通过包nn来定义损失函数。神经网络中定义了常见的损失函数,如均方误差、多分类交叉熵、两分类交叉熵等。调用这些定义的损失函数也很简单。
标准=nn。CrossEntropyLoss()
损失=标准(输出,目标)
这样就可以得到我们的输出和真实目标之间的损失函数。
00-1010卷积层conv=nn.conv2d (1,1,(3,3),1,偏差=假)
池层池=nn。AvgPool2d(2,2)
线性:全连接层线性=nn。线性(3,4)
BatchNorm:批处理规范化层bn=nn。batchnom1d(4)
压差:压差层压差=nn。辍学(0.5)#0.5概率拒绝
激活relu=nn功能。ReLU(真)
#嵌入层,有4个字,每个字用一个5维向量表示。
嵌入=nn。嵌入(4,5)
00-1010当我们构建一个神经网络时,我们可以将几个神经网络层组合在一起,我们可以使用顺序和模块化方法。
让我们看看顺序,我们可以把它看作一个模块。
编写# Sequential的三种方法
方法1:为每个神经网络层添加一个名称。
net1=nn。顺序()
net1.add_module('conv ',nn。Conv2d(3,3,3))
net 1 . add _ module(' batch ORM ',nn。batchnom2d(3))
net 1 . add _ module(' activation _ layer ',nn。ReLU())
因为有名字,所以我们可以根据名字提取神经网络的每一层。
net1.conv
net 1 . batch ORM
正向传播输出=net1(输入)
写作2:
net2=nn。顺序(
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(1*14*14, 10))
def forward(self, x):
return self.net(x)