摘要: 如果说机器学习是AI的核心引擎,那么深度学习就是这台引擎的超级涡轮增压器。它推动了计算机视觉、自然语言处理等领域的革命性进步。本文将深入浅出地介绍深度学习的基本原理、核心网络结构,并通过一个PyTorch代码实例,手把手教你构建一个图像分类神经网络。
关键词: 深度学习, 神经网络, PyTorch, 计算机视觉, CNN, AI
一、从机器学习到深度学习
在上一篇《机器学习入门》中,我们提到机器学习需要手动从原始数据(如图片像素、文本词汇)中提取特征(如图像的边缘、纹理),然后再将这些特征输入给模型。
深度学习的革命性在于:它能够自动从原始数据中学习多层次的特征表示,无需复杂的人工特征工程。
-
浅层学习:机器学习模型(如KNN、SVM)通常只有1-2层,学习能力有限。
-
深度学习 :使用被称为神经网络的模型,其拥有多达数十、数百甚至上千层,因此被称为"深度"网络。每一层都能学习到数据不同抽象层次的特征。
以识别猫为例:
第一层神经元 可能学习到识别边缘和角落。
第二层神经元 组合边缘,学习到识别眼睛、鼻子、胡子等局部特征。
第三层及更深层神经元组合局部特征,最终学习到"猫"的全局概念。
二、神经网络的核心概念
-
神经元 :神经网络的基本单元。它接收输入,进行加权求和,并通过一个激活函数产生输出。
- 激活函数:为网络引入非线性,使其能够拟合复杂函数。常见的有ReLU, Sigmoid, Tanh。
-
层:神经元的集合。包括:
-
输入层:接收原始数据。
-
隐藏层:介于输入和输出之间,进行特征变换和学习的核心部分。
-
输出层:输出最终预测结果。
-
-
前向传播:数据从输入层流向输出层的过程。
-
损失函数:衡量模型预测值与真实值之间的差距。
-
反向传播:深度学习的关键算法。它根据损失函数的计算结果,从输出层反向逐层调整网络中的权重参数,以减小误差。这个过程就像老师批改作业后,学生根据错误来修正自己的学习方法。
-
优化器 :执行参数更新的具体算法,最著名的是梯度下降及其变种(如Adam)。
三、主流深度学习网络架构
-
卷积神经网络:
-
专长领域:计算机视觉(图像、视频)。
-
核心思想 :通过卷积核 在图像上滑动,有效提取空间特征(如纹理、形状),并具有平移不变性(无论猫在图片的哪个角落,都能识别出来)。
-
-
循环神经网络:
-
专长领域:序列数据(文本、语音、时间序列)。
-
核心思想:具有"记忆"功能,能够处理前后依赖关系。例如,理解一个句子的意思需要结合上下文的词汇。
-
-
Transformer:
-
专长领域:已成为自然语言处理的新霸主,并开始进军视觉领域。
-
核心思想 :通过自注意力机制,能够并行处理序列数据并捕捉长距离依赖关系,效率远高于RNN。GPT、BERT等著名模型都基于此。
-
四、实战:用PyTorch构建CNN识别Fashion-MNIST数据集
我们将使用PyTorch框架,构建一个卷积神经网络来对Fashion-MNIST(一个流行的衣物图像数据集)进行分类。
环境准备:
pip install torch torchvision matplotlib
代码步骤详解:
python
# 1. 导入必要的库
import torch
import torch.nn as nn
import torch.optim as optim
import torchvision
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
# 2. 准备数据
# 定义数据预处理:转换为Tensor并归一化
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
# 下载并加载训练集和测试集
trainset = torchvision.datasets.FashionMNIST(root='./data', train=True,
download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=64,
shuffle=True)
testset = torchvision.datasets.FashionMNIST(root='./data', train=False,
download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=64,
shuffle=False)
# 数据集类别标签
classes = ('T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle Boot')
# 3. 定义神经网络模型(一个简单的CNN)
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 32, 3) # 输入通道1,输出通道32,卷积核3x3
self.pool = nn.MaxPool2d(2, 2) # 最大池化层,窗口2x2
self.conv2 = nn.Conv2d(32, 64, 3) # 输入通道32,输出通道64,卷积核3x3
self.fc1 = nn.Linear(64 * 5 * 5, 128) # 全连接层
self.fc2 = nn.Linear(128, 10) # 输出层,10个类别
def forward(self, x):
x = self.pool(torch.relu(self.conv1(x))) # 卷积 -> ReLU -> 池化
x = self.pool(torch.relu(self.conv2(x)))
x = x.view(-1, 64 * 5 * 5) # 展平特征图
x = torch.relu(self.fc1(x))
x = self.fc2(x)
return x
net = Net()
# 4. 定义损失函数和优化器
criterion = nn.CrossEntropyLoss() # 交叉熵损失,适用于多分类
optimizer = optim.Adam(net.parameters(), lr=0.001) # Adam优化器
# 5. 训练网络
print("开始训练...")
for epoch in range(5): # 在完整数据集上训练5轮
running_loss = 0.0
for i, data in enumerate(trainloader, 0):
# 获取输入数据
inputs, labels = data
# 梯度清零
optimizer.zero_grad()
# 前向传播 + 反向传播 + 优化
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
# 打印统计信息
running_loss += loss.item()
if i % 200 == 199: # 每200个batch打印一次
print(f'[{epoch + 1}, {i + 1:5d}] loss: {running_loss / 200:.3f}')
running_loss = 0.0
print('训练完毕!')
# 6. 在测试集上评估模型
correct = 0
total = 0
with torch.no_grad(): # 测试时不需要计算梯度
for data in testloader:
images, labels = data
outputs = net(images)
_, predicted = torch.max(outputs.data, 1) # 获取预测结果
total += labels.size(0)
correct += (predicted == labels).sum().item()
print(f'测试集准确率: {100 * correct / total:.2f} %')
# 7. 可视化一些预测结果
def imshow(img):
img = img / 2 + 0.5 # 反归一化
npimg = img.numpy()
plt.imshow(np.transpose(npimg, (1, 2, 0)))
plt.show()
# 获取一批测试图片
dataiter = iter(testloader)
images, labels = next(dataiter)
# 显示图片
imshow(torchvision.utils.make_grid(images[:4]))
print('真实标签: ', ' '.join(f'{classes[labels[j]]}' for j in range(4)))
# 进行预测
outputs = net(images)
_, predicted = torch.max(outputs, 1)
print('预测结果: ', ' '.join(f'{classes[predicted[j]]}' for j in range(4)))
代码解读:
-
数据加载 :使用
torchvision方便地下载和加载标准数据集,并用DataLoader进行批处理。 -
模型定义 :我们构建了一个简单的CNN,包含两个卷积层和两个全连接层。
ReLU作为激活函数,MaxPool2d用于下采样。 -
训练循环:
-
optimizer.zero_grad():在每次反向传播前清空梯度,防止累积。 -
loss.backward():计算损失相对于所有参数的梯度(反向传播)。 -
optimizer.step():根据梯度更新网络参数。
-
-
评估:在测试集上计算整体准确率,并可视化部分预测结果,直观感受模型性能。
五、总结与展望
通过本篇文章,你不仅理解了深度学习的基本原理,还亲手实现了一个卷积神经网络。深度学习的核心优势在于其端到端的学习能力和对复杂模式的强大拟合能力。
下一步学习方向:
-
更深的网络:尝试ResNet, VGG等经典深层架构。
-
自然语言处理:学习RNN, LSTM和Transformer,使用它们处理文本数据。
-
调参技巧:学习如何使用学习率调度、Dropout、Batch Normalization等提升模型性能和稳定性。
-
预训练模型:学习如何使用Hugging Face等平台的预训练模型进行迁移学习,用少量数据达到极好的效果。