Theano 中的卷积是否旋转过滤器?
Does convolution in Theano rotate the filters?
我有一个像这样的 3 通道 5×5 图像:
1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
还有一个像这样的 3 通道 3×3 滤波器:
10 20 30 0.1 0.2 0.3 1 2 3
40 50 60 0.4 0.5 0.6 4 5 6
70 80 90 0.7 0.8 0.9 7 8 9
当用过滤器对图像进行卷积时,我期待这样的输出:
369.6 514.8 316.8
435.6 594. 356.4
211.2 277.2 158.4
然而,Theano(使用 keras)给我这个输出:
158.4 277.2 211.2
356.4 594. 435.6
316.8 514.8 369.6
输出似乎旋转了 180 度,我想知道为什么会这样,我怎样才能得到正确的答案。这是我的测试代码:
def SimpleNet(weight_array,biases_array):
model = Sequential()
model.add(ZeroPadding2D(padding=(1,1),input_shape=(3,5,5)))
model.add(Convolution2D(1, 3, 3, weights=[weight_array,biases_array],border_mode='valid',subsample=(2,2)))
return model
im = np.asarray([
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
2,2,2,2,2,
2,2,2,2,2,
2,2,2,2,2,
2,2,2,2,2,
2,2,2,2,2,
3,3,3,3,3,
3,3,3,3,3,
3,3,3,3,3,
3,3,3,3,3,
3,3,3,3,3])
weight_array = np.asarray([
10,20,30,
40,50,60,
70,80,90,
0.1,0.2,0.3,
0.4,0.5,0.6,
0.7,0.8,0.9,
1,2,3,
4,5,6,
7,8,9])
im = np.reshape(im,[1,3,5,5])
weight_array = np.reshape(weight_array,[1,3,3,3])
biases_array = np.zeros(1)
model = SimpleNet(weight_array,biases_array)
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(optimizer=sgd, loss='categorical_crossentropy')
out = model.predict(im)
print out.shape
print out
这是卷积的定义。它的优点是,如果您对仅由零组成的图像进行卷积,但某处只有一个 1,则卷积会将过滤器的副本放置在该位置。
Theano 完全按照数学定义执行这些卷积。这意味着在对图像块进行点积之前翻转过滤器(操作是 filter[:, :, ::-1, ::-1]
)。请注意,这些不是旋转 180 度,至少不是一般情况。
看来您要查找的是 cross-correlation,它在图像的每个点处使用 non-flipped 版本的过滤器进行点积。
另见 this answer,其中显示 theano.tensor.nnet.conv2d
与 scipy
对应部分完全相同。
我有一个像这样的 3 通道 5×5 图像:
1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
1 1 1 1 1 2 2 2 2 2 3 3 3 3 3
还有一个像这样的 3 通道 3×3 滤波器:
10 20 30 0.1 0.2 0.3 1 2 3
40 50 60 0.4 0.5 0.6 4 5 6
70 80 90 0.7 0.8 0.9 7 8 9
当用过滤器对图像进行卷积时,我期待这样的输出:
369.6 514.8 316.8
435.6 594. 356.4
211.2 277.2 158.4
然而,Theano(使用 keras)给我这个输出:
158.4 277.2 211.2
356.4 594. 435.6
316.8 514.8 369.6
输出似乎旋转了 180 度,我想知道为什么会这样,我怎样才能得到正确的答案。这是我的测试代码:
def SimpleNet(weight_array,biases_array):
model = Sequential()
model.add(ZeroPadding2D(padding=(1,1),input_shape=(3,5,5)))
model.add(Convolution2D(1, 3, 3, weights=[weight_array,biases_array],border_mode='valid',subsample=(2,2)))
return model
im = np.asarray([
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
1,1,1,1,1,
2,2,2,2,2,
2,2,2,2,2,
2,2,2,2,2,
2,2,2,2,2,
2,2,2,2,2,
3,3,3,3,3,
3,3,3,3,3,
3,3,3,3,3,
3,3,3,3,3,
3,3,3,3,3])
weight_array = np.asarray([
10,20,30,
40,50,60,
70,80,90,
0.1,0.2,0.3,
0.4,0.5,0.6,
0.7,0.8,0.9,
1,2,3,
4,5,6,
7,8,9])
im = np.reshape(im,[1,3,5,5])
weight_array = np.reshape(weight_array,[1,3,3,3])
biases_array = np.zeros(1)
model = SimpleNet(weight_array,biases_array)
sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(optimizer=sgd, loss='categorical_crossentropy')
out = model.predict(im)
print out.shape
print out
这是卷积的定义。它的优点是,如果您对仅由零组成的图像进行卷积,但某处只有一个 1,则卷积会将过滤器的副本放置在该位置。
Theano 完全按照数学定义执行这些卷积。这意味着在对图像块进行点积之前翻转过滤器(操作是 filter[:, :, ::-1, ::-1]
)。请注意,这些不是旋转 180 度,至少不是一般情况。
看来您要查找的是 cross-correlation,它在图像的每个点处使用 non-flipped 版本的过滤器进行点积。
另见 this answer,其中显示 theano.tensor.nnet.conv2d
与 scipy
对应部分完全相同。