我正在使用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实现中实现引导的反向传播。