参数解析:

conv2d是创建一个卷积层,对输入数据进行卷积操作,先看一下原函数:

keras.layers.Conv2D(filters, kernel_size, strides=(1, 1), padding='valid', data_format=None, dilation_rate=(1, 1), activation=None, use_bias=True, kernel_initializer='glorot_uniform', bias_initializer='zeros', kernel_regularizer=None, bias_regularizer=None, activity_regularizer=None, kernel_constraint=None, bias_constraint=None
)

常用参数:

filters: 卷积核的数量,决定输出数据的最后一维(channels)的大小。
kernel_size:卷积核的大小(形状),决定输出数据 height, width 维度的大小。
strides: 卷积操作时步长,可以是一个整数代表height, width方向的步长相同,也可以是(x, y)表示height方向的步长为x,width方向的步长为y。
padding:等于’valid’时卷积核在 输入数据形状(height, width)最大范围内 进行移动,等于’same’时如果(height, width)没有恰好完全符合设定的kernel_size和strides,超出的部分将会填充0.
activation: 激活函数
use_bias: 是否使用偏置量
kernel_initializer: 卷积核的初始化方式
bias_initializer: 偏置量的初始化方式

(输入是一个四维的数据(batch, height, width, channels),其他参数用到时再回来补充)

卷积过程:

创建一个模型,只有一层conv2d层,输入为数据为(4, 4, 1)形状的单通道数据:

def conv2d_test():#为了更直观看出结果,这里kernel_initializer 设为oens使核参数都为1.model = Sequential()model.add(layers.Conv2D(filters = 3, kernel_size=(2,2) , input_shape = (4, 4, 1), strides = 1, kernel_initializer = 'ones'))return model

测试:(需要引入numpy模块)

def test():conv2d_model = conv2d_test()data_test = np.random.randint(1, 3, (1, 4, 4, 1)) predict_result = conv2d_model.predict(data_test)print(data_test)print(predict_result)print(np.shape(predict_result))
if __name__ == '__main__':test()

先看data_test的输出:
np.random.randint: 生成值为 1 到 3 -1 形状为(1, 4, 4, 1)的矩阵:(下面是处理过的输出格式 方便观察)
[[
[[2],[2],[2],[1]],
[[2],[1],[2],[2]],
[[1],[2],[1],[2]],
[[1],[2],[1],[1]]
]]

再看predict_result 的输出:
[[
[[7. 7. 7.]
[7. 7. 7.]
[7. 7. 7.]]

[[6. 6. 6.]
[6. 6. 6.]
[7. 7. 7.]]

[[6. 6. 6.]
[6. 6. 6.]
[5. 5. 5.]]
]]

predict_result的形状:
(1, 3, 3, 3)

用图解析上面的结果:
卷积核的形状为:
(2,2)
因为kernel_initializer 设为oens,所以核参数为:
[[1,1],
[1,1] ]
如下图:


如图所示,
第一步运行会在红色框内进行,覆盖的范围与卷积核大小相同并且每个位置的值相互对应,可以理解为将核覆盖在输入数据左上角,运行的过程为:2 x 1 + 2 x 1 + 2 x 1 + 1 x 1 = 7

第二步运行会在黄色框内进行,因为strides = 1,width轴方向上的步长也为1.实际上是将核往右移动一步。运行的过程为:2 x 1 + 2 x 1 + 1 x 1 + 2 x 1 = 7

同理 第三部又会进行右移一步到绿色框内,运行的过程为:2 x 1 + 1 x 1 + 2 x 1 + 2 x 1 = 7
此时width方向已经走完,核将会在height + 1 方向上从头进行,也就是到蓝色框中,因为height方向上的步长也是1。以此类推,走完一轮后得到的结果将会是:
[
[[7],[7],[7]]
[[6],[6],[7]]
[[6],[6],[5]]
]

