【机器学习】卷积神经网络(三)

四、理论分析

4.1 反卷积运算

9367788e46ee0ef1c26c5e45a72e8901.png

b577b54e4d3385fbba855b10ef3f37c9.png

我们可以将过滤器转换为 Toeplitz matrix ,将图像转换为向量,然后仅通过一个矩阵乘法进行卷积,而不是使用 for-loops 对图像(或任何其他 2D 矩阵)执行 2D 卷积。 (当然还要对乘法结果进行一些后处理以获得最终结果)。

有许多高效的矩阵乘法算法,因此使用它们我们可以有效地实现卷积运算

这个过程的数学和算法解释:

fe9e6e5e60ebcc9cf7d26b24bdd3f149.png

25ac51daeeadf92042dc497f5f465491.png

以下给出这个算法的简单 Python 实现,以使其更加清晰。

import numpy as np # 导入numpy库,用于处理数组和矩阵
from scipy.linalg import toeplitz # 导入scipy库中的toeplitz函数,用于生成托普利茨矩阵




def matrix_to_vector(input): # 定义一个函数,将一个矩阵转换为一个向量
    input_h, input_w = input.shape # 获取输入矩阵的行数和列数
    output_vector = np.zeros(input_h*input_w, dtype=input.dtype) # 创建一个全零的向量,长度为输入矩阵的元素个数,数据类型与输入矩阵相同
    # flip the input matrix up-down because last row should go first
    input = np.flipud(input) # 将输入矩阵上下翻转,因为最后一行应该放在向量的最前面
    for i,row in enumerate(input): # 遍历输入矩阵的每一行,i是行的索引,row是行的内容
        st = i*input_w # 计算向量中对应的起始位置
        nd = st + input_w # 计算向量中对应的结束位置
        output_vector[st:nd] = row # 将矩阵的一行复制到向量的相应位置
    return output_vector # 返回转换后的向量




def vector_to_matrix(input, output_shape): # 定义一个函数,将一个向量转换为一个矩阵
    output_h, output_w = output_shape # 获取输出矩阵的行数和列数
    output = np.zeros(output_shape, dtype=input.dtype) # 创建一个全零的矩阵,形状为输出矩阵的形状,数据类型与输入向量相同
    for i in range(output_h): # 遍历输出矩阵的每一行
        st = i*output_w # 计算向量中对应的起始位置
        nd = st + output_w # 计算向量中对应的结束位置
        output[i, :] = input[st:nd] # 将向量的一部分复制到矩阵的一行
    # flip the output matrix up-down to get correct result
    output=np.flipud(output) # 将输出矩阵上下翻转,以得到正确的结果
    return output # 返回转换后的矩阵




