思路:

采用纯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()