from mxnet import gluon, init, nd
from mxnet.gluon import nn
X = nd.array([[[1,2,0],[1,1,3],[0,2,2]],[[0,2,1],[0,3,2],[1,1,0]],
[[1,2,1],[0,1,3],[3,3,2]]])
X = X.reshape((1,3,3,3))
X
[[[[1. 2. 0.]
[1. 1. 3.]
[0. 2. 2.]]
[[0. 2. 1.]
[0. 3. 2.]
[1. 1. 0.]]
[[1. 2. 1.]
[0. 1. 3.]
[3. 3. 2.]]]]
<NDArray 1x3x3x3 @cpu(0)>
K = nd.array([[[1,1],[2,2]],[[1,1],[1,1]],[[0,1],[1,0]]])
K = K.reshape((1,3,2,2))
conv = nn.Conv2D(channels=1, kernel_size=2)
conv.initialize(init = init.Constant(K))
conv(X)
[[[[14. 20.]
[15. 24.]]]]
<NDArray 1x1x2x2 @cpu(0)>
K[0][0].flatten()
[[1. 1.]
[2. 2.]]
<NDArray 2x2 @cpu(0)>
首先把核函数展开为12 * 1
W_k = nd.concat(K[0][0][0],K[0][0][1],K[0][1][0],K[0][1][1],K[0][2][0],K[0][2][1],
dim = 0)
W_k = W_k.reshape((W_k.size, 1))
W_k
[[1.]
[1.]
[2.]
[2.]
[1.]
[1.]
[1.]
[1.]
[0.]
[1.]
[1.]
[0.]]
<NDArray 12x1 @cpu(0)>
然后把输入展开为4 * 12:
X[:,:,0:2,0:2], X[:,:,0:2,1:3]
(
[[[[1. 2.]
[1. 1.]]
[[0. 2.]
[0. 3.]]
[[1. 2.]
[0. 1.]]]]
<NDArray 1x3x2x2 @cpu(0)>,
[[[[2. 0.]
[1. 3.]]
[[2. 1.]
[3. 2.]]
[[2. 1.]
[1. 3.]]]]
<NDArray 1x3x2x2 @cpu(0)>)
X[:,:,0:2,0:2].reshape((1,X[:,:,0:2,0:2].size))
[[1. 2. 1. 1. 0. 2. 0. 3. 1. 2. 0. 1.]]
<NDArray 1x12 @cpu(0)>
X_k = nd.concat(X[:,:,0:2,0:2].reshape((1,12)), X[:,:,0:2,1:3].reshape((1,12)),
X[:,:,1:3,0:2].reshape((1,12)), X[:,:,1:3,1:3].reshape((1,12)),
dim=0)
X_k
[[1. 2. 1. 1. 0. 2. 0. 3. 1. 2. 0. 1.]
[2. 0. 1. 3. 2. 1. 3. 2. 2. 1. 1. 3.]
[1. 1. 0. 2. 0. 3. 1. 1. 0. 1. 3. 3.]
[1. 3. 2. 2. 3. 2. 1. 0. 1. 3. 3. 2.]]
<NDArray 4x12 @cpu(0)>
计算矩阵乘法:
nd.dot(X_k,W_k).reshape((1,1,2,2))
[[[[14. 20.]
[15. 24.]]]]
<NDArray 1x1x2x2 @cpu(0)>
和之前卷积层计算的一样