2017-05-15 2 views
3

J'utilise le modèle Conv2D de Keras 2.0. Cependant, je ne peux pas entièrement comprendre ce que la fonction fait mathématiquement. J'essaie de comprendre les mathématiques en utilisant les données générées au hasard et un réseau très simple:Math derrière la fonction Conv2D dans Keras

import numpy as np 
import keras 
from keras.layers import Input, Conv2D 
from keras.models import Model 
from keras import backend as K 

# create the model 
inputs = Input(shape=(10,10,1)) # 1 channel, 10x10 image 
outputs = Conv2D(32, (3, 3), activation='relu', name='block1_conv1')(inputs) 
model = Model(outputs=outputs, inputs=inputs) 

# input 
x = np.random.random(100).reshape((10,10)) 

# predicted output for x 
y_pred = model.predict(x.reshape((1,10,10,1))) # y_pred.shape = (1,8,8,32) 

J'ai essayé de calculer, par exemple, la valeur de la première ligne, la première colonne de la première carte de fonction, suite à la démonstration au here.

w = model.layers[1].get_weights()[0] # w.shape = (3,3,1,32) 
w0 = w[:,:,0,0] 
b = model.layers[1].get_weights()[1] # b.shape = (32,) 
b0 = b[0] # b0 = 0 

y_pred_000 = np.sum(x[0:3,0:3] * w0) + b0 

Mais relu(y_pred_000) n'est pas égal à y_pred[0][0][0][0]. Est-ce que quelqu'un pourrait indiquer ce qui ne va pas avec ma compréhension? Je vous remercie.

+0

Quels sont les résultats que vous obtenez lorsque je courais votre code je reçois 'y_pred_000 = 0.14973172296210166' et' y_pred [0] [0] [0] [? 0] = 0.14973173' qui semble assez proche – sietschie

+0

Merci pour votre commentaire. ts j'ai eu (sur Windows 10, python 2.7, K.backend() == theano) était 'y_pred_000 = 0.091446961680955799' et' y_pred [0] [0] [0] [0] = 0.033766586'. Mais après avoir changé le back-end en tensorflow (python 3.5, K.backend() == tensorflow), les deux résultats étaient les mêmes! ('y_pred_000 = 0.025001197995700348' et 'y_pred [0] [0] [0] [0] = 0.025001198') Je suppose que c'est un problème spécifique à theano ou à python2. – hikaru

Répondre

2

C'est facile et cela vient de Theano dim ordre. Le résultat de l'application du filtre est stocké dans une dimension appelée channel. Dans le cas de TensorFlow c'est la dernière dimension et c'est pourquoi les résultats sont bons. En cas de Theano il est deuxième dimension (résultat de convolution a une forme (cases, channels, width, height) ainsi afin de résoudre votre problème, vous devez changer de ligne de prédiction:

y_pred = model.predict(x.reshape((1,1,10,10))) 

vous devez également modifier la façon dont vous obtenez les poids comme poids dans Theano a une forme (output_channels, input_channels, width, height) vous devez changer le getter de poids:

w = model.layers[1].get_weights()[0] # w.shape = (32,1,3,3) 
w0 = w[0,0,:,:] 
+0

Merci pour votre commentaire. J'ai modifié le code comme vous l'avez dit, mais j'ai eu l'erreur: 'ValueError: Erreur lors de la vérification: input_8 attendu pour avoir la forme (None, 10, 10, 1) mais got array with shape (1L, 1L, 10L, 10L) Je suppose que la 'shape' de' Input' ne correspond pas à la forme de l'entrée remodelée. Comment dois-je modifier le code? (Dans mon .keras.keras.json, '" image_data_format ":" channels_last "') – hikaru

+0

Ok - alors laissez la ligne de prédiction comme il était et essayez seulement le deuxième changement. Comment ça marche alors? –

+0

Encore une fois j'ai eu l'erreur: 'ValueError: les opérandes ne pouvaient pas être diffusés avec des formes (3,3) (1,32)'. La forme de 'w [0,0,:,:]' est '(1,32)', donc ce n'est pas un noyau. – hikaru