2017-04-02 191 views
1

我已经为这个问题写了下面的代码,其中有两个卷积层(简称Conv1和Conv2),并且我想绘制每个图层的所有输出(它是独立的)。 Conv1的一切都很好,但我错过了关于Conv2的一些事情。Keras卷积层输出的可视化

我正在向Conv1提供一个1x1x25x25(num图像,num通道,高度,宽度(我的约定,TF或Theano惯例))图像,它有四个5x5滤镜。这意味着它的输出形状是4x1x1x25x25(num filters,num images,num channels,height,width),产生4个图。

现在,这个输出被送到具有6个3x3滤波器的Conv1。因此,Conv2的输出应该是6x(4x1x1x25x25),但它不是!它相当于6x1x1x25x25。这意味着,只有6个地块而不是6x4,但为什么?以下功能也打印每个输出的形状,它们是

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

而应该是

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

,对吗?

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) 

回答

0

卷积层的输出被捆绑为一个图像与多个通道。这些可以被认为是特征通道,与色彩通道相反。例如,如果卷积图层具有F数量的过滤器,则无论输入图像具有多少(颜色或特征)通道,它都将输出具有F通道数量的图像。这就是Conv2生成6个特征地图而不是6x4的原因。 更详细地说,卷积滤波器将对所有输入通道进行卷积,卷积的线性组合将被馈送到其激活函数。

+0

如果您知道任何参考资料,请分享。 – Miladiouss