2016-01-13 6 views
0

J'ai un 3 canaux 5 par 5 l'image comme ceci:Est-ce que la convolution dans Theano fait tourner les filtres?

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 

Et 3 canaux 3 par 3 filtre comme ceci:

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 

Lorsque convoluer l'image avec le filtre, je me attends à cette sortie:

369.6 514.8 316.8 
435.6 594. 356.4 
211.2 277.2 158.4 

Cependant, Théano (en utilisant keras) me donne cette sortie:

158.4 277.2 211.2 
356.4 594. 435.6 
316.8 514.8 369.6 

Il semble que la sortie est tournée de 180 degrés, je me demande pourquoi cela se produit et comment puis-je obtenir la bonne réponse. Voici mon code de test:

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 

Répondre

1

Ceci est la définition de la convolution. Il a l'avantage que si vous convolvez une image qui ne contient que des zéros sauf un seul, la convolution placera une copie du filtre à cette position. Theano fait exactement ces circonvolutions, tel que défini mathématiquement. Cela implique de retourner les filtres (l'opération est filter[:, :, ::-1, ::-1]) avant de prendre des produits scalaires avec les patchs d'image. Notez que ce ne sont pas des rotations de 180 degrés, du moins pas en général.

Il semble que ce que vous cherchez est la corrélation croisée, qui prend des produits dot avec les versions non retournées des filtres à chaque point de l'image.

Voir également this answer dans lequel theano.tensor.nnet.conv2d est montré pour faire exactement la même chose que la contrepartie scipy.

+0

Merci. Vous avez raison sur la corrélation croisée, c'est exactement ce que je cherche. J'ai résolu ce problème en inversant d'abord les poids. Par exemple, un poids dans un canal est inversé pour être [90,80,70,60,50,40,30,20,10], de cette façon il me donne la corrélation croisée. – Demonedge