1.定义
1×1卷积层就是卷积窗口形状为1×1(kh=kw=1)的多通道卷积层.
由于使用了最小窗口,1×1卷积层失去了卷积层可以识别高和宽维度上相邻元素构成的模式的功能.
1×1卷积层主要计算发生在通道维上.
1×1卷积层的输入数据和输出数据具有相同的高和宽.
输出数据中的每个元素来自输入数据中在高和宽上相同位置的元素在不同通道之间的按权重累加.
假设我们将通道维当做特征维,将高和宽维度上的元素当成数据样本,那么1×1卷积层的作用与全连接层等价.--NiN网络.
image.png
from mxnet import nd
def corr2d(X, K):
"""Compute 2D cross-correlation."""
h, w = K.shape
Y = nd.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
def corr2d_multi_in(X, K):
# 首先沿着X和K的第0维(通道维)遍历
# 然后使用*将结果列表变成add_n函数的位置参数(positional argument)来进行相加
return nd.add_n(*[corr2d(x,k) for x, k in zip(X, K)])
def corr2d_multi_in_out(X, K):
# 对K的第0维遍历,
# 每次同输入X做互相关计算,所有结果使用stack函数合并在一起.
return nd.stack(*[corr2d_multi_in(X, k) for k in K])
def corr2d_multi_in_out_11(X,K):
c_i, h, w = X.shape
c_o = K.shape[0]
# 通道为当成特征维
# 将高和宽上的元素当成数据样本
X = X.reshape((c_i,h*w))
K = K.reshape((c_o,c_i))
Y = nd.dot(K,X) #全连接层的矩阵乘法
return Y.reshape((c_o, h, w))
if __name__ == "__main__":
# # 2通道输入数据
# X = nd.array([[[0, 1, 2],[3, 4, 5],[6, 7, 8]],
# [[1, 2, 3],[4, 5, 6],[7, 8, 9]]])
# K = nd.array([[[0,1],[2,3]],[[1,2],[3,4]]])
# K = nd.stack(K, K+1, K+2)
# # 3输出通道,2输入通道,2行2列
# print(K.shape)
# # 卷积层的多通道输出
# # 每个输出通道上的结果由卷积核在该输出通道上的核数组与整个输入数组计算而来
# print(corr2d_multi_in_out(X, K))
X = nd.random.uniform(shape=(3,3,3))
K = nd.random.uniform(shape=(2,3,1,1))
Y1 = corr2d_multi_in_out_11(X,K)
Y2 = corr2d_multi_in_out(X,K)
print((Y1-Y2).norm().asscalar() <1e-6)
结果True
参考:
动手学深度学习第5.4章节
网友评论