深度学习blog-卷积神经网络(CNN)

server/2024/12/29 11:06:11/

卷积神经网络(Convolutional Neural Network,CNN)是一种广泛应用于计算机视觉领域,如图像分类、目标检测和图像分割等任务中的深度学习模型。

1. 结构
卷积神经网络一般由以下几个主要层组成:
输入层:接收原始图像数据,通常是三维(高、宽、通道)的张量。
卷积层(Convolutional Layer):使用多个卷积核(滤波器)对输入数据进行卷积操作,提取特征。该层的输出是特征图,显示了输入数据中的特征。卷积层是 CNN 的核心组成部分,它的主要功能是通过卷积操作提取局部特征。
在这里插入图片描述

卷积操作是通过一个小的滤波器(或卷积核)在输入图像上滑动来计算的,每次滑动时,卷积核与局部区域的像素值做点积运算,并输出一个新的值。这些新值组成了特征图(feature map)。

步长指定卷积核在输入数据上滑动的步伐。
填充(Padding)
填充是为了确保卷积操作不会丢失边缘信息,通常会在输入数据的边缘添加一些零值,称为零填充。
激活层(Activation Layer):常用的激活函数包括ReLU(修正线性单元)等,负责引入非线性因素,提高网络学习能力。通常放在卷积层之后。
池化层(Pooling Layer):对特征图进行下采样,通常使用最大池化或平均池化,减少特征的尺寸,降低计算复杂度,同时保留重要特征。避免过拟合。
常见的池化操作有最大池化和平均池化
最大池化(Max Pooling),对每个子区域选择最大值。
平均池化(Average Pooling),对每个子区域取平均值。

全连接层(Fully Connected Layer):将高层次的特征输出转换为最终的分类结果。每个神经元与前一层的所有神经元相连接。(将提取的高维特征映射到标签空间)

输出层:提供最终的预测结果,比如分类标签或回归值。

  1. 原理
    卷积神经网络的核心原理是利用卷积操作进行特征提取。卷积层通过卷积核在输入图像上滑动,不断提取局部区域的特征,能够自动学习并优化这些特征。
    卷积操作:通过卷积核与输入图像的局部区域进行点积,生成特征图。这个过程能够捕捉图像中的边缘、角点等基础特征。
    参数共享:同一个卷积核在整个图像上重复使用,可以减少模型参数,提高模型的泛化能力。
    局部感知:卷积核的大小限制了每个神经元的感知范围,使网络能学习到局部特征。

  2. 工作流程
    卷积神经网络的工作流程通常包括以下几个步骤:
    图像输入:将图像数据输入到网络中。
    特征提取:
    在卷积层中,通过多个卷积核对输入图像进行卷积,生成特征图。
    通过激活函数引入非线性。
    使用池化层进行特征降维。
    分类阶段:
    将经过多层特征提取后的特征图展平成一维向量,输入到全连接层。
    使用激活函数进行处理。
    损失计算:通过损失函数计算预测值与真实值之间的误差。
    反向传播:通过反向传播算法更新网络中的权重和偏置,以最小化损失。
    预测输出:经过最后的输出层,网络给出分类结果或回归输出。

例子,识别手写数字:

