Pytorch 神经网络基础(nn.Module、卷积层、池化层、线性层)

发布时间:2026/11/4 7:08:00
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. 两个核心函数

  1. __init__():构造函数,定义网络层(卷积、全连接等,在这里注册参数)
  2. 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)

五、常见踩坑总结

  1. Conv2d 输入格式:[batch, channel, height, width],和opencv、PIL的HWC相反!
  2. 卷积之后进全连接,一定要flatten展平,否则维度对不上
  3. padding的作用:控制特征图尺寸不变,same padding
  4. 池化层不改变通道数,只缩小高宽
  5. nn.Module里面的层会自动管理参数,不需要手动设置requires_grad