深度学习之图像分类(一)

前言

  图像回归主要是对全连接进行理解 而图像分类任务主要是对卷积的过程进行理解 这一部分会介绍一些基础的概念 卷积的过程(包括单通道和多通道) 理解一个卷积神经网络工作的过程 以及常见的模型的类别和创新点 

图像分类是什么

定义

  图像分类是指将输入的图像分配到一个或多个预定义的类别中的任务。简单来说,就是让计算机“看”一张图片,然后告诉用户这张图片属于什么类别。例如,判断一张图片是猫、狗还是汽车等。

与回归任务的区别

  • 回归分类的主要区别在于目标变量的类型(连续 vs. 离散)。

  • 回归关注的是预测具体的数值,而分类关注的是将数据划分到不同的类别中。

  • 回归解决函数拟合的问题 而回归任务注重决策边界划分的问题

训练流程的区别 

图像分类与图像回归输出的对比

特性图像分类图像回归
输出类型类别标签或概率分布连续数值
输出层激活函数Softmax(多类别)或Sigmoid(二分类)线性(无激活函数)
损失函数交叉熵损失均方误差(MSE)、平均绝对误差(MAE)
应用场景判断图像内容(如猫/狗分类、疾病诊断)预测连续数值(如物体大小、位置、年龄)
输出示例“猫” 或 “猫的概率为0.8,狗的概率为0.2”“宽度为120像素” 或 “[100, 150, 20

评价的区别

卷积神经网络架构

一个典型的CNN结构通常按照以下顺序堆叠:

  1. 输入层:输入图像或特征图。

  2. 卷积层 + 激活层(可选):提取局部特征。

  3. 池化层(可选):降低特征图尺寸。

  4. 重复步骤2和3:通过多层卷积和池化提取更高级的特征。

  5. 归一化层(可选):对特征进行归一化处理。

  6. Dropout层(可选):防止过拟合。

  7. 全连接层:整合特征,输出最终结果。

  8. 输出层:根据任务类型,输出分类概率(Softmax)或回归值。


卷积神经网络(CNN)相关概念

1. 卷积运算

卷积运算是CNN的核心操作,用于从输入数据中提取特征。它通过卷积核(滤波器)在输入数据上滑动并计算点积,生成特征图(Feature Map)。

2. 输入通道

输入通道是指输入图像的维度。例如:

  • 对于灰度图像,输入通道为1。

  • 对于RGB图像,输入通道为3(分别对应红、绿、蓝三个颜色通道)。

3. 输出通道

输出通道是指卷积层输出的特征图数量。每个卷积核会生成一个特征图,因此输出通道的数量等于卷积核的数量。

4. 卷积核(滤波器)

卷积核是一个小的矩阵,用于在输入数据上滑动并计算卷积。卷积核的大小(如3×3、5×5)和数量决定了卷积层的复杂性和特征提取能力。

5. 特征图(Feature Map)

特征图是卷积运算的输出,表示输入数据在某个特定卷积核下的特征表示。每个特征图对应一个卷积核。

6. Padding(填充)

填充是在输入数据的边界添加额外的零值像素,用于控制特征图的大小。常见的填充方式包括:

  • 无填充(Valid Padding):不添加任何填充,特征图的大小会减小。

  • 同态填充(Same Padding):添加填充使特征图的大小与输入数据相同。

控制输出大小:填充可以灵活调整输出特征图的空间维度。

6.1 填充是什么

填充是指在输入图像或特征图的边缘添加额外的像素(通常为0),以控制卷积操作后的输出尺寸。在每张图的长宽上填充 左右上下都要填充

6.2填充的作用
  • 保留边界信息:在没有填充的情况下,卷积操作会使输出特征图的尺寸逐渐减小,导致边缘信息丢失。

  • 保持输入输出尺寸一致:通过填充,可以使卷积后的特征图与输入图像保持相同的尺寸。

6.3填充的方式
  • 零填充(Zero Padding):在输入图像周围添加零值像素。这是最常用的填充方式,因为它简单且计算效率高。

  • 边缘复制填充(Edge Replication Padding):将输入图像边缘的像素复制到填充区域。

  • 镜像填充(Mirror Padding):将输入图像边缘的像素进行镜像翻转后填充。

7. 步长(Stride)

步长是卷积核在输入数据上滑动的步数。步长为1表示卷积核每次移动一个像素;步长为2表示每次移动两个像素。较大的步长会导致特征图尺寸减小。

7.1 步长是什么

步长是指卷积核在输入图像上滑动的步数。步长越大,卷积核滑动越快,输出特征图的尺寸越小。

7.2 不同步长的作用
  1. 控制输出尺寸:较大的步长可以快速减小特征图的尺寸,减少计算量。

  2. 增加感受野:较大的步长可以使卷积核覆盖更广的区域,从而增加模型的感受野

8. 卷积过程计算

卷积过程是通过卷积核在输入数据上滑动并计算点积来完成的。

9. 多通道卷积

在多通道输入(如RGB图像)中,卷积核会同时作用于所有通道,并将结果相加生成一个特征图。例如,对于一个3×3×3的卷积核和一个5×5×3的输入数据,卷积核会分别与每个通道进行卷积运算,然后将结果相加。


池化层(Pooling Layer)

1. 池化层是什么?

池化层用于降低特征图的空间维度,减少计算量并提取重要特征。常见的池化操作包括:

  • 最大池化(Max Pooling):取池化窗口内的最大值。

  • 平均池化(Average Pooling):取池化窗口内的平均值。

2. 为什么使用池化层?
  • 降低计算量:减少特征图的尺寸。

  • 提取重要特征:保留关键信息,去除冗余信息。

  • 增强模型的平移不变性:对输入数据的小范围平移不敏感。

3. 池化层工作原理?

池化层通常在卷积层之后使用,窗口大小和步长是其主要参数。例如,一个2×2的最大池化层,步长为2,会将特征图的尺寸减半。


归一化技术

1. 归一化是什么?

归一化是将输入数据或特征值调整到一个统一的范围(如0到1或-1到1)。常见的归一化技术包括:

  • Min-Max Scaling:将数据缩放到0到1之间。

  • Z-Score标准化:将数据转换为均值为0、标准差为1的分布。

  • Batch Normalization:在训练过程中对每个小批量数据进行归一化,加速训练并提高模型性能。

2. 为什么使用归一化?
  • 加速训练:归一化后的数据分布更均匀,有助于优化算法更快收敛。

  • 提高模型性能:避免某些特征对模型的影响过大。

  • 减少数值不稳定:避免梯度爆炸或消失问题。

3. 怎么办?
  • 数据预处理阶段:对输入图像进行归一化处理。

  • 模型训练阶段:使用Batch Normalization等技术对中间层的特征进行归一化。


损失函数与交叉熵损失

1. 损失函数的定义

损失函数(Loss Function)是机器学习和深度学习中用于衡量模型预测值与真实值之间差异的函数。它的目的是通过优化模型的参数,使损失值最小化,从而提高模型的预测准确性。

2. 交叉熵损失的定义

交叉熵损失(Cross-Entropy Loss)是深度学习中分类问题常用的损失函数,特别适用于多分类任务。它通过度量预测分布与真实分布之间的差异来衡量模型输出的准确性。

3. 交叉熵损失的数学公式
  • 二分类问题:假设真实标签 y∈{0,1},预测概率为 y^​,则交叉熵损失公式为:

    当真实类别 y=1 时,若模型预测 y^​ 接近 1(正确预测),损失接近 0;若预测接近 0(错误预测),损失接近无穷大。

  • 多分类问题:假设 K 为类别数,y 为真实类别(one-hot 编码),y^​i​ 为第 i 类的预测概率,则交叉熵损失公式为:

    由于 one-hot 编码中只有真实类别的 yi​=1,其余为 0,因此公式可以简化为:

    其中 c 是真实类别的索引。

4. 交叉熵损失与 Softmax 的关系

交叉熵损失通常与 Softmax 函数结合使用。Softmax 函数将模型输出的 logits(未归一化的分数)转换为概率分布:

其中 zi​ 是第 i 类的 logits。

5. 交叉熵损失的应用

交叉熵损失广泛应用于分类任务,如图像分类、文本分类等。它能够对错误的高置信度预测施加较大的惩罚,从而促进模型学习更准确的概率分布。

交叉熵损失 是分类问题中的核心工具,用于衡量预测分布与真实分布之间的差异。

它通过 Softmax 函数将 logits 转换为概率分布,然后计算损失。

常见网络架构

AlexNet

AlexNet的创新点

  • ReLU激活函数:引入了修正线性单元(ReLU)激活函数,它能够加速网络的训练并提高模型的泛化能力。

  • Dropout:使用了Dropout技术来防止过拟合,通过在训练过程中随机丢弃一部分神经元,使模型更加鲁棒。

  • 池化:通过池化层降低特征图的维度,同时保留重要特征,增强模型的平移不变性。

  • 归一化它可以让模型关注数据的分布,而不受数据量纲的影响。 保持学习有效性, 缓解梯度消失和梯度爆炸。

实现

import torch.nn as nnclass myAlexNet(nn.Module):def __init__(self, out_dim):super(myAlexNet, self).__init__()self.conv1 = nn.Conv2d(3,64,11,4,2)self.pool1 = nn.MaxPool2d(3, 2)self.conv2 = nn.Conv2d(64,192,5,1,2)self.pool2 = nn.MaxPool2d(3, 2)self.conv3 = nn.Conv2d(192,384,3,1,1)self.conv4 = nn.Conv2d(384, 256, 3, 1, 1)self.conv5 = nn.Conv2d(256, 256, 3, 1, 1)self.pool3 = nn.MaxPool2d(3, 2)self.pool4 = nn.AdaptiveAvgPool2d(6)self.fc1 = nn.Linear(9216, 4096)self.fc2 = nn.Linear(4096, 4096)self.fc3 = nn.Linear(4096, out_dim)def forward(self,x):x =self.conv1(x)x = self.pool1(x)x =self.conv2(x)x = self.pool2(x)x =self.conv3(x)x =self.conv4(x)x = self.conv5(x)x = self.pool3(x)x = self.pool4(x)x = x.view(x.size()[0], -1)  #拉直。 batchx = self.fc1(x)x = self.fc2(x)x = self.fc3(x)return xmodel = myAlexNet(1000)

VggNet

创新

用小卷积核代替大的卷积核

小卷积核能够代替大卷积核的关键在于它们可以通过堆叠多层来达到相同的感受野,同时减少参数数量,增加网络深度,提高模型的表达能力和计算效率。这种设计使得网络更加轻量化,易于训练和部署,同时保持或提高模型的性能。

模块化设计

比如下面的两次卷积 一次池化

实现

class vggLayer(nn.Module):#模块化 def __init__(self,in_cha, mid_cha, out_cha):super(vggLayer, self).__init__()self.relu = nn.ReLU() # 定义激活函数self.pool = nn.MaxPool2d(2) # 定义池化方式self.conv1 = nn.Conv2d(in_cha, mid_cha, 3, 1, 1) # 定义卷积核self.conv2 = nn.Conv2d(mid_cha, out_cha, 3, 1, 1) # 定义卷积核def forward(self,x):x = self.conv1(x)x= self.relu(x)x = self.conv2(x)x = self.relu(x)x = self.pool(x)return xclass MyVgg(nn.Module):def __init__(self): # 定义结构super(MyVgg, self).__init__()self.layer1 = vggLayer(3, 64, 64)self.layer2 = vggLayer(64, 128, 128)self.layer3 = vggLayer(128, 256, 256)self.layer4 = vggLayer(256, 512, 512)self.layer5 = vggLayer(512, 512, 512)self.adapool = nn.AdaptiveAvgPool2d(7)self.relu = nn.ReLU()self.fc1 = nn.Linear(25088, 4096)self.fc2 = nn.Linear(4096, 4096)self.fc3 = nn.Linear(4096, 1000)def forward(self,x):x = self.layer1(x)x = self.layer2(x)x = self.layer3(x)x = self.layer4(x)x = self.layer5(x)x = self.adapool(x)x = x.view(x.size()[0], -1)x = self.fc1(x)x = self.relu(x)x = self.fc2(x)x = self.relu(x)x = self.fc3(x)x = self.relu(x)return x

ResNet

创新点

没问题,我们可以用更简单的方式来解释1x1卷积和残差连接(Residual Connection),这样即使是初学者也能理解。

1x1卷积

想象一下,你有一堆彩色的画笔(代表图像中的颜色通道),每个画笔都有不同的颜色。1x1卷积就像是一个神奇的画笔混合器,它不改变画笔的数量(也就是图像的宽度和高度),但可以改变画笔的颜色组合(也就是改变图像的通道数)。

  • 为什么使用1x1卷积?

    • 减少计算量:如果图像有很多通道,1x1卷积可以减少通道的数量,从而减少后续计算的复杂度。

    • 增加非线性:虽然1x1卷积本身是线性操作,但通常我们会在它后面加上一个非线性激活函数(比如ReLU),这样可以增加模型的表达能力。

残差连接(Residual Connection)

现在,想象你正在学习画一幅画。残差连接就像是你有一个基础的画(输入),然后你尝试在这幅画上添加更多的细节(通过神经网络的层)。但是,有时候添加的细节太多,反而让画变得混乱。

  • 什么是残差连接?

    • 直接连接:残差连接允许你将基础的画(输入)直接复制一份,然后和添加的细节(通过神经网络层处理后的输出)放在一起。这样,即使添加的细节不完美,最终的画也不会太差,因为基础的画还在。

    • 解决梯度消失问题:在深层神经网络中,信息从一层传递到另一层时可能会丢失(梯度消失)。残差连接通过直接将输入传递到后面的层,帮助信息更顺畅地流动,从而解决这个问题。

  • 为什么使用残差连接?

    • 更容易训练深层网络:残差连接使得训练非常深的神经网络变得更容易,因为信息可以更容易地从一层传递到另一层。

    • 提高性能:在很多情况下,使用残差连接的网络比没有使用残差连接的网络表现得更好。

总结
  • 1x1卷积:是一种特殊的卷积操作,可以改变图像的通道数,但不改变图像的宽度和高度。它常用于减少计算量和增加非线性。

  • 残差连接:是一种网络结构设计,允许输入直接跳过一些层,与后面的层的输出相加。它有助于解决深层网络训练中的梯度消失问题,并提高网络的性能。

希望这个解释能帮助你更好地理解这两个概念!如果你还有其他问题,随时可以问。

实现

class Residual_block(nn.Module):  #@savedef __init__(self, input_channels, out_channels, down_sample=False, strides=1):super().__init__()self.conv1 = nn.Conv2d(input_channels, out_channels,kernel_size=3, padding=1, stride=strides)self.conv2 = nn.Conv2d(out_channels, out_channels,kernel_size=3, padding=1, stride= 1)if input_channels != out_channels:self.conv3 = nn.Conv2d(input_channels, out_channels,kernel_size=1, stride=strides)else:self.conv3 = Noneself.bn1 = nn.BatchNorm2d(out_channels)self.bn2 = nn.BatchNorm2d(out_channels)self.relu = nn.ReLU()def forward(self, X):out = self.relu(self.bn1(self.conv1(X)))out= self.bn2(self.conv2(out))if self.conv3:X = self.conv3(X)out += Xreturn self.relu(out)class MyResNet18(nn.Module):def __init__(self):super(MyResNet18, self).__init__()self.conv1 = nn.Conv2d(3, 64, 7, 2, 3)self.bn1 = nn.BatchNorm2d(64)self.pool1 = nn.MaxPool2d(3, stride=2, padding=1)self.relu = nn.ReLU()self.layer1 = nn.Sequential(Residual_block(64, 64),Residual_block(64, 64))self.layer2 = nn.Sequential(Residual_block(64, 128, strides=2),Residual_block(128, 128))self.layer3 = nn.Sequential(Residual_block(128, 256, strides=2),Residual_block(256, 256))self.layer4 = nn.Sequential(Residual_block(256, 512, strides=2),Residual_block(512, 512))self.flatten = nn.Flatten()self.adv_pool = nn.AdaptiveAvgPool2d(1)self.fc = nn.Linear(512, 1000)def forward(self, x):x = self.conv1(x)x = self.bn1(x)x = self.relu(x)x = self.pool1(x)x = self.layer1(x)x = self.layer2(x)x = self.layer3(x)x = self.layer4(x)x = self.adv_pool(x)x = self.flatten(x)x = self.fc(x)return xmyres = MyResNet18()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/895859.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AutoDock CrankPep or ADCP进行蛋白质多肽对接

需求描述 使用AutoDock CrankPep or ADCP进行蛋白质多肽对接 硬件及系统配置 自用电脑型号如下: 电脑:Precision Tower 7810 (Dell Inc.) CPU : Intel Xeon CPU E5-2686 v4 2.30GHz GPU: NVIDIA GeForce GTX 1070 Linux版本&a…

Django 5实用指南(二)项目结构与管理

2.1 Django5项目结构概述 当你创建一个新的 Django 项目时,Django 会自动生成一个默认的项目结构。这个结构是根据 Django 的最佳实践来设计的,以便开发者能够清晰地管理和维护项目中的各种组件。理解并管理好这些文件和目录结构是 Django 开发的基础。…

LabVIEW利用CANopen的Batch SDO写入

本示例展示了如何通过CANopen协议向设备写入Batch SDO(批量服务数据对象)。Batch SDO允许用户在一次操作中配置多个参数,适用于设备的批量配置和参数设置。此方法能够简化多个参数的写入过程,提高设备管理效率。 主要步骤&#xf…

WPF9-数据绑定进阶

目录 1. 定义2. 背景3. Binding源3.1. 使用Data Context作为Binding的源3.2. 使用LINQ检索结果作为Binding的源 4. Binding对数据的转换和校验4.1. 需求4.2. 实现步骤4.3. 值转换和校验的好处4.3.1. 数据转换的好处 4.4. 数据校验的好处4.5. 原理4.5.1. 值转换器原理4.5.2. 数据…

大数据治理:数字时代的关键密码

大数据治理:数字时代的关键密码 在信息技术飞速发展的今天,数字化浪潮席卷全球,深刻地改变着我们的生活和工作方式。数据,作为数字化时代的核心资产,正以前所未有的速度增长和积累。据国际数据公司(IDC&am…

LeetCode 1299.将每个元素替换为右侧最大元素:倒序遍历,维护最大值,原地修改

【LetMeFly】1299.将每个元素替换为右侧最大元素:倒序遍历,维护最大值,原地修改 力扣题目链接:https://leetcode.cn/problems/replace-elements-with-greatest-element-on-right-side/ 给你一个数组 arr ,请你将每个…

机器学习面试题汇总

1. 基础知识 什么是监督学习和无监督学习? 监督学习是基于已标注的训练数据来学习预测模型;无监督学习则是在没有标签的数据上进行学习,寻找数据的结构或模式。什么是过拟合和欠拟合? 过拟合是指模型在训练数据上表现很好,但在测试数据上表现差。欠拟合是指模型在训练数据…

【SQL教程|07】sql中条件查询where用法示例

SQL WHERE 条件查询教程 在SQL中,WHERE 条件用于在 SELECT 语句后过滤结果集,只返回符合条件的记录。它帮助我们从大量数据中提取所需的信息。以下是使用 WHERE 条件的逐步指南。 1. 基本语法 SELECT [字段] FROM [表] WHERE [条件];SELECT&#xff1a…

力扣 跳跃游戏 II

贪心算法,存下每一步的最远,去达到全局的最小跳跃次数。 题目 从题中要达到最少次数,肯定是每一步尽可能走远一点。但注意j被限制了范围,这种不用想每一步遍历时肯定选最大的num[i],但要注意,题中是可以到…

如何查看 Linux 服务器的 MAC 地址:深入解析与实践指南

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Linux驱动学习(二)--字符设备

设备分类 字符设备块设备网络设备 内核结构图&#xff1a; 字符设备号 字符设备号是32位的无符号整型值 高12位&#xff1a;主设备号低20位&#xff1a;次设备号 查看设备号 cat /proc/devices 设备号构造 直接使用宏MKDEV #define MKDEV(ma,mi) (((ma) << MINORBITS…

开发小技巧分享 02:xml解析工具

1.百度词条 可扩展标记语言 (Extensible Markup Language, XML) &#xff0c;标准通用标记语言的子集&#xff0c;可以用来标记数据、定义数据类型&#xff0c;是一种允许用户对自己的标记语言进行定义的源语言。 XML是标准通用标记语言 可扩展性良好,内容与形式分离,遵循严格的…

ffmpeg configure 研究1-命令行参数的分析

author: hjjdebug date: 2025年 02月 14日 星期五 17:16:12 CST description: ffmpeg configure 研究1 ./configure 命令行参数的分析 文章目录 1 configure 对命令行参数的分析,在4019行1.1 函数名称: is_in1.2. 函数名称: enable1.3. 函数名称: set_all 2 执行退出判断的关键…

Linux操作系统:从分布式计算到容器化的实践

Linux集群与高可用性技术&#xff1a;从分布式计算到容器化的实践 摘要 随着云计算和大数据技术的飞速发展&#xff0c;Linux集群和高可用性技术已成为现代IT架构的核心组成部分。本文以幽默风趣的方式&#xff0c;深入探讨了Linux集群技术&#xff08;如Hadoop、Spark等分布…

python和pycharm 和Anaconda的关系

好的&#xff0c;下面我会详细说明 Python、PyCharm 和 Anaconda 三者的关系&#xff0c;并逐一解释它们的功能和作用。 1. Python&#xff08;编程语言&#xff09; 定义&#xff1a;Python 是一种高级编程语言&#xff0c;设计简洁&#xff0c;易于学习&#xff0c;且功能强…

STM32 外部中断和NVIC嵌套中断向量控制器

目录 背景 外部中断/事件控制器(EXTI) 主要特性 功能说明 外部中断线 嵌套向量中断控制器 特性 ‌中断线&#xff08;Interrupt Line&#xff09; 中断线的定义和作用 STM32中断线的分类和数量 优先级分组 抢占优先级&#xff08;Preemption Priority&#xff09; …

代码随想录算法【Day49】

Day49 42. 接雨水 思路 这道题利用单调栈进行横向求解。对于每一个元素&#xff0c;找到它右边第一个比它大的元素和左边第一个比它大&#xff08;或者与它相等的元素&#xff0c;当然这种情况可以忽略&#xff09;&#xff0c;最后计算雨水的存储量&#xff1a;&#xff08…

PHP 网络编程介绍

PHP 学习资料 PHP 学习资料 PHP 学习资料 在当今数字化时代&#xff0c;网络编程是开发各类应用必不可少的技能。PHP 作为一门广泛应用于 Web 开发的编程语言&#xff0c;同样具备强大的网络编程能力。接下来&#xff0c;我们将深入探讨 PHP 中网络连接的建立、Socket 编程、…

《深度学习》——ResNet网络

文章目录 ResNet网络ResNet网络实例导入所需库下载训练数据和测试数据设置每个批次的样本个数判断是否使用GPU定义残差模块定义ResNet网络模型导入GPU定义训练函数定义测试函数创建损失函数和优化器训练测试数据结果 ResNet网络 ResNet&#xff08;Residual Network&#xff0…

为什么要学习AI、掌握AI技能有什么用?

随着人工智能的迅速的发展&#xff0c;DeepSeek的爆火&#xff0c;加之目前就业环境的走向&#xff0c;越来越多的职场朋友开始关注到AI的发展&#xff0c;重视AI技能的掌握。不少同学都会问&#xff1a;“职场人为什么要学习AI、掌握AI技能&#xff1f;” 为什么要学AI 现…