import tensorflow as tf from tensorflow.contrib import slim from nets import vgg from utils.rpn_msr.anchor_target_layer import anchor_target_layer as anchor_target_layer_py def mean_image_subtraction(images, means=[123.68, 116.78, 103.94]): num_channels = images.get_shape().as_list()[-1] if len(means) != num_channels: raise ValueError('len(means) must match the number of channels') channels = tf.split(axis=3, num_or_size_splits=num_channels, value=images) for i in range(num_channels): channels[i] -= means[i] return tf.concat(axis=3, values=channels) def make_var(name, shape, initializer=None): return tf.get_variable(name, shape, initializer=initializer) def Bilstm(net, input_channel, hidden_unit_num, output_channel, scope_name): # width--->time step with tf.variable_scope(scope_name) as scope: shape = tf.shape(net) N, H, W, C = shape[0], shape[1], shape[2], shape[3] net = tf.reshape(net, [N * H, W, C]) net.set_shape([None, None, input_channel]) lstm_fw_cell = tf.contrib.rnn.LSTMCell(hidden_unit_num, state_is_tuple=True) lstm_bw_cell = tf.contrib.rnn.LSTMCell(hidden_unit_num, state_is_tuple=True) lstm_out, last_state = tf.nn.bidirectional_dynamic_rnn(lstm_fw_cell, lstm_bw_cell, net, dtype=tf.float32) lstm_out = tf.concat(lstm_out, axis=-1) lstm_out = tf.reshape(lstm_out, [N * H * W, 2 * hidden_unit_num]) init_weights = tf.contrib.layers.variance_scaling_initializer(factor=0.01, mode='FAN_AVG', uniform=False) init_biases = tf.constant_initializer(0.0) weights = make_var('weights', [2 * hidden_unit_num, output_channel], init_weights) biases = make_var('biases', [output_channel], init_biases) outputs = tf.matmul(lstm_out, weights) + biases outputs = tf.reshape(outputs, [N, H, W, output_channel]) return outputs def lstm_fc(net, input_channel, output_channel, scope_name): with tf.variable_scope(scope_name) as scope: shape = tf.shape(net) N, H, W, C = shape[0], shape[1], shape[2], shape[3] net = tf.reshape(net, [N * H * W, C]) init_weights = tf.contrib.layers.variance_scaling_initializer(factor=0.01, mode='FAN_AVG', uniform=False) init_biases = tf.constant_initializer(0.0) weights = make_var('weights', [input_channel, output_channel], init_weights) biases = make_var('biases', [output_channel], init_biases) output = tf.matmul(net, weights) + biases output = tf.reshape(output, [N, H, W, output_channel]) return output def model(image,language):#改 image = mean_image_subtraction(image) with slim.arg_scope(vgg.vgg_arg_scope()): conv5_3 = vgg.vgg_16(image) rpn_conv = slim.conv2d(conv5_3, 512, 3) lstm_output = Bilstm(rpn_conv, 512, 128, 512, scope_name='BiLSTM') bbox_pred = lstm_fc(lstm_output, 512, 10 * 4, scope_name="bbox_pred") cls_pred = lstm_fc(lstm_output, 512, 10 * 3, scope_name="cls_pred")#改 # transpose: (1, H, W, A x d) -> (1, H, WxA, d) cls_pred_shape = tf.shape(cls_pred) cls_pred_reshape = tf.reshape(cls_pred, [cls_pred_shape[0], cls_pred_shape[1], -1, 3])#改 cls_pred_reshape_shape = tf.shape(cls_pred_reshape) cls_prob = tf.reshape(tf.nn.softmax(tf.reshape(cls_pred_reshape, [-1, cls_pred_reshape_shape[3]])), [-1, cls_pred_reshape_shape[1], cls_pred_reshape_shape[2], cls_pred_reshape_shape[3]], name="cls_prob") return bbox_pred, cls_pred, cls_prob def anchor_target_layer(cls_pred, bbox, im_info, scope_name): with tf.variable_scope(scope_name) as scope: # 'rpn_cls_score', 'gt_boxes', 'im_info' rpn_labels, rpn_bbox_targets, rpn_bbox_inside_weights, rpn_bbox_outside_weights = \ tf.py_func(anchor_target_layer_py, [cls_pred, bbox, im_info, [16, ], [16]], [tf.float32, tf.float32, tf.float32, tf.float32]) rpn_labels = tf.convert_to_tensor(tf.cast(rpn_labels, tf.int32), name='rpn_labels') rpn_bbox_targets = tf.convert_to_tensor(rpn_bbox_targets, name='rpn_bbox_targets') rpn_bbox_inside_weights = tf.convert_to_tensor(rpn_bbox_inside_weights, name='rpn_bbox_inside_weights') rpn_bbox_outside_weights = tf.convert_to_tensor(rpn_bbox_outside_weights, name='rpn_bbox_outside_weights') return [rpn_labels, rpn_bbox_targets, rpn_bbox_inside_weights, rpn_bbox_outside_weights] def smooth_l1_dist(deltas, sigma2=9.0, name='smooth_l1_dist'): with tf.name_scope(name=name) as scope: deltas_abs = tf.abs(deltas) smoothL1_sign = tf.cast(tf.less(deltas_abs, 1.0 / sigma2), tf.float32) return tf.square(deltas) * 0.5 * sigma2 * smoothL1_sign + \ (deltas_abs - 0.5 / sigma2) * tf.abs(smoothL1_sign - 1) def loss(bbox_pred, cls_pred, bbox, im_info): # rpn_labels : (HxWxA, 1), for each anchor, 0 denotes bg, 1 fg, -1 dontcare #rpn_bbox_targets: (HxWxA, 4), distances of the anchors to the gt_boxes(may contains some transform) # that are the regression objectives #rpn_bbox_inside_weights: (HxWxA, 4) weights of each boxes, mainly accepts hyper param in cfg #rpn_bbox_outside_weights: (HxWxA, 4) used to balance the fg/bg, # beacuse the numbers of bgs and fgs mays significiantly different rpn_data = anchor_target_layer(cls_pred, bbox, im_info, "anchor_target_layer")#改 # classification loss # transpose: (1, H, W, A x d) -> (1, H, WxA, d) cls_pred_shape = tf.shape(cls_pred) cls_pred_reshape = tf.reshape(cls_pred, [cls_pred_shape[0], cls_pred_shape[1], -1, 3])#改 rpn_cls_score = tf.reshape(cls_pred_reshape, [-1, 3])#改 rpn_label = tf.reshape(rpn_data[0], [-1]) # ignore_label(-1) fg_keep = tf.not_equal(rpn_label, -1)&tf.not_equal(rpn_label, 0)#改 rpn_keep = tf.where(tf.not_equal(rpn_label, -1)) rpn_cls_score = tf.gather(rpn_cls_score, rpn_keep) rpn_label = tf.gather(rpn_label, rpn_keep) rpn_cross_entropy_n = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=rpn_label, logits=rpn_cls_score) # box loss rpn_bbox_pred = bbox_pred rpn_bbox_targets = rpn_data[1] rpn_bbox_inside_weights = rpn_data[2] rpn_bbox_outside_weights = rpn_data[3] rpn_bbox_pred = tf.gather(tf.reshape(rpn_bbox_pred, [-1, 4]), rpn_keep) # shape (N, 4) rpn_bbox_targets = tf.gather(tf.reshape(rpn_bbox_targets, [-1, 4]), rpn_keep) rpn_bbox_inside_weights = tf.gather(tf.reshape(rpn_bbox_inside_weights, [-1, 4]), rpn_keep) rpn_bbox_outside_weights = tf.gather(tf.reshape(rpn_bbox_outside_weights, [-1, 4]), rpn_keep) rpn_loss_box_n = tf.reduce_sum(rpn_bbox_outside_weights * smooth_l1_dist( rpn_bbox_inside_weights * (rpn_bbox_pred - rpn_bbox_targets)), reduction_indices=[1]) rpn_loss_box = tf.reduce_sum(rpn_loss_box_n) / (tf.reduce_sum(tf.cast(fg_keep, tf.float32)) + 1) rpn_cross_entropy = tf.reduce_mean(rpn_cross_entropy_n) model_loss = rpn_cross_entropy + rpn_loss_box regularization_losses = tf.get_collection(tf.GraphKeys.REGULARIZATION_LOSSES) total_loss = tf.add_n(regularization_losses) + model_loss tf.summary.scalar('model_loss', model_loss) tf.summary.scalar('total_loss', total_loss) tf.summary.scalar('rpn_cross_entropy', rpn_cross_entropy) tf.summary.scalar('rpn_loss_box', rpn_loss_box) return total_loss, model_loss, rpn_cross_entropy, rpn_loss_box