深度学习框架PyTorch-- 第四章神经网络工具箱

本文详细介绍了PyTorch中的神经网络工具箱,包括构建神经网络的基本模块、自动求导机制以及训练过程中的优化器和损失函数。通过实例展示了如何使用这些工具快速搭建和训练深度学习模型。
摘要由CSDN通过智能技术生成
"""
第四章 神经网络工具箱nn
上一章中提到,使用autograd可实现深度学习模型,但其抽象程度较低,如果用其来实现深度学习模型,则需要编写的代码量极大。
在这种情况下,torch.nn应运而生,其是专门为深度学习而设计的模块。
torch.nn的核心数据结构是Module,它是一个抽象概念,既可以表示神经网络中的某个层(layer),也可以表示一个包含很多层的神经网络。
在实际使用中,最常见的做法是继承nn.Module,撰写自己的网络/层。
下面先来看看如何用nn.Module实现自己的全连接层。
全连接层,又名仿射层,输出y和输入x满足y=wx+b,w和b是可学习的参数。
"""
import torch as t
from torch import nn

class Linear(nn.Module):
    def __init__(self,in_features,out_features):
        super(Linear,self).__init__()#等价于nn.Module.__init__(self)
        self.w=nn.Parameter(t.rand(in_features,out_features))
        self.b=nn.Parameter(t.rand(out_features))

    def forward(self,x):
        x=x.mm(self.w)
        return x+self.b.expand_as(x)

layer = Linear(4,3)
input = t.randn(2,4)
output = layer(input)
print(output)

for name, parameter in layer.named_parameters():
    print(name, parameter) # w and b

"""
全连接层的实现需要注意一下几点:
1.自定义层Linear必须继承nn.Module,并且在其构造函数中需要调用nn.Moudle的构造函数
即super(Linear,self).__init__()或者nn.Moudle.__init__(self),推荐第一种
2.在构造函数__init__中必须自己定义可学习的参数,并封装成Parameter,如在本例中我们把w和b封装成parameter。
parameter是一种特殊的Tensor,但其默认需要求导(requires_grad = True)
3.forward函数实现前向传播过程,其输入可以是一个或多个tensor
4.无需写反向传播函数,nn.Module能够利用autograd自动实现反向传播,这点比Function简单许多。
5.使用时,直观上可将layer看成数学概念中的函数,调用layer(input)即可得到input对应的结果。它等价于layers.__call__(input),在__call__函数中,主要调用的是 layer.forward(x),另外还对钩子做了一些处理
6.Module中的可学习参数可以通过named_parameters()或者parameters()返回迭代器,前者会给每个parameter都附上名字,使其更具有辨识度。
"""

"可见利用Module实现的全连接层,比利用Function实现的更为简单,因其不再需要写反向传播函数。"


class Perceptron(nn.Module):
    def __init__(self,in_features,hidden_features,out_features):
        nn.Module.__init__(self)
        self.layer1 = Linear(in_features,hidden_features) #此处的Linear是前面自定义的全连接
        self.layer2 = Linear(hidden_features,out_features)
    def forward(self, x):
        x= self.layer1(x)
        x=t.sigmoid(x)
        return self.layer2(x)

perceptron=Perceptron(3,4,1)
for name,param in perceptron.named_parameters():
    print(name,param.size())

"""
可见,即使是稍复杂的多层感知机,其实现依旧很简单。
构造函数__init__中,可利用前面自定义的Linear层(module),作为当前module对象的一个子module,它的可学习参数,也会成为当前module的可学习参数。

module中parameter的命名规范:

对于类似self.param_name = nn.Parameter(t.randn(3, 4)),命名为param_name
对于子Module中的parameter,会其名字之前加上当前Module的名字。如对于self.sub_module = SubModel(),SubModel中有个parameter的名字叫做param_name,那么二者拼接而成的parameter name 就是sub_module.param_name。
为方便用户使用,PyTorch实现了神经网络中绝大多数的layer,这些layer都继承于nn.Module,封装了可学习参数parameter,并实现了forward函数,且很多都专门针对GPU运算进行了CuDNN优化,其速度和性能都十分优异。本书不准备对nn.Module中的所有层进行详细介绍,具体内容读者可参照官方文档1或在IPython/Jupyter中使用nn.layer?来查看。阅读文档时应主要关注以下几点:

构造函数的参数,如nn.Linear(in_features, out_features, bias),需关注这三个参数的作用。
属性、可学习参数和子module。如nn.Linear中有weight和bias两个可学习参数,不包含子module。
输入输出的形状,如nn.linear的输入形状是(N, input_features),输出为(N,output_features),N是batch_size。
这些自定义layer对输入形状都有假设:输入的不是单个数据,而是一个batch。输入只有一个数据,则必须调用tensor.unsqueeze(0) 或 tensor[None]将数据伪装成batch_size=1的batch
"""

"""
4.1常用神经网络层
4.1.1图像相关层
图像相关层主要包括卷积层(Conv)、池化层(Pool)等,这些层在实际使用中可分为一维(1D)、二维(2D)、三维(3D),
池化方式又分为平均池化(AvgPool)、最大值池化(MaxPool)、自适应池化(AdaptiveAvgPool)等。
而卷积层除了常用的前向卷积之外,还有逆卷积(TransposeConv)。
"""
import matplotlib.pyplot as plt
from PIL import Image
from torchvision.transforms import ToTensor,ToPILImage

to_tensor=ToTensor()# img->tensor
to_pil=ToPILImage()
lena=Image.open('imags/lena.png')
plt.imshow(lena)
plt.show()

#输入是一个batch,batch_size=1
input=to_tensor(lena).unsqueeze(0)

#锐化卷积层
kernel=t.ones(3,3)/9
kernel[1][1]=1
conv=nn.Conv2d(1,1,(3,3),1,bias=False)

out=conv(input)
to_pil(out.data.squeeze(0))

"池化层可以看作是一种特殊的卷积层,用来下采样。但池化层没有可学习参数,其weight是固定的。"
pool=nn.AvgPool2d(2,2)
print(list(pool.parameters()))

"""
除了卷积层和池化层,深度学习中还将常用到以下几个层:

Linear:全连接层。
BatchNorm:批规范化层,分为1D、2D和3D。除了标准的Ba
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值