没错,得到的结果就是predict_result 的输出的第一列(直观上)。那为什么predict_result的输出有三列? 因为核的数量有3个(filters = 3),每一个核都进行了上述同样的操作,每个核运算得到的结果将会填充一层channel。所以predict_result的形状中channels = 3。height = 3和width = 3又是怎么来的呢? 可以理解为运算过程中在width 方向中走的步数和height方向走的步数,很明显结果由kernel_size和strides的大小决定。每个方向只能走3步,所以height,width都是3。另外,batch是数据块的大小,传入是多少输出就是多少,卷积过程不会改变batch的大小。

如果输入数据的channels不是1而是2或者3会怎么样呢?比如一般图片输入都是3通道的数据。

改一下代码,将input_shape改为3通道的数据格式:

def conv2d_test():#为了更直观看出结果,这里kernel_initializer 设为oens使核参数都为1.model = Sequential()model.add(layers.Conv2D(filters = 3, kernel_size=(2,2) , input_shape = (4, 4, 3), strides = 1, kernel_initializer = 'ones'))return model

生成数据也改为3通道:

def test():conv2d_model = conv2d_test()data_test = np.random.randint(1, 3, (1, 4, 4, 3)) predict_result = conv2d_model.predict(data_test)print(data_test)print(predict_result)print(np.shape(predict_result))

先看data_test的输出:
np.random.randint: 生成值为 1 到 3 -1 形状为(1, 4, 4, 3)的矩阵:

[[[[2 1 2]
[2 2 1]
[2 2 2]
[1 1 1]]

[[1 2 2]
[2 2 1]
[1 1 1]
[2 2 2]]

[[1 1 2]
[1 1 1]
[1 2 2]
[2 2 2]]

[[2 1 2]
[2 2 1]
[2 2 2]
[1 1 1]]]]

再看predict_result 的输出:

[[[[20. 20. 20.]
[19. 19. 19.]
[18. 18. 18.]]

[[17. 17. 17.]
[16. 16. 16.]
[20. 20. 20.]]

[[17. 17. 17.]
[19. 19. 19.]
[20. 20. 20.]]]]

predict_result的形状:
(1, 3, 3, 3)

可以看出修改后predict_result的形状channel依然是3,因为这只由核的数量决定。

对于多通道的数据,卷积过程为:
核在每个通道上进行卷积运算,每一个通道运算的结果进行相加,最后得到一个一通道的(x, y, 1)的数据结构。所以,如果有3个核,将会得到(x, y, 3)的数据结构。
如上面predict_result 的输出中左上角的20的计算过程为:
第一个核在第一channel: 2 * 1 + 2 * 1 + 1 * 1 + 2 * 1 = 7
第一个核在第二channel: 1 * 1 + 2 * 1 + 2 * 1 + 2 * 1 = 7
第一个核在第三channel: 2 * 1 + 1 * 1 + 2 * 1 + 1 * 1 = 6
所以第一次卷积的结果为: 7 + 7 + 6 = 20,其他的步骤以此类推。

最后,附带一个计算卷积操作输出形状的公式:

OH = (H + 2P - FH) / S + 1
OW = (W + 2P - FW) / S + 1

OH: 输出高(height)
OW: 输出宽(width)
H: 输入高
W: 输入宽
FH: 核高
FW: 核宽
P: 填充
S: 步长

