当前位置: 首页 > article >正文

cnn以及例子

cnn

CNN 即卷积神经网络(Convolutional Neural Network),是一种专门为处理具有网格结构数据(如图像、音频)而设计的深度学习模型,在计算机视觉、语音识别等诸多领域都有广泛应用。以下是 CNN 的详细介绍:
基本原理
卷积层:是 CNN 的核心组成部分,通过卷积核在数据上滑动进行卷积操作,自动提取数据中的局部特征。例如,在处理图像时,卷积核可以检测图像中的边缘、线条等简单特征。卷积操作大大减少了模型的参数数量,降低计算量,同时也能有效地捕捉数据的空间相关性。
池化层:通常接在卷积层之后,主要作用是对数据进行下采样,减少数据的维度,降低计算量,同时保留数据的主要特征。常见的池化方法有最大池化和平均池化。最大池化是取卷积核覆盖区域内的最大值,平均池化则是取平均值。
全连接层:一般位于 CNN 的最后部分,将池化层输出的特征图展开成一维向量,然后与全连接的神经元进行连接,用于对提取到的特征进行综合判断和分类。全连接层的神经元之间是完全连接的,其权重矩阵包含了模型对数据整体特征的学习结果。
网络结构
输入层:负责接收原始数据,对于图像数据,通常是一个三维的张量,维度分别代表图像的高度、宽度和通道数(如 RGB 图像通道数为 3)。
隐藏层:包含多个卷积层、池化层和可能的其他类型的层(如批量归一化层、激活函数层等)。这些层通过不断地卷积、池化等操作,逐步提取数据的高级特征。
输出层:根据具体任务的不同,输出层的形式也有所不同。在图像分类任务中,输出层通常是一个具有 softmax 激活函数的全连接层,用于输出各类别的概率分布;在目标检测任务中,输出层可能包含边界框的坐标信息和类别信息等。

反向传播算法

误差计算:在训练过程中,首先计算模型输出与真实标签之间的误差,常用的损失函数有交叉熵损失函数、均方误差损失函数等。以交叉熵损失函数为例,它衡量的是模型预测的概率分布与真实标签的概率分布之间的差异。
误差反向传播:将误差从输出层反向传播到输入层,通过链式求导法则计算每一层的参数梯度。在卷积层中,需要计算卷积核的梯度;在全连接层中,需要计算权重矩阵和偏置项的梯度。
参数更新:根据计算得到的梯度,使用优化算法(如随机梯度下降、Adagrad、Adadelta、Adam 等)来更新模型的参数,使得损失函数逐渐减小,模型的性能不断提升。

应用领域

计算机视觉:在图像分类、目标检测、图像分割、人脸识别等任务中取得了巨大成功。例如,在图像分类中,CNN 可以准确地识别出图像中的物体类别;在目标检测中,能够定位并识别图像中的多个目标物体。
语音识别:用于对语音信号进行特征提取和分类,将语音转换为文字。CNN 可以有效地捕捉语音信号中的声学特征,提高语音识别的准确率。
自然语言处理:在文本分类、情感分析、机器翻译等任务中也有应用。通过将文本数据转换为向量表示,然后利用 CNN 提取文本中的局部特征,进行语义理解和分类。

识别猫狗的例子

# 导入必要的库
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms, models
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt

# 2. 数据加载和预处理
# 定义数据预处理操作的组合
# Compose 函数用于将多个数据预处理操作组合在一起,按顺序依次执行
transform = transforms.Compose([
    # 将图片的大小调整为 224x224 像素
    # 这是因为许多预训练的模型输入要求为 224x224 大小
    transforms.Resize((224, 224)),  
    # 将图片从 PIL 图像格式转换为 PyTorch 张量格式
    # 张量是 PyTorch 中用于存储和处理数据的基本数据结构
    transforms.ToTensor(),  
    # 对图像进行归一化处理
    # 这里使用的均值和标准差是在 ImageNet 数据集上统计得到的
    # 归一化有助于模型更快收敛和提高稳定性
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])  
])

