Python 使用Keras中的非零梯度计算感受野时出错

Python 使用Keras中的非零梯度计算感受野时出错,python,keras,Python,Keras,我试图根据非零梯度计算一些特定神经元的感受野,但发现了一件奇怪的事情 以下是在keras中构建的简单NN模型。剩下的部分是计算conv2d_4 w.r.t其输入的输出梯度(此处为目标神经元,其pos在第一个通道上为(0,2))。通过在梯度图上寻找这些非零值,我们可以很容易地定位一个神经元的感受野。conv2d_4 w.r.t输出中一个神经元的理想感受野其输入应为3x3,因为conv2d_4的内核大小为3x3,但非零梯度图为4x5面片(由f_和中的真值给出) import numpy as np

我试图根据非零梯度计算一些特定神经元的感受野,但发现了一件奇怪的事情

以下是在keras中构建的简单NN模型。剩下的部分是计算conv2d_4 w.r.t其输入的输出梯度(此处为目标神经元,其pos在第一个通道上为(0,2))。通过在梯度图上寻找这些非零值,我们可以很容易地定位一个神经元的感受野。conv2d_4 w.r.t输出中一个神经元的理想感受野其输入应为3x3,因为conv2d_4的内核大小为3x3,但非零梯度图为4x5面片(由f_和中的真值给出)

import numpy as np
import keras.backend as K
import matplotlib.pyplot as plt
from keras.models import load_model, Model
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D,Input, AveragePooling2D, Lambda

def model_build_func(input_shape=(25,25,1)):
    inp = Input(shape=input_shape, name='input')

    x = Conv2D(32, (3,3), activation='linear', name='conv2d_1')(inp)
    x = Conv2D(32, (3,3), activation='linear', name='conv2d_2')(x)
    x = AveragePooling2D(pool_size=(2,2))(x)

    x = Conv2D(64, (3,3), activation='linear', name='conv2d_3')(x)
    x = Conv2D(64, (3,3), activation='linear', name='conv2d_4')(x)
    x = AveragePooling2D(pool_size=(2,2))(x)

    x = Flatten()(x)
    x = Dense(units=64, name='dense_1')(x)
    x = Dense(units=2, name='dense_2')(x)

    model = Model(inputs=inp, outputs=x)
    return model

# used for building the Lambda layer
def get_mask_tensor(input_tensors, x_pos, y_pos, channel_idx):
    mask_tensor = K.tf.gradients(input_tensors[0][:,x_pos,y_pos,channel_idx], input_tensors[1])[0]
    return mask_tensor

#specify the position of the neuron that we want to compute the RF
x_pos = 0
y_pos = 2
channel_idx = 0

layer_idx = 5 # the layer: conv2d_4

model = model_build_func()
current_layer = model.layers[layer_idx]

#get the gradient tensor
mask_tensor = Lambda(get_mask_tensor, output_shape=K.int_shape(model.input),
                     arguments={'x_pos':x_pos, 'y_pos':y_pos, 'channel_idx':channel_idx})([current_layer.output, current_layer.input])

#create a keras model
new_model = Model(inputs=[model.input], outputs=[mask_tensor])

#get the value of the gradient map
gradient_map = new_model.predict(0.1*(np.random.random(size=(32,25,25,1))-0.05))
f_sum = np.sum(np.abs(gradient_map), axis=-1)
f_sum = np.sum(np.abs(f_sum), axis=0)

#f_sum is a binary array. 
#It should has a 3x3 patch with TRUE values, but here it's 4x5
plt.imshow(f_sum!=0)
plt.grid()
plt.show()