首页 > 其他分享 >深度学习 - CNN

深度学习 - CNN

时间:2024-06-11 16:00:42浏览次数:23  
标签:loss nn self torch 0.5 学习 深度 CNN model

第一部分:基础知识

1. 什么是卷积神经网络(CNN)

定义和基本概念
卷积神经网络(CNN)是一种专门用于处理具有网格结构数据(如图像)的深度学习模型。它们在图像识别和计算机视觉领域表现尤为突出。与传统的全连接神经网络不同,CNN利用局部连接和共享权重的方式,能够有效减少参数数量,提高计算效率。

CNN在图像处理中的优势

  • 局部连接:只处理图像的局部区域,减少参数量。
  • 共享权重:同一个滤波器在图像不同位置扫描,进一步减少参数量。
  • 池化操作:通过降采样减少数据维度,提取重要特征。
2. CNN的基本结构

输入层
处理输入数据,比如一张图片,通常用三维数组表示(宽度,高度,颜色通道数)。

卷积层
通过应用不同的滤波器来提取特征。滤波器滑过输入图像,生成特征映射。

池化层
进行降采样,减少数据维度,提高计算效率,同时保留重要特征。

全连接层
将卷积层和池化层提取的特征展开成一维向量,并通过多个全连接层进行分类。

输出层
根据具体任务(如分类、回归)输出最终结果。
在这里插入图片描述

第二部分:深入理解

卷积操作(Convolution Operation)

实例:
假设有一个3x3的输入图像和一个2x2的滤波器:

输入图像:

1 2 3
4 5 6
7 8 9

滤波器:

1 0
0 -1

卷积操作是将滤波器应用于图像的每个局部区域,计算它们的点积和:

1*1 + 2*0 + 4*0 + 5*(-1) = 1 - 5 = -4
2*1 + 3*0 + 5*0 + 6*(-1) = 2 - 6 = -4
4*1 + 5*0 + 7*0 + 8*(-1) = 4 - 8 = -4
5*1 + 6*0 + 8*0 + 9*(-1) = 5 - 9 = -4

最终得到的特征映射:

-4 -4
-4 -4
激活函数(ReLU, Sigmoid, Tanh等)

实例:
ReLU(Rectified Linear Unit):f(x) = max(0, x)
假设输入为[-1, 2, -3, 4],经过ReLU后:

ReLU([-1, 2, -3, 4]) = [0, 2, 0, 4]
池化操作(Max Pooling, Average Pooling)

实例:
Max Pooling:
输入:

1 2
3 4

最大池化结果:

4

Average Pooling:
输入:

1 2
3 4

平均池化结果:

(1+2+3+4)/4 = 2.5
损失函数(Cross-Entropy Loss等)

实例:
假设有两个类别,实际标签为[1, 0](表示第一类),预测概率为[0.8, 0.2]。
交叉熵损失计算:

Loss = - (1 * log(0.8) + 0 * log(0.2)) = - log(0.8) = 0.223

第三部分:实战应用

1. 使用PyTorch实现CNN

安装和配置PyTorch

pip install torch torchvision

构建简单的CNN模型

import torch.nn as nn
import torch.nn.functional as F

class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()
        self.conv1 = nn.Conv2d(3, 16, 3, 1)  # 3个输入通道,16个输出通道,3x3的卷积核,步长1
        self.conv2 = nn.Conv2d(16, 32, 3, 1)
        self.fc1 = nn.Linear(32 * 6 * 6, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.max_pool2d(x, 2, 2)
        x = F.relu(self.conv2(x))
        x = F.max_pool2d(x, 2, 2)
        x = x.view(-1, 32 * 6 * 6)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)

数据预处理

import torchvision.transforms as transforms
from torchvision.datasets import CIFAR10
from torch.utils.data import DataLoader

transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])

trainset = CIFAR10(root='./data', train=True, download=True, transform=transform)
trainloader = DataLoader(trainset, batch_size=32, shuffle=True)

训练和评估模型

import torch.optim as optim

model = SimpleCNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

for epoch in range(10):  # 训练10个epoch
    running_loss = 0.0
    for i, data in enumerate(trainloader, 0):
        inputs, labels = data
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
        if i % 100 == 99:    # 每100个批次打印一次
            print(f'Epoch {epoch + 1}, Batch {i + 1}, Loss: {running_loss / 100:.3f}')
            running_loss = 0.0

print('Finished Training')
2. 经典CNN架构

LeNet
由Yann LeCun提出,适用于手写数字识别。

AlexNet
由Alex Krizhevsky提出,首次在ImageNet竞赛中大放异彩。

VGGNet
由Oxford大学Visual Geometry Group提出,使用多个小卷积核代替大卷积核。

GoogLeNet/Inception
由Google提出,使用Inception模块提高模型性能。

ResNet
由Microsoft提出,引入残差连接解决深层网络训练困难问题。

DenseNet
由Cornell大学提出,通过密集连接提高梯度流动。