def convolution_as_maultiplication(I, F, print_ir=False): # 定义一个函数,将卷积运算转换为矩阵乘法
    # number of columns and rows of the input 
    I_row_num, I_col_num = I.shape # 获取输入矩阵的行数和列数


    # number of columns and rows of the filter
    F_row_num, F_col_num = F.shape # 获取滤波器矩阵的行数和列数


    #  calculate the output dimensions
    output_row_num = I_row_num + F_row_num - 1 # 计算输出矩阵的行数,为输入矩阵和滤波器矩阵的行数之和减一
    output_col_num = I_col_num + F_col_num - 1 # 计算输出矩阵的列数,为输入矩阵和滤波器矩阵的列数之和减一
    if print_ir: print('output dimension:', output_row_num, output_col_num) # 如果print_ir为真,打印输出矩阵的维度


    # zero pad the filter
    F_zero_padded = np.pad(F, ((output_row_num - F_row_num, 0),
                               (0, output_col_num - F_col_num)),
                            'constant', constant_values=0) # 将滤波器矩阵用零填充,使其形状与输出矩阵相同
    if print_ir: print('F_zero_padded: ', F_zero_padded) # 如果print_ir为真,打印零填充后的滤波器矩阵


    # use each row of the zero-padded F to creat a toeplitz matrix. 
    #  Number of columns in this matrices are same as numbe of columns of input signal
    toeplitz_list = [] # 创建一个空列表,用于存储托普利茨矩阵
    for i in range(F_zero_padded.shape[0]-1, -1, -1): # 从零填充后的滤波器矩阵的最后一行遍历到第一行,i是行的索引
        c = F_zero_padded[i, :] # 取出第i行的内容,作为托普利茨矩阵的第一列
        r = np.r_[c[0], np.zeros(I_col_num-1)] # 以第一列的第一个元素和输入矩阵列数减一个零组成一个数组,作为托普利茨矩阵的第一行
        toeplitz_m = toeplitz(c,r) # 用scipy库中的toeplitz函数生成一个托普利茨矩阵
        toeplitz_list.append(toeplitz_m) # 将生成的托普利茨矩阵添加到列表中
        if print_ir: print('F '+ str(i)+'\n', toeplitz_m) # 如果print_ir为真,打印生成的托普利茨矩阵


        # doubly blocked toeplitz indices: 
    #  this matrix defines which toeplitz matrix from toeplitz_list goes to which part of the doubly blocked
    c = range(1, F_zero_padded.shape[0]+1) # 生成一个从1到零填充后的滤波器矩阵的行数的序列,作为双重阻塞托普利茨矩阵的索引矩阵的第一列
    r = np.r_[c[0], np.zeros(I_row_num-1, dtype=int)] # 以第一列的第一个元素和输入矩阵行数减一个零组成一个数组,作为双重阻塞托普利茨矩阵的索引矩阵的第一行
    doubly_indices = toeplitz(c, r) # 用scipy库中的toeplitz函数生成一个双重阻塞托普利茨矩阵的索引矩阵
    if print_ir: print('doubly indices \n', doubly_indices) # 如果print_ir为真,打印双重阻塞托普利茨矩阵的索引矩阵


    ## creat doubly blocked matrix with zero values
    toeplitz_shape = toeplitz_list[0].shape # 获取列表中的一个托普利茨矩阵的形状
    h = toeplitz_shape[0]*doubly_indices.shape[0] # 计算双重阻塞托普利茨矩阵的高度,为一个托普利茨矩阵的高度乘以索引矩阵的高度
    w = toeplitz_shape[1]*doubly_indices.shape[1] # 计算双重阻塞托普利茨矩阵的宽度,为一个托普利茨矩阵的宽度乘以索引矩阵的宽度
    doubly_blocked_shape = [h, w] # 创建一个列表,存储双重阻塞托普利茨矩阵的形状
    doubly_blocked = np.zeros(doubly_blocked_shape) # 创建一个全零的矩阵,形状为双重阻塞托普利茨矩阵的形状


    # tile toeplitz matrices for each row in the doubly blocked matrix
    b_h, b_w = toeplitz_shape # hight and withs of each block
    for i in range(doubly_indices.shape[0]):
        for j in range(doubly_indices.shape[1]):
            start_i = i * b_h # 计算双重阻塞托普利茨矩阵中每个块的起始行位置
            start_j = j * b_w # 计算双重阻塞托普利茨矩阵中每个块的起始列位置
            end_i = start_i + b_h # 计算双重阻塞托普利茨矩阵中每个块的结束行位置
            end_j = start_j + b_w # 计算双重阻塞托普利茨矩阵中每个块的结束列位置
            doubly_blocked[start_i: end_i, start_j:end_j] = toeplitz_list[doubly_indices[i,j]-1] # 将列表中对应的托普利茨矩阵复制到双重阻塞托普利茨矩阵中的相应位置


    if print_ir: print('doubly_blocked: ', doubly_blocked) # 如果print_ir为真,打印双重阻塞托普利茨矩阵


    # convert I to a vector
    vectorized_I = matrix_to_vector(I) # 调用之前定义的函数,将输入矩阵转换为一个向量
    if print_ir: print('vectorized_I: ', vectorized_I) # 如果print_ir为真,打印转换后的向量
    
    # get result of the convolution by matrix mupltiplication
    result_vector = np.matmul(doubly_blocked, vectorized_I) # 用numpy库中的matmul函数,将双重阻塞托普利茨矩阵和向量相乘,得到卷积的结果向量
    if print_ir: print('result_vector: ', result_vector) # 如果print_ir为真,打印结果向量


    # reshape the raw rsult to desired matrix form
    out_shape = [output_row_num, output_col_num] # 创建一个列表,存储输出矩阵的形状
    output = vector_to_matrix(result_vector, out_shape) # 调用之前定义的函数,将结果向量转换为输出矩阵
    if print_ir: print('Result of implemented method: \n', output) # 如果print_ir为真,打印输出矩阵
    return output # 返回输出矩阵


