理解 CNN

news2024/11/17 22:36:43

理解 CNN

注意:下面提到的图像指位图

目录

  • 理解 CNN
    • CNN
      • 人类的视觉原理
      • 几个关键层
        • 卷积层(fliter、kernel)
        • 池化层 (pooling)
        • 激活层(activate)
        • 全连接层(Linear)
      • pytorch实现TextCNN
      • 卷积传播图解
      • 不同视角看CNN
    • 参考

CNN

卷积神经网络-CNN 最擅长的就是图片的处理。它受到人类视觉神经系统的启发。

CNN的两大特点:

  • 能够有效的将大数据量的图片降维成小数据量
  • 能够有效的保留图片特征,符合图片处理的原则

人类的视觉原理

详见:浅谈人类视觉系统与卷积神经网络(CNN)的联系和区别

深度学习的许多研究成果,离不开对大脑认知原理的研究,尤其是视觉原理的研究。

1981 年的诺贝尔医学奖,颁发给了 David Hubel(出生于加拿大的美国神经生物学家) 和TorstenWiesel,以及 Roger Sperry。前两位的主要贡献,是“发现了视觉系统的信息处理”,可视皮层是分级的。

人类的视觉原理如下:从原始信号摄入开始(瞳孔摄入像素 Pixels),接着做初步处理(大脑皮层某些细胞发现边缘和方向),然后抽象(大脑判定,眼前的物体的形状,是圆形的),然后进一步抽象(大脑进一步判定该物体是只气球)。下面是人脑进行人脸识别的一个示例:

dd622-2019-06-24-rennao.png

其实对于我们看不同的物体也是类似的,在最底层基本上是类似的。先是看各种边缘,越往上,就越能提取出此类物体的一些特征(鼻子、眼睛、嘴巴),到最上层,不同的高级特征最终组合成相应的图像,从而能够让人类准确区分不同的物体。这种逐层提取信息的方式就是许多深度学习算法(包括CNN)的灵感来源。

后面我们就来通过对几个层的讲解来对CNN有进一步的了解。

几个关键层

典型的CNN一般由3个部分构成:

  1. 卷积层
  2. 池化层
  3. 全连接层
名称作用简述
卷积层提取图像特征
池化层降维、防止过拟合
全连接层输出结果

卷积层(fliter、kernel)

在这部分我们来看一下卷积的过程。假设我们要提取出下面这个 5 × 5 5 \times 5 5×5 的矩阵的特征(其实位图图像存储底层就是通过这种矩阵的方式存储的,不过位图一般有r、g、b三层的矩阵信息)。

20201210101713334

同时我们定义一个 3 × 3 3 \times 3 3×3的矩阵,在CNN中其实被称作 filterkernelfeature detector

20201210101730473

ok有了前面一个输入矩阵和 kernel 矩阵的定义,我们可以观察下图看看, kernel是如何对输入矩阵的特征进行提取的。其实很简单,就是每次将 kernel中的元素与输入矩阵中的每个元素对应相乘然后累加,得到 Convolved Feature 中的一个元素。

f144f-2019-06-19-juanji

针对上述例子的附加解释,顺便讲解一下torch.nn.Conv1d 的参数 :

  • in_channels(输入通道数): 前面提到了我们的输入矩阵是只有一个,其实对应的就是in_channels = 1,如果说是那种位图信息输入包含r、g、b三层矩阵信息的话 in_channels = 3。

  • out_channels(输出通道数): 卷积产生的通道。有多少个 out_channels,就需要多少一个1维卷积。例如上图中只输出了一个 Convoled Feature所以 out_channels = 1。

  • stride(步长): 卷积步长其实指的就是 kernel 在与输入矩阵进行计算的时候,每次移动的步数,这里stride = 1。这可以理解为一个动态的过程,可以观察上图, kernel每次移动都是向一个方向平移一格。

  • kernel_size(核的大小): kernel_size指的就是 kernel的大小。上面对应的是一个二维的卷积,kernel_size = (3 * 3)。

  • padding: 输入的每一条边补充0的层数。换一个说法就是,我们比较案例中的Image和Convolved Feature的维度,因为卷积的时候是没加padding的所以让卷积后维度下降。如果我们设置padding = 1, 作用就是在进行卷积的时候,会先对Image的最外一圈用0去扩充。可以让最后得到的卷积的结果与原始Image一致。

    在这里插入图片描述

  • dilation(卷积核膨胀): 卷积核的膨胀,设置的是卷积核元素的间隔,如下图所示:

    image-20221201211528758

  • groups: 从输入通道到输出通道的阻塞连接数。当groups=1的时候,假设此时 输入的通道数为n,输出的通道数为m,那么理解为把输入的通道分成1组(不分组),每一个输出通道需要在所有的输入通道上做卷积,也就是一种参数共享的局部全连接。如果把groups改成2,可以理解为把 输入的通道分成两组,此时每一个输出通道只需要在其中一组上做卷积。如果groups=in_channels,也就是把 输入的通道分成in_channels组(每一组也就一个通道),此时每一个输出通道只需要在其中一个输入通道上做卷积。

  • bias: 如果bias = True,则添加偏置,偏置就是用来在卷积得到的结果后加上一个项,以调整整个数据的区间。因为卷积的结果后面是要输入到激活层的嘛,我们可以通过下图看bias对这个数据的影响。其实本质的意思就是有了偏置项让数据整体分布上有了平移的效果,从而根激活函数更好地配合起来。

    20180815160507461