3. 转移学习与预训练模型

使用预训练模型

from torchvision import models

resnet = models.resnet18(pretrained=True)

微调(Fine-Tuning)

for param in resnet.parameters():
    param.requires_grad = False

resnet.fc = nn.Linear(resnet.fc.in_features, 10)

第四部分:高级主题

1. 优化与调整

学习率调度

scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)

正则化方法

self.dropout = nn.Dropout(0.5)  # 在网络中使用dropout防止过拟合

批量归一化

self.bn1 = nn.BatchNorm2d(16)  # 在卷积层后添加批量归一化层
2. 增强技术

数据增强

transform = transforms.Compose([
    transforms.RandomHorizontalFlip(),
    transforms.RandomCrop(32, padding=4),
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])

混合精度训练

from torch.cuda.amp import GradScaler, autocast

scaler = GradScaler()

for epoch in range(10):
    for inputs, labels in trainloader:
        optimizer.zero_grad()
        with autocast():
            outputs = model(inputs)
            loss = criterion(outputs, labels)
        scaler.scale(loss).backward()
        scaler.step(optimizer)
        scaler.update()
3. CNN的其他应用

对抗生成网络(GANs)
生成与判别网络相互竞争,提高生成图像质量。

目标检测(Object Detection)
检测图像中的多个对象并定位它们的边界框。

语义分割(Semantic Segmentation)
将图像中的每个像

素分类到特定类别。

第五部分:项目与实践

1. 手写数字识别(MNIST)

项目介绍
MNIST数据集是一个经典的手写数字识别数据集,包含60,000个训练样本和10,000个测试样本。每个样本是28x28的灰度图像,表示从0到9的数字。

步骤

  1. 数据准备
  2. 模型构建
  3. 模型训练
  4. 模型评估

详细过程

  1. 数据准备
import torch
import torchvision
import torchvision.transforms as transforms

transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))
])

trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True)

testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=32, shuffle=False)
  1. 模型构建
import torch.nn as nn
import torch.nn.functional as F

class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, 3, 1)
        self.conv2 = nn.Conv2d(32, 64, 3, 1)
        self.fc1 = nn.Linear(12 * 12 * 64, 128)
        self.fc2 = nn.Linear(128, 10)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.max_pool2d(self.conv2(x), 2)
        x = torch.flatten(x, 1)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)
  1. 模型训练
import torch.optim as optim

model = SimpleCNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

for epoch in range(5):  # 训练5个epoch
    model.train()
    running_loss = 0.0
    for inputs, labels in trainloader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
    print(f'Epoch {epoch + 1}, Loss: {running_loss / len(trainloader):.3f}')
  1. 模型评估
model.eval()
correct = 0
total = 0
with torch.no_grad():
    for inputs, labels in testloader:
        outputs = model(inputs)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f'Accuracy: {100 * correct / total:.2f}%')
2. 图像分类(CIFAR-10)

项目介绍
CIFAR-10数据集包含60,000张32x32的彩色图像,分为10个类别。每个类别有6,000张图像。

步骤

  1. 数据准备
  2. 模型构建
  3. 模型训练
  4. 模型评估

详细过程

  1. 数据准备
transform = transforms.Compose([
    transforms.RandomHorizontalFlip(),
    transforms.RandomCrop(32, padding=4),
    transforms.ToTensor(),
    transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
])

trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=32, shuffle=True)

testset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=32, shuffle=False)
  1. 模型构建
class CIFAR10CNN(nn.Module):
    def __init__(self):
        super(CIFAR10CNN, self).__init__()
        self.conv1 = nn.Conv2d(3, 32, 3, 1)
        self.conv2 = nn.Conv2d(32, 64, 3, 1)
        self.conv3 = nn.Conv2d(64, 128, 3, 1)
        self.fc1 = nn.Linear(128 * 2 * 2, 256)
        self.fc2 = nn.Linear(256, 10)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.max_pool2d(F.relu(self.conv2(x)), 2)
        x = F.max_pool2d(F.relu(self.conv3(x)), 2)
        x = torch.flatten(x, 1)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)
  1. 模型训练
model = CIFAR10CNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

for epoch in range(10):  # 训练10个epoch
    model.train()
    running_loss = 0.0
    for inputs, labels in trainloader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
    print(f'Epoch {epoch + 1}, Loss: {running_loss / len(trainloader):.3f}')
  1. 模型评估
model.eval()
correct = 0
total = 0
with torch.no_grad():
    for inputs, labels in testloader:
        outputs = model(inputs)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f'Accuracy: {100 * correct / total:.2f}%')
3. 自然图像识别(ImageNet)

项目介绍
ImageNet数据集包含超过100万张带标签的高分辨率图像,分为1000个类别。它是深度学习和计算机视觉领域的标准数据集。

步骤

  1. 使用预训练模型
  2. 微调模型
  3. 模型评估