# test on different examples


# fill I an F with random numbers
I = np.random.randn(10, 13) # 用numpy库中的random.randn函数,生成一个10行13列的矩阵,元素为服从标准正态分布的随机数,作为输入矩阵
F = np.random.randn(30, 70) # 用numpy库中的random.randn函数,生成一个30行70列的矩阵,元素为服从标准正态分布的随机数,作为滤波器矩阵


my_result = convolution_as_maultiplication(I, F) # 调用之前定义的函数,将输入矩阵和滤波器矩阵进行卷积运算,得到输出矩阵,赋值给my_result
print('my result: \n', my_result) # 打印my_result的内容
    
from scipy import signal # 导入scipy库中的signal模块,用于处理信号
lib_result = signal.convolve2d(I, F, "full") # 用signal模块中的convolve2d函数,将输入矩阵和滤波器矩阵进行卷积运算,得到输出矩阵,赋值给lib_result
print('lib result: \n', lib_result) # 打印lib_result的内容


assert(my_result.all() == lib_result.all()) # 用assert语句,断言my_result和lib_result的所有元素是否相等,如果不相等,抛出异常




# input signal
I = np.array([[1, 2, 3], [4, 5, 6]])
print('I: ', I.shape)
print(I)


 # filter 
F = np.array([[10, 20], [30, 40]])
print('F: ',F.shape)
print(F)


my_result = convolution_as_maultiplication(I, F) # 调用之前定义的函数,将输入矩阵和滤波器矩阵进行卷积运算,得到输出矩阵,赋值给my_result
print('my result: \n', my_result) # 打印my_result的内容


lib_result = signal.convolve2d(I, F, "full") # 用signal模块中的convolve2d函数,将输入矩阵和滤波器矩阵进行卷积运算,得到输出矩阵,赋值给lib_result
print('lib result: \n', lib_result) # 打印lib_result的内容


assert(my_result.all() == lib_result.all()) # 用assert语句,断言my_result和lib_result的所有元素是否相等,如果不相等,抛出异常

输出结果:

be660853f663e4bd3b7123d01f40f904.png

4.2 卷积层可视化

如何使用反卷积技术进行特征可视化?

8ec9dc515b21d96b1f896c4dc02a09be.png

卷积层可视化

2fc53d14a4c7a9552c6c22e96379bc4b.png

66cc94becedce28f66f78f1875c8bd50.png

4.3 理论解释

对卷积网络的表示能力、映射函数特性的数学分析

67e5ce5024d3ebda8ab216216e088a36.png

将卷积网络看作是用一组级联的线性加权滤波器和非线性函数对数据进行散射

83a10abaabf23f8711b4164459e02d21.png

多层卷积网络与人脑视觉系统的关系

7d5352ade0d1bdee54839b45dc1a4bd6.png

分层卷积神经网络

409029017395d38d19780e903e09d692.png

胶囊网络

289a68a6f770cab1a12c00b7623d949a.png

五、 挑战与改进措施

从哪几个方面对卷积网络的改进

81eca598350404490cf6c1aff84dff99.png

针对深层网络难以训练的问题,有哪些典型网络

5466502424c42938df8adadc2f14a549.png

5.1  卷积层

就卷积层而言,有哪些改进的方案

badbbd8b681d9f591d1cdfb45c0dee97.png

network in network机制介绍

5e4e6be8f7df32cb14ddf97f64fdfd94.png

如何选择合适的卷积核大小和数量?

b6adec20b44856164d890509b6bcae16.png

1x1卷积核

146302d384a4671f260180ef2ca6ea27.png

如何使用1x1卷积核进行降维或升维操作?

0bd5f8eba1009400d0e85a4c8dfb1723.png

5.2 池化层

针对池化层的改进措施有哪些

