卷积神经网络是含有卷积层(convolutional layer)的神经网络。本章中卷积神经网络均使用最常见的二维卷积层。它有高和宽两个空间维度,常用来处理图像数据,我们将介绍简单形式的二维卷积层的工作原理。
import numpy as np
from copy import deepcopy
def corr2d(X, K):
'''
2D 卷积运算(实际是互相关)
'''
h, w = K.shape
Y = np.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))
for i in range(Y.shape[0]):
for j in range(Y.shape[1]):
Y[i, j] = (X[i: i + h, j: j + w] * K).sum()
return Y
我们可以构造输入数组 、核数组 来验证二维互相关运算的输出:
X = np.array([[7, 1, 4, 3], [3, 9, 5, 1], [5, 1, 8, 9], [7, 9, 3, 1]])
K = np.array([[7, 1], [2, 3]])
corr2d(X, K)
array([[83., 44., 44.],
[43., 94., 79.],
[77., 42., 74.]])
为了提高运算速度,我们可用矩阵乘法来计算卷积:
矩阵乘法来计算卷积
class Exchange:
def exchangeTwo(self, L, i=0, j=-1):
'''
交换列表中的元素顺序
'''
L[i], L[j] = L[j], L[i]
def loopInterchange(self, L, offset=0):
'''
循环列表
'''
n = len(L)
assert offset < n
for i in range(n):
self.exchangeTwo(L, offset, i)
def corr2d(self, X, K):
'''
使用矩阵乘法计算 2D 卷积
'''
X_ = X.flatten()
h, w = K.shape
A = np.zeros_like(X)
A[:w, :h] = K
A_ = A.flatten().tolist()
h_ = X.shape[0] - h + 1
w_ = X.shape[1] - w+1
L = deepcopy(A_)
M = []
for i in range(w_):
for j in range(w_):
M.append(deepcopy(L))
self.loopInterchange(L)
continue
self.loopInterchange(L)
Y = np.dot(np.array(M), X_)
Y_ = Y.reshape((h_, w_))
return Y_
ex = Exchange()
ex.corr2d(X, K)
array([[83, 44, 44],
[43, 94, 79],
[77, 42, 74]])
这种计算方式是 caffe 的实现方式。
在频域计算卷积
公式
大体是通过 FFT 转换到频域做乘法,然后再变换回去得到卷积后的结果。Torch、Theano 和 cudnn 使用的卷积计算方式。
网友评论