pytorch深度学习实战lesson18

news2024/9/22 5:40:28

第十八课 卷积层

卷积是深度学习最重要的概念之一,下面来学习和回顾一下卷积的基本概念。

目录

理论部分

从全连接层到卷积层

卷积层

实践部分


理论部分

从全连接层到卷积层

还是从一个例子开始:假设我要对猫和狗进行分类。

假设我用一千二百万像素的手机拍照,排成的图片是RGB图片(有3个通道),RGB图像有三千六百万个元素。假设用隐藏层大小为100的mlp进行训练的话,这个模型就要有36亿个参数,远远多于世界上猫狗的总量了,还不如记住世界上所有的猫狗来的划算。

所以使用mlp处理比较大的图片的时候必须要考虑和解决这个问题。

下面回顾一下单隐藏层的mlp。

如上图所示,我输入有三千六百万个时,当输入到有100个隐藏层神经元的神经网络时,需要有三千六百万乘100个权重,也就是36亿个元素,这大概需要14个G去存权重,这仅仅是单层神经网络存权重所需要的空间,那么对于多层来讲那就爆炸了,这是很荒谬的。

下面玩一个游戏:在人群中寻找图片左边的“Waldo”同志。

找的过程中需要遵循两个原则:

1、平移不变性

平移不变性是指,对于同一个图片分类器,无论被识别对象出现在图片的哪个位置,都能准确是识别出来。也就是说识别器不会因图片出现的位置而发生改变。

2、局部性

图片搜索的范围不用太大,区域够用即可。

全连接层到卷积层在数学层面的变化:

卷积的操作如上图所示。

也就是说,在w_{i,j,k,l}中,i,j代表输出的点在输出矩阵中的位置,k,l代表输入点在输入的图(或者矩阵)中的位置。那么这个权重矩阵应该记录输入中的每一个点对于输出中的每一个点的影响(也就是权重)。举例来说,比如输入图是4x4的,输出图是2x2的。我需要记录输入图中(1,1), (1,2), ..., (2,1), ..., (4,4)这些所有的点对输出图(1,1)的影响,同理也需要记录这些所有点对输出图中(1,2), ...., (2,2)的影响。那么这时候对于每一组点就有4个参数:输入图的横坐标、纵坐标,输出图的横坐标、纵坐标。所以要想完全记录所有的权重,所以需要一个4维张量。

下面看一下如何运用第一个原则——平移不变性。

这里要求无论i,j如何变换,v都不该变化,也就是说进行卷积计算时,所乘的权重矩阵,也就是卷积核,与位置(i, j)无关

原则二的意思就是说:研究输出hij时,我的卷积核不要太大,就只关注xij附近的元素即可。

卷积层

卷积的具体计算过程如上图所示。它的输出矩阵我们可以看到是卷积核与对应的输入阵进行按元素乘法和的结果。每算完一个卷积核的元素,卷积核就相对输入矩阵往右移一个,右移完了就往下移并且移到最左边,再开始计算。

关于卷积的例子:

不同的卷积核可以带来不同的效果。神经网络可以去学出来这些核去达到我们想要的图像效果。

这里给出的是二维交叉相关和二维卷积的区别,神经网络中的卷积层其实应用的是二维交叉相关这个公式。我们可以看到,它俩的区别从几何方面讲就是上下左右翻转的关系,所以卷积层和实际的数学领域的二维卷积是有一定区别的。

一维交叉相关的话,权重是个向量,一维交叉相关更适合处理一维的数据,比如文本、语言等;三维交叉相关参数也跟着变成了三维,它更适合处理视频、医学图像这种三维数据;二维交叉相关参数是二维的,它适合处理图像。它们之间的思想都大同小异。

卷积层相比全连接层的优点主要体现在参数计算量更小。

  全连接层每一个节点都要与下一层的每一个节点全部连接,每一个连接都有参数参与运算;而卷积层参数只与卷积核大小以及输出特征图的通道数相关。

  卷积层通过权值共享和稀疏连接来保证单层卷积中训练参数少。

实践部分

代码:

#图像卷积
#互相关运算
import torch
from torch import nn
from d2l import torch as d2l
def corr2d(X, K):#输入x,k是核矩阵。二维交叉相关运算。
    """计算二维互相关运算。"""
    h, w = K.shape#h是卷积核的行数,w是卷积核的列数
    #初始化高度和宽度分别为“X.shape[0] - h + 1, X.shape[1] - w + 1”的输出零矩阵
    Y = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))
    for i in range(Y.shape[0]):
        for j in range(Y.shape[1]):
            #输出等于【输入从i行开始,往后看h-1行,从j列开始往后看w-1列】再与卷积核矩阵进行点积再求和,
            #把结果遍历到输出矩阵Y【i,j】中。
            #这里要保证被卷积的区域是和卷积核的维度是一样的。
            Y[i, j] = (X[i:i + h, j:j + w] * K).sum()
    return Y
#验证上述二维交叉相关运算的输出
X = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
K = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
print(corr2d(X, K))
print("###########################################################################")
#实现二维卷积层
class Conv2D(nn.Module):
    def __init__(self, kernel_size):
        super().__init__()
        self.weight = nn.Parameter(torch.rand(kernel_size))#初始化权重维度为kernel_size的矩阵
        self.bias = nn.Parameter(torch.zeros(1))#偏移初始化为0
    def forward(self, x):#前向运算就是输入和权值进行互相关运算再加上偏移
        return corr2d(x, self.weight) + self.bias
#卷积层的一个简单应用: 检测图像中不同颜色的边缘
X = torch.ones((6, 8))
X[:, 2:6] = 0
print("输入矩阵")
print(X)#从生成的输入矩阵可以看到左右都有一个由黑变白的竖线。这里就是要检测出这两个竖线
K = torch.tensor([[1.0, -1.0]])
#输出Y中的1代表从白色到黑色的边缘,-1代表从黑色到白色的边缘
Y = corr2d(X, K)
print("边缘检测结果")
print(Y)
#卷积核K只可以检测垂直边缘,加入把输入矩阵给转置,再使用K做卷积的话是检测不出来的
#解决办法就是把卷积核也转置,就能检测出水平边缘了
print(corr2d(X.t(), K))
print("###########################################################################")

#学习由X生成Y的卷积核,已知输入和输出矩阵,通过深度学习学出卷积核
#直接定义输入通道为1(黑白图像为1,彩色为3),输出通道也为1,卷积核为1*2的卷积运算
conv2d = nn.Conv2d(1, 1, kernel_size=(1, 2), bias=False)
X = X.reshape((1, 1, 6, 8))#输出矩阵是输入通道为1,输出通道也为1,6*8的矩阵
Y = Y.reshape((1, 1, 6, 7))#输出矩阵是输入通道为1,输出通道也为1,6*7的矩阵
'''print(X)
print(Y)
print("###########################################################################")'''
for i in range(10):#迭代10次
    Y_hat = conv2d(X)#将X输入到卷积运算中去,得到预测的输出
    l = (Y_hat - Y)**2#使用均方误差得到损失
    conv2d.zero_grad()#梯度置零
    l.sum().backward()#求和后求backward,计算梯度
    conv2d.weight.data[:] -= 3e-2 * conv2d.weight.grad#更新后的权值=初始权值-学习率0.01*梯度
    if (i + 1) % 2 == 0:#每隔两个batch输出一下损失
        print(f'batch {i+1}, loss {l.sum():.3f}')
print("###########################################################################")
#所学的卷积核的权重张量
print(conv2d.weight.data.reshape((1, 2)))#最终学得的卷积核

tensor([[19., 25.],
        [37., 43.]])
###########################################################################
输入矩阵
tensor([[1., 1., 0., 0., 0., 0., 1., 1.],
        [1., 1., 0., 0., 0., 0., 1., 1.],
        [1., 1., 0., 0., 0., 0., 1., 1.],
        [1., 1., 0., 0., 0., 0., 1., 1.],
        [1., 1., 0., 0., 0., 0., 1., 1.],
        [1., 1., 0., 0., 0., 0., 1., 1.]])
边缘检测结果
tensor([[ 0.,  1.,  0.,  0.,  0., -1.,  0.],
        [ 0.,  1.,  0.,  0.,  0., -1.,  0.],
        [ 0.,  1.,  0.,  0.,  0., -1.,  0.],
        [ 0.,  1.,  0.,  0.,  0., -1.,  0.],
        [ 0.,  1.,  0.,  0.,  0., -1.,  0.],
        [ 0.,  1.,  0.,  0.,  0., -1.,  0.]])