# 加载训练集数据
# ImageFolder 函数用于从指定的根目录加载图像数据集
# 根目录下的每个子文件夹代表一个类别,文件夹名即为类别名
train_dataset = datasets.ImageFolder(root='train', transform=transform)
# 加载测试集数据
test_dataset = datasets.ImageFolder(root='test', transform=transform)

# 创建训练集的数据加载器
# DataLoader 用于将数据集封装成可迭代的数据加载对象
# batch_size 表示每次从数据集中取出的样本数量
# shuffle=True 表示在每个训练周期开始时对数据进行打乱,增加数据的随机性
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True)
# 创建测试集的数据加载器
# 测试集不需要打乱数据,所以 shuffle=False
test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False)

# 3. 定义神经网络模型
# 定义一个简单的卷积神经网络类,继承自 nn.Module
class SimpleCNN(nn.Module):
    def __init__(self):
        # 调用父类的构造函数
        super(SimpleCNN, self).__init__()
        # 第一个卷积层
        # 输入通道数为 3(对应 RGB 三个通道)
        # 输出通道数为 16,表示该层会提取 16 种不同的特征
        # 卷积核大小为 3x3,padding=1 表示在图像边缘填充 1 个像素,以保持输出图像大小不变
        self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)
        # 激活函数 ReLU,用于引入非线性因素
        self.relu1 = nn.ReLU()
        # 第一个最大池化层
        # 池化核大小为 2x2,用于减小特征图的尺寸,同时保留重要特征
        self.pool1 = nn.MaxPool2d(2)
        # 第二个卷积层
        # 输入通道数为 16,与上一层的输出通道数一致
        # 输出通道数为 32,表示该层会提取 32 种不同的特征
        self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)
        # 激活函数 ReLU
        self.relu2 = nn.ReLU()
        # 第二个最大池化层
        self.pool2 = nn.MaxPool2d(2)
        # 第一个全连接层
        # 输入特征数为 32 * 56 * 56,这是经过两次池化后特征图的尺寸和通道数的乘积
        # 输出特征数为 128
        self.fc1 = nn.Linear(32 * 56 * 56, 128)
        # 激活函数 ReLU
        self.relu3 = nn.ReLU()
        # 第二个全连接层
        # 输入特征数为 128,与上一层的输出特征数一致
        # 输出特征数为 2,对应猫和狗两个类别
        self.fc2 = nn.Linear(128, 2)  

    def forward(self, x):
        # 前向传播过程
        # 输入数据经过第一个卷积层、ReLU 激活函数和最大池化层
        x = self.pool1(self.relu1(self.conv1(x)))
        # 再经过第二个卷积层、ReLU 激活函数和最大池化层
        x = self.pool2(self.relu2(self.conv2(x)))
        # 将多维的特征图展平为一维向量,以便输入到全连接层
        x = x.view(-1, 32 * 56 * 56)
        # 经过第一个全连接层和 ReLU 激活函数
        x = self.relu3(self.fc1(x))
        # 经过第二个全连接层,得到最终的输出
        x = self.fc2(x)
        return x

# 创建模型实例
model = SimpleCNN()

# 4. 定义损失函数和优化器
# 定义交叉熵损失函数,用于分类问题
# 交叉熵损失函数可以衡量模型预测结果与真实标签之间的差异
criterion = nn.CrossEntropyLoss()
# 定义 Adam 优化器,用于更新模型的参数
# lr 表示学习率,控制参数更新的步长
optimizer = optim.Adam(model.parameters(), lr=0.001)

# 5. 训练模型
# 定义训练的总周期数
num_epochs = 10
# 用于记录每个周期的训练损失
train_losses = []

