Skip to main content

神经网络框架

经典神经网络架构

AlexNet

AlexNet是由Alex Krizhevsky、Ilya Sutskever和Geoffrey Hinton在2012年提出的深度卷积神经网络,在ImageNet大规模视觉识别挑战赛(ILSVRC)中取得了突破性成果,标志着深度学习在计算机视觉领域的崛起。

主要特点:

  • 深度结构:包含5个卷积层和3个全连接层
  • ReLU激活函数:首次在大型CNN中广泛使用ReLU代替传统的tanh或sigmoid函数
  • 局部响应归一化(LRN):提高泛化能力
  • 重叠池化:减少过拟合并提高特征提取能力
  • 数据增强与Dropout:采用多种方法防止过拟合

网络结构:

  1. 输入:227×227×3的RGB图像
  2. 第一卷积层:96个11×11的卷积核,步长为4
  3. 最大池化层:3×3,步长为2
  4. 第二卷积层:256个5×5的卷积核,填充为2
  5. 最大池化层:3×3,步长为2
  6. 第三卷积层:384个3×3的卷积核,填充为1
  7. 第四卷积层:384个3×3的卷积核,填充为1
  8. 第五卷积层:256个3×3的卷积核,填充为1
  9. 最大池化层:3×3,步长为2
  10. 全连接层:4096个神经元
  11. 全连接层:4096个神经元
  12. 输出层:1000个类别的softmax分类器

ResNet (残差网络)

ResNet由微软研究院的Kaiming He等人在2015年提出,通过引入残差连接解决了深度网络训练困难的问题,赢得了ILSVRC 2015的冠军。ResNet的出现使得训练更深的神经网络成为可能。

主要特点:

  • 残差块:核心创新是残差连接(skip connection),允许梯度直接流过多层网络
  • 批量归一化:每个卷积层后应用批量归一化
  • 深度灵活:有多个变体,如ResNet-18、ResNet-34、ResNet-50、ResNet-101和ResNet-152等
  • 瓶颈设计:较深的版本使用"瓶颈"设计降低计算复杂度

残差块结构: 基本残差块包含两个3×3的卷积层,每层后跟批量归一化和ReLU激活函数。跳跃连接将输入直接添加到这两个卷积层的输出上,形成:

输出 = F(x) + x

其中F(x)是卷积层的输出,x是输入。

瓶颈残差块: 在更深的ResNet变体中,采用1×1 -> 3×3 -> 1×1的卷积序列,其中1×1卷积用于降维和升维,减少计算量。

VGG

VGG网络由牛津大学Visual Geometry Group在2014年提出,以其简洁统一的架构著称。

主要特点:

  • 统一结构:使用小尺寸卷积核(3×3)构建网络
  • 深层设计:有多个变体,如VGG-16(16层)和VGG-19(19层)
  • 固定池化窗口:所有最大池化层均采用2×2窗口,步长为2
  • 全连接层统一:三个全连接层,前两个各有4096个神经元

网络结构(VGG-16):

  1. 输入:224×224×3的RGB图像
  2. 两个3×3卷积层(64个滤波器),最大池化
  3. 两个3×3卷积层(128个滤波器),最大池化
  4. 三个3×3卷积层(256个滤波器),最大池化
  5. 三个3×3卷积层(512个滤波器),最大池化
  6. 三个3×3卷积层(512个滤波器),最大池化
  7. 三个全连接层(4096-4096-1000)

GoogLeNet (Inception)

GoogLeNet由Google团队在2014年提出,引入了Inception模块,在保持计算效率的同时增加网络宽度和深度。

主要特点:

  • Inception模块:并行使用不同大小的卷积核(1×1, 3×3, 5×5)和池化操作
  • 1×1卷积:用于降维,减少计算量
  • 辅助分类器:在中间层添加辅助分类器帮助训练
  • 全局平均池化:替代全连接层减少参数数量

Inception模块结构: 同时进行四个并行操作,然后在深度方向上拼接结果:

  1. 1×1卷积
  2. 1×1卷积降维 -> 3×3卷积
  3. 1×1卷积降维 -> 5×5卷积
  4. 3×3最大池化 -> 1×1卷积

MobileNet

MobileNet由Google团队开发,专为移动和嵌入式设备优化,保持较高准确率的同时显著减少参数量和计算复杂度。

主要特点:

  • 深度可分离卷积:将标准卷积分解为深度卷积(depthwise)和逐点卷积(pointwise)
  • 宽度乘数:控制每层滤波器数量
  • 分辨率乘数:控制输入图像分辨率
  • 轻量级设计:比传统CNN模型小得多,计算效率高

深度可分离卷积:

  1. 深度卷积:对输入的每个通道单独应用单一滤波器
  2. 逐点卷积:使用1×1卷积组合深度卷积的输出

MobileNet V2进一步引入了倒置残差结构和线性瓶颈层,提升了性能。

PyTorch实现示例

import cv2
import os
import torch
from torchvision import transforms, datasets, models
from tqdm import tqdm
from torchvision.models import ResNet18_Weights
from torch.utils.data import DataLoader
import torch.nn as nn
import torch.optim as optim
# 保存模型的文件
PROJECT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# 指定设备
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")

#数据增强
train_transform = transforms.Compose([
transforms.RandomResizedCrop((224, 224)),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])]
)

# 构建数据集
train_data = datasets.ImageFolder(root='train_balanced',transform=train_transform)

# 构建数据加载器
train_loader = DataLoader(train_data, batch_size=32, shuffle=True)

# --------------------------------------------------------------------
# 预加载模型
model = models.resnet18(weights=ResNet18_Weights.IMAGENET1K_V1).to(device)
# 修改全连接层
out_features = model.fc.in_features
model.fc = nn.Linear(out_features, 7)
model = model.to(device)

# 构建损失函数与优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# --------------------------------------------------------------------
model.train()
# 训练
epochs = 15
best_acc = 0.0
for epoch in range(epochs):
totle_loss = 0
totle_cur = 0
# 进度条
train_bar = tqdm(train_loader, desc=f"Epoch {epoch+1}/{epochs}")

for image, label in train_bar:
image, label = image.to(device), label.to(device)
# 前向传播
outpout = model(image)
loss = criterion(outpout, label)

totle_loss += loss.item()

# 反向传播
optimizer.zero_grad()
loss.backward()
optimizer.step()

# 计算准确率
_, predict = torch.max(outpout, 1)
totle_cur += torch.sum(predict==label.data).item()

train_loss = totle_loss / len(train_loader.dataset)
train_acc = float(totle_cur) / len(train_loader.dataset)

if train_acc > best_acc:
best_acc = train_acc
if not os.path.exists("./models"):
os.makedirs("./models")
torch.save(model.state_dict(), "./models/best_mask_model.pth")
print(f'最新保存的模型准确率为: {100 * train_acc:.2f}%')

print(f"Best Test Accuracy: {100 * best_acc:.4f}")