前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深度理解卷积--使用im2col实现卷积

深度理解卷积--使用im2col实现卷积

作者头像
languageX
发布2021-01-29 10:36:08
2.1K0
发布2021-01-29 10:36:08
举报
文章被收录于专栏:计算机视觉CV计算机视觉CV

上一篇我们了解了卷积的概念,并且使用numpy实现了卷积。另一篇介绍了如何在tensorflow框架中调用API进行卷积操作。今天再介绍一个实现卷积操作的方案,使用im2col实现卷积,实际在OpenCV源码中也可以看到im2col的算法,顺便提一下opencv也可以直接部署深度学习模型,调用方法可以参考这里

im2col

im2col算法原理

im2col就是把图像转化为列向量,很多文章都有讲解,https://zhuanlan.zhihu.com/p/63974249 链接讲的比较详细。我按自己理解画了几个图,也方面大家理解

上图就是im2col的原理,把一个矩阵转化为一行。(实际应该是im2row)

如果看过numpy实现卷积的文章应该都知道卷积的过程,如果是二维图像,卷积核会在图像上滑动进行卷积,那在im2col实现卷积,怎么操作呢?

如果核大小是3*3,那每次卷积的图像就是依次为右边的四个矩阵了~

再把四个矩阵按图一的方式转化为一行,就是下图

同样,我们把卷积核也按im2col进行转化

总结下

一个6_3的图像,我们转换为了9_4的矩阵

一个3_3的卷积核,我们转换为了9_1的矩阵

两个矩阵相乘,是不是一个41的矩阵~

_如果是正常卷积呢?回忆下卷积过程,或者跑下代码,应该也是得到一个4_1的结果~(以VALID方式)

对比下:

标准卷积的计算过程:4次3_3矩阵和3_3矩阵相乘累加

im2col实现卷积的计算过程:9_4矩阵和1_9矩阵相乘

根据矩阵相乘的定义,两个结果是一致的,但im2col肯定是优化版的卷积过程~

通过上面几个图,大家应该就就了解了什么叫im2col,以及它如何实现卷积了。

下面简单直接~上代码

im2col实现卷积代码实现

对于基础知识reshape和transpose的加深理解这里

下面我们直接写im2col的代码,注释已经比较详细

def im2col(inputs,filter,padding="SAME",stride=1):
    N, C, H ,W = inputs.shape
    filter_size = filter.shape[2]
    # default np.floor
    filter_center = int(filter_size / 2.0)
    filter_center_ceil = int(np.ceil(filter_size / 2.0))
    # SAME模式,输入和输出大小一致,所以要在外面填充0
    if padding == "SAME":
        padding_inputs = np.zeros([N,C,H + filter_center_ceil, W + filter_center_ceil], np.float32)
        padding_inputs[:,:,filter_center:-filter_center, filter_center:-filter_center] = inputs
        inputs = padding_inputs
    N ,C,H2, W2 = inputs.shape
    print("N ,C,H2, W2",N ,C,H2, W2,"inputs\n",inputs)
    out_h = H
    out_w = W
    col = np.empty((N * H * W, filter_size * filter_size * C))
    outsize = out_w * out_h
    #每个样本outsize行,每行就是fs*fs*C按行顺序reshape,如果是N个样本就是N行
    for y in range(out_h):
        y_min = y * stride
        y_max = y_min + filter_size
        y_start = y * out_w
        for x in range(out_w):
            x_min = x * stride
            x_max = x_min + filter_size
            #取出kernel大小的数据块reshape为一行,N个样本reshape为N行
            #这里::outsize就是间隔outsize放下一个样本的行
            col[y_start + x::outsize, :] = inputs[:,:,y_min:y_max, x_min:x_max].reshape(N, -1)
    return col

同样把filter进行im2col操作

def trans_weight(filter):
    # print("filter\n",filter)
    C_out, C_in, K, K = filter.shape
    weight = filter.reshape(C_out,-1)
    # print("weight\n",weight)
    return weight

然后进行卷积操作,为了和之前numpy实现的卷积以及Tensorflow进行卷积的结果对比,我们输入和之前一样:

inputs = np.zeros([1, 3, 9, 9])
    for n in range(1):
        for i in range(3):
            for j in range(9):
                for z in range(9):
                    inputs[n][i][j][z] = i + j + z

filter = np.zeros([2, 3, 3, 3])
    for i in range(2):
        for j in range(3):
            for x in range(3):
                for y in range(3):
                    filter[i][j][x][y] = i + j + x + y
conv_out = conv_im2col(inputs, filter)
#[1,9,9,2]---[1,2,9,9]
conv_out =np.transpose(conv_out,(0,3,1,2))
print(conv_out)

大家可以自己动手跑下,卷积结果和之前我们使用numpy实现卷积结果是一致的~

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-12-18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • im2col
    • im2col算法原理
      • im2col实现卷积代码实现
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档