FA :Formulas and Algorithm, CNN:Convolutional Neural Network
1. 引言
在深度学习的学习过程中,我们经常会遇到一个核心问题:神经网络到底在训练什么? 简单来说,神经网络训练的就是函数系数 KkK_{k}Kk 与偏置项 ddd。通过不断调整这些参数,网络能够学习到输入与输出之间的映射关系。
在图像分类任务中,我们通常需要将多维的图片数据转换为适合全连接层处理的格式。本文将基于 PyTorch 和 CIFAR10 数据集,带你一步步理解**线性拉平(Flatten)和 线性层(Linear Layer)**的核心概念与实战用法。

2. 环境准备
在开始之前,请确保你的环境中已经安装了以下依赖:
python
import torch
import torchvision
from torch import nn
from torch.nn import ReLU
from torch.nn import Sigmoid
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
本文使用的数据集为 CIFAR10,它包含 10 个类别的彩色图片,每张图片的尺寸为 3×32×32(通道×高×宽)。
3. 线性拉平(Flatten)
3.1 什么是线性拉平
线性拉平是将多维张量展开为一维向量的操作。在将图片数据输入全连接层之前,我们必须先将多维数据"拉平"。
3.2 方法一:使用 torch.reshape
python
import torch
import torchvision
from torch import nn
from torch.nn import ReLU
from torch.nn import Sigmoid
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size=64)
for data in dataloader:
imgs, targets = data
print(imgs.shape)
output = torch.reshape(imgs, (1, 1, 1, -1))
print(output.shape)
运行结果:
text
torch.Size([64, 3, 32, 32])
torch.Size([1, 1, 1, 196608])
可以看到,原本形状为 [64, 3, 32, 32] 的批量图片数据,经过 torch.reshape 后被拉平为 [1, 1, 1, 196608]。其中 196608 = 64 × 3 × 32 × 32,即所有元素被展开成一维。
3.3 方法二:使用 torch.flatten
除了 torch.reshape,PyTorch 还提供了更直观的 torch.flatten 方法,直接将张量展开为一维:
python
output = torch.flatten(imgs) # 展开为一维
print(output.shape)
运行结果:
text
torch.Size([196608])
两种方法都能实现拉平操作,但 torch.flatten 的语义更加清晰,推荐在实际项目中使用。
4. 线性层(Linear Layer)
4.1 什么是线性层
线性层(全连接层)是神经网络中最基础的层之一,它的作用是对输入数据进行线性变换。其数学表达式为:
y=xWT+by = xW^T + by=xWT+b
其中 WWW 是权重矩阵,bbb 是偏置项。
4.2 实战:将拉平后的数据输入线性层
下面我们定义一个简单的神经网络,将拉平后的 CIFAR10 图片数据(196608 维)映射到 10 个类别:
python
import torch
import torchvision
from torch import nn
from torch.nn import Linear
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size=64, drop_last=True)
class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__init__()
self.linear1 = Linear(196608, 10)
def forward(self, input):
output = self.linear1(input)
return output
tudui = Tudui()
writer = SummaryWriter("logs")
step = 0
for data in dataloader:
imgs, targets = data
print(imgs.shape)
writer.add_images("input", imgs, step)
output = torch.reshape(imgs, (1, 1, 1, -1)) # 方法一:拉平
print(output.shape)
output = tudui(output)
print(output.shape)
writer.add_images("output", output, step)
step = step + 1
运行结果:
text
torch.Size([64, 3, 32, 32])
torch.Size([1, 1, 1, 196608])
torch.Size([1, 1, 1, 10])
可以看到,数据经过线性层后,从 196608 维被映射到了 10 维,正好对应 CIFAR10 的 10 个类别。


4.3 使用 torch.flatten 的完整示例
python
import torch
import torchvision
from torch import nn
from torch.nn import Linear
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
dataset = torchvision.datasets.CIFAR10("./dataset", train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size=64, drop_last=True)
class Tudui(nn.Module):
def __init__(self):
super(Tudui, self).__init__()
self.linear1 = Linear(196608, 10)
def forward(self, input):
output = self.linear1(input)
return output
tudui = Tudui()
writer = SummaryWriter("logs")
step = 0
for data in dataloader:
imgs, targets = data
print(imgs.shape)
writer.add_images("input", imgs, step)
output = torch.flatten(imgs) # 方法二:拉平,展开为一维
print(output.shape)
output = tudui(output)
print(output.shape)
step = step + 1
运行结果:
text
torch.Size([64, 3, 32, 32])
torch.Size([196608])
torch.Size([10])
5. 使用 TensorBoard 可视化
为了更直观地观察训练过程中的输入与输出,我们可以使用 TensorBoard 进行可视化。
在 Anaconda 终端中,激活你的 Python 环境(例如 py3.6.3),然后输入以下命令:
bash
tensorboard --logdir=C:\Users\wangy\Desktop\03CV\logs
将输出的网址复制到浏览器地址栏并回车,即可在 TensorBoard 中查看日志信息。
6. 总结
本文通过实战代码,带你理解了 PyTorch 中两个重要的基础操作:
- 线性拉平(Flatten) :将多维张量展开为一维向量,是连接卷积层与全连接层的桥梁。常用方法有
torch.reshape和torch.flatten。 - 线性层(Linear Layer):对输入进行线性变换,将高维特征映射到目标维度(如分类任务的类别数)。
理解这两个概念,是深入学习卷积神经网络(CNN)和全连接网络的基础。希望本文能帮助你更好地掌握 PyTorch 的核心操作,为后续的深度学习之旅打下坚实的基础。