2017-04-02 5 views
1

J'ai écrit le code suivant pour cette question où il y a deux couches de convolution (Conv1 et Conv2 en abrégé) et je voudrais tracer toutes les sorties de chaque couche (c'est autonome). Tout va bien pour Conv1, mais il me manque quelque chose à propos de Conv2. J'alimente une image 1x1x25x25 (images num, canaux num, hauteur, largeur (mes conventions, ni convention TF ou Theano)) à Conv1 qui a quatre filtres 5x5. Cela signifie que sa forme de sortie est 4x1x1x25x25 (filtres num, images num, num canaux, hauteur, largeur), résultant en 4 graphiques.Visualisation des sorties de la couche de convolution Keras

Maintenant, cette sortie est envoyée à Conv1 qui a des filtres SIX 3x3. Par conséquent, la sortie de Conv2 devrait être 6x (4x1x1x25x25), mais ce n'est pas le cas! C'est plutôt 6x1x1x25x25. Cela signifie qu'il n'y a que 6 parcelles au lieu de 6x4, mais pourquoi? Les fonctions suivantes imprime également la forme de chaque sortie qu'ils sont

(1, 1, 25, 25, 4) 
------------------- 
(1, 1, 25, 25, 6) 
------------------- 

mais devraient être

(1, 1, 25, 25, 4) 
------------------- 
(1, 4, 25, 25, 6) 
------------------- 

droit?

import numpy as np 
#%matplotlib inline #for Jupyter ONLY 
import matplotlib.pyplot as plt 

from keras.models  import Sequential 
from keras.layers  import Conv2D 
from keras   import backend as K 

model = Sequential() 

# Conv1 
conv1_filter_size = 5 
model.add(Conv2D(nb_filter=4, nb_row=conv1_filter_size, nb_col=conv1_filter_size, 
       activation='relu', 
       border_mode='same', 
       input_shape=(25, 25, 1))) 

# Conv2 
conv2_filter_size = 3 
model.add(Conv2D(nb_filter=6, nb_row=conv2_filter_size, nb_col=conv2_filter_size, 
       activation='relu', 
       border_mode='same')) 

# The image to be sent through the model 
img = np.array([ 
[[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.]], 
[[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.]], 
[[1.],[1.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[1.],[1.],[1.],[1.],[1.],[1.],[1.]], 
[[1.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[0.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[0.],[0.],[1.],[1.],[1.],[1.],[1.]], 
[[1.],[1.],[1.],[1.],[0.],[0.],[0.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[0.],[1.],[1.],[1.],[1.]], 
[[1.],[1.],[1.],[1.],[0.],[0.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[0.],[1.],[1.],[1.]], 
[[1.],[1.],[1.],[0.],[0.],[1.],[1.],[1.],[0.],[0.],[0.],[1.],[1.],[1.],[0.],[0.],[0.],[1.],[1.],[1.],[0.],[0.],[1.],[1.],[1.]], 
[[1.],[1.],[0.],[0.],[1.],[1.],[1.],[0.],[0.],[0.],[0.],[0.],[1.],[0.],[0.],[0.],[0.],[0.],[1.],[1.],[1.],[0.],[0.],[1.],[1.]], 
[[1.],[1.],[0.],[0.],[1.],[1.],[1.],[0.],[0.],[0.],[0.],[0.],[1.],[0.],[0.],[0.],[0.],[0.],[1.],[1.],[1.],[1.],[0.],[1.],[1.]], 
[[1.],[0.],[0.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[0.],[1.],[1.],[1.],[0.],[0.],[0.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[1.]], 
[[1.],[0.],[0.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[1.]], 
[[1.],[0.],[0.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[1.]], 
[[1.],[0.],[0.],[1.],[1.],[1.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[1.],[1.],[1.],[0.],[0.],[1.]], 
[[1.],[0.],[0.],[1.],[1.],[1.],[0.],[0.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[1.],[1.],[1.],[0.],[0.],[1.]], 
[[1.],[0.],[0.],[1.],[1.],[1.],[0.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[0.],[1.],[1.],[1.],[0.],[0.],[1.]], 
[[1.],[0.],[0.],[1.],[1.],[1.],[0.],[0.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[1.],[1.],[1.],[0.],[0.],[1.]], 
[[1.],[1.],[0.],[1.],[1.],[1.],[1.],[0.],[0.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[0.],[1.],[1.],[1.],[0.],[1.],[1.]], 
[[1.],[1.],[0.],[0.],[1.],[1.],[1.],[0.],[0.],[0.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[0.],[1.],[1.],[1.],[0.],[0.],[1.],[1.]], 
[[1.],[1.],[1.],[0.],[0.],[1.],[1.],[1.],[1.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[1.],[1.],[1.],[0.],[0.],[1.],[1.],[1.]], 
[[1.],[1.],[1.],[0.],[0.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[0.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[1.],[1.],[1.]], 
[[1.],[1.],[1.],[1.],[0.],[0.],[0.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[0.],[1.],[1.],[1.],[1.]], 
[[1.],[1.],[1.],[1.],[1.],[0.],[0.],[0.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[0.],[1.],[1.],[1.],[1.],[1.]], 
[[1.],[1.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[1.],[1.],[1.],[1.],[1.],[1.],[1.]], 
[[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[0.],[0.],[0.],[0.],[0.],[0.],[0.],[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.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.],[1.]]]) 

def get_layer_outputs(image): 
    '''This function extracts the numerical output of each layer.''' 
    outputs = [layer.output for layer in model.layers] 
    comp_graph = [K.function([model.input] + [K.learning_phase()], [output]) for output in outputs] 

    # Feeding the image 
    layer_outputs_list = [op([[image]]) for op in comp_graph] 

    layer_outputs = [] 
    for layer_output in layer_outputs_list: 
     print(np.array(layer_output).shape, end='\n-------------------\n') 
     layer_outputs.append(layer_output[0][0]) 

    return layer_outputs 

def plot_layer_outputs(image, layer_number): 
    '''This function handels plotting of the layers''' 
    layer_outputs = get_layer_outputs(image) 

    x_max = layer_outputs[layer_number].shape[0] 
    y_max = layer_outputs[layer_number].shape[1] 
    n  = layer_outputs[layer_number].shape[2] 

    L = [] 
    for i in range(n): 
     L.append(np.zeros((x_max, y_max))) 

    for i in range(n): 
     for x in range(x_max): 
      for y in range(y_max): 
       L[i][x][y] = layer_outputs[layer_number][x][y][i] 


    for img in L: 
     plt.figure() 
     plt.imshow(img, interpolation='nearest') 

plot_layer_outputs(img, 1) 

Répondre

0

La sortie d'une couche de convolution est regroupée en une image avec plusieurs canaux. Ceux-ci pourraient être considérés comme des canaux de fonctionnalités, contrairement aux canaux de couleur. Par exemple, si une couche de convolution a un nombre de filtres de F, elle produira une image avec le nombre de canaux F, quel que soit le nombre de canaux (de couleur ou de caractéristique) de l'image d'entrée. C'est pourquoi Conv2 produit 6 cartes de caractéristiques plutôt que 6x4. Plus de détails, un filtre de convolution se convolve sur tous les canaux d'entrée et la combinaison linéaire de sa convolution serait alimentée à sa fonction d'activation.

+0

Si vous connaissez des références, s'il vous plaît partager. – Miladiouss