思路:
采用纯for循环加list实现
输入数据[[1,2,3],[1,2,3]]是2维的,相当h=2,w=3。
拿2维矩阵卷积来举例,具体思路就是先遍历h,再遍历w,卷积的方式选择是VALID,就是不足卷积核大小的数据就舍弃。
这里说一下VALID模式下输出矩阵大小的计算公式,【(H-K_h+1) / s】 ,这里【】代表向上取整,H代表输入大小,K_h代表卷积核大小,【9.5】等于10.。。。哈哈打不出向上取整的符号。
# 这些库仅做显示使用
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
def conv3(data, kernel, s):
channels = len(data)
rows = len(data[0])
cols = len(data[0][0])
H = len(kernel[0])
W = len(kernel[0][0])
res = []
for cha in range(channels):
lines = []
for r in range(0, rows-H+1, s):
line = []
for c in range(0, cols-W+1, s):
sums = 0
for h in range(H):
for w in range(W):
sums += data[cha][r+h][c+w] * kernel[cha][h][w]
line.append(sums)
lines.append(line)
res.append(lines)
return res
def conv2(data, kernel, s):
rows = len(data)
cols = len(data[0])
H = len(kernel)
W = len(kernel[0])
lines = []
for r in range(0, rows-H+1, s):
line = []
for c in range(0, cols-W+1, s):
sums = 0
for h in range(H):
for w in range(W):
sums += data[r+h][c+w] * kernel[h][w]
line.append(sums)
lines.append(line)
return lines
data = [
[1,1,1],
[0,0,0],
[1,1,1],
]
k_2 = [
[1,1],
[1,0]
]
k_3 = [
[1,1,1],
[1,0,1],
[1,1,1]
]
res = conv2(data, k_2, s=1)
# 这是针对2维矩阵的卷积
img = Image.open("/home/lfy/Pictures/eg_tulip.jpg")
gray = np.array(img.convert('L'))
res = conv2(gray, k_3, s=2)
res = np.array(res)
plt.figure()
plt.imshow(res)
plt.show()
# 这是针对3维矩阵的卷积
# img = Image.open("/home/lfy/Pictures/eg_tulip.jpg")
# img = np.array(img)
# img = img.transpose((2,0,1))
# res1 = conv3(img, [k_3, k_3, k_3])
# res1 = np.array(res1 )
# res1 = np.array(res1).transpose(1,2,0)
# plt.figure()
# plt.imshow(res1 )
# plt.show()