1. 输入 4 维数据

CNN 中各层间传递的数据是 4 维数据。所谓 4 维数据,比如数据的形状是(10, 1, 28, 28),则它对应 10 个高为 28、长为 28、通道为 1 的数据。用 Python 实现如下:

In [2]: a = np.random.rand(3, 1, 4, 4)In [4]: a.shape
Out[4]: (3, 1, 4, 4)In [5]:

如果要访问第 1 个数据的第 1 个通道的空间数据,可以写成下面这样。

In [5]: a[0][0]

或者

In [6]: a[0, 0]

2. 基于im2col 的展开

im2col 是一个函数,将输入数据展开以适合滤波器(权重)。如图7-17 所示,对 3 维的输入数据应用 im2col 后,数据转换为 2 维矩阵(正确地讲,是把包含批数量的 4 维数据转换成了2 维数据)。

具体地说,如图7-18 所示,对于输入数据,将应用滤波器的区域(3 维方块)横向展开为 1 列。im2col
在所有应用滤波器的地方进行这个展开处理。

在图7-18 中,为了便于观察,将步幅设置得很大,以使滤波器的应用区域不重叠。而在实际的卷积运算中,滤波器的应用区域几乎都是重叠的。

在滤波器的应用区域重叠的情况下,使用 im2col 展开后,展开后的元素个数会多于原方块的元素个数。因此,使用 im2col 的实现存在比普通的实现消耗更多内存的缺点。

但是,汇总成一个大的矩阵进行计算,对计算机的计算颇有益处。比如,在矩阵计算的库(线性代数库)等中,矩阵计算的实现已被高度最优化,可以高速地进行大矩阵的乘法运算。因此,通过归结到矩阵计算
上,可以有效地利用线性代数库。

im2col 这个名称是 image to column 的缩写,翻译过来就是“从图像到矩阵”的意思。CaffeChainer 等深度学习框架中有名为 im2col 的函数,并且在卷积层的实现中,都使用了 im2col

使用 im2col 展开输入数据后,之后就只需将卷积层的滤波器(权重)纵向展开为1 列,并计算 2 个矩阵的乘积即可(参照图7-19)。这和全连接层的 Affine 层进行的处理基本相同。

如图7-19 所示,基于 im2col 方式的输出结果是 2 维矩阵。因为 CNN 中数据会保存为 4 维数组,所以要将 2 维输出数据转换为合适的形状。以上就是卷积层的实现流程。

im2col 函数代码实现如下:

def im2col(input_data, filter_h, filter_w, stride=1, pad=0):"""Parameters----------input_data : 由(数据量, 通道, 高, 长)的4维数组构成的输入数据filter_h : 滤波器的高filter_w : 滤波器的宽stride : 步幅pad : 填充Returns-------col : 2维数组"""N, C, H, W = input_data.shapeout_h = (H + 2*pad - filter_h)//stride + 1out_w = (W + 2*pad - filter_w)//stride + 1img = np.pad(input_data, [(0,0), (0,0), (pad, pad), (pad, pad)], 'constant')col = np.zeros((N, C, filter_h, filter_w, out_h, out_w))for y in range(filter_h):y_max = y + stride*out_hfor x in range(filter_w):x_max = x + stride*out_wcol[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N*out_h*out_w, -1)return col

应用示例:

In [8]: x1 = np.random.rand(1, 3, 7, 7)In [9]: col1 = im2col(x1, 5, 5, stride=1, pad=0)In [10]: col1.shape
Out[10]: (9, 75)In [14]: x2 = np.random.rand(10, 3, 7, 7)In [15]: col2 = im2col(x2, 5, 5, stride=1, pad=0)In [16]: col2.shape
Out[16]: (90, 75)In [17]:

第一个是批大小为1、通道为3 的7 × 7 的数据,第二个的批大小为10,数据形状和第一个相同。

分别对其应用 im2col 函数,在这两种情形下,第 2 维的元素个数均为 75。这是滤波器(通道为 3、大小为
5 × 5)的元素个数的总和。批大小为1 时,im2col 的结果是(9, 75)。而第 2个例子中批大小为10,所以保存了10 倍的数据,即(90, 75)。

3. 卷积层实现

卷积层的初始化方法将滤波器(权重)、偏置、步幅、填充作为参数接收。滤波器是(FN , C , FH , FW ) 的 4 维形状。另外,FNCFHFW 分别是 FilterNumber (滤波器数量)、ChannelFilter HeightFilter Width 的缩写。

