Pytorch 神经网络基础(nn.Module、卷积层、池化层、线性层)
标签:#Pytorch #深度学习 #神经网络 #nn.Module #卷积神经网络
阅读时长:10min
前言
前面我们学习了张量Tensor、自动求导Autograd,这两个是Pytorch最底层的基石。在真实项目中,我们不会手动去写大量求导逻辑,torch.nn模块封装好了神经网络各类层、损失函数,让我们快速搭建网络。本篇重点讲解nn.Module以及常用网络层:卷积Conv、池化Pool、全连接Linear。
一、nn.Module:所有网络的基类
nn.Module是Pytorch里所有网络模型、网络层的父类,自定义网络必须继承它。
之前你问的def __init__(self): super().__init__()就是在这里使用。
1. 两个核心函数
__init__():构造函数,定义网络层(卷积、全连接等,在这里注册参数)forward():前向传播函数,定义数据流动逻辑,不能手动调用,模型() 方式自动执行
✅ 最简模板(必背)
importtorchimporttorch.nnasnnclassMyNet(nn.Module):def__init__(self):super().__init__()# 调用父类构造,必须写!# 在这里定义层self.linear=nn.Linear(10,5)defforward(self,x):# 前向计算out=self.linear(x)returnout net=MyNet()x=torch.randn(2,10)res=net(x)# 自动调用forwardprint(res.shape)⚠️ 坑点提醒:
- 网络层一定要写在
__init__里面,不要写在forward里面,否则无法注册参数,无法参与训练- forward只负责计算,不要写反向传播代码,autograd自动处理
二、常用网络层详解
1. 全连接层 nn.Linear
公式:y=xWT+by = xW^T + by=xWT+b
nn.Linear(in_features,out_features,bias=True)- in_features:输入特征维度
- out_features:输出特征维度
- bias:是否增加偏置,默认True
示例:
# 输入10维,输出2维linear=nn.Linear(10,2)x=torch.randn(3,10)print(linear(x).shape)# torch.Size([3, 2])特点:把所有输入神经元和输出神经元全部相连;一般放在网络最后做分类。
2. 二维卷积层 nn.Conv2d(CNN最核心)
nn.Conv2d(in_channels,out_channels,kernel_size,stride=1,padding=0)参数说明:
| 参数 | 含义 |
|---|---|
| in_channels | 输入通道数,RGB图像=3,灰度图=1 |
| out_channels | 输出通道数,等价于卷积核数量 |
| kernel_size | 卷积核大小,如3代表3×3 |
| stride | 步长,滑动一次走几格 |
| padding | 填充,四周补0,保持尺寸常用padding=1,kernel=3 |
输出尺寸计算公式:
Hout=⌊Hin+2×padding−kernel_sizestride+1⌋ H_{out} = \lfloor \frac{H_{in}+2\times padding - kernel\_size}{stride} +1 \rfloorHout=⌊strideHin+2×padding−kernel_size+1⌋
示例:
# 输入3通道,输出16通道,3*3卷积conv=nn.Conv2d(3,16,3,stride=1,padding=1)img=torch.randn(2,3,32,32)# batch, C, H, Wout=conv(img)print(out.shape)# torch.Size([2, 16, 32, 32])3. 池化层 nn.MaxPool2d / nn.AvgPool2d
池化:下采样,降低特征图宽高,减少计算量、保留主要特征,没有可训练参数
- MaxPool2d:最大池化,取窗口最大值(最常用)
- AvgPool2d:平均池化,取窗口平均值
pool=nn.MaxPool2d(kernel_size=2,stride=2)feat=torch.randn(2,16,32,32)out=pool(feat)print(out.shape)# torch.Size([2, 16, 16, 16])4. 激活函数层
激活函数引入非线性,如果没有激活函数,再多卷积也等价于线性变换。
nn.ReLU()# 最常用nn.Sigmoid()# 输出0~1,二分类nn.Softmax(dim=1)# 多分类,输出概率和为1使用示例:
relu=nn.ReLU()x=torch.tensor([-1.0,2.0])print(relu(x))# tensor([0., 2.])三、搭一个简单CNN示例(整合上面所有层)
importtorchimporttorch.nnasnnclassSimpleCNN(nn.Module):def__init__(self):super().__init__()self.conv1=nn.Conv2d(3,16,3,padding=1)self.pool=nn.MaxPool2d(2,2)self.conv2=nn.Conv2d(16,32,3,padding=1)self.relu=nn.ReLU()self.fc1=nn.Linear(32*8*8,10)defforward(self,x):x=self.conv1(x)x=self.relu(x)x=self.pool(x)x=self.conv2(x)x=self.relu(x)x=self.pool(x)# 展平:batch不动,其余维度拉平x=x.flatten(1)x=self.fc1(x)returnx net=SimpleCNN()test_img=torch.randn(4,3,32,32)res=net(test_img)print(res.shape)# torch.Size([4,10])四、查看网络参数
# 方式1:打印模型结构print(net)# 方式2:遍历参数forname,paraminnet.named_parameters():print(name,param.shape)五、常见踩坑总结
- Conv2d 输入格式:
[batch, channel, height, width],和opencv、PIL的HWC相反! - 卷积之后进全连接,一定要flatten展平,否则维度对不上
- padding的作用:控制特征图尺寸不变,same padding
- 池化层不改变通道数,只缩小高宽
- nn.Module里面的层会自动管理参数,不需要手动设置requires_grad