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填充原始图像, 在水平方向与垂直方向添加padding
  • conv_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循环
      ```py

      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循环迭代, 这样简单
      ```py

      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
      ```py

      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, :]
      ```

  • 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

原文地址:https://www.cnblogs.com/megachen/p/10606617.html

时间: 2024-10-23 18:03:15

CNN理解与实现的相关文章

基于pytorch的CNN、LSTM神经网络模型调参小结

(Demo) 这是最近两个月来的一个小总结,实现的demo已经上传github,里面包含了CNN.LSTM.BiLSTM.GRU以及CNN与LSTM.BiLSTM的结合还有多层多通道CNN.LSTM.BiLSTM等多个神经网络模型的的实现.这篇文章总结一下最近一段时间遇到的问题.处理方法和相关策略,以及经验(其实并没有什么经验)等,白菜一枚. Demo Site:  https://github.com/bamtercelboo/cnn-lstm-bilstm-deepcnn-clstm-in-

cuda-convnet 在其他数据集上的使用教程

cuda-convnet 是Alex Krizhevsky公开的一套CNN代码,运行于Linux系统上,使用GPU做运算,在cuda-convnet中仅仅提供了Cifar数据集的demo,并且网站上并没有说明cuda-convnet代码是如何用于其它数据库的,所以博主我就尝试修改源码,以用于MNIST数据集上,做一个手写数字的识别CNNdemo 文章分三个部分: 首先,IO模块 其次,修改Layer的参数 最后是里面一些Python文件的说明,博主我也是为了这套代码才学习的Python与Cuda

卷积神经网络CNN介绍:结构框架,源码理解【转】

1. 卷积神经网络结构 卷积神经网络是一个多层的神经网络,每层都是一个变换(映射),常用卷积convention变换和pooling池化变换,每种变换都是对输入数据的一种处理,是输入特征的另一种特征表达:每层由多个二维平面组成,每个平面为各层处理后的特征图(feature map). 常见结构: 输入层为训练数据,即原始数据,网络中的每一个特征提取层(C-层)都紧跟着一个二次提取的计算层(S-层),这种特有的两次特征提取结构使网络在识别时对输入样本有较高的畸变容忍能力.具体C层和S层的个数不确定

Tensorflow的MNIST进阶教程CNN网络参数理解

背景 问题说明 分析 LeNet5参数 MNIST程序参数 遗留问题 小结 背景 之前博文中关于CNN的模型训练功能上是能实现,但是研究CNN模型内部结构的时候,对各个权重系数w,偏差b的shape还是存在疑惑,为什么要取1024,为什么取7*7*64,最近找到了一些相关资料,对这个问题有了新的理解,下面和大家分享一下. 问题说明 # Input Layer x = tf.placeholder('float',[None,784]) y_ = tf.placeholder('float',[N

理解CNN卷积层与池化层计算

概述 深度学习中CNN网络是核心,对CNN网络来说卷积层与池化层的计算至关重要,不同的步长.填充方式.卷积核大小.池化层策略等都会对最终输出模型与参数.计算复杂度产生重要影响,本文将从卷积层与池化层计算这些相关参数出发,演示一下不同步长.填充方式.卷积核大小计算结果差异. 一:卷积层 卷积神经网络(CNN)第一次提出是在1997年,杨乐春(LeNet)大神的一篇关于数字OCR识别的论文,在2012年的ImageNet竞赛中CNN网络成功击败其它非DNN模型算法,从此获得学术界的关注与工业界的兴趣

理解NLP中的卷积神经网络(CNN)

此篇文章是Denny Britz关于CNN在NLP中应用的理解,他本人也曾在Google Brain项目中参与多项关于NLP的项目. · 翻译不周到的地方请大家见谅. 阅读完本文大概需要7分钟左右的时间,如果您有收获,请点赞关注 :) 一.理解NLP中的卷积神经网络(CNN) 现在当我们听到神经网络(CNN)的时候,一般都会想到它在计算机视觉上的应用,尤其是CNN使图像分类取得了巨大突破,而且从Facebook的图像自动标注到自动驾驶汽车系统,CNN已经成为了核心. 最近,将CNN应用于NLP也

CNN卷积概念理解

实质理解: 训练过程: CNN在做卷积的时候,每一层的输出(可理解为形成的高维特征向量)是通过卷积的前向传播算法和反向传播算法(也就是梯度下降算法),结合真实的标签(前向传播结果与真实标签做误差), 将前向传播的结果无限逼近具有真实标签,在此过程中不断的更新权重,形成具有真实标签类别信息的权重矩阵. 预测过程: 利用训练高的权重矩阵去计算预测的输入数据,并产生一个结果,这个结果就是预测数据的类别或预测值. 理解: 从上述过程中可以得到以下结论: 预测过程----->就是为了得到适合该类数据的权重

可视化并理解CNN

参考:https://zhuanlan.zhihu.com/p/24833574 学习论文[1311.2901] Visualizing and Understanding Convolutional Networks 知乎专栏这篇可视化CNN讲的挺不错,我再稍微提炼下. Visualization with a Deconvnet:将feature map中的特征通过反池化.反激活.反卷积映射到像素. 反池化可通过记录最大激活值的位置来实现,反激活直接使用ReLU,反卷积采用该卷积核的转置来进

《Benign and maligenant breast tumors classification based on region growing and CNN segmentation》翻译阅读与理解

注明:本人英语水平有限,翻译不当之处,请以英文原版为准,不喜勿喷,另,本文翻译只限于学术交流,不涉及任何版权问题,若有不当侵权或其他任何除学术交流之外的问题,请留言本人,本人立刻删除,谢谢!! <基于区域生长的良性和恶性乳腺肿瘤的分类> 摘要 良性肿瘤被认为是导致女性死亡的常见起因之一,对良性肿瘤的早期检测能够提高患者的生存率,因此创造一个能够检测乳腺的可疑组织的系统是非常重要的.本文提出两种自动检测良性和恶性肿瘤的方法,第一种方法中,使用自动的区域生长法进行图形分割,区域生长法的门限值是通过