详细过程

  1. 使用预训练模型
from torchvision import models

model = models.resnet18(pretrained=True)
  1. 微调模型
# 冻结除最后一层外的所有层
for param in model.parameters():
    param.requires_grad = False

# 替换最后一层
model.fc = nn.Linear(model.fc.in_features, 1000)

# 仅训练最后一层
optimizer = optim.Adam(model.fc.parameters(), lr=0.001)
  1. 模型训练
for epoch in range(5):  # 训练5个epoch
    model.train()
    running_loss = 0.0
    for inputs, labels in trainloader:
        optimizer.zero_grad()
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        running_loss += loss.item()
    print(f'Epoch {epoch + 1}, Loss: {running_loss / len(trainloader):.3f}')
  1. 模型评估
model.eval()
correct = 0
total = 0
with torch.no_grad():
    for inputs, labels in testloader:
        outputs = model(inputs)
        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum().item()

print(f'Accuracy: {100 * correct / total:.2f}%')

标签:loss,nn,self,torch,0.5,学习,深度,CNN,model
From: https://blog.csdn.net/weixin_47552266/article/details/139601051

相关文章

  • 初阶java学习2
    Notepad软件高级记事本有行号,而且Java中的一些特殊单词会高亮显示方便我们对报错进行修改;常见的高级记事本Editplus、Notepad++、Sublime(前端程序员常用)等Notepad++下载方式百度网盘:百度网盘请输入提取码提取码:e36o编码选择ANSI可以让我们输出中文;JAVA的三......
  • 机器学习之支持向量机
    什么是SVMSVM(全称SupportVectorMachine)中文名支持向量机。SVM是一种监督机器学习算法,是一种二分类模型,它的目的是寻找一个超平面来对样本进行分割,分割的原则是间隔最大化,最终转化为一个凸二次规划问题来求解。可用于分类或回归挑战。然而,它主要用于分类问题。最大间隔与分类......
  • Lucene的IK分词器学习,增加支持单个特殊符号搜索
    前言感谢CSDN这篇文章,原始代码基于这里。正常对于“[email protected]”这段文字,搜索'@'这个符号是搜不出来的。本文主要修改是扩展IK分词器,增加了对诸如"@-"这种特殊文字的检索。当然这个其实并没有多少实际意义,所以基本也是出于学习的目的。正文IK分词器分析这里不深入原理,......
  • 安全防护与隐私保护:淘宝在线扭蛋机用户数据安全的深度解析
    淘宝在线扭蛋机作为一种集购物与娱乐于一体的新型平台,用户数据的安全性至关重要。本文将深入探讨如何采取有效措施,确保在线扭蛋机用户数据的安全性,防止数据泄露和滥用。一、构建多层次安全防护体系为了应对复杂的网络安全威胁,我们将构建多层次的安全防护体系。这包括网络层......
  • 机器学习实践——支持向量机
    一.什么是支持向量机支持向量机(SVM)是一种广泛使用的监督学习方法,主要用于分类和回归分析。它的基本原理是找到一个超平面(在二维空间中是一条直线),以最大化不同类别之间的边界。以下是SVM的关键概念:超平面:决策边界,用于分类的直线或平面。 边界(Margin):从超平面到最近的数据点的最......
  • 我所理解的机器学习
    (2017年写的博客,搬过来)断断续续看了几个月的机器学习,我觉得是时候总结一下了。正如题目讲的那样,我只说我所理解的机器学习,我不能保证我理解的都对,很多东西可能是我的误解,但无论说错了什么,我都认。如果有人发现错误,恳请指正,不胜感激。我不讲算法也不讲公式推导,因为,我从头到尾都......
  • 由AtCoder_ABC357D引发的除法同余学习
    鉴于最近的Atcoder周赛又出现除法求余,下定决心学习逆元相关内容同余概述定义同余定义:若a和b是整数,且m|(a-b),则称a和b模m同余。即两者除以m得到的余数相同。剩余系:一个模m完全剩余系是一个整数集合,任何一个整数恰好与该集合中的一个元素模m同余。例如0,1,...,m-1的集......
  • Java与机器学习:从零开始的入门指南
    引言随着人工智能和大数据的迅猛发展,机器学习已经成为现代技术的核心之一。虽然Python在机器学习领域占据主导地位,但Java凭借其稳定性、跨平台性和丰富的生态系统,依然是许多企业级应用的首选语言。在本系列文章中,我们将深入探讨如何使用Java进行机器学习,从基础概念到实际应......
  • nofile参数的学习与整理
    nofile参数的学习与整理背景前段时间正好总结了文件描述符泄露的问题.最近在客户现场,也遇到了一个问题.其实两个问题都是因为nofile参数限制所引发.所以总结一下:nginx的worker的连接数是受到到nofile的限制的.虽然那可以通过修改配置文件和直接ulimit-HSn进......
  • Python数据分析与机器学习在电子商务推荐系统中的应用
    文章目录......