我有一个现有的分类模型,使用theano.tensor.nnet下的theano' conv2d进行训练。现在我必须使用这个模型在Java中进行某种预测。
我在Python中实现了一个简单的卷积(最后,我将用Java编写代码),根据一些文档(https://developer.apple.com/Library/ios/documentation/Performance/Conceptual/vImage/ConvolutionOperations/ConvolutionOperations.html)。例如,对于2 * 2内核(k11,k12,k21,k22),内核下的一个区域是(a11,a12,a21,a22)。卷积由a11 * k11 + a12 * k12 + a21 * k21 + a22 * k22执行。
不幸的是,当我用一些虚拟矩阵和内核测试我的卷积码和theano的转码时,它们给出了不同的结果。只有在极少数情况下,它们才会给出相同的结果。
在我看来,卷积算法有很多变种,我必须实现与theano的ConvOp使用的完全相同的卷积算法。但是,我找不到任何描述theano的Conv2d算法的材料。
你能解释一下theano的conv2d算法吗?
以下是我的卷积python代码:
def convolution(img_arr, kernel):
h, w = img_arr.shape
k = len(kernel)
k_flat = kernel.flatten()
neww = w - len(kernel) + 1
newh = h - len(kernel) + 1
after = np.zeros((newh, neww))
for i in range(neww):
for j in range(newh):
after[j,i] = (img_arr[j:j+k,i:i+k].flatten()*k_flat).sum()
return after
答案 0 :(得分:3)
Theano卷积与scipy.signal.convolve2d
完全相同。这被利用/测试,例如here。要获得自包含,请尝试复制+粘贴:
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()))
输出
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
由于scipy实现了标准卷积,theano也是如此。
答案 1 :(得分:1)
其实你和(Theano,Scripy)都没问题。原因是:你正在使用不同的卷积2D。 Theano和Script使用Math中定义的convolution2D来旋转内核。但你没有(参考:http://www.songho.ca/dsp/convolution/convolution.html#convolution_2d)。 如果您的内核是这样的话:
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
而不是将其改为(中心对称):
[9, 8, 7]
[6, 5, 4]
[3, 2, 1]
因此,使用您的方法将获得与Theano / Scripy
相同的答案