用例

import torch
import torch.nn as nn

d = torch.Tensor(3, 5)
conv = nn.Conv1d(
  in_channels=3,
  out_channels=2,
  kernel_size=2,
  padding=1,
  stride=2,
  bias=True,
)
print(d)
print(conv.weight)
print(conv(d))

"""
## Output
## 因为torch.nn中设置的卷积核(kernel)内的数据是随机的,运行的时候输出可能会不一样但数据的维度应当是一样的
tensor([[4.9592e-39, 4.2246e-39, 1.0286e-38, 1.0653e-38, 1.0194e-38],
        [8.4490e-39, 1.0469e-38, 9.3674e-39, 9.9184e-39, 8.7245e-39],
        [9.2755e-39, 8.9082e-39, 9.9184e-39, 8.4490e-39, 9.6429e-39]])
Parameter containing:
tensor([[[ 0.3349,  0.2759],
         [-0.0143, -0.3235],
         [-0.2177, -0.0688]],

        [[ 0.2330,  0.3502],
         [-0.3834, -0.0521],
         [-0.1585,  0.3144]]], requires_grad=True)
tensor([[-0.0977, -0.0977, -0.0977],
        [-0.2637, -0.2637, -0.2637]], grad_fn=<SqueezeBackward1>)
"""

卷积后得到 OutPutShape

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qcf7pu33-1669972715833)(https://raw.githubusercontent.com/yuyuyu258963/pic-go-picStore/main/%E5%8D%B7%E7%A7%AFOutputShape%E8%AE%A1%E7%AE%97.png)]

我们可以通过下图的例子进一步理解卷积的过程。

image-20221202141938555

池化层 (pooling)

池化层(Pooling)是卷积神经网络中另一个重要的概念,它实际上是一种形式的降采样。有多种不同形式的非线性池化函数,而其中“最大池化(Max pooling)”是最为常见的。它是将输入的图像划分为若干个矩形区域,对每个子区域输出最大值。直觉上,这种机制能够有效地原因在于,在发现一个特征之后,它的精确位置远不及它和其它特征的相对位置的关系重要。池化层会不断地减小数据的空间大小,因此参数的数量和计算量也会下降,这在一定程度上也控制了过拟合。通常来说,CNN的卷积层之间都会周期性地插入池化层。

池化层通常会分别作用域每个输入的特征并减小其大小。当前最常用形式的池化层是每隔2个元素从图像划分出 2 × 2 2 \times 2 2×2的区块,然后对每个区块中的4个数取最大值。这将会减少75%的数据量。

991470-20190208201508704-368644792

池化的作用

池化操作后的结果相比其输入缩小了。池化层的引入是仿照人的视觉系统对视觉输入对象进行降维和抽象。在卷积神经网络过去的工作中,研究者普遍认为池化层有如下三个功效:

  1. 特征不变性:池化操作是模型更加关注是否存在某些特征而不是特征具体的位置
  2. 特征降维:池化相当于在空间范围内做了维度约减,从而使模型可以抽取更加广阔的特征。同时减少了下一层的输入大小,进而减少计算量和参数个数
  3. 在一定程度上防止过拟合:更方便优化

用例

import numpy as np
import torch

d = np.array([[1.0,0.0,1.0,2.0,3.0,4.0]])
input = torch.from_numpy(d)
print(input)
"""ouput
tensor([[1., 0., 1., 2., 3., 4.]], dtype=torch.float64)
"""
import torch.nn.functional as F
ouput = F.max_pool1d(input, kernel_size = 2, stride = 1)
print(ouput)
ouput = F.avg_pool1d(input, kernel_size = 2, stride = 1)
print(ouput)
"""ouput
tensor([[1., 1., 2., 3., 4.]], dtype=torch.float64)
tensor([[0.5000, 0.5000, 1.5000, 2.5000, 3.5000]], dtype=torch.float64)
"""

上述的用例中展示了,最大池化(MaxPooling)和平均池化(AvgPooling)的用例。因为池化也涉及到这个子区域的选择嘛,所以里面的一些参数就和前面的torch.nn.Conv1d中的参数很类似。

激活层(activate)

激活层里面其实就是激活函数,就是在人工神经网络的神经元上运行的函数,负责将神经元的输入映射到输出端。

激活函数对于人工神经网络模型去学习、理解非常复杂和非线性的函数来说具有非常重要的作用。它们将给线性特性引入到我们的网络中。引入激活函数是为了增加神经网络模型的非线性。没有激活函数的每层都相当于矩阵相乘。就算你叠加了若干层之后,无非还是个矩阵相乘罢了。

下面是一张关于常见激活函数的表:

dd0342af-f6b1-4e41-9dcc-05bcc06d0d2a

全连接层(Linear)

全连接层在整个CNN网络中起到“分类器”的作用。如果说前面的卷积层、池化层和激活函数等操作是将原始数据映射到隐层特征空间,全连接层起到的将学到的特征表示映射到样本的标记空间的作用。

全连接层实现原理


991470-20190209123250272-1769907112

在卷积神经网络的最后,往往会出现一两层全连接层,全连接一般会把卷积输出的二维特征图转化为一维的向量。如上图中最后两列表示的就是两个全连接层,在最后一层卷积结束后,进行了最后一次池化,输出了20个 12 × 12 12 \times 12 12×12的图像,然后通过了一个全连接层变成了 1 × 100 1 \times 100 1×100的向量。这么一看前面的工作我么做的就是一个降维的操作,然后我们将得到的向量输入全连接层进行输出。

用例

input = torch.Tensor(1, 10)
linear = nn.Linear(10, 2)
print(input)
print(linear(input))
"""output
tensor([[5.1429e-39, 4.5000e-39, 4.9592e-39, 4.2246e-39, 1.0286e-38, 1.0653e-38,
         1.0194e-38, 8.4490e-39, 1.0469e-38, 9.3674e-39]])
tensor([[-0.1961,  0.2197]], grad_fn=<AddmmBackward0>)
"""

比如用例中我们可能在前面得到了一个一百维的向量,然后这个任务的是一个二分类的任务。我们就可以设置通过全连接层输出的向量维度为(1,2)。其中的2与二分类任务对应。上面输出的tensor([[-0.1961, 0.2197]],那么一般来说我们认为这个得到的分类结果是第2类。

pytorch实现TextCNN

class TextCNN(nn.Module):
  def __init__(self, vocab_size, embedding_dim, kernel_sizes, num_channels, dropout, vectors=None):
    super(TextCNN, self).__init__()
    self.word_embeddings = nn.Embedding(vocab_size, embedding_dim)  # embedding之后的shape: torch.Size([200, 8, 300])
    if vectors is not None:
      self.word_embeddings = self.word_embeddings.from_pretrained(vectors, freeze=False)
    # dropout 代表每个神经元不被激活的概率
    self.dropout = nn.Dropout(dropout)
    self.decoder = nn.Linear(sum(num_channels), 2)
    # 时序最大池化层没有权重,所以可以共用一个实例
    self.pool = F.GlobalMaxPool1d()
    self.convs = nn.ModuleList([
      nn.Sequential(
        nn.Conv1d(
                  in_channels = embedding_dim, 
                  out_channels = c, 
                  kernel_size = k
                  ),
        nn.ReLU(),
        nn.MaxPool1d(2, padding=1),
      )
      for c, k in zip(num_channels, kernel_sizes)
    ])  # 创建多个一维卷积层

  def forward(self, sentence):
    embeds = self.word_embeddings(sentence)
    embeds = embeds.permute(0, 2, 1)
    # 对于每个一维卷积层,在时序最大池化后会得到一个形状为(批量大小, 通道大小, 1)的
    # Tensor。使用flatten函数去掉最后一维,然后在通道维上连结
    encoding = torch.cat([self.pool(conv(embeds)).squeeze(-1) for conv in self.convs], dim=1)
    # 应用丢弃法后使用全连接层得到输出
    outputs = self.decoder(self.dropout(encoding))
    return outputs

卷积传播图解

先来看得到卷积的过程

image-20221202170924036

(单个元素的梯度计算)不考虑前后的层,比如我们已经得到了Delta Output的梯度矩阵,可以观察下图如何得到在原矩阵中 x 2 , 2 x_{2,2} x2,2的梯度值。

image-20221202171053434

(推广到全部元素) 这里就是对Delta d做了一个padding之后然后反向做了卷积。

image-20221202171321823

不同视角看CNN

这部分图来自:https://cloud.tencent.com/developer/article/1594092

比如有原始数据矩阵

x63ow0e4cs

filter

peqmt82v0z

得到的Convoled Feature

b76y9airil

卷积计算的视角

vz21ujws11

等式计算角度

unsbshwn6n

网络角度

iav0xgvm5l

矩阵乘法角度

5sm34b0rcr

Dense神经网络角度

ezbjn8h0qy

在这个角度下我们可以更好地理解传统神经网络和CNN之间的联系,其中左图是传统神经网络,右图数Dense神经网络视角下的CNN。灰度连接对应于不可训练的0.

参考

  • 多视角理解CNN
  • 神经网络中偏置的作用
  • 卷积核膨胀解析
  • PyTorch 中文文档
  • https://easyai.tech/ai-definition/cnn/

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

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

相关文章

[附源码]JAVA毕业设计机房预约系统(系统+LW)

[附源码]JAVA毕业设计机房预约系统&#xff08;系统LW&#xff09; 目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&…

Spring Data JPA 中的分页和排序

让我们学习如何使用 在 Spring 数据 JPA 中使用分页和排序有效地处理大量记录。 什么是分页和排序&#xff1f; 大多数情况下&#xff0c;来自数据库的结果集可能会让人不知所措。它可能会让人不知所措&#xff0c;以至于系统崩溃&#xff0c;因为它们无法在一次传递中处理那…

2019-10《信息资源管理 02378》真卷(独家文字版),圈定章节考点+统计真题分布

本系列博客合计 21 篇&#xff0c;每篇都将解析一张《信息资源管理》真卷&#xff0c;并附带答案解析与背诵技巧。 搜索 梦想橡皮擦&#xff0c;擦姐整理 全国 2019 年 10 月自学考试信息资源管理试题&#xff08;02378&#xff09; 单选题 1,信息技术是应用信息科学的原理和…

Linux基本工具——yum

Linux基本工具软件包管理器yum什么是软件包Linux的软件包yum的三板斧yum的扩展软件包管理器yum 工具的本质就是指令 什么是软件包 我们平时用手机与电脑的时候&#xff0c;如果想安装一个软件就需要去下载它的安装包&#xff08;软件包&#xff09;&#xff0c;下载安装包的…

前端怎么才能找到项目做?

前言 一般找项目最常用的就是在Github上&#xff0c;题主已经具备了html、css、js和vue的知识体系&#xff0c;那么在github或者找一些项目教程视频来实践是锻炼的最好途径&#xff0c;下面我整理了一些在github和B站上找了一些前端的经典项目&#xff0c;希望对你有所帮助~ …

Kotlin 开发Android app(十六):ContentProvider的使用

android的四大组件&#xff0c;已经介绍了两个&#xff0c;这一节介绍ContentProvider。前面的广播可以进行 app内的通讯&#xff0c;如果需要进行app之间的通讯&#xff0c;在android 中使用的是ContentProvider。ContentProvider 也分为三种&#xff0c;一&#xff0c;作为数…

物通博联持续参与京东方(BOE)工厂数字化项目

创新引领 数字驱动 京东方科技集团股份有限公司&#xff08;BOE&#xff09;创立于1993年&#xff0c;是全球领先的半导体显示技术、产品与服务提供商&#xff0c;核心业务包括显示器件、智慧系统和健康服务。产品广泛应用于手机、平板电脑、笔记本电脑、显示器、电视、车载、…

php万年历源代码!源代码![上一年、上一月、下一月、下一年、附加当天日期加背景颜色]-私聊源码

//当前年 $year isset($_GET[year])?$_GET[year]:date(Y); //echo $year; //制作当前月的变量 $monthisset($_GET[month])?$_GET[month]:date(n); //本月有多少天 $day date(t,mktime(0,0,0,$month,1,$year)); //本月从1号开始是星期几 $w date(w,mktime(0,0,0,$month,1…

python处理csv文件

如何使用python处理csv文件 素材准备 ​ csv⽂件其实就是⽂本⽂件&#xff0c;遵循了⼀定的格式&#xff0c;常⻅的csv⽂件⼀般是⽤逗号来隔开列&#xff0c;⽤换⾏符隔开不同的⾏&#xff0c;注意这⾥的符号都是英⽂符号。我们可以直接⽤open函数来打开csv⽂件&#xff1b; …

.net----数据库的访问ADO.NET、DataAdapter和DataSet

数据库的访问前言ADO.NET的概述ADO.NET数据源访问处理数据类库的两个组件&#xff1a;引用System.Data.dll和System.Xml.dll使用ADO.NET连接和操作数据库使用数据提供程序访问数据库操作的典型步骤&#xff1a;&#xff08;1&#xff09;建立数据库连接&#xff08;2&#xff0…

艾美捷曲妥珠单抗Trastuzumab参数和相关研究

曲妥珠单抗是一种重组人源化单克隆抗体&#xff0c;特异性地作用于人表皮生长因子受体-2(HER2)的细胞外部位。此抗体含人IgG1 框架&#xff0c;互补决定区源自鼠抗p185 HER2 抗体&#xff0c;能够与HER2 绑定。 HER2 原癌基因或C-erbB2 编码一个单一的受体样跨膜蛋白&#xff0…

Tyramide Cy5.5,Cyanine5.5 Tyramide,花青素Cy5.5酪酰胺远红色近红外发射染料

​一、理论分析&#xff1a; 中文名&#xff1a;花青素Cy5.5 酪酰胺 英文名&#xff1a;Cyanine5.5 Tyramide&#xff0c;Cy5.5 Tyramide&#xff0c;Tyramide Cy5.5 CAS号&#xff1a;N/A 化学式&#xff1a;C48H52CIN3O2 分子量&#xff1a;738.4 二、产品详情&#xff1a; 外…

【D3.js】1.20-给 D3 元素添加工具提示

title: 【D3.js】1.20-给 D3 元素添加工具提示 date: 2022-12-02 15:04 tags: [JavaScript,CSS,HTML,D3.js,SVG] 继续增强交互性&#xff1a;给元素添加悬停提示。 一、学习目标 如何给元素添加悬停提示&#xff1f; 通过title元素&#xff1a;增加title元素&#xff0c;通过.…

HTML+CSS+JS网页设计期末课程大作业——海贼王(8个页面)动漫网页设计

HTML实例网页代码, 本实例适合于初学HTML的同学。该实例里面有设置了css的样式设置&#xff0c;有div的样式格局&#xff0c;这个实例比较全面&#xff0c;有助于同学的学习,本文将介绍如何通过从头开始设计个人网站并将其转换为代码的过程来实践设计。 精彩专栏推荐&#x1f4…

vector类的常用接口说明

目录 一、(constructor)构造函数声明 二、vector的迭代器 三、vector的增删改查 四、insert和erase&#xff0c;以及查找find&#xff08;find不属于vector&#xff0c;是stl提供的算法&#xff09; 五、三种遍历方式 六、源代码 vector是可变大小数组的序列容器 一、(c…

海豚调度器分布式部署

前置准备 服务器 node01,node02,node03三台服务器&#xff08;本教程服务器系统版本Linux version 3.10.0-1160.el7.x86_64&#xff09; node01作为master&#xff0c;api&#xff0c;alert节点&#xff0c;node02和node03作为worker节点 安装包下载 下载dolphinscheduler和…

RFID数据采集成为MES系统精准数据

随着信息化、自动化成为企业发展趋势&#xff0c;制造执行系统(MES)是连接计划层和现场控制层之间的纽带&#xff0c;成为企业制造战略重要技术手段。MES生产执行系统主要在生产过程层及管理层之间加强数据集成与分析的力度&#xff0c;拓展优化技术应用的范围&#xff0c;真正…

猿创征文|Python学习工具千千万,我心中的TOP10

前言&#xff1a; 大家好&#xff0c;我是是Dream呀&#xff0c;在我们平时的开发和生活中&#xff0c;每天都在使用、寻找、贡献、创作各类开发者工具&#xff0c;包括开源服务、付费软件、API等。好的工具可以极大帮助我们提升效率&#xff0c;服务业务。作为一名资深的Pytho…

MFC下拉框控件用法

目录 一、属性方式设置下拉框内容 1.Combo Box下拉框 2.Data属性 3.Type属性 4.Sort属性 二、初始化OnInitDialog设置下拉框内容 1.添加Combo Box下拉框变量 2.AddString方法添加选项 3.SetCurSel设置默认显示内容 4.InsertString方法插入内容 4.DeleteString删除指…

数据中心网络设计- 叶脊(Spine-Leaf)网络架构

大家好&#xff0c;我是技福的小咖老师。 随着业务形态的变化&#xff0c;数据中心网络的交换架构也在不断的发展。传统的三层网络结构应用广泛而且技术成熟&#xff0c;但随着技术的发展趋势&#xff0c;它的瓶颈也不断涌现&#xff0c;导致越来越多的网络工程师放弃这种结构…