CNN理解与实现
CNN理解与实现
组成部分
- Convolution Layer
- Pool Layer:
- Max-pooling layer
- Average-pooling layer
- Full Connected(FC) Layer
需要的函数
注意
- 参数\(W\), \(b\)和数据\(X\)它们的维度是一样的, 这个非常重要, 在使用代码实现的时候不至于搞懵; 如果\(X\)是RGB图像, 它的维度假设为\((100, 24, 24, 3)\), 100表示样本数量, 24与24位图像的高与宽(我们人类习惯讲成宽与高, 但是在编程语言领域中, 如Matlab和Python中, 都是先锁定y轴, 再锁定x轴的, 同样迁移过来, 我们应该采用高与宽), 此时的W也是4个维度的, 加入为\((3, 3, 3, 8)\), 这里前两个3表示W(filter)的高与宽, 第三个3位通道数量, 要与X的通道数一致, 8表示W(filter)的个数, 可就是这次过滤器过滤之后得到的结果的通道数, 为b就简单了, 为\((1, 1, 1, 8)\), 每一个filter对应一个b
实现
zero_pad: 使用0填充原始图像, 在水平方向与垂直方向添加paddingconv_single: 使用一个过滤器\(W\)对原始图像中的slice进行卷积conv_forward: 卷积的前向传播- 根据公式计算出过滤之后的维度: \(n_h=int({(n_{hprev}+2p-f)\over{s}}+1)\), \(n_w=int({(n_{wprev}+2p-f)\over{s}}+1)\), 其中\(n_{hprev}\)为上一层的高度, \(n_{wprev}\)为上一层的宽度, \(f\)为filter的维度, filter一般为\(f \times f\), \(p\)为padding, \(n_h\)表示通过过滤器之后得到的结果的高度, \(n_w\)表示通过过滤器之后得到的结果的宽度, \(s\)表示stride, 为步幅
- 调用
zero_pad函数为\(A_{prev}\)添加padding, 使用\(int()\)是为了向下取整 - 由于卷积比较复杂, 这里不适用矩阵的计算, 而是采用多个嵌套的for循环
for i in range(m):
# 获取到一个样本, 因为我们不打算使用矩阵化提高计算速率, 这样简单一点
a_prev_pad = A_prev_pad[i, :, :, :]
for h in range(n_h):
for w in range(n_w):
for c in range(n_C):
# 此公式将从原始的a_prev_pad单样本的图像中获取到一个Convolution Window
vert_start = h * stride
vert_end = vert_start + f
horiz_start = w * stride
horiz_end = horiz_start + f
# 得到在原始图像中与filter同样大小窗口
a_slice_prev = a_prev_pad[vert_start:vert_end, horiz_start:horiz_end, :]
# 调用conv_single进行卷积计算
Z[i, h, w, c] = conv_single(a_slice_prev, W[:, :, :, c], b[:, :, :, c])
# 计算激活函数
A[i, h, w, c] = activate(Z[i, h, w, c])
pool_forward: 池化层的前向传播- 根据公式计算出\(n_h\)与\(n_w\)
- 同样不使用矩阵计算, 使用多个for循环迭代, 这样简单
for i in range(m):
a_prev = A_prev[i, :, :, :]
for h in range(n_h):
for w in range(n_w):
for c in range(n_c):
# 计算窗口坐标
vert_start = h * stride
vert_end = vert_start + f
horiz_start = w * stride
horiz_end = horiz_start + f
a_slice = a_prev[vert_start:vert_end, horiz_start:horiz_end, c]
# 这里采用Max-pooling的计算方法
# 其中A为我们函数的返回矩阵
A[i, h, w, c] = np.max(a_slice)
compute_cost: 计算损失函数\(J\)conv_backward:- 计算dA, dW和db
for i in range(m):
da_prev_pad = dA_prev_pad[i, :, :, :]
a_prev_pad = A_prev_pad[i, :, :, :]
for h in range(n_h):
for w in range(n_w):
for c in range(n_C):
vert_start = h * stride
vert_end = vert_start + f
horiz_start = h * stride
horiz_end = horiz_start + f
a_slice = a_prev_pad[vert_start:vert_end, horiz_start:horiz_end, :]
da_prev_pad[vert_start:vert_end, horiz_start:horiz_end, :] += dZ[i, h, w, c] * W[:, :, :, c]
dW[:, :, :, c] += dZ[i, h, w, c] * a_slice
db[:, :, :, c] += dZ[i, h, w, c]
dA_prev[i, :, :, :] = da_prev_pad[pad:-pad, pad:-pad, :]
- 计算dA, dW和db
pool_backward:- 与
conv_backward类似
for i in range(m):
a_prev = A_prev[i, :, :, :]
for h in range(n_h):
for w in range(n_w):
for c in range(n_C):
vert_start = h * stride
vert_end = vert_start + f
horiz_start = w * stride
horiz_end = horiz_start + f
a_slice = a_prev[vert_start:vert_end, horiz_start:horiz_end, c]
mask = create_mask_from_window(a_slice)
dA_prev[i, vert_start: vert_end, horiz_start: horiz_end, c] += np.multiply(mask, dA[i,h,w,c])
- 与
总结反向传播用到的公式
- 对于单个样本来说, 不使用矩阵表达式
- \(da += dw \times dz\)
- \(dw += dz \times a\)
- \(db += dz\)
使用的结构
- Conv->ReLU->Pool->Conv->ReLU->Pool->FC
CNN理解与实现的更多相关文章
- 卷积神经网络CNN理解
自今年七月份以来,一直在实验室负责卷积神经网络(Convolutional Neural Network,CNN),期间配置和使用过theano和cuda-convnet.cuda-convnet2. ...
- 基于pytorch的CNN、LSTM神经网络模型调参小结
(Demo) 这是最近两个月来的一个小总结,实现的demo已经上传github,里面包含了CNN.LSTM.BiLSTM.GRU以及CNN与LSTM.BiLSTM的结合还有多层多通道CNN.LSTM. ...
- 卷积神经网络CNN介绍:结构框架,源码理解【转】
1. 卷积神经网络结构 卷积神经网络是一个多层的神经网络,每层都是一个变换(映射),常用卷积convention变换和pooling池化变换,每种变换都是对输入数据的一种处理,是输入特征的另一种特征表 ...
- Deep Learning 学习随记(八)CNN(Convolutional neural network)理解
前面Andrew Ng的讲义基本看完了.Andrew讲的真是通俗易懂,只是不过瘾啊,讲的太少了.趁着看完那章convolution and pooling, 自己又去翻了翻CNN的相关东西. 当时看讲 ...
- CNN笔记:通俗理解卷积神经网络【转】
本文转载自:https://blog.csdn.net/v_july_v/article/details/51812459 通俗理解卷积神经网络(cs231n与5月dl班课程笔记) 1 前言 2012 ...
- 理解NLP中的卷积神经网络(CNN)
此篇文章是Denny Britz关于CNN在NLP中应用的理解,他本人也曾在Google Brain项目中参与多项关于NLP的项目. · 翻译不周到的地方请大家见谅. 阅读完本文大概需要7分钟左右的时 ...
- 理解CNN中的通道 channel
在深度学习的算法学习中,都会提到 channels 这个概念.在一般的深度学习框架的 conv2d 中,如 tensorflow .mxnet ,channels 都是必填的一个参数. channel ...
- Deep Visualization:可视化并理解CNN(转)
转载地址:https://zhuanlan.zhihu.com/p/24833574 一.前言 CNN作为一个著名的深度学习领域的“黑盒”模型,已经在计算机视觉的诸多领域取得了极大的成功,但是,至今没 ...
- 理解CNN中的感受野(receptive-field)
1. 阅读论文:Understanding the Effective Receptive Field in Deep Convolutional Neural Networks 理解感受野 定义:r ...
随机推荐
- Markdown编辑器——常用语法
Markdown是什么? 简短来说,他就是一款特别适用于写博客的编辑器.为什么适合呢,因为它特别的方便.以博客园的编辑界面来说,它原本的界面是这样的(有没有一种Word2003的既视感): 但是,当你 ...
- CentOS将普通用户加入管理员组
将用户username加入wheel组: usermod -aG wheel username 将普通用户username加入root组: usermod -aG sudo username 永久生效 ...
- Rest-assured 写日志到 log4j
背景: 采用Rest-assured,日志采用log4j,发现Rest-assured本身只支持打印日志到控制台,但期望打印到文件中以便排查问题 请求打印的语句只能输出到控制台 given().log ...
- Android Library 使用规则
1. 一个项目必须声明为 is library.使用该 library 的项目导入该 library. 2. library 的 manifect 中 activity 的声明需明确包名以避免找不到. ...
- OpenStack 业务链networking-sfc介绍 (2) - 底层原理
原文链接:https://blog.csdn.net/bc_vnetwork/article/details/65630475 1. SFC底层实现原理 port chain和ovs driver/ ...
- jQuery查找标签--选择器,筛选器,模态对话框, 左侧菜单栏
查找标签 选择器: 基本选择器(同css) id选择器 $("#id") 标签选择器 $('tagName') class选择器 $(".className") ...
- 关于Tomcat控制台乱码解决办法___ 解决 IntelliJ IDEA Tomcat 控制台中文输出乱码问题
Tomcat 控制台UTF-8乱码问题 1.修改cmd的编码格式 快捷键win+R打开运行程序,输入regedit打开注册表,找到以下路劲并且修改. [HKEY_LOCAL_MACHINE\SOFTW ...
- Flask_WTF升级到最新版本
用pip $ pip install -U Flask-WTF 看熊哥的后端管理系统时候报错ImportError: cannot import name FlaskForm. 那一行的代码:from ...
- C++实现二叉树的相应操作
1. 二叉树的遍历:先序(递归.非递归),中序(递归.非递归),后序(递归.非递归). #include <iostream> #include <string> #inclu ...
- json 模块的基本使用学习
内容大纲 1: 为什么要学习json模块 >1:因为网络之间的通信,还有不同语言之间的相互内容沟通,需要用到json 模式进行沟通 >2:写入部分文件用json文件保存, 2:json的序 ...