import numpy as np
import tensorflow as tf
from tensorflow.keras import datasets, layers, models
import matplotlib.pyplot as plt# 加载 MNIST 数据集
(x_train, y_train), (x_test, y_test) = datasets.mnist.load_data()
x_train, x_test = x_train / 255.0, x_test / 255.0
x_train = x_train.reshape((x_train.shape[0], 28, 28, 1))
x_test = x_test.reshape((x_test.shape[0], 28, 28, 1))
y_train = tf.keras.utils.to_categorical(y_train, 10)
y_test = tf.keras.utils.to_categorical(y_test, 10)# 构建 CNN 模型
model = models.Sequential([layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),layers.MaxPooling2D((2, 2)),layers.Conv2D(64, (3, 3), activation='relu'),layers.MaxPooling2D((2, 2)),layers.Conv2D(64, (3, 3), activation='relu'),layers.Flatten(),layers.Dense(64, activation='relu'),layers.Dropout(0.15),layers.Dense(10, activation='softmax')  # 10 类输出
])# 编译模型
model.compile(optimizer='adam',loss='categorical_crossentropy',metrics=['accuracy'])# 训练模型
history = model.fit(x_train, y_train, epochs=5, batch_size=64, validation_data=(x_test, y_test))# 在测试集上评估模型
test_loss, test_acc = model.evaluate(x_test, y_test)
print(f"Test accuracy: {test_acc:.4f}")# 随机选择一些测试图像的索引
num_images = 10
random_indices = np.random.choice(x_test.shape[0], num_images, replace=False)test_images = x_test[random_indices]
true_labels = np.argmax(y_test[random_indices], axis=1)
predicted_labels = np.argmax(model.predict(test_images), axis=1)plt.figure(figsize=(12, 4))
for i in range(num_images):plt.subplot(2, 5, i + 1)plt.imshow(test_images[i].reshape(28, 28), cmap='gray')plt.title(f"True: {true_labels[i]}\nPred: {predicted_labels[i]}")plt.axis('off')
plt.show()# 绘制训练过程中的准确率和损失
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(history.history['accuracy'], label='Training Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.legend()
plt.title('Training and Validation Accuracy')

在这里插入图片描述
pytorch实现:

import numpy as np
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
from torchvision import datasets# 加载 MNIST 数据集
transform = transforms.Compose([transforms.ToTensor(),  # 转换为 tensor,并归一化为 [0, 1] 区间
])
train_dataset = datasets.MNIST(root='../../data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST(root='../../data', train=False, download=True, transform=transform)# 数据加载器
train_loader = DataLoader(dataset=train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(dataset=test_dataset, batch_size=64, shuffle=False)# 构建 CNN 模型
class CNN(nn.Module):def __init__(self):super(CNN, self).__init__()self.conv1 = nn.Conv2d(1, 32, kernel_size=3, stride=1, padding=1)  # 28x28x1 -> 28x28x32self.pool = nn.MaxPool2d(kernel_size=2, stride=2)  # 下采样self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)  # 28x28x32 -> 28x28x64self.conv3 = nn.Conv2d(64, 64, kernel_size=3, stride=1, padding=1)  # 28x28x64 -> 28x28x64self.fc1 = nn.Linear(64 * 7 * 7, 64)  # 根据池化后特征的形状计算输入大小self.dropout = nn.Dropout(0.15)  # Dropout 层self.fc2 = nn.Linear(64, 10)  # 输出10类def forward(self, x):x = self.pool(torch.relu(self.conv1(x)))  # Conv1 + ReLU + Poolingx = self.pool(torch.relu(self.conv2(x)))  # Conv2 + ReLU + Poolingx = torch.relu(self.conv3(x))               # Conv3 + ReLUx = x.view(-1, 64 * 7 * 7)  # 展平x = torch.relu(self.fc1(x))  # FC1 + ReLUx = self.dropout(x)           # Dropoutx = self.fc2(x)               # FC2return x# 创建模型实例
model = CNN()# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters())# 训练模型
num_epochs = 5
for epoch in range(num_epochs):model.train()for batch_images, batch_labels in train_loader:optimizer.zero_grad()  # 梯度清零outputs = model(batch_images)  # 前向传播loss = criterion(outputs, batch_labels)  # 计算损失loss.backward()  # 反向传播optimizer.step()  # 更新参数print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}')# 在测试集上评估模型
model.eval()
test_loss = 0
correct = 0
with torch.no_grad():for batch_images, batch_labels in test_loader:outputs = model(batch_images)  # 前向传播loss = criterion(outputs, batch_labels)  # 计算损失test_loss += loss.item()  # 累加损失_, predicted = torch.max(outputs.data, 1)  # 预测correct += (predicted == batch_labels).sum().item()  # 统计正确样本数# 计算准确率
test_accuracy = correct / len(test_dataset)
print(f"Test accuracy: {test_accuracy:.4f}")# 随机选择一些测试图像的索引并可视化
num_images = 10
random_indices = np.random.choice(len(test_dataset), num_images, replace=False)test_images = []
true_labels = []
predicted_labels = []for idx in random_indices:img, label = test_dataset[idx]test_images.append(img)true_labels.append(label)test_images_tensor = torch.stack(test_images)
with torch.no_grad():outputs = model(test_images_tensor)  # 前向传播_, predicted = torch.max(outputs.data, 1)  # 预测predicted_labels = predicted.numpy()# 可视化结果
plt.figure(figsize=(12, 4))
for i in range(num_images):plt.subplot(2, 5, i + 1)plt.imshow(test_images[i].numpy()[0], cmap='gray')  # 仅显示通道1plt.title(f"True: {true_labels[i]}\nPred: {predicted_labels[i]}")plt.axis('off')
plt.show()

在这里插入图片描述


http://www.ppmy.cn/server/154183.html

相关文章

Vue3响应式:Proxy设计原理解析

# Vue3响应式:Proxy设计原理解析 了解Proxy 在Vue3中,由于Proxy的设计原理,使得其响应式系统更加灵活和高效。那么什么是Proxy呢?Proxy是ES6新增的特性,可以用来自定义对象的操作。通过Proxy,我们可以重写对象的默认行…

【每日学点鸿蒙知识】屏幕高度、证书签名、深色模式对上架影响、Taskpool上下文、List触底加载更多

1、HarmonyOS 关于屏幕高度? display.getDefaultDisplaySync 可以获取到整个屏幕的高度, 那顶部的状态栏和底部的安全区高度 怎么获取? 可以在EntryAbility里获取并存储,获取到的高度是px,所以用px2vp()转…

【C++ 真题】P5733 【深基6.例1】自动修正

【深基6.例1】自动修正 题目描述 大家都知道一些办公软件有自动将字母转换为大写的功能。输入一个长度不超过 100 100 100 且不包括空格的字符串。要求将该字符串中的所有小写字母变成大写字母并输出。 输入格式 输入一行,一个字符串。 输出格式 输出一个字符…

基于人工智能时代政务智慧转型的实现前景初探

去年6月,我有幸聆听了由华政公共管理与政治学院精心组织的2019年MPA研究生高端论坛,上午场:由董海军(中共上海市委机构编制委员会办公室处长)主讲的深化机构改革的探索与实践,以及下午场:由束金…

小程序基础 —— 02 微信小程序账号注册

微信小程序账号注册 小程序开发与网页开发不一样,在开始微信小程序开发之前,需要访问微信公众平台,注册一个微信小程序账号。 有了小程序的账号以后,才可以开发和管理小程序,后续需要通过该账号进行开发信息的设置、…

python实战项目55:多线程爬取笔趣阁小说

python实战项目55:多线程爬取笔趣阁小说 一、明确需求二、单本小说下载三、使用concurrent.futures线程池模块下载并实现文件合并四、使用threading模块实现多线程下载并合并文件一、明确需求 需求是使用多线程爬取笔趣阁网站小说的所有章节内容并保存,多线程分别使用了conc…

服务器反应慢,秒杀设计

目录 服务器反应慢 线上服务器cup飙升,如果定位Java代码? 服务器变慢如何诊断处理? 线上接口负载剧增,快扛不住了,解决方法是什么? 秒杀设计 从全局角度如何设计一个秒杀系统 秒杀活动里遇到的问题 …

【黑马头条】day20—xxl-job

目录 1 今日内容 1.1 需求分析 1.2 实现思路 1.3 定时计算 1.4 定时任务框架-xxljob 1.5 学习目录 2.分布式任务调度 2.1 什么是分布式任务调度 2.2 xxl-Job简介 2.3 XXL-Job-环境搭建 2.4 配置部署调度中心-docker安装 2.5 xxl-job入门案例编写 2.6 任务详解-执行…