2014-09-02 2 views
0

theano.tensor.nnet에서 theano의 conv2d를 사용하여 학습 한 기존 분류 모델이 있습니다. 이제 Java에서 일종의 예측을 수행하기 위해이 모델을 사용해야합니다.은 theano의 conv2d에서와 똑같은 컨볼 루션을 수행합니다.

나는 약간의 문서 (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의 conv 코드를 테스트 할 때 다른 결과가 나타납니다. 드문 경우지만, 같은 결과를줍니다.

convolution 알고리즘에는 많은 변형이 있으며 theano의 ConvOp에서 사용 된 것과 동일한 정확한 회선 알고리즘을 구현해야합니다. 그러나, 나는 theano의 Conv2d 알고리즘을 설명하는 자료를 찾을 수 없습니다.

theano의 conv2d 알고리즘에 대해 조금 설명해 주시겠습니까?

다음은 회선 내 파이썬 코드 :

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

는 것 같다 벤더에 대한 질문. vImage의 회선을 재교육 할 수 있습니까? 특히 정수 이미지의 경우 결과가 잘 정의되어 있습니다. –

답변

3

Theano의 회선이 scipy.signal.convolve2d와 똑같은 일을한다. 예 : 악용/테스트되었습니다. here. 자기 containedness를 들어, 붙여 넣기 + 복사하려고 :

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 않습니다.

+0

당신의 구현에 관해서는, 당신이 교차 상관을 계산하는 것처럼 보이며, 회선은 아닙니다. 코드에서'k_flat = kernel [:: - 1, :: - 1] .flatten()'을 시도하십시오. – eickenberg

+0

씨앗 42, 네가 그곳에서 한 짓을 본다. – kaufmanu

1

실제로 당신과 (Theano, Scripy) 괜찮습니다. 그 이유는 당신이 다른 회선을 사용하고 있기 때문입니다. Theano와 Script는 Math에 정의 된 convolution2D를 사용하여 커널을 회전시켜야합니다. 그러나 당신은하지 않았다 (ref : http://www.songho.ca/dsp/convolution/convolution.html#convolution_2d). 가 SO 커널이 같은 경우 :

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

(중앙 대칭)로 변경보다 :

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

그래서 Theano 같은 대답을 얻을 것이다 방법을 사용하여/Scripy

관련 문제