深度学习四 —— 手撕池化层

手撕池化层(numpy)

池化层定义

池化是缩小高、长方向上的空间的运算

在这里插入图片描述

除了max池化,还有average池化,一般来说,池化的窗口大小会和步幅设定成一样的值

池化层没有要学习的参数,输入数据和输出数据的通道数不会发生变化,计算是按通道独立进行。对输入数据发生微小变卦具有鲁棒性(健壮)

numpy手撕池化

池化过程和卷积过程相同,会涉及到im2colcol2im的操作,由于卷积部分我已经说过了,所以池化部分就不说了,想了解的可以看手撕卷积层

import os, sys
import collections
import numpy as np
class Pooling:
    def __init__(self, pool_h, pool_w, stride=1, padding=0):
        self.pool_h = pool_h
        self.pool_w = pool_w
        self.stride = stride
        self.padding = padding

        self.x = None
        self.arg_max = None

    def foward(self, x):
        N, C, H, W = x.shape
        out_h = int(1 + (H - self.pool_h) / self.stride)
        out_w = int(1 + (W - self.pool_w) / self.stride)

        col = self.im2col(x, self.pool_h, self.pool_w, self.stride, self.padding)
        col = col.reshape(-1, self.pool_h * self.pool_w)

        arg_max = np.argmax(col, axis=1)
        out = np.max(col, axis=1)
        out = out.reshape(N, out_h, out_w, C).transpose(0, 3, 1, 2)

        self.x = x
        self.arg_max = arg_max
        return out

    def backward(self, dout):
        dout = dout.transpose(0, 2, 3, 1)

        pool_size = self.pool_h * self.pool_w
        dmax = np.zeros(dout.size, pool_size)
        dmax[np.arange(self.arg_max.size), self.arg_max.flatten()] = dout.flatten()
        dmax = dmax.reshape(dout.shape + (pool_size, ))

        dcol = dmax.reshape(dmax.shape[0] * dmax.shape[1] * dmax.shape[2], -1)
        dx = self.col2im(dcol, self.x.shape, self.pool_h, self.pool_w, self.stride, self.padding)
        return dx

    def im2col(self, input_data, conv_h, conv_w, stride=1, padding=0):
        """

        :param input_data: N x C x H x W
        :param conv_h: 卷积核的高
        :param conv_w: 卷积核的长
        :param stride: 步幅
        :param padding: 填充
        :return: col 2维数据
        """
        N, C, H, W = input_data.shape
        out_h = (H + 2 * padding - conv_h) // stride + 1
        out_w = (W + 2 * padding - conv_w) // stride + 1

        img = np.pad(input_data, [(0, 0), (0, 0), (padding, padding), (padding, padding)], "constant")
        col = np.zeros(N, C, conv_h, conv_w, out_h, out_w)
        for y in range(conv_h):
            y_max = y + stride * out_h
            for x in range(conv_w):
                x_max = x + stride * out_w
                col[:, :, y, x, :, :] = img[:, :, y:y_max:stride, x:x_max:stride]
        col = col.transpose(0, 4, 5, 1, 2, 3).reshape(N * out_h * out_w, -1)
        return col

    def col2im(self, col, input_shape, conv_h, conv_w, stride=1, padding=0):
        """

        :param col:
        :param input_shape: 输入数据形式 例如:(10, 1, 28, 28)
        :param conv_h:
        :param conv_w:
        :param stride:
        :param padding:
        :return:
        """
        N, C, H, W = input_shape
        out_h = (H + 2 * padding - conv_h) // stride + 1
        out_w = (W + 2 * padding - conv_w) // stride + 1

        col = np.zeros(N, out_h, out_w, C, conv_h, conv_w).transpose(0, 3, 4, 5, 1, 2)

        img = np.zeros((N, C, H + 2 * padding + stride - 1, W + 2 * padding + stride - 1))
        for y in range(conv_h):
            y_max = y + stride * out_h
            for x in range(conv_w):
                x_max = x + stride * out_h
                img[:, :, y:y_max:stride, x:x_max:stride] += col[:, :, y, x, :, :]

        return img[:, :, padding:H + padding, padding:W + padding]


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

L☆★

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值