python:4维数据最大池化及卷积自定义函数实现

#不断修改,减少对numpy的依赖,尽量底层#

最大池化

第一次定义

import numpy as np
import tensorflow as tf#测试使用
def max_pooling(x, pooling, strides=(2, 2), padding=(0, 0)):
    """
    最大池化前向过程
    :param x: 卷积层矩阵,形状(N,C,H,W),N为batch_size,C为通道数
    :param pooling: 池化大小(k1,k2)
    :param strides: 步长 参数可改
    :param padding: 0填充  参数可改
    #28/2=0>pad=0
    :return:
    """
    N, H, W, C = x.shape

    # 零填充
    #如((1,2),(2,2)),表示在第一个维度上水平方向上padding=1,垂直方向上padding=2,在第二个维度上水平方向上padding=2,垂直方向上padding=2。如果直接输入一个整数,则说明各个维度和各个方向所填补的长度都一样。
    padding_z = np.pad(x, ((0, 0), (padding[0], padding[0]), (padding[1], padding[1]), (0, 0)), 'constant',
                       constant_values=0)

    # 输出的高度和宽度
    out_h = (H + 2 * padding[0] - pooling[0]) // strides[0] + 1
    out_w = (W + 2 * padding[1] - pooling[1]) // strides[1] + 1

    pool_z = np.zeros((N, out_h, out_w, C))

    for n in np.arange(N):
        for c in np.arange(C):
            for i in np.arange(out_h):
                for j in np.arange(out_w):
                    pool_z[n, i, j, c] = np.max(padding_z[n, strides[0] * i:strides[0] * i + pooling[0],
                                                strides[1] * j:strides[1] * j + pooling[1], c])
    return pool_z  # N,H, W, C

第二次定义

import numpy as np
def max_pooling(x, pooling, strides=2, padding=0):
    """
    最大池化前向过程
    :param x: 卷积层矩阵,形状(N,C,H,W),N为batch_size,C为通道数
    :param pooling: 池化大小(k1,k2)
    :param strides: 步长  参数可改,H与W步长不一致可参考第一次strides表示
    :param padding: 0填充  参数可改 H与W填充不一致可参考第一次pad表示
    #28/2=0>pad=0
    :return:
    """
    N, H, W, C = x.shape

    # 零填充
    #如((1,2),(2,2)),表示在第一个维度上水平方向上padding=1,垂直方向上padding=2,在第二个维度上水平方向上padding=2,垂直方向上padding=2。如果直接输入一个整数,则说明各个维度和各个方向所填补的长度都一样。
    #padding_z = np.pad(x, ((0, 0), (padding[0], padding[0]), (padding[1], padding[1]), (0, 0)), 'constant',constant_values=0)
    
    padding_z = np.zeros((N, H + 2 * padding, W + 2 * padding, C))  # 填充pad 后的维度
    padding_z[:, padding:padding + H, padding:padding + W, :] = x  # 填充pad 后的x
    
    

    # 输出的高度和宽度
    out_h = (H + 2 * padding - pooling) // strides + 1
    out_w = (W + 2 * padding - pooling) // strides + 1

    pool_z = np.zeros((N, out_h, out_w, C))
    max_z  = np.zeros((N, pooling, pooling, C))

    for n in range(N):
        for c in range(C):
            for i in range(out_h):
                for j in range(out_w):
                    for p in range(pooling):                      
                        for q in range(pooling):                        
                            max_z[n, p, q, c]=padding_z[n, strides * i + p, strides * j + q, c]       
                    pool_z[n, i, j, c] = np.max(max_z[n, : ,: , c])              #当用max求二维列表中最大值时,输出的结果是子列表首元素最大的那个列表
    return pool_z  # N,H, W, C

第三次定义

import numpy as np
def max_pooling(x, pooling, strides=2, padding=0):
    """
    最大池化前向过程
    :param x: 卷积层矩阵,形状(N,C,H,W),N为batch_size,C为通道数
    :param pooling: 池化大小(k1,k2)
    :param strides: 步长  参数可改 H与W步长不一致可参考第一次strides表示
    :param padding: 0填充 参数可改 H与W填充不一致可参考第一次pad表示
    #28/2=0>pad=0
    :return:
    """
    N, H, W, C = x.shape

    # 零填充
    #如((1,2),(2,2)),表示在第一个维度上水平方向上padding=1,垂直方向上padding=2,在第二个维度上水平方向上padding=2,垂直方向上padding=2。如果直接输入一个整数,则说明各个维度和各个方向所填补的长度都一样。
    #padding_z = np.pad(x, ((0, 0), (padding[0], padding[0]), (padding[1], padding[1]), (0, 0)), 'constant',constant_values=0)
    
    padding_z = np.zeros((N, H + 2 * padding, W + 2 * padding, C))  # 填充pad 后的维度
    padding_z[:, padding:padding + H, padding:padding + W, :] = x  # 填充pad 后的x
    
    

    # 输出的高度和宽度
    out_h = (H + 2 * padding - pooling) // strides + 1
    out_w = (W + 2 * padding - pooling) // strides + 1

    pool_z = np.zeros((N, out_h, out_w, C))#输出
    max_z  = np.zeros((N, pooling, pooling, C))#池化的值
    max_p = np.zeros((N,  1, C))#大小比较

    for n in range(N):
        for c in range(C):
            for i in range(out_h):
                for j in range(out_w):
                    for p in range(pooling):
                        max_p[n,: ,c]=padding_z[n, strides * i,  strides * j,  c]
                        for q in range(pooling):                        
                            max_z[n, p, q, c]=padding_z[n, strides * i + p, strides * j + q, c]
                            if  max_z[n, p, q, c] > max_p[n,:,c]:
                                max_p[n,:,c]=max_z[n, p, q, c]
                    pool_z[n, i, j, c] = max_p[n, : , c]
                    #pool_z[n, i, j, c] = np.max(max_z[n, : ,: , c])              #当用max求二维列表中最大值时,输出的结果是子列表首元素最大的那个列表
    return pool_z  # N,H, W, C
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

卷积

第一次

import numpy as np
import tensorflow as tf #测试使用
def conv2d(x, w, b, Stride, Pad):
    """
     输入包含N个数据,每个数据具有C个通道,高度H和宽度W.
     用F个不同的滤波器对每个输入进行卷积,每个滤波器跨越所有C通道,高度HH和宽度HH。
    - x: (N,H, W, C)
    - w:  (HH, WW,C,F)
    - b: (F,)
    - 'stride':移动步长
    - 'pad': 输入零填充的像素数
    - Output data:(N, F, H', W')
      H' = 1 + (H + 2 * pad - HH) // stride
      W' = 1 + (W + 2 * pad - WW) // stride
    """
    out = None
    N, H, W, C = x.shape  # N,H, W, C
    HH, WW, _, F = w.shape  # HH, WW, C,F

    Ho = 1 + (H + 2 * Pad - HH) // Stride  # 输出H
    Wo = 1 + (W + 2 * Pad - WW) // Stride  # 输出W

    x_pad = np.zeros((N, H + 2 * Pad, W + 2 * Pad, C))  # 填充pad 后的维度
    x_pad[:, Pad:Pad + H, Pad:Pad + W, :] = x  # 填充pad 后的x
    out = np.zeros((N, Ho, Wo, F))  # 输出

    for f in range(F):
        for i in range(Ho):
            for j in range(Wo):  # N*C*HH*WW, C*HH*WW = N*C*HH*WW, sum -> N*1
                out[:, i, j, f] = np.sum(x_pad[:, i * Stride: i * Stride + HH, j * Stride: j * Stride + WW, :] * w[:, :, :, f],axis=(1, 2, 3))#把axis对应的维度压缩相加
        out[:, :, :, f] += b[f]  # 加偏置
    return out  # N,H,W,F

第二次

import numpy as np
import tensorflow as tf #测试使用
def conv2d(x, w, b, Stride, Pad):
    """
     输入包含N个数据,每个数据具有C个通道,高度H和宽度W.
     用F个不同的滤波器对每个输入进行卷积,每个滤波器跨越所有C通道,高度HH和宽度HH。
    - x: (N,H, W, C,)
    - w:  (HH, WW,C,F)
    - b: (F,)
    - 'stride':移动步长
    - 'pad': 输入零填充的像素数
    - Output data:(N, F, H', W')
      H' = 1 + (H + 2 * pad - HH) // stride
      W' = 1 + (W + 2 * pad - WW) // stride
    """
    out = None
    N, H, W, C = x.shape  # N,H, W, C
    HH, WW, CC, F = w.shape  # HH, WW, C,F

    Ho = 1 + (H + 2 * Pad - HH) // Stride  # 输出H
    Wo = 1 + (W + 2 * Pad - WW) // Stride  # 输出W

    x_pad = np.zeros((N, H + 2 * Pad, W + 2 * Pad, C))  # 填充pad 后的维度
    x_pad[:, Pad:Pad + H, Pad:Pad + W, :] = x  # 填充pad 后的x
    
    kernel= np.zeros((N, HH, WW, CC))
    
    out = np.zeros((N, Ho, Wo, F))  # 输出

    for f in range(F):
        for i in range(Ho):
            for j in range(Wo):  # N*C*HH*WW, C*HH*WW = N*C*HH*WW, sum -> N*1
                for m in range(HH):
                    for n in range(WW):
                        kernel[:,m,n,:]=x_pad[:, i * Stride + m, j * Stride + n, :] * w[m, n, :,f]
                out[:,i,j,f]=np.sum(kernel[:,:,:,:], axis=(1, 2,3) ) #把axis对应的维压缩相加。             
        out[:, :, :, f] += b[f]  # 加偏置
    return out  # N,H,W,F

你可能感兴趣的:(深度学习与Python,python,卷积,深度学习,池化,numpy)