tensor([[0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0.],
        [0., 0., 0., 0., 0.]])
###########################################################################
tensor([[[[1., 1., 0., 0., 0., 0., 1., 1.],
          [1., 1., 0., 0., 0., 0., 1., 1.],
          [1., 1., 0., 0., 0., 0., 1., 1.],
          [1., 1., 0., 0., 0., 0., 1., 1.],
          [1., 1., 0., 0., 0., 0., 1., 1.],
          [1., 1., 0., 0., 0., 0., 1., 1.]]]])
tensor([[[[ 0.,  1.,  0.,  0.,  0., -1.,  0.],
          [ 0.,  1.,  0.,  0.,  0., -1.,  0.],
          [ 0.,  1.,  0.,  0.,  0., -1.,  0.],
          [ 0.,  1.,  0.,  0.,  0., -1.,  0.],
          [ 0.,  1.,  0.,  0.,  0., -1.,  0.],
          [ 0.,  1.,  0.,  0.,  0., -1.,  0.]]]])
###########################################################################
batch 2, loss 8.089
batch 4, loss 2.323
batch 6, loss 0.785
batch 8, loss 0.294
batch 10, loss 0.116
###########################################################################
tensor([[ 1.0241, -0.9548]])

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

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

相关文章

3年经验,光靠自动化测试基础,你可能连17k的测试岗都找不到,认清现实.....

相信对于每一个求职者来说都有被面试的经历吧,曾经作为一位测试小白的我,每一次面试过后都会各种吐槽面试官的不是,吐槽HR人事的不足,以及自己的有点没有发挥出来,今天我终于体会了一次面试官的心情.... 起因&#xf…

【夯实Kafka知识体系及基本功】分析一下(Broker)服务的可靠性机制分析「原理篇」

