perform the exact same convolution as in theano's conv2d

感情迁移 提交于 2019-12-01 11:59:35

Theano convolution does exactly the same thing as scipy.signal.convolve2d. This is exploited/tested e.g. here. For self-containedness, try copy+pasting:

import numpy as np
from scipy.signal import convolve2d
import theano
import theano.tensor as T

rng = np.random.RandomState(42)
image = rng.randn(500, 500).astype(np.float32)
conv_filter = rng.randn(32, 32).astype(np.float32)

img = T.tensor4()
fil = T.tensor4()

for border_mode in ["full", "valid"]:
    scipy_convolved = convolve2d(image, conv_filter, mode=border_mode)
    theano_convolve2d = theano.function([img, fil], T.nnet.conv2d(img, fil,
                                        border_mode=border_mode))
    theano_convolved = theano_convolve2d(image.reshape(1, 1, 500, 500),
                                         conv_filter.reshape(1, 1, 32, 32))
    l2_discrepancy = np.sqrt(((scipy_convolved - theano_convolved) ** 2).sum())
    print "Discrepancy %1.5e for border mode %s" % (l2_discrepancy, border_mode)
    print "Norms of convolutions: %1.5e, %1.5e" % (
        np.linalg.norm(scipy_convolved.ravel()),
        np.linalg.norm(theano_convolved.ravel()))

It outputs

Discrepancy 9.42469e-03 for border mode full
Norms of convolutions: 1.65433e+04, 1.65440e+04
Discrepancy 9.03687e-03 for border mode valid
Norms of convolutions: 1.55051e+04, 1.55054e+04

Since scipy implements a standard convolution, so does theano.

Actually you and the (Theano, Scripy) are all right. the reason is that: your are using the different convolution2D. the Theano and Script using the convolution2D defined in Math that should rotate the kernel. but you did not (ref: http://www.songho.ca/dsp/convolution/convolution.html#convolution_2d). SO if your kernel is like this:

[1, 2, 3]
[4, 5, 6]
[7, 8, 9]

than change it to (center symmetry):

[9, 8, 7]
[6, 5, 4]
[3, 2, 1]

So using your method will get the same answer as Theano/Scripy

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!