9125c2aaa7a47e5a15cffcbcd07aa6fc.png

池化策略 L-P、SPP原理介绍

edbf60e438dcf78daa55ad5207d7f69d.png

5.3 激活函数

激活函数的左饱和与右饱和,左硬饱和与右硬饱和

5772bd458b7f3a08864fa7104dcc6408.png

饱和性与梯度消失问题

2ae9d62971dcbd16227fd03d91996693.png

ReLU  ELU  PReLU 激活函数与梯度消失问题

3b0f5bae59ea8e56b9a626d7c7948763.png

5.4 损失函数

全连接神经网络一般使用哪些损失函数

cada69b1177a45552fcd275e6d5c906c.png

多任务损失函数

c55bb22977a1d59e92b249db157b1b83.png

5.5 网络结构

高速公路网络

a853153f8dd3b966987b4d40bff4b92a.png

58cb903f6c91b97da99e6b4a88d5af59.png

047f0c083533fe77aff4b51aa64252a2.png

残差网络

55d305393e15c624bb469526f232efee.png

e2db8395f997d664b210ddf94d23a22d.png

残差F(x)的形式

0c0bab9cb496d81462251acc29d58670.png

全卷积网络:

全卷积网络(Fully Convolutional Network,简称FCN)是一种深度学习模型,主要用于图像分割任务。与传统的卷积神经网络(CNN)不同,全卷积网络没有全连接层,而是将所有的全连接层替换为卷积层。

全卷积网络的基本结构如下:

输入图像
  |
  V
卷积层 - 激活函数 - 池化层
  |
  V
卷积层 - 激活函数 - 池化层
  |
  V
...
  |
  V
卷积层 - 激活函数 - 池化层
  |
  V
卷积层 - 激活函数
  |
  V
输出图像(分割结果)

全卷积网络的一个重要特点是它可以接受任意大小的输入图像,并且输出图像的大小与输入图像的大小相同。这是因为全卷积网络没有全连接层,所以不需要固定输入图像的大小。此外,全卷积网络在每个像素上都进行了预测,因此输出图像的每个像素都对应了一个分割结果。

全卷积网络在图像分割任务中取得了非常好的效果,它的这种设计思想也影响了许多后续的深度学习模型的设计。例如,U-Net就是在全卷积网络的基础上,引入了跳跃连接,从而进一步提高了图像分割的精度。

全卷积网络有哪些变种?

9a1e5e2dfea5aa7649ad78e99070b613.png

卷积网络的多尺度处理

34dd649a93014e6962416244b473dd76.png

5.6 批量归一化

57a092b30fa9c999c0923a35906c092d.png

内部协变量漂移

487e9d7e0000afdc824e65bf1ca9a234.png

在训练阶段,批量归一化(Batch Normalization,简称BN)会计算每个批次的均值和方差,然后用这些统计量来归一化数据。这是因为在训练阶段,我们一次处理一个批次的样本,所以可以直接计算出这个批次的均值和方差。

然而,在测试阶段,我们通常一次只对一个样本进行预测,因此无法计算出批次的均值和方差。为了解决这个问题,我们通常会在训练阶段计算出每一层的移动平均均值和方差,然后在测试阶段使用这些移动平均统计量来归一化数据。这样,即使在测试阶段一次只处理一个样本,我们也可以利用训练阶段的统计信息来进行归一化,从而保证模型的性能。这种方法被称为“推断模式”(Inference Mode)或“测试模式”(Test Mode)的批量归一化。

高速公路网络、残差网络、不使用全连接层的全卷积网络适用于哪些场景

4ed60182bbf42a02bee4a7019f8a1bfb.png

参考网址:

https://github.com/alisaaalehi/convolution_as_multiplication/blob/main/Convolution_as_multiplication.ipynb  

https://www.telesens.co/2018/04/09/initializing-weights-for-the-convolutional-and-fully-connected-layers/

https://ai.stackexchange.com/questions/11172/how-can-the-convolution-operation-be-implemented-as-a-matrix-multiplication

https://arxiv.org/abs/1512.03385  Deep Residual Learning for Image Recognition


    The End

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于YOLOv8的目标跟踪技术