# 开始训练循环,遍历每个周期
for epoch in range(num_epochs):
    # 初始化每个周期的累计损失
    running_loss = 0.0
    # 遍历训练集中的每个批次数据
    for i, (images, labels) in enumerate(train_loader):
        # 清空优化器中的梯度信息
        # 因为 PyTorch 会累积梯度,所以每个批次都需要清空
        optimizer.zero_grad()
        # 将输入图像数据输入到模型中,得到模型的预测输出
        outputs = model(images)
        # 计算预测输出与真实标签之间的损失
        loss = criterion(outputs, labels)
        # 进行反向传播,计算损失函数关于模型参数的梯度
        loss.backward()
        # 根据计算得到的梯度更新模型的参数
        optimizer.step()
        # 累加当前批次的损失
        running_loss += loss.item()

    # 计算当前周期的平均损失
    epoch_loss = running_loss / len(train_loader)
    # 将当前周期的平均损失添加到损失记录列表中
    train_losses.append(epoch_loss)
    # 打印当前周期的损失信息
    print(f'Epoch {epoch + 1}/{num_epochs}, Loss: {epoch_loss:.4f}')

# 绘制训练损失曲线
# 以周期数为横坐标,训练损失为纵坐标绘制曲线
plt.plot(train_losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training Loss')
plt.show()

# 6. 评估模型
# 将模型设置为评估模式
# 在评估模式下,一些层(如 Dropout、BatchNorm 等)的行为会发生变化
model.eval()
# 初始化正确预测的样本数
correct = 0
# 初始化总的样本数
total = 0
# 关闭梯度计算,因为在评估阶段不需要计算梯度
with torch.no_grad():
    # 遍历测试集中的每个批次数据
    for images, labels in test_loader:
        # 将输入图像数据输入到模型中,得到模型的预测输出
        outputs = model(images)
        # 找到每个样本预测概率最大的类别索引
        # _ 表示忽略的变量,predicted 为预测的类别索引
        _, predicted = torch.max(outputs.data, 1)
        # 累加当前批次的样本数
        total += labels.size(0)
        # 累加当前批次中预测正确的样本数
        correct += (predicted == labels).sum().item()

# 计算并打印模型在测试集上的准确率
print(f'Accuracy on test set: {100 * correct / total:.2f}%')

代码解释

数据加载和预处理:使用 torchvision.datasets.ImageFolder 加载图片数据集,并使用 transforms 对图片进行预处理,包括调整大小、转换为张量和归一化。
模型定义:定义了一个简单的卷积神经网络 SimpleCNN,包含两个卷积层、两个池化层和两个全连接层。
损失函数和优化器:使用交叉熵损失函数 nn.CrossEntropyLoss 和 Adam 优化器 optim.Adam。
模型训练:在训练过程中,遍历训练集,计算损失并进行反向传播更新模型参数。
模型评估:在测试集上评估模型的准确率。
请确保你已经安装了 PyTorch 和 torchvision 库,并且将猫和狗的图片按照指定的文件夹结构放置。如果需要提高模型的性能,可以尝试使用更复杂的预训练模型(如 ResNet、VGG 等)进行微调。

http://www.kler.cn/a/544584.html

相关文章:

  • AI时代前端工程师的职业发展新路径
  • IS-IS 泛洪机制 | LSP 处理流程
  • 【Unity3D杂谈】使用NDK命令行工具翻译Android Vitals上的内存堆栈
  • 如何部署DeepDeepSeek-V3 大模型部署全流程解析:从云平台到本地化实践Seek—V3
  • OpenAI推出全新AI助手“Operator”:让人工智能帮你做事的新时代!
  • ConcurrentHashMap扩容
  • Spring Boot 中的事务管理:默认配置、失效场景及集中配置
  • Android原生的HighCPU使用率查杀机制
  • 基于Python的医院运营数据可视化平台:设计、实现与应用(下)
  • 使用CherryStudio、Ollama、腾讯云搭建本地个人知识库、智能体
  • LabVIEW外腔二极管激光器稳频实验
  • 【leetcode】关于循环数组的深入分析
  • Opensearch/ElasticSearch-ctx查询内容不全的问题
  • Python从0到100(八十八):LSTM网络详细介绍及实战指南
  • 基于千兆5G网关的5G急救车方案
  • git用法(简易版)
  • SSH 代理与私钥持久化:让你的开发环境不再因重启而中断
  • windows系统 从 Hugging Face网站上使用 huggingface-cli 命令下载AI大模型到本地
  • 模糊聚类分析方法:从模糊等价矩阵到动态分类
  • 【Java常用】注解与反射_2.反射