执行完全相同的卷积在theano的conv2d卷积、完全相同、conv2d、theano

2023-09-12 21:25:07 作者:反差帅

我有一个用下theano.tensor.nnet theano的conv2d训练有素的现有分类模型。现在我已经使用这个模型做某种prediction在Java中。

我在Python中实现一个简单的卷积(在最后,我将$ C C $它在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。

不幸的是,测试我卷积code和theano的转化率code有一些虚拟矩阵和内核,他们给不同的结果。只有在极少数情况下,他们给相同的结果。

在我看来,有卷积算法有很多变种,而我所使用的theano的ConvOp实行完全相同的卷积算法。但是,我找不到任何材料描述theano的Conv2d算法。

你能不能解释一下有关theano的conv2d算法?

以下是我的Python code卷积:

 高清卷积(img_arr,内核):
    H; W = img_arr.shape
    K = LEN(内核)
    k_flat = kernel.flatten()
    东西方妇女网络= W  -​​  LEN(内核)+ 1
    newh = H  -  LEN(内核)+ 1
    后= np.zeros((newh,东西方妇女网络))
    因为我在范围内(东西方妇女网络):
        对于j的范围(newh):
            之后[J,I] =(img_arr [J:J + K,I:I + K] .flatten()* k_flat).SUM()
    后返回
 

解决方案

Theano卷积不完全一样的东西作为 scipy.signal.convolve2d 。这是开发/测试,例如此处。对于自足,试图复制+粘贴:

 进口numpy的为NP
从scipy.signal进口convolve2d
进口theano
进口theano.tensor为T

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

IMG = T.tensor4()
FIL = T.tensor4()

对于border_mode在[满,有效]:
    scipy_convolved = convolve2d(图像,conv_filter,模式= 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())
    打印差异%1.5E边境模式%的%(l2_discrepancy,border_mode)
    打印卷积规范:%1.5E,1.5E%%(
        np.linalg.norm(scipy_convolved.ravel()),
        np.linalg.norm(theano_convolved.ravel()))
 

它输出

 差异9.42469e-03的边界模式的全
卷积规范:1.65433e + 04,1.65440e + 04
差异9.03687e-03的边界模式下有效
卷积规范:1.55051e + 04,1.55054e + 04
 
CVPR 2019 PointConv 在点云上高效实现卷积操作

由于SciPy的实现了一个标准的卷积,所以不会theano。

I have an existing classification model that was trained using theano's conv2d under theano.tensor.nnet. Now I have to use this model to do some sort of prediction in Java.

I implement a simple convolution in Python(In the end, I will code it in Java) as per some documentation(https://developer.apple.com/Library/ios/documentation/Performance/Conceptual/vImage/ConvolutionOperations/ConvolutionOperations.html). For example, for a 2*2 kernel (k11,k12,k21,k22), one of the areas under the kernel is (a11,a12,a21,a22). The convolution is performed by a11*k11 + a12*k12 + a21*k21 + a22*k22.

Unfortunately, as I test my convolution code and theano's conv code with some dummy matrix and kernels, they give different results. Only in some rare cases, they give same results.

It seems to me that there are many variants of convolution algorithm and I have to implement the exact same convolution algorithm as used by theano's ConvOp. However, I can't find any material describing theano's Conv2d algorithm.

Could you explain a little bit about theano's conv2d algorithm?

The following is my python code for convolution:

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

解决方案

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.