zoukankan      html  css  js  c++  java
  • 卷积神经网络CNN

    padding 有时候容易迷糊,这里汇总一下

    卷积中的 padding

    当取 SAME 时,原则上保持输入和输出尺寸相同但这只是在 步长为1时 如此

    总结来说,

    n 表示 输入尺寸

    f 表示 卷积核尺寸

    s 表示 步长

    p 表示 padding 的尺寸

    out 表示 输出尺寸

    p = (f - 1) / 2

    out = (n + 2p - f + 1) / s 向上取整

    也可以这么 out = (n + 2p - f) / s + 1 向下取整

    变换一下,out = (n + 2p - f) / s + 1 = (n + f -1 - f) / s + 1 = (n - 1) / s + 1 向下取整,不好记

    这么变换,out = (n + 2p - f + 1) / s = (n + f - 1 - f + 1) / s = n / s 向上取整

    当取 VALID 时

    VALID 原则就一条,不填充,就是正常滑动,滑完是多少就是多少,

    公式就简单了 out = (n - f + 1) / s 向上取整

    池化中的 padding

    当取 SAME 时,也会填充,但不是保持尺寸不变,而是当 池化野 滑到边界时,如果边界剩余尺寸小于池化野,则填充至一样大,否则不填充

    当取 VALID 时,不填充

    公式好像和 卷积 一样

    另外,

    卷积核尺寸最好是奇数,更容易找到卷积锚点

    池化的步长最好大于1,这样才能起到降维作用

    示例

    x = tf.Variable(np.random.randint(1, 3, size=(1, 5, 5, 3)), dtype=tf.float32)
    
    
    ##### 卷积
    w = tf.Variable(np.random.uniform(0, 1, size=(3, 3, 3, 4)), dtype=tf.float32)
    w2 = tf.Variable(np.random.uniform(0, 1, size=(2, 2, 3, 4)), dtype=tf.float32)  # size 为偶数
    w3 = tf.Variable(np.random.uniform(0, 1, size=(4, 4, 3, 4)), dtype=tf.float32)  # size 为偶数
    
    ### padding = SAME
    # stride = 1
    y1 = tf.nn.conv2d(x, w, strides=(1, 1, 1, 1), padding='SAME')     # p=(3-1)/2=1 (5+2*1-3+1)/1=5
    print(y1.shape)     # (1, 5, 5, 4)
    y12 = tf.nn.conv2d(x, w2, strides=(1, 1, 1, 1), padding='SAME')   # p=(2-1)/2=0.5 不向上取整 (5+2*0.5-2+1)/1=5
    print(y12.shape)     # (1, 5, 5, 4)
    # strider != 1
    y2 = tf.nn.conv2d(x, w, strides=(1, 2, 2, 1), padding='SAME')     # p同上 (5+2*1-3+1)/2=2.5 向上取整3
    print(y2.shape)     # (1, 3, 3, 4)
    y22 = tf.nn.conv2d(x, w2, strides=(1, 2, 2, 1), padding='SAME')   # p同上 (5+2*0.5-2+1)/2=2.5 向上取整3
    print(y22.shape)     # (1, 3, 3, 4)
    
    ### padding = VALID
    # stride = 1
    y3 = tf.nn.conv2d(x, w, strides=(1, 1, 1, 1), padding='VALID')      # (5-3+1)/1=3
    print(y3.shape)     # (1, 3, 3, 4)
    y32 = tf.nn.conv2d(x, w2, strides=(1, 1, 1, 1), padding='VALID')      # (5-2+1)/1=4
    print(y32.shape)     # (1, 4, 4, 4)
    # strider != 1
    y4 = tf.nn.conv2d(x, w, strides=(1, 2, 2, 1), padding='VALID')      # (5-3+1)/2=1.5 向上取整2
    print(y4.shape)     # (1, 2, 2, 4)
    y42 = tf.nn.conv2d(x, w2, strides=(1, 2, 2, 1), padding='VALID')      # (5-2+1)/2=2  此时有列信息被忽略了
    print(y42.shape)     # (1, 2, 2, 4)
    
    
    ##### 池化
    w = [1, 3, 3, 1]
    
    ### padding = SAME
    # stride = 1
    y5 = tf.nn.max_pool(x, w, strides=(1, 1, 1, 1), padding='SAME')    # 5/1=5
    print(y5.shape)     # (1, 5, 5, 3)
    # strider != 1
    y6 = tf.nn.max_pool(x, w, strides=(1, 2, 2, 1), padding='SAME')     # 5/2=2.5 向上取整3
    print(y6.shape)     # (1, 3, 3, 3)
    
    ### padding = VALID
    # stride = 1
    y7 = tf.nn.max_pool(x, w, strides=(1, 1, 1, 1), padding='VALID')    # (5-3+1)/1=3
    print(y7.shape)     # (1, 3, 3, 3)
    # strider != 1
    y8 = tf.nn.max_pool(x, w, strides=(1, 2, 2, 1), padding='VALID')    # (5-3+1)/2=1.5 向上取整2
    print(y8.shape)     # (1, 2, 2, 3)

    参考资料:

    https://www.cnblogs.com/CK85/p/10287142.html  最简单直接

    https://zhuanlan.zhihu.com/p/77471866 

    https://cloud.tencent.com/developer/article/1080155

    https://zhuanlan.zhihu.com/p/74159232

    https://zhuanlan.zhihu.com/p/46744988

  • 相关阅读:
    [译文] 实体与值对象到底是不是一回事?
    实现 WebApi 自托管服务宿主于 WinForms 及其交互
    [译文] C# 8 已成旧闻, 向前, 抵达 C# 9!
    [译文] 为什么你在 C# 里总是应该使用 "var" 关键字
    通过设置iis在局域网中访问网页
    windows 10 安装使用kafka
    ASP.NET Core 2.1 中的 HttpClientFactory (Part 4) 整合Polly实现瞬时故障处理
    ASP.NET Core 2.1 中的 HttpClientFactory (Part 3) 使用Handler实现传出请求中间件
    ASP.NET Core 2.1 中的 HttpClientFactory (Part 2) 定义命名化和类型化的客户端
    Asp.net Core 2.0 OpenId Connect Handler缺失Claims?
  • 原文地址:https://www.cnblogs.com/yanshw/p/15497984.html
Copyright © 2011-2022 走看看