💡💡💡本文摘要:介绍了YOLOv8自带的目标跟踪技术以及评价指标,并教会你如何在YOLOv8使用 1.YOLOv8自带两种跟踪方法 ultralytics/cfg/trackers/文件夹下 1.1 ByteTrack介绍 https://arxiv.org/pdf/2110.06864.pdf 摘…

Ubuntu基础之vim编辑器

前言 Vim是一个文本编辑器,通常在Unix和Linux系统上使用。它是Vi编辑器的改进版本,具有更多的功能和定制选项。Vim是一个强大的编辑器,可以通过命令模式和插入模式来编辑文本文件。它也有许多插件和扩展 1. 启动 Vim 在终端中输入以下命令来…

System.out::println是什么 ? Lambda表达式和方法引用

System.out::printlin 可以很好的串联Java8新特性中的Lambda表达式和方法引用 List<Integer> list Arrays.asList(1, 2, 3, 4, 5);//完成对集合元素的遍历输出list.forEach(System.out::println);首先用Lambda体简化匿名内部类了解函数式接口的概念方法引用的用法Consum…

【快速全面掌握 WAMPServer】11.安装 PHP 扩展踩过的坑

网管小贾 / sysadm.cc 我们在调试程序代码时&#xff0c;总会遇到一些 PHP 项目需要某些扩展组件。 而在 WAMPServer 下通常的 PHP 扩展的安装也不算有多麻烦。 具体关于 PHP 扩展的区分&#xff08;比如安全线程或非安全线程&#xff09;&#xff0c;以及怎么安装小伙伴们可…

【Emgu.CV教程】第18篇 、色彩处理之AdaptiveThreshold()自适应阈值化处理

之前学了Threshold()二值化函数&#xff0c;这个是在每一张照片里面&#xff0c;用同一个阈值进行二值化操作&#xff0c;但是对于一些对比度比较大的图片&#xff0c;可能会出现问题。比如这张照片想要提取出黑色文字文字&#xff1a; 如果执行以下代码&#xff1a; CvInvoke…

基于Flutter构建小型新闻App

目录 1. 概述 1.1 功能概述 1.2 技术准备 1.3 源码地址 2. App首页 2.1 pubspec依赖 2.2 热门首页组件 2.2.1 DefaultTabController 2.2.2 Swiper 2.3 新闻API数据访问 2.4 热门首页效果图 3. 新闻分类 3.1 GestureDetector 3.2 新闻分类效果图 4. 收藏功能 4…

详解 MySql InnoDB 的 MVCC 实现机制

目录 一. 前言 二. 认识 MVCC 2.1. 什么是 MVCC&#xff1f; 2.2. 什么是当前读和快照读&#xff1f; 2.3. 当前读、快照读和 MVCC 的关系 2.4. MVCC 能解决什么问题&#xff0c;好处是什么&#xff1f; 2.5. 小结 三. MVCC 的实现原理 3.1. 隐式字段 3.2. undo 日志…

SQL常见面试题

今天刷了一遍牛客里的必知必会题&#xff0c;一共50道题&#xff0c;大部分都比较基础&#xff0c;下面汇总一下易错题。 SQL81 顾客登录名 本题几个关键点&#xff1a; 登录名是其名称和所在城市的组合&#xff0c;因此需要使用substring()和concat()截取和拼接字段。得到登…

SpringBoot解决前后端分离跨域问题:状态码403拒绝访问

最近在写和同学一起做一个前后端分离的项目&#xff0c;今日开始对接口准备进行 登录注册 的时候发现前端在发起请求后&#xff0c;抓包发现后端返回了一个403的错误&#xff0c;解决了很久发现是【跨域问题】&#xff0c;第一次遇到&#xff0c;便作此记录✍ 异常描述 在后端…

前端:html+css+js实现CSDN首页

提前说一下&#xff0c;只实现了部分片段哈&#xff01;如下&#xff1a; 前端&#xff1a;htmlcssjs实现CSDN首页 1. 实现效果2. 需要了解的前端知识3. 固定定位的使用4. js 监听的使用4. 参考代码和运行结果 1. 实现效果 我的实现效果为&#xff1a; 原界面如下,网址为&…

