Python numpy实现卷积操作

Python numpy实现卷积操作

● 原理见链接
● 没有考虑batchsize和偏差项
反向传播有待补充
在这里插入图片描述

import numpy as np

class Conv2D:
    # Not considering of batch size and bias
    # Referenced this blog https://github.com/GYee/CV_interviews_Q-A/blob/master/%E8%AE%A1%E7%AE%97%E6%9C%BA%E8%A7%86%E8%A7%89/03_%E4%BB%A3%E7%A0%81%E5%AE%9E%E7%8E%B0%E5%8D%B7%E7%A7%AF%E6%93%8D%E4%BD%9C.md
    def __init__(self, input_channel,
                 output_channel,
                 kernel_size,
                 stride=1,
                 padding=True):
        self.input_channel = input_channel
        self.output_channel = output_channel
        self.kernel_size = kernel_size
        self.stride = stride
        self.padding = padding
        self.weight = np.random.rand(self.input_channel * kernel_size * kernel_size, self.output_channel)

    def forward(self, feature_map):
        # input feature_map size c * h * w
        # circle_h = (ori_h + 2 * padding - kernel_size) / 2 + 1
        # circle_w = (ori_w + 2 * padding - kernel_size) / 2 + 1
        # output size self.output_channel * circle_h * circle_w
        (ori_c, ori_h, ori_w) = feature_map.shape
        # padding
        if self.padding:
            feature_map = np.pad(feature_map, ((0, 0), (self.kernel_size//2, self.kernel_size//2), (self.kernel_size//2, self.kernel_size//2)), 'constant')
            (c, h, w) = feature_map.shape
            circle_h = (h - self.kernel_size) // self.stride + 1
            circle_w = (w - self.kernel_size) // self.stride + 1
        else:
            circle_h = (ori_h - self.kernel_size) // self.stride + 1
            circle_w = (ori_w - self.kernel_size) // self.stride + 1
        # feature to matrix
        mat_feature_map = np.zeros([circle_h * circle_w, ori_c * self.kernel_size * self.kernel_size], np.float32)
        output = np.zeros([self.output_channel, circle_h, circle_w], np.float32)
        row = 0
        for i in range(circle_h):
            for j in range(circle_w):
                roi = feature_map[:, i * self.stride:(i * self.stride + self.kernel_size), j * self.stride:(j * self.stride + self.kernel_size)]
                mat_feature_map[row] = roi.flatten()
                row += 1
        mat_out = np.dot(mat_feature_map, self.weight)
        for i in range(self.output_channel):
            roi = mat_out[:, i]
            output[i] = np.reshape(roi, (circle_h, circle_w))
        return output

    def backword(self, dx, lr):
        # How to calculate dx to be added
        assert dx.shape == self.weight.shape
        self.weight -= dx * lr


if __name__ == '__main__':
    x = np.random.rand(2, 8, 8)
    conv = Conv2D(2, 3, 3, stride=2, padding=False)
    y = conv.forward(x)






  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值