套用第二个例子:
H: 输入高 = 4
W: 输入宽 = 4
FH: 核高 = 2
FW: 核宽 = 2
P: 填充 = 0 (因为padding='valid’不会进行填充)
S: 步长 = 1

OH = (4 + 0 - 2)/ 1 + 1 = 3
OW = (4 + 0 - 2)/ 1 + 1 = 3

keras conv2d 解析相关推荐

  1. keras.metrics解析

    目录 前言 metrics原理解析(以metrics.Mean为例) 创建自定义metrics 创建无状态 metrics 通过继承Metric创建有状态 metrics add_metric() 方 ...

  2. 简易的深度学习框架Keras代码解析与应用

    北京 | 深度学习与人工智能研修12月23-24日 再设经典课程 重温深度学习阅读全文> 正文约12690个字,22张图,预计阅读时间:32分钟. 总体来讲keras这个深度学习框架真的很&qu ...

  3. conv2d 公式_理解keras中conv2d层的输出形状

    这个问题在互联网上以各种形式被问到,而且有一个简单的答案,常常被忽略或混淆: 简单回答: Keras Conv2D层在多通道输入(例如彩色图像)的情况下,将在所有颜色通道上应用滤波器,并将结果求和,生 ...

  4. 【tf.keras】tf.keras模型复现

    keras 构建模型很简单,上手很方便,同时又是 tensorflow 的高级 API,所以学学也挺好. 模型复现在我们的实验中也挺重要的,跑出了一个模型,虽然我们可以将模型的 checkpoint ...

  5. 数据科学竞赛-人脸表情识别

    人脸表情识别 简介 这是科赛网曾今的一次计算机视觉类的分类赛,属于一个视觉基础任务.关于人脸表情识别,Kaggle等平台也举办过相关的比赛,难度并不算大,但是对技巧的要求比较高.本文详述该比赛的主要步 ...

  6. TensorFlow实时任意风格迁移,送女朋友的创意礼物有了

    TensorFlow实时任意风格迁移,送女朋友的创意礼物有了 前言 自适应实例规范化 风格迁移网络 编码器结构与实现 通过反射填充(reflection padding)减少块伪影 解码器结构与实现 ...

  7. 【Tensorflow学习三】神经网络搭建八股“六步法”编写手写数字识别训练模型

    神经网络搭建八股"六步法"编写手写数字识别训练模型 Sequential用法 model.compile(optimizer=优化器,loss=损失函数,metrics=[&quo ...

  8. Mask RCNN代码

    matterport/Mask rcnn model.py是网络主要构建的文件 utils.py中的anchor产生函数部分,主要是涉及函数: RPN部分 scales:(32, 64, 128, 2 ...

  9. 深度学习入门-参考资料汇总

    1.<Keras深度学习框架配置> http://www.jianshu.com/p/b8a703df5318 2.<简易的深度学习框架Keras代码解析与应用> http:/ ...

最新文章

  1. windows自启动项位置
  2. 云平台管理与部署---虚拟化平台-----KVM
  3. Linux下的awk用法详解
  4. RDL/RDLC批量单据打印 [转]
  5. php httphelper,C#的HttpHelper类post ,get
  6. java 获取sqlsession_获取Java的MyBatis框架项目中的SqlSession的方法
  7. spring框架搭建第一天
  8. C++ enum 枚举
  9. ABAP CCDEF, CCIMP, CCMAC, CCAU, CMXXX这些东东是什么鬼
  10. 江西财经研究生834c语言试卷,江西财经大学2006年考研C语言程序设计试题(B卷)
  11. 高性能并发TCP网络服务-IOCP框架修正VC2008版本
  12. Node.js 模块之Nimble流程控制
  13. Omni Converter全能转换器安装教程
  14. SQL语句 常用语句
  15. matlab画矩阵中的两列,matlab 图例 两列
  16. 公司网络很慢很卡的原因分析与处理
  17. java中加号_java中加号+的作用
  18. 商城静态页面(仿小米官网)
  19. 小白都能看得懂的ZBrush基础教学
  20. 软件测试和软件开发哪个发展更好

热门文章

  1. 浏览器对于网络安全做了什么
  2. 4年估值140亿的元气森林 内忧外患的壁垒困境
  3. ArcGIS一张图的制作过程,很详细的步骤!值得收藏!
  4. VC获取进程的cpu使用率、内存、线程数、句柄数等信息
  5. Transformers文本分类微调和TensorRT推理加速
  6. SP1043 GSS1 - Can you answer these queries I(猫树)
  7. 密码算法的分类与数字信封
  8. 【matlab】计算根据圆面积使用三角形来模拟产生的误差
  9. 手把手教你Python爬取女神套图
  10. 开发者可轻易发现网页代码漏洞——Google发布Chrome扩展DOM Snitch