计算机网络(1)

计算机网络&#xff08;1&#xff09; 小程一言专栏链接: [link](http://t.csdnimg.cn/ZUTXU) 计算机网络和因特网&#xff08;1&#xff09;因特网概念解读服务常见的服务 协议网络边缘特点强调 网络核心特点强调 小程一言 我的计算机网络专栏&#xff0c;是自己在计算机网络…

1. Spring概述

概述 Spring 是一个开源框架Spring 为简化企业级开发而生&#xff0c;使用 Spring&#xff0c;JavaBean 就可以实现很多以前要靠 EJB 才能实现的功能。同样的功能&#xff0c;在 EJB 中要通过繁琐的配置和复杂的代码才能够实现&#xff0c;而在 Spring 中却非常的优雅和简洁。…

软件运维实施维保方案

1.项目情况 2.服务简述 2.1服务内容 2.2服务方式 2.3服务要求 2.4服务流程 2.5工作流程 2.6业务关系 2.7培训 3.资源提供 3.1项目组成员 3.2服务保障 项目开发、管理、实施、运维、结项、验收等全文档获取&#xff1a;软件开发全套资料-CSDN博客

【LeetCode每日一题】1599. 经营摩天轮的最大利润(模拟)—2024新年快乐!

2024-1-1 文章目录 [1599. 经营摩天轮的最大利润](https://leetcode.cn/problems/maximum-profit-of-operating-a-centennial-wheel/)思路&#xff1a; 1599. 经营摩天轮的最大利润 思路&#xff1a; 1.对摩天轮的运转情况进行模拟&#xff0c; 2.遍历数组&#xff0c;分别计…

简单FTP客户端软件开发——JavaFX开发FTP客户端

文章目录 导入外部包commons-net-3.10.0.jarJavaFX开发客户端 FTP客户端要求如下&#xff1a; 简单FTP客户端软件开发 网络环境中的一项基本应用就是将文件从一台计算机中复制到另一台可能相距很远的计算机中。而文件传送协议FTP是因特网上使用得最广泛的文件传送协议。FTP使用…

Golang leetcode707 设计链表 (链表大成)

文章目录 设计链表 Leetcode707不使用头节点使用头节点 推荐** 设计链表 Leetcode707 题目要求我们通过实现几个方法来完成对链表的各个操作 由于在go语言中都为值传递&#xff0c;&#xff08;注意这里与值类型、引用类型的而区别&#xff09;&#xff0c;所以即使我们直接在…

RocketMQ 生产者源码分析:DefaultMQProducer、DefaultMQProducerImpl

&#x1f52d; 嗨&#xff0c;您好 &#x1f44b; 我是 vnjohn&#xff0c;在互联网企业担任 Java 开发&#xff0c;CSDN 优质创作者 &#x1f4d6; 推荐专栏&#xff1a;Spring、MySQL、Nacos、Java&#xff0c;后续其他专栏会持续优化更新迭代 &#x1f332;文章所在专栏&…

【面试】面向对象编程的三大概念(实例辅助记忆)

【面试】面向对象编程的三大概念&#xff08;实例辅助记忆&#xff09; 虑面向对象编程的三大特性&#xff0c;它们是&#xff1a; 封装&#xff08;Encapsulation&#xff09;&#xff1a; 将对象的状态和行为封装在一起&#xff0c;对外部隐藏对象的内部实现细节。这样可以防…

Nginx 简介和入门 - part1

虽然作为1个后端程序员&#xff0c; 终究避不开这东西 安装Nginx 本人的测试服务器是debian &#xff0c; 安装过程跟ubuntu基本一样 sudo apt-get install nginx问题是 nginx 安装后 执行文件在/usr/sbin 而不是/usr/bin 所以正常下普通用户是无法使用的。 必须切换到root…

事件循环的理解

1.单线程 Js是一个单线程的语言,代码只能一行一行去执行,遇到同步的代码就直接执行了,如果遇到异步的代码怎么办&#xff1f; 不可能等到异步的代码执行完&#xff0c;在去执行后面同步的代码。 2.主线程 遇到同步的代码,就在主线程里面直接执行了。 3.任务队列 遇到异步的…