class Convolution:def __init__(self, W, b, stride=1, pad=0):self.W = Wself.b = bself.stride = strideself.pad = paddef forward(self, x):FN, C, FH, FW = self.W.shapeN, C, H, W = x.shapeout_h = int(1 + (H + 2*self.pad - FH) / self.stride)out_w = int(1 + (W + 2*self.pad - FW) / self.stride)col = im2col(x, FH, FW, self.stride, self.pad)col_W = self.W.reshape(FN, -1).T # 滤波器的展开out = np.dot(col, col_W) + self.bout = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2)return out

其中:

        col = im2col(x, FH, FW, self.stride, self.pad)col_W = self.W.reshape(FN, -1).T # 滤波器的展开out = np.dot(col, col_W) + self.b

是用 im2col 展开输入数据,并用 reshape 将滤波器展开为 2 维数组。然后,计算展开后的矩阵的乘积。

将各个滤波器的方块纵向展开为 1 列。这里通过 reshape(FN,-1) 将参数指定为 -1,这是 reshape 的一个便利的功能。通过在 reshape 时指定为 -1,reshape 函数会自动计算 -1 维度上的元素个数,以使多维数组的元素个数前后一致。比如,(10, 3, 5, 5) 形状的数组的元素个数共有 750 个,指定 reshape(10,-1) 后,就会转换成(10, 75) 形状的数组。

forward 的实现中,最后会将输出大小转换为合适的形状。转换时使用了 NumPytranspose 函数。transpose 会更改多维数组的轴的顺序。如图 7-20 所示,通过指定从 0 开始的索引(编号)序列,就可以更改轴的顺序。


以上就是卷积层的 forward 处理的实现。通过使用 im2col 进行展开,接下来是卷积层的反向传播的实现,因为和 Affine 层的实现有很多共通的地方,所以就不再介绍了。但有一点需要注意,在进行卷积层的反向传播时,必须进行 im2col 的逆处理。col2im 代码如下:

def col2im(col, input_shape, filter_h, filter_w, stride=1, pad=0):"""Parameters----------col :input_shape : 输入数据的形状(例:(10, 1, 28, 28))filter_h :filter_wstridepadReturns-------"""N, C, H, W = input_shapeout_h = (H + 2*pad - filter_h)//stride + 1out_w = (W + 2*pad - filter_w)//stride + 1col = col.reshape(N, out_h, out_w, C, filter_h, filter_w).transpose(0, 3, 4, 5, 1, 2)img = np.zeros((N, C, H + 2*pad + stride - 1, W + 2*pad + stride - 1))for y in range(filter_h):y_max = y + stride*out_hfor x in range(filter_w):x_max = x + stride*out_wimg[:, :, y:y_max:stride, x:x_max:stride] += col[:, :, y, x, :, :]return img[:, :, pad:H + pad, pad:W + pad]

除了使用 col2im 这一点,卷积层的反向传播和 Affine 层的实现方式都一样。卷积层反向传播代码如下所示:

class Convolution:def __init__(self, W, b, stride=1, pad=0):self.W = Wself.b = bself.stride = strideself.pad = pad# 中间数据(backward时使用)self.x = None   self.col = Noneself.col_W = None# 权重和偏置参数的梯度self.dW = Noneself.db = Nonedef forward(self, x):FN, C, FH, FW = self.W.shapeN, C, H, W = x.shapeout_h = 1 + int((H + 2*self.pad - FH) / self.stride)out_w = 1 + int((W + 2*self.pad - FW) / self.stride)col = im2col(x, FH, FW, self.stride, self.pad)col_W = self.W.reshape(FN, -1).Tout = np.dot(col, col_W) + self.bout = out.reshape(N, out_h, out_w, -1).transpose(0, 3, 1, 2)self.x = xself.col = colself.col_W = col_Wreturn outdef backward(self, dout):FN, C, FH, FW = self.W.shapedout = dout.transpose(0,2,3,1).reshape(-1, FN)self.db = np.sum(dout, axis=0)self.dW = np.dot(self.col.T, dout)self.dW = self.dW.transpose(1, 0).reshape(FN, C, FH, FW)dcol = np.dot(dout, self.col_W.T)dx = col2im(dcol, self.x.shape, FH, FW, self.stride, self.pad)return dx