副本机制 分布式系统中,为了提高可靠性,最常用、最有效的策略是“副本机制”,Kafka也不例外。 Kafka 为每个 Partition 维护了一个 AR(Assigned Replicas)列表,由 ISR(In-Sync Replicas&#x…

通过瑞利判据对显微镜物镜进行分辨率研究

摘要 通常可以采用瑞利判据理论表征显微镜的分辨率,瑞利判据是1896年由第三代瑞利男爵约翰威廉斯特拉特(John William Strutt)提出的。该理论认为,当一个艾里图样的中心与另一个艾里图样的第一个最小值重叠时,就可以分辨它们。在这个例子中…

力扣(LeetCode)3. 无重复字符的最长子串(C++)

滑动窗口 设置滑动窗口, lll 维护左窗口 , rrr 维护右窗口 ,利用哈希表统计字母出现次数。 遍历字符串 sss ,lll 循环右移,每次移动 , lll 指向的字母 s[l]s[l]s[l] 出现次数 。如果窗口内 s[l]s[l]s[l] …

NCMMSC 2021丨长短视频多语种多模态识别挑战赛

比赛背景 2021年第十六届全国人机语音通讯学术会议(National Conference on Man-Machine Speech Communication,NCMMSC2021)将于2021年10月15-18日在江苏徐州举行。本次会议由中国中文信息学会和中国计算机学会联合主办。 针对本次会议&…

STA -- clock gating check

对于现在design中例化好的icg以及工具插进去的icg,不存在clock gating check的问题,因为clock gating 搞成了一个lib cell,不再是latch加上与门的组合。不过design中除了这些icg,还有一些的clock gating check的出现,这…

写给 Android 开发:从0到1,再从1到N,都离不开 Framework

作为过来人,发现很多学习者和实践者都在 Android Framework上面临着很多的困扰,比如: 工作场景中遇到难题,往往只能靠盲猜和感觉,用临时性的补救措施去掩盖,看似解决了问题,但下次同样的问题又…

Node.js开发、CommondJS 、ES-Module模块化设计

目录 Node.js是什么 基础使用 Node的REPL 全局变量 模块化设计 CommondJS规范 基础使用exports和module.exports require CommondJS优缺点 AMD和CMD规范 ES_Module 基本使用方法 导出 导入 结合使用 默认导出 ES Module解析流程 Node.js是什么 Node与浏览器的对比 在…

两点云求差集和交集

这里两点云的差集指从点云1中删除属于点云2的点得到的点集,并集指既属于点云1又属于点云2的点集。 两点云求差集 基于kd-tree搜索的方法较快速,当然也可以暴力搜索。思路如下: step1 在点云2建立kd-tree,设置容忍误差&#xff0…

UI控件DevExpress WinForm新手指南——如何在应用启动时执行操作

DevExpress WinForm拥有180组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForm能完美构建流畅、美观且易于使用的应用程序,无论是Office风格的界面,还是分析处理大批量的业务数据,它都能轻松胜任…

RESTful 接口设计

文章目录RESTful 接口设计1.获取所有员工列表2.增加一个员工3.更新员工4.删除员工5.查询单个员工RESTful 接口设计 1.获取所有员工列表 /*** 获取所有员工* 1. 请求路径--确认资源--员工--/employees* 2. 请求方法--get* 3. 请求参数--无* 4. 请求响应--多个员工--List<Em…

苹果iOS App Store上架操作流程

很多开发者在开发完iOS APP、进行内测后&#xff0c;下一步就面临上架App Store&#xff0c;不过也有很多同学对APP上架App Store的流程不太了解&#xff0c;下面我们来说一下iOS APP上架App Store的具体流程&#xff0c;如有未涉及到的部分&#xff0c;大家可以及时咨询&#…

基于微信小程序的学生购电系统设计与实现-计算机毕业设计源码+LW文档

小程序开发说明 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09; 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Mave…

服务端Skynet(二)——消息调度机制

服务端Skynet(二)——消息调度机制 文章目录服务端Skynet(二)——消息调度机制1、提前了解知识1.1、互斥锁&#xff08;mutex lock : **mut**ual **ex**clusion lock&#xff09;1.2、自旋锁&#xff08;spinlock&#xff09;1.3、读写锁&#xff08;readers–writer lock&…

最简单的git图解(多远程仓库)

上一节我们讲了git操作最基本的命令&#xff1a;最简单的git图解&#xff08;最基本命令&#xff09;_jerry_dyy的博客-CSDN博客 这一节我们来讲一下面对多个远程仓库的场景&#xff0c;应该如何来处理。 为什么要有多个远程仓库&#xff1f; 在企业内部开发团队开发过程中&a…

什么是CDN?CDN的技术原理是什么?

什么是CDN&#xff1f; CDN的全称是Content Delivery Network&#xff0c;中文名称“内容分发网络”。其主要原理是在现有网络中增加一层新的网络架构&#xff0c;将源站中的内容发布到不同的网络节点上&#xff0c;使用户可以就近获得所需的内容&#xff0c;从而提高用户访问…

【学习记录】镭神激光雷达与PC机的NTP同步

本文仅用于记录自己在实现镭神C32激光雷达和PC机进行NTP同步时的一些总结。 吐槽在先&#xff0c;镭神的文档写极其不完善&#xff0c;很多都只是提了一句&#xff0c;但并没有完整的说应该具体怎么做。前前后后折腾了三四天&#xff0c;在一知半解的官方技术支持和实验室大佬…

立创EDA仿真入门1 基本操作

立创EDA仿真入门1 基本操作一、进入EDA仿真环境二、画原理图1. 新建工程2. 绘制如下电路图三、仿真1. 运行仿真2. 导出波形图3. 查看仪表一、进入EDA仿真环境 网址&#xff1a; https://lceda.cn/ 进入EDA标准版&#xff0c;点击左上角切换到仿真模式。 二、画原理图 1. 新…

java毕业设计——基于java+Socket+sqlserver的办公自动化系统设计与实现(毕业论文+程序源码)——办公自动化系统

基于javaSocketsqlserver的办公自动化系统设计与实现&#xff08;毕业论文程序源码&#xff09; 大家好&#xff0c;今天给大家介绍基于javaSocketsqlserver的办公自动化系统设计与实现&#xff0c;文章末尾附有本毕业设计的论文和源码下载地址哦。 文章目录&#xff1a; 基于…

qemu创建linux虚拟机(亲测有效)

1&#xff0c;网桥的搭建 Bridge方式原理 Bridge方式即虚拟网桥的网络连接方式&#xff0c;是客户机和子网里面的机器能够互相通信。可以使虚拟机成为网络中具有独立IP的主机。 桥接网络&#xff08;也叫物理设备共享&#xff09;被用作把一个物理设备复制到一台虚拟机。网桥多…