conv2d简单实现

直接上代码

前置内容可以参考:conv1d简单实现

def myconv2d(infeat, convkernel, padding=0, stride=1):
    b, c, h, w = len(infeat), len(infeat[0]), len(infeat[0][0]), len(infeat[0][0][0])
    out_c, in_c, kh, kw = len(convkernel), len(convkernel[0]), len(convkernel[0][0]), len(convkernel[0][0][0])
    # 不使用分组卷积,c = in_c
    # 卷积核为正方形,kh = kw
    
    res = [[[[0] * (w-kw+1) for _ in range(h-kh+1)] for _ in range(out_c)] for _ in range(b)]
    # 最终输出形状:b*out_c*(h-kh+1)*(w-kw+1)
    # print(len(res), len(res[0]), len(res[0][0]), len(res[0][0][0]))
    for i in range(b):
        # 关于batch,目前只能串行完成
        
        for j in range(out_c):
            # 计算每一组的结果
            
            for m in range(c):
                for n in range(h-kh+1):
                    for g in range(w-kw+1):
                        # 计算每一个位置的值
                        
                        ans = 0
                        for k1 in range(kh):
                            for k2 in range(kw):
                                ans += infeat[i][m][n+k1][g+k2] * convkernel[j][m][k1][k2]
                        res[i][j][n][g] += ans
    return res


# 我的卷积
infeat = [[[[1,0,2,2,2], [0,0,0,0,0], [2,0,2,2,2], [1,0,0,0,0], [1,0,0,2,1]],
           [[1,0,1,0,1], [0,0,0,0,1], [0,0,2,0,0], [2,0,0,0,0], [0,0,1,0,0]],
           [[0,2,2,0,0], [0,0,0,0,1], [1,1,2,0,2], [2,0,0,0,0], [0,1,1,0,1]]]]

convkernel = [[[[1,0,0], [-1,0,0], [0,-1,1]],
               [[-1,-1,0], [-1,-1,1], [1,0,0]],
               [[1,1,0], [0,-1,1], [1,1,1]]],
              
              [[[1,-1,0], [-1,0,0], [0,1,-1]],
               [[0,1,-1], [0,0,0], [0,1,1]],
               [[0,-1,0], [1,1,-1], [-1,0,1]]]]
outfeat = myconv2d(infeat, convkernel)
print(outfeat)


# pytorch源码计算结果
from torch.nn.functional import conv2d
import torch
import numpy

infeat = torch.tensor(numpy.array(infeat))
convkernel = torch.tensor(numpy.array(convkernel))

outfeat_pytorch = conv2d(infeat, convkernel)
print(outfeat_pytorch)

输出结果如下,和官方的计算结果相同:

[[[[8, 6, 11], [5, -4, -2], [3, 5, 4]], [[-1, -2, -2], [-4, 3, -3], [2, -4, 1]]]]
tensor([[[[ 8,  6, 11],
          [ 5, -4, -2],
          [ 3,  5,  4]],

         [[-1, -2, -2],
          [-4,  3, -3],
          [ 2, -4,  1]]]], dtype=torch.int32)

思考

pytorch中是直接按照滑动窗口点乘相加的,与传统的卷积定义(反褶,移位,相乘,相加)不同,没有反褶的操作

猜你喜欢

转载自blog.csdn.net/qq_45510888/article/details/123460943
今日推荐