机器学习入门(17)— 输入 4 维数据、基于 im2col 展开来实现卷积层相关推荐

  1. 机器学习入门的书单(数据挖…

    原文地址:机器学习入门的书单(数据挖掘.模式识别等一样)转 作者:想法简单 (写在前面)昨天说写个机器学习书单,那今天就写一个吧.这个书单主要是入门用的,很基础,适合大二.大三的孩子们看看:当然你要是 ...

  2. A.机器学习入门算法(五):基于企鹅数据集的决策树分类预测

    [机器学习入门与实践]入门必看系列,含数据挖掘项目实战:数据融合.特征优化.特征降维.探索性分析等,实战带你掌握机器学习数据挖掘 专栏详细介绍:[机器学习入门与实践]合集入门必看系列,含数据挖掘项目实 ...

  3. A.机器学习入门算法[七]:基于英雄联盟数据集的LightGBM的分类预测

    [机器学习入门与实践]入门必看系列,含数据挖掘项目实战:数据融合.特征优化.特征降维.探索性分析等,实战带你掌握机器学习数据挖掘 专栏详细介绍:[机器学习入门与实践]合集入门必看系列,含数据挖掘项目实 ...

  4. 深度学习入门 (九):卷积层和池化层的实现

    目录 卷积神经网络 CNN 整体结构 卷积层 全连接层存在的问题 卷积运算 乘积累加运算 偏置 填充 (padding) 步幅 (stride) 小结:卷积层的输出特征图的大小 3 维数据的卷积运算 ...

  5. 【城市污水处理过程中典型异常工况智能识别】(基于迁移学习,拓扑结构卷积神经网络的污水异常工况识别)

    基于迁移学习拓扑结构卷积神经网络的污水异常工况识别 **摘 要:针对城市污水处理过程的异常工况识别问题,本文提出了基于图像纹理性分析的工况识别方法.首先总结了几种典型的异常工况的特点,并且分析了卷积神 ...

  6. 机器学习入门(15)— 全连接层与卷积层的区别、卷积神经网络结构、卷积运算、填充、卷积步幅、三维数据卷积、多维卷积核运算以及批处理

    卷积神经网络(Convolutional Neural Network,CNN)CNN 被用于图像识别.语音识别等各种场合,在图像识别的比赛中,基于深度学习的方法几乎都以 CNN 为基础. 1. 全连 ...

  7. 《基于张量网络的机器学习入门》学习笔记7

    <基于张量网络的机器学习入门>学习笔记7 量子算法 什么是量子算法 三个经典量子算法 Grover算法 背景 基本原理 例题 量子算法 什么是量子算法 例如我们求解一个问题,一个111千克 ...

  8. 《基于张量网络的机器学习入门》学习笔记8(Shor算法)

    <基于张量网络的机器学习入门>学习笔记8 Shor算法 来源 Shor算法的大致流程 因数分解 周期求取与量子傅里叶变换(QFT) Shor算法 来源 1994 1994 1994年,应用 ...

  9. adf机器_智能运维高招 | 基于机器学习的磁盘故障预测

    原标题:智能运维高招 | 基于机器学习的磁盘故障预测 导读 RGF算法+迁移学习精确预测硬盘故障.<Predicting Disk Replacement towards Reliable Da ...

最新文章

  1. win7笔记本设置wifi热点
  2. 微软发布了Spartan项目的细节,并证实了某些流言
  3. 【CyberSecurityLearning 33】Nginx和Tomcat服务的搭建、Nginx负载均衡
  4. FFmpeg 源代码:avcodec_find_encoder()和avcodec_find_encoder_by_name()
  5. unity3d曲线text文本
  6. 深度linux 转中文,Linux Deepin 中文Linux系统的新希望?
  7. 第 1-6 课:玩转时间 + 面试题
  8. c++-串的模式匹配
  9. win10中linux系统下载软件,win10 上安装 Debian Linux子系统
  10. 【Zookeeper】基于Zookeeper实现分布式锁
  11. 红帽高级总监谈 OpenJDK 的未来:Java 的未来从未如此光明
  12. REACT是否真的就比VUE强?(文末附两个框架的学习福利)
  13. Mysql配置项sync_binlog=0
  14. 【第40题】2019年OCP认证12C题库062考试最新考试原题
  15. NLP文本情感——SNOWNLP简易版
  16. windows server2012 R2 离线中文语言包下载与安装
  17. mysql生成数据字典
  18. Elastic Stack应用性能监控APM初窥门径
  19. csdn中Markdown编辑器的使用
  20. 三个案例详解不同网段之间如何互通

热门文章

  1. Linux通过端口号杀死指定进程
  2. 【Learning Notes】线性链条件随机场(CRF)原理及实现
  3. LeetCode简单题之重塑矩阵
  4. Typora+PicGo图床配置(本地图片-->网络url~博客必备)
  5. TVM darknet yolov3算子优化与量化代码的配置方法
  6. 有了NPU,还要DSP吗?
  7. Imec推出高性能芯片的低成本冷却解决方案
  8. 2021年大数据Flink(二十三):​​​​​​​Watermaker案例演示
  9. Django 模型成员2.2
  10. [C] 图的广度优先遍历