替换Keras图层的BackPropagation功能

时间:2018-08-22 01:34:15

标签: python tensorflow machine-learning keras conv-neural-network

我正在使用yolo v3 keras implmementation,并希望添加一个guided backpropagation模块来进一步分析网络的行为。

在yolo.py文件中,我已添加此函数以尝试计算反向传播:

def propb_guided(self, image, layer_index):
    from tensorflow.python.ops import nn_ops, gen_nn_ops
    from tensorflow.python.framework import ops
    box_confidence = self.yolo_model.layers[layer_index].output[..., 4:5]
    box_class_probs = self.yolo_model.layers[layer_index].output[...,5:]

    #box_class_probs = tf.Print(box_class_probs, [tf.shape(box_class_probs)], message="box class probs")
    scores = tf.reduce_sum(box_class_probs[0] * box_confidence[0], axis=2)
    #scores = tf.contrib.layers.flatten(scores)
    print(self.yolo_model.input.get_shape(), "input blabal")
    scores = tf.Print(scores, [tf.shape(scores)], message="scores")
    #grads = tf.map_fn(lambda x: tf.gradients(x, image)[0], tf.contrib.layers.flatten(scores), dtype=tf.float32)
    # gradients are the 1,1,w,h,c shape, c = 3 because RGB

    grads = tf.reduce_mean(tf.gradients(scores, self.yolo_model.input)[0][0], axis=2)
    grads = tf.Print(grads, [tf.shape(grads)], message="grad shape")

    # prepare image for forward prop
    if self.model_image_size != (None, None):
        assert self.model_image_size[0]%32 == 0, 'Multiples of 32 required'
        assert self.model_image_size[1]%32 == 0, 'Multiples of 32 required'
        boxed_image = letterbox_image(image, tuple(reversed(self.model_image_size)))
    else:
        new_image_size = (image.width - (image.width % 32),
                          image.height - (image.height % 32))
        boxed_image = letterbox_image(image, new_image_size)
    image_data = np.array(boxed_image, dtype='float32')

    print(image_data.shape)
    image_data /= 255.
    image_data = np.expand_dims(image_data, 0)  # Add batch dimension.

    # replace all relu layers with guided relu:
    # TODO replacing backprop layers doesn't work. The gradient override map doesnt work in this case
    @ops.RegisterGradient("GuidedReluBP")
    def _GuidedReluGrad(op, grad):
        #return tf.where(0. < grad, gen_nn_ops.relu_grad(grad, op.outputs[0]), tf.zeros(tf.shape(grad)))
        return 100000000

    tf_graph = K.get_session().graph
    layers = [op.name for op in tf_graph.get_operations() if op.type=="Maximum"]
    print(layers, "layers are")
    with tf_graph.gradient_override_map({'Maximum': 'GuidedReluBP'}):

        activation = sess.run(grads, feed_dict={
            self.yolo_model.input: image_data,
            self.input_image_shape: [image.size[1], image.size[0]], 
            K.learning_phase(): 0})

        return activation

现在,该函数获取最后一层(形状(?,?,255)),并将第5个过滤器(框置信度)乘以类logits(过滤器6至80,称为box_class_probs)。然后将所有过滤器的乘积求和,并将其存储在分数张量中。

然后根据分数相对于某些输入图像计算每个像素的梯度,并将其存储在渐变中(渐变为tf.Print具有形状(416,416),即输入图像的宽度和高度)。 / p> 最后,

(注释为“用引导的relu替换所有relu层)”,我想获取所有泄漏的relu keras层,并替换其反向传播机制。我注意到,keras泄漏的relu层最后有一个“ maximum”操作,因此我尝试用我进行的指导relu操作替换每个maximise操作。虽然此方法不起作用。相反,无论我是否实现RegisterGradient代码,此函数返回的激活变量均无效。

如何替换某些keras图中每个泄漏的relu的反向传播机制?这样一来,我就可以在keras yolo v3实现中实现引导的反向传播。

0 个答案:

没有答案