#不断修改,减少对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