用 Numpy 手动实现矩阵卷积运算
卷积神经网络(CNN)的核心是卷积运算,但很多人对其原理一知半解。今天我用 Numpy 手动实现一个简单的矩阵卷积,带你直观理解 CNN 的核心操作!
🌰 举个栗子
我们用一个 5×5 的输入矩阵(模拟灰度图像)和一个 3×3 的垂直边缘检测卷积核,看看会发生什么:
输入矩阵(中间有一条竖线):
input_matrix = np.array([ [0, 0, 255, 0, 0], [0, 0, 255, 0, 0], [0, 0, 255, 0, 0], [0, 0, 255, 0, 0], [0, 0, 255, 0, 0] ], dtype=np.float32) |
垂直边缘检测卷积核:
kernel = np.array([ [-1, 0, 1], [-1, 0, 1], [-1, 0, 1] ], dtype=np.float32) |
🚀 手动实现卷积运算
关键代码来了!通过两层循环实现卷积核的滑动和点积运算:
def convolution(input_mat, kernel): input_h, input_w = input_mat.shape kernel_h, kernel_w = kernel.shape output_h = input_h - kernel_h + 1 output_w = input_w - kernel_w + 1 output_mat = np.zeros((output_h, output_w), dtype=np.float32)
# 核心:滑动窗口与点积运算 for i in range(output_h): for j in range(output_w): window = input_mat[i:i+kernel_h, j:j+kernel_w] output_mat[i, j] = np.sum(window * kernel) return output_mat |
🌟 运行结果
卷积后的输出矩阵:
[[ 0. 765. 0.] [ 0. 765. 0.] [ 0. 765. 0.]] |
可以看到,中间一列的值为 765(255×3),其他位置为 0。这说明卷积核成功检测到了垂直边缘!
🧠 核心原理解析
- 滑动窗口机制:卷积核在输入矩阵上滑动,每次覆盖一个局部区域
- 点积运算:窗口内元素与卷积核权重相乘后求和,得到输出值
- 特征提取:卷积核的权重决定了它对特定特征的敏感性(如垂直边缘)
通过这个简单的例子,你可以直观理解 CNN 是如何通过卷积运算提取图像特征的。实际的 CNN 会有更多卷积核,提取更复杂的特征,但基本原理是一样的!