예제 #1
0
      def get_loss(idx):
        anchor = h[idx, :]
        anchor_class = targets[idx]
        class_division = tf.cast(tf.equal(targets, anchor_class), tf.int32)
        partitioned_output = tf.dynamic_partition(h, class_division, 2)

        # Positives
        positive_distances = tf.abs(anchor - partitioned_output[1])
        pos_dis_val = tf.norm(positive_distances,axis=1)
        hardest_positive_idx = tf.arg_max(pos_dis_val,0)
        pos_div_size = smart_shape(partitioned_output[1])[0]
        pos_divider = tf.one_hot(hardest_positive_idx,pos_div_size,dtype=tf.int32)
        hardest_positive = tf.dynamic_partition(positive_distances,pos_divider,2)[1]
        hardest_positive_class = tf.gather(targets, hardest_positive_idx)
        hardest_positive = tf.norm(hardest_positive, axis=1)

        # Negatives
        negative_distances = tf.abs(anchor - partitioned_output[0])
        neg_dis_val = tf.norm(negative_distances, axis=1)
        hardest_negative_idx = tf.arg_min(neg_dis_val,0)
        neg_div_size = smart_shape(partitioned_output[0])[0]
        neg_divider = tf.one_hot(hardest_negative_idx,neg_div_size,dtype=tf.int32)
        hardest_negative = tf.dynamic_partition(negative_distances,neg_divider,2)[1]
        hardest_negative_class = tf.gather(targets,hardest_negative_idx)
        hardest_negative = tf.norm(hardest_negative, axis=1)

        # margin = 1
        # loss = tf.maximum(0., margin + hardest_positive - hardest_negative)
        loss = tf.log1p(tf.exp(hardest_positive - hardest_negative))

        return loss
예제 #2
0
  def __init__(self, name, inputs, targets, tower_setup, merge_type):
    super(CompleteSiameseMerge, self).__init__()
    curr, n_features_inp = prepare_input(inputs)

    batch_size = smart_shape(curr)[0]
    curr1 = curr[:,tf.newaxis,:]
    curr2 = curr[tf.newaxis,:,:]

    if merge_type == "concat":
      # curr1_big = tf.reshape(tf.tile(curr1, [batch_size]), [batch_size, -1])
      # curr2_big = tf.reshape(tf.tile(curr2, [batch_size]), [batch_size, -1])

      curr1 = tf.transpose(curr1, perm=[1, 0, 2])
      curr1_big = tf.tile(curr1, [batch_size,1,1])
      curr1_big = tf.transpose(curr1_big, perm=[1, 0, 2])
      curr2_big = tf.tile(curr2, [batch_size,1,1])

      whole_mat = tf.concat((curr1_big,curr2_big),2)
    elif merge_type == "add":
      whole_mat = curr1 + curr2
    elif merge_type == "subtract":
      whole_mat = curr1 - curr2
    elif merge_type == "abs_subtract":
      whole_mat = tf.abs(curr1 - curr2)
    else:
      raise ValueError("No correct merge type")

    targets1 = targets[:,tf.newaxis]
    targets2 = targets[tf.newaxis,:]
    whole_targets = tf.cast(tf.equal(targets1,targets2),tf.int32)

    boolean_target = tf.cast(tf.ones([batch_size,batch_size]),tf.bool)
    #### Following extracts one sided + diagonal, but for now we are using both sided as concat is non-symmetric
    #### In future may want to remove the diagonal
    # boolean_target = tf.matrix_band_part(boolean_target, -1, 0),tf.bool
    targets_list = tf.boolean_mask(whole_targets,boolean_target)
    vectors_list = tf.boolean_mask(whole_mat,boolean_target)

    debug = 0
    if debug:
      # Print - debug example code
      def test(a):
        print(a)
        return numpy.array([5], dtype="int32")

      t, = tf.py_func(test, [smart_shape(targets_list)], [tf.int32])
      with tf.control_dependencies([t]):
        targets_list = tf.identity(targets_list)

      t, = tf.py_func(test, [smart_shape(vectors_list)], [tf.int32])
      with tf.control_dependencies([t]):
        targets_list = tf.identity(targets_list)

    self.outputs = [vectors_list]
    self.out_labels = targets_list
예제 #3
0
        def Expand(idx):
            anchor = curr[idx, :]
            anchor_class = targets[idx]
            classes, _ = tf.unique(targets)
            class_division = tf.cast(tf.equal(targets, anchor_class), tf.int32)
            partitioned_output = tf.dynamic_partition(curr, class_division, 2)
            partitioned_targets = tf.dynamic_partition(targets, class_division,
                                                       2)

            # Positives
            positives = partitioned_output[1]
            size_positives = smart_shape(positives)[0]
            anchor_positive_repmat = tf.reshape(
                tf.tile(anchor, [size_positives]), [size_positives, -1])
            positives_combined = tf.concat((anchor_positive_repmat, positives),
                                           1)
            new_targets_positive = tf.ones(
                [smart_shape(positives_combined)[0]], dtype=tf.int32)

            # Negatives
            negative_size = smart_shape(classes)[0]

            def Get_negatives(neg_idx):
                curr_neg_class = classes[neg_idx]
                neg_class_division = tf.cast(tf.equal(targets, curr_neg_class),
                                             tf.int32)
                neg_partitioned_output = tf.dynamic_partition(
                    curr, neg_class_division, 2)
                negative_set = neg_partitioned_output[1]
                size_negative_set = smart_shape(negative_set)[0]
                random_negative_idx = tf.random_shuffle(
                    tf.range(1, size_negative_set))[0]
                random_negative = negative_set[random_negative_idx, :]
                return random_negative

            looper = tf.range(0, anchor_class)
            iter_val = tf.minimum(anchor_class + 1, negative_size)
            looper = tf.concat([looper, tf.range(iter_val, negative_size)], 0)
            negatives = tf.map_fn(Get_negatives, looper, dtype=tf.float32)
            size_negatives = smart_shape(negatives)[0]
            anchor_negative_repmat = tf.reshape(
                tf.tile(anchor, [size_negatives]), [size_negatives, -1])
            negatives_combined = tf.concat((anchor_negative_repmat, negatives),
                                           1)
            new_targets_negative = tf.zeros(
                [smart_shape(negatives_combined)[0]], dtype=tf.int32)

            all_combined = tf.concat((positives_combined, negatives_combined),
                                     0)
            new_targets_combined = tf.concat(
                (new_targets_positive, new_targets_negative), 0)
            return all_combined, new_targets_combined
예제 #4
0
                def if_not_end_net():
                    test_size = self.idx_placeholder[2]
                    test_num = self.idx_placeholder[3]

                    def _load_imgs(idx):
                        label = 0
                        img = path + tf.as_string(
                            idx + 1, width=4,
                            fill="0") + "_" + tf.as_string(test_size +
                                                           test_num) + ".png"

                        tag = img
                        img = self.data_dir + img

                        img_val = load_normalized_image_tensorflow(img,
                                                                   jpg=False)
                        img_val.set_shape(self.input_size + (3, ))

                        return img_val, label, tag

                    imgs, labels, tags = tf.map_fn(
                        _load_imgs,
                        tf.range(start_idx, end_idx),
                        dtype=(tf.float32, tf.int32, tf.string))
                    shape = smart_shape(imgs)
                    imgs = tf.reshape(imgs, shape)
                    return imgs, labels, tags
예제 #5
0
 def add_mask_summary(self, mask, name):
     from datasets.Util.Util import smart_shape
     assert len(smart_shape(mask)) == 2
     im = tf.tile(tf.cast(mask, tf.float32)[
                  tf.newaxis, :, :, tf.newaxis], multiples=[1, 1, 1, 3])
     summary = tf.summary.image(name, im)
     self.summaries.append(summary)
예제 #6
0
파일: Reader.py 프로젝트: mrteera/OnAVOS
def create_tensor_dict(unnormalized_img,
                       label,
                       tag,
                       raw_label=None,
                       old_label=None,
                       flow_past=None,
                       flow_future=None,
                       use_index_img=False,
                       u0=None,
                       u1=None):
    tensors = {
        "unnormalized_img": unnormalized_img,
        "label": label,
        "tag": tag
    }
    if raw_label is None:
        tensors["raw_label"] = label
    else:
        tensors["raw_label"] = raw_label
    if old_label is not None:
        tensors["old_label"] = old_label
    if flow_past is not None:
        tensors["flow_past"] = flow_past
    if flow_future is not None:
        tensors["flow_future"] = flow_future
    if u0 is not None:
        tensors[Constants.DT_NEG] = u0
    if u1 is not None:
        tensors[Constants.DT_POS] = u1
    if use_index_img:
        shape = smart_shape(unnormalized_img)
        index_img = create_index_image(shape[0], shape[1])
        tensors["index_img"] = index_img
    return tensors
예제 #7
0
                def if_end_net():
                    pdx = self.idx_placeholder[2]

                    def _load_imgs(idx):
                        img1_idx = pdx + 1
                        img2_idx = idx + 1
                        label = tf.cond(
                            abs(img1_idx - img2_idx) <= 0,
                            lambda: img1_idx * 0 + 1, lambda: img1_idx * 0)

                        img1 = path + tf.as_string(img1_idx, width=4,
                                                   fill="0") + "_1.png"
                        img2 = path + tf.as_string(img2_idx, width=4,
                                                   fill="0") + "_2.png"
                        tag = img1 + " " + img2 + " " + tf.as_string(label)

                        img_val1 = tf.zeros(self.input_size + (3, ))
                        img_val1.set_shape(self.input_size + (3, ))
                        img_val2 = tf.zeros(self.input_size + (3, ))
                        img_val2.set_shape(self.input_size + (3, ))
                        pair = tf.stack([img_val1, img_val2])

                        return pair, label, tag

                    imgs, labels, tags = tf.map_fn(
                        _load_imgs,
                        tf.range(start_idx, end_idx),
                        dtype=(tf.float32, tf.int32, tf.string))

                    shape = smart_shape(imgs)
                    shape2 = shape[1:]
                    shape2[0] *= end_idx - start_idx
                    imgs = tf.reshape(imgs, shape2)

                    return imgs, labels, tags
예제 #8
0
 def Get_negatives(neg_idx):
     curr_neg_class = classes[neg_idx]
     neg_class_division = tf.cast(tf.equal(targets, curr_neg_class), tf.int32)
     neg_partitioned_output = tf.dynamic_partition(curr, neg_class_division, 2)
     negative_set = neg_partitioned_output[1]
     size_negative_set = smart_shape(negative_set)[0]
     random_negative_idx = tf.random_shuffle(tf.range(1, size_negative_set))[0]
     random_negative = negative_set[random_negative_idx, :]
     return random_negative
예제 #9
0
파일: Reader.py 프로젝트: gaoyang07/PReMVOS
def create_tensor_dict(unnormalized_img,
                       label,
                       tag,
                       raw_label=None,
                       old_label=None,
                       flow_past=None,
                       flow_future=None,
                       use_index_img=False,
                       u0=None,
                       u1=None,
                       bboxes=None,
                       ids=None,
                       classes=None,
                       img_id=None,
                       ignore_regions=None,
                       scene_infos=None,
                       old_label_as_dt=None):
    tensors = {"unnormalized_img": unnormalized_img, "tag": tag}
    #note that "label" is a bit a misnomer, since it's actually a mask. better rename it at some point
    if label is not None:
        tensors["label"] = label
    if raw_label is None:
        if label is not None:
            tensors["raw_label"] = label
    else:
        tensors["raw_label"] = raw_label
    if old_label is not None:
        tensors["old_label"] = old_label
    if flow_past is not None:
        tensors["flow_past"] = flow_past
    if flow_future is not None:
        tensors["flow_future"] = flow_future
    if bboxes is not None:
        tensors[Constants.BBOXES] = bboxes
    if ids is not None:
        tensors[Constants.IDS] = ids
    if classes is not None:
        tensors[Constants.CLASSES] = classes
    if u0 is not None:
        tensors[Constants.DT_NEG] = u0
    if u1 is not None:
        tensors[Constants.DT_POS] = u1
    if img_id is not None:
        tensors[Constants.IMG_IDS] = img_id
    if ignore_regions is not None:
        tensors[Constants.IGNORE_REGIONS] = ignore_regions
    if scene_infos is not None:
        tensors[Constants.SCENE_INFOS] = scene_infos
    if old_label_as_dt is not None:
        tensors[Constants.OLD_LABEL_AS_DT] = old_label_as_dt
    if use_index_img:
        shape = smart_shape(unnormalized_img)
        index_img = create_index_image(shape[0], shape[1])
        tensors["index_img"] = index_img
    return tensors
예제 #10
0
    def embed(image, offset, pad_mode):
        """
        Embeds the image and performs reflection padding.

        :param image: The tensor to translate.
        :param offset: The offset by which we translate.
        :param pad_mode: The padding mode, or a constant
        :return: The augmented image.
        """
        # Compute offsets and sizes
        # shape = image.get_shape().as_list()
        shape = smart_shape(image)
        start = [tf.maximum(-offset[0], 0), tf.maximum(-offset[1], 0)]
        size = [shape[0] - tf.abs(offset[0]), shape[1] - tf.abs(offset[1])]

        # Pad the image on the opposite side
        padding = [[tf.maximum(0, offset[0]),
                    tf.maximum(0, -offset[0])],
                   [tf.maximum(0, offset[1]),
                    tf.maximum(0, -offset[1])]]

        # no padding on channel dimension for images
        if len(image.get_shape().as_list()) == 3:
            start.append(0)
            size.append(shape[2])
            padding.append([0, 0])

        # Extract the image region that is defined by the offset
        region = tf.slice(image, start, size)
        # region = image[max(-offset[0], 0):shape[0]-max(0, offset[0]),
        #               max(-offset[1], 0):shape[1]-max(0, offset[1])]

        if isinstance(pad_mode, str):
            region = tf.pad(region, padding, mode=pad_mode)
            return region
        else:
            const = pad_mode
            dtype = region.dtype
            region = tf.cast(region, tf.int32) - const
            region = tf.pad(region, padding, mode='CONSTANT')
            region = region + const
            return tf.cast(region, dtype)
예제 #11
0
    def apply(self, tensors, scale=None):
        if scale is None:
            # atm minval 1.0 to only zoom in, later also allow smaller values
            scale = tf.random_uniform([1],
                                      minval=1.0,
                                      maxval=1.25,
                                      dtype=tf.float32,
                                      seed=None)

        img = tensors["unnormalized_img"]
        h, w = smart_shape(img)[:2]
        crop_size = (h, w)
        h_scaled = tf.to_int32(tf.ceil(tf.cast(h, scale.dtype) * scale))
        w_scaled = tf.to_int32(tf.ceil(tf.cast(w, scale.dtype) * scale))
        scaled_size = tf.concat([h_scaled, w_scaled], axis=0)
        offset = None
        aug_tensors = tensors.copy()

        def _scale(key, bilinear, offset_, force_key=False):
            if force_key:
                assert key in tensors
            if key in tensors:
                im = tensors[key]
                aug_im = resize_image(im, scaled_size, bilinear)
                aug_im, offset_ = random_crop_image(aug_im, crop_size, offset_)
                aug_tensors[key] = aug_im
            return offset_

        offset = _scale("unnormalized_img", True, offset, True)
        _scale("label", False, offset, False)
        _scale("old_label", False, offset)
        _scale("index_img", False, offset)
        _scale("flow_past", True, offset)
        _scale("flow_future", True, offset)
        #attention: when we zoom in, the shift in number of pixels (i.e. optical flow) gets larger
        if "flow_past" in aug_tensors:
            aug_tensors["flow_past"] *= scale
        if "flow_future" in aug_tensors:
            aug_tensors["flow_future"] *= scale

        _scale("flow", True, offset)
        return aug_tensors
예제 #12
0
def clustering_features_extractor(engine, output_layer):
    outputs = output_layer.outputs[0]
    features = output_layer.y_class_features
    det_boxes, det_scores, reid, det_classes, num_detections = outputs
    det_boxes = tf.squeeze(det_boxes, axis=2)
    #conceptual problem: the features before the softmax are shared across anchors
    #let's just ignore that for now and replicate the features for each anchor
    n_anchors = 9
    shape = smart_shape(features)
    features = tf.tile(tf.expand_dims(features, axis=2),
                       multiples=[1, 1, n_anchors, 1])
    features = tf.reshape(features, tf.stack([shape[0], -1, shape[-1]],
                                             axis=0))

    def extract(filename, extract_boxes):
        data = engine.valid_data
        feed_dict = {
            data.img_filename_placeholder: filename,
            data.bboxes_placeholder: extract_boxes
        }
        det_boxes_val, det_features_val, det_scores_val = engine.session.run(
            [det_boxes, features, det_scores], feed_dict=feed_dict)
        #remove batch dimension
        batch_size = det_boxes_val.shape[0]
        assert batch_size == 1
        det_boxes_val = det_boxes_val[0]
        det_features_val = det_features_val[0]
        det_scores_val = det_scores_val[0]
        #compute IOUs and select most overlapping, for convenience let's do this with numpy instead of tensorflow
        ious = compute_ious(det_boxes_val, extract_boxes)
        indices = ious.argmax(axis=1)
        det_features_out = det_features_val[indices]
        det_scores_out = det_scores_val[indices]
        return det_features_out, det_scores_out

    return extract
예제 #13
0
파일: Resize.py 프로젝트: gaoyang07/PReMVOS
def resize_detection_fixed_size(tensors, input_size, for_testing=False):
    tensors_out = tensors.copy()
    #ignore_regions are currently not supported in this resize mode
    if Constants.IGNORE_REGIONS in tensors_out:
        del tensors_out[Constants.IGNORE_REGIONS]
    img = tensors[Constants.UNNORMALIZED_IMG]
    original_img = img
    bboxes = tensors[Constants.BBOXES]

    # remove the padding
    n_real_detections = tf.reduce_sum(
        tf.cast(tensors[Constants.IDS] > 0, tf.int32))
    bboxes = bboxes[:n_real_detections]
    classes = tensors[Constants.CLASSES][:n_real_detections]

    # permute y1, y2, x1, x2 -> y1, x1, y2, x1
    bboxes = tf.stack(
        [bboxes[..., 0], bboxes[..., 2], bboxes[..., 1], bboxes[..., 3]],
        axis=-1)

    # normalize bboxes to [0..1]
    height = tf.shape(img)[0]
    width = tf.shape(img)[1]
    bboxes = tf.cast(bboxes, tf.float32) / tf.cast(
        tf.stack([height, width, height, width], axis=0), tf.float32)

    import object_detection.core.preprocessor as preproc
    if not for_testing:
        #crop (ssd style)
        img, bboxes, classes = preproc.ssd_random_crop(img, bboxes, classes)
        #alternative
        #img, bboxes, classes = preproc.random_crop_image(img, real_boxes, real_boxes)

        # include random horizontal flip augmentation here
        img, bboxes = preproc.random_horizontal_flip(img, bboxes)

    #resize image, note: boxes don't need resizing as they are in relative coordinates
    img = preproc.resize_image(img,
                               new_height=input_size[0],
                               new_width=input_size[1])

    if for_testing:
        _, bboxes = preproc.scale_boxes_to_pixel_coordinates(
            original_img, bboxes)
    else:
        _, bboxes = preproc.scale_boxes_to_pixel_coordinates(img, bboxes)

    #permute back y1, x1, y2, x1 -> y1, y2, x1, x2
    bboxes = tf.stack(
        [bboxes[..., 0], bboxes[..., 2], bboxes[..., 1], bboxes[..., 3]],
        axis=-1)

    #pad the stuff needs to be padded back to the maximum size
    padded_size = smart_shape(tensors[Constants.CLASSES])[0]
    n_real_detections_after_crop = smart_shape(bboxes)[0]
    pad_size = padded_size - n_real_detections_after_crop
    paddings_bboxes = [[0, pad_size], [0, 0]]
    bboxes = tf.pad(bboxes, paddings=paddings_bboxes)
    paddings_classes_ids = [[0, pad_size]]
    classes = tf.pad(classes, paddings=paddings_classes_ids)
    ids = tf.pad(tf.range(n_real_detections_after_crop) + 1,
                 paddings=paddings_classes_ids)
    if isinstance(padded_size, int):
        bboxes.set_shape((padded_size, 4))
        classes.set_shape((padded_size, ))
        ids.set_shape((padded_size, ))
    else:
        bboxes.set_shape((None, 4))
    #note that we do not retain the original ids, but it does not matter since this resize_mode is only meant for
    #isolated frames
    tensors_out[Constants.UNNORMALIZED_IMG] = img
    tensors_out[Constants.BBOXES] = bboxes
    tensors_out[Constants.CLASSES] = classes
    tensors_out[Constants.IDS] = ids
    tensors_out[Constants.RESIZED_SIZES] = tf.shape(img)[:2]
    if for_testing:
        tensors_out[Constants.ORIGINAL_SIZES] = tf.shape(original_img)[:2]
    return tensors_out
예제 #14
0
    def __init__(self,
                 name,
                 inputs,
                 targets,
                 n_classes,
                 n_features,
                 tower_setup,
                 imgs_raw=None,
                 original_labels=None,
                 activation="linear",
                 dropout=0.0,
                 batch_norm=False,
                 batch_norm_decay=BATCH_NORM_DECAY_DEFAULT,
                 l2=L2_DEFAULT,
                 negative_weighting_factor=1):
        super(FullyConnectedWithTripletLoss, self).__init__()
        self.measures = {}
        inp, n_features_inp = prepare_collapsed_input_and_dropout(
            inputs, dropout)
        with tf.variable_scope(name, reuse=tf.AUTO_REUSE):
            if batch_norm:
                inp = tf.expand_dims(inp, axis=0)
                inp = tf.expand_dims(inp, axis=0)
                inp = self.create_and_apply_batch_norm(inp, n_features_inp,
                                                       batch_norm_decay,
                                                       tower_setup)
                inp = tf.squeeze(inp, axis=[0, 1])
            W = self.create_weight_variable("W", [n_features_inp, n_features],
                                            l2, tower_setup)
            b = self.create_bias_variable("b", [n_features], tower_setup)
            z = tf.matmul(inp, W) + b
            h = get_activation(activation)(z)
            self.outputs = [h]

            if original_labels is not None:
                self.measures[Constants.EMBEDDING] = [h]
                self.measures[Constants.ORIGINAL_LABELS] = [original_labels]

            self.add_scalar_summary(tf.norm(h[0]), "embedding_norm")
            self.summaries.append(tf.summary.histogram("embedding", h))

            size = smart_shape(h)[0]
            eps = 1e-10

            # New print debug example
            def my_print(x, name):
                with tf.control_dependencies([
                        tf.assert_equal(
                            tf.reduce_all(tf.greater(tf.shape(x), 0)), True)
                ]):
                    if x.dtype in (tf.float32, tf.float64):
                        with tf.control_dependencies([
                                tf.assert_equal(tf.reduce_all(tf.is_finite(x)),
                                                True)
                        ]):
                            return tf.Print(x, [
                                tf.shape(x),
                                tf.reduce_all(tf.is_finite(x)), x
                            ],
                                            name,
                                            summarize=200)
                    else:
                        return tf.Print(x, [tf.shape(x), x], name)

            def get_loss(idx):
                anchor = h[idx, :]
                anchor_class = targets[idx]

                ###### New code ######
                class_division = tf.equal(targets, anchor_class)
                not_self_mask = tf.logical_not(
                    tf.cast(tf.one_hot(idx, depth=size), tf.bool))
                positive_output = tf.boolean_mask(
                    h, tf.logical_and(class_division, not_self_mask))
                negative_output = tf.boolean_mask(
                    h, tf.logical_not(class_division))
                # negative_output = tf.boolean_mask(h, tf.logical_and(tf.logical_not(class_division),not_self_mask))
                # positive_output = my_print(positive_output,"positive_output")
                # negative_output = my_print(negative_output, "negative_output")

                positive_distances = tf.abs(anchor - positive_output)
                pos_dis_val = tf.norm(positive_distances + eps, axis=1)
                hardest_positive, hardest_positive_idx = tf.nn.top_k(
                    pos_dis_val, 1)

                negative_distances = tf.abs(anchor - negative_output)
                neg_dis_val = tf.norm(negative_distances + eps, axis=1)
                minus_neg_dis_val = tf.negative(neg_dis_val)
                # minus_neg_dis_val = tf.Print(minus_neg_dis_val,[minus_neg_dis_val])
                # minus_neg_dis_val = tf.Print(minus_neg_dis_val, [minus_neg_dis_val.shape])
                minus_hardest_negative, hardest_negative_idx = tf.nn.top_k(
                    minus_neg_dis_val, 1)
                hardest_negative = tf.negative(minus_hardest_negative)

                # minus_hardest_negative, hardest_negative_idx = tf.nn.top_k(minus_neg_dis_val, negative_weighting_factor)
                # hardest_negative = tf.negative(minus_hardest_negative)
                # hardest_negative = tf.reduce_sum(hardest_negative,-1)

                ###### Old code with dynamic partition ######
                # class_division = tf.cast(tf.equal(targets, anchor_class), tf.int32)
                # not_self_mask = tf.logical_not(tf.cast(tf.one_hot(idx, depth=size), tf.bool))
                # partitioned_output = tf.dynamic_partition(h, class_division, 2)
                # positive_output = partitioned_output[1]
                # negative_output = partitioned_output[0]

                # class_division = tf.equal(targets, anchor_class)
                # not_self_mask = tf.logical_not(tf.cast(tf.one_hot(idx, depth=size),tf.bool))
                # positive_output = tf.boolean_mask(h, tf.logical_and(class_division, not_self_mask))
                # negative_output = tf.boolean_mask(h, tf.logical_not(class_division))
                #
                #
                # positive_distances = tf.abs(anchor - positive_output)
                # pos_dis_val = tf.norm(positive_distances+eps, axis=1)
                # hardest_positive_idx = tf.argmax(pos_dis_val,0)
                # pos_div_size = smart_shape(positive_output)[0]
                # pos_divider = tf.one_hot(hardest_positive_idx,pos_div_size,dtype=tf.int32)
                # hardest_positive = tf.dynamic_partition(positive_distances,pos_divider,2)[1]
                # hardest_positive_class = tf.gather(targets, hardest_positive_idx)
                # hardest_positive = tf.norm(hardest_positive+eps, axis=1)
                #
                # negative_distances = tf.abs(anchor - negative_output)
                # neg_dis_val = tf.norm(negative_distances+eps, axis=1)
                # hardest_negative_idx = tf.argmin(neg_dis_val,0)
                # neg_div_size = smart_shape(negative_output)[0]
                # neg_divider = tf.one_hot(hardest_negative_idx,neg_div_size,dtype=tf.int32)
                # hardest_negative = tf.dynamic_partition(negative_distances,neg_divider,2)[1]
                # hardest_negative_class = tf.gather(targets,hardest_negative_idx)
                # hardest_negative = tf.norm(hardest_negative+eps, axis=1)

                # hardest_positive = my_print(hardest_positive,"hardest_positive")
                # hardest_negative = my_print(hardest_negative,"hardest_negative")

                #### Next two lines should be the same
                loss = tf.nn.softplus(hardest_positive - hardest_negative)
                # loss = tf.nn.softplus(hardest_positive - negative_weighting_factor*hardest_negative)
                # loss = tf.log1p(tf.exp(hardest_positive - hardest_negative))

                #### Code for using a hard margin rather than a softmargin
                # margin = 1
                # loss = tf.maximum(0., margin + hardest_positive - hardest_negative)

                anchor_img = tf.zeros([], tf.float32)
                hard_pos_img = tf.zeros([], tf.float32)
                hard_neg_img = tf.zeros([], tf.float32)
                if imgs_raw is not None:
                    positive_images = tf.boolean_mask(
                        imgs_raw, tf.logical_and(class_division,
                                                 not_self_mask))
                    negative_images = tf.boolean_mask(
                        imgs_raw, tf.logical_not(class_division))
                    anchor_img = imgs_raw[idx]
                    hard_pos_img = positive_images[tf.squeeze(
                        hardest_positive_idx)]
                    hard_neg_img = negative_images[tf.squeeze(
                        hardest_negative_idx)]

                    # self.summaries.append(tf.summary.image("anchor_image", imgs_raw[idx]))
                    # positive_images = tf.squeeze(tf.boolean_mask(imgs_raw, tf.logical_and(class_division, not_self_mask)))
                    # negative_images = tf.squeeze(tf.boolean_mask(imgs_raw, tf.logical_not(class_division)))
                    # self.summaries.append(tf.summary.image("hardest_postive_image",positive_images[hardest_positive_idx]))
                    # self.summaries.append(tf.summary.image("hardest_negative_image", negative_images[hardest_negative_idx]))

                return loss, hardest_positive, hardest_negative, anchor_img, hard_pos_img, hard_neg_img

            #### Next two lines should be the same
            loss, hardest_positive, hardest_negative, anchor_imgs, hard_pos_imgs, hard_neg_imgs = \
              tf.map_fn(get_loss, tf.range(0, size), dtype=(tf.float32,tf.float32,tf.float32, tf.float32, tf.float32, tf.float32))
            # loss, hardest_positive, hardest_negative = [get_loss(idx) for idx in xrange(size)]

            self.loss = tf.reduce_sum(loss)
            hardest_positive = tf.reduce_sum(hardest_positive)
            hardest_negative = tf.reduce_sum(hardest_negative)
            self.add_scalar_summary(self.loss, "loss")
            self.add_scalar_summary(hardest_positive, "hardest_positive")
            self.add_scalar_summary(hardest_negative, "hardest_negative")
            # tf.summary.image()
            self.n_features = n_features

            if imgs_raw is not None:
                self.summaries.append(
                    tf.summary.image("anchor_image", anchor_imgs))
                self.summaries.append(
                    tf.summary.image("hardest_postive_image", hard_pos_imgs))
                self.summaries.append(
                    tf.summary.image("hardest_negative_image", hard_neg_imgs))
예제 #15
0
  def __init__(self, name, inputs, targets, tower_setup, merge_type):
    super(ExpandedSiameseMerge, self).__init__()
    curr, n_features_inp = prepare_input(inputs)
    size = smart_shape(curr)[0]

    def Expand(idx):
      anchor = curr[idx, :]
      anchor_class = targets[idx]
      classes,classes_ids = tf.unique(targets)
      anchor_class_id = classes_ids[idx]
      class_division = tf.cast(tf.equal(targets, anchor_class), tf.int32) - tf.cast(tf.equal(list(range(0,size)),idx),tf.int32)
      partitioned_output = tf.dynamic_partition(curr, class_division, 2)
      #partitioned_targets = tf.dynamic_partition(targets, class_division, 2)

      # Positives
      positives = partitioned_output[1]

      size_positives = smart_shape(positives)[0]
      anchor_positive_repmat = tf.reshape(tf.tile(anchor,[size_positives]),[size_positives,-1])
      positives_combined = tf.concat((anchor_positive_repmat,positives),1)
      new_targets_positive = tf.ones([smart_shape(positives_combined)[0]],dtype=tf.int32)

      # Negatives
      negative_size = smart_shape(classes)[0]

      def Get_negatives(neg_idx):
        curr_neg_class = classes[neg_idx]
        neg_class_division = tf.cast(tf.equal(targets, curr_neg_class), tf.int32)
        neg_partitioned_output = tf.dynamic_partition(curr, neg_class_division, 2)
        negative_set = neg_partitioned_output[1]
        size_negative_set = smart_shape(negative_set)[0]
        random_negative_idx = tf.random_shuffle(tf.range(1, size_negative_set))[0]
        random_negative = negative_set[random_negative_idx,:]
        return random_negative

      looper = tf.range(0, anchor_class_id)
      iter_val = tf.minimum(anchor_class_id+1,negative_size)
      # looper = tf.range(0, idx)
      # iter_val = tf.minimum(idx + 1, negative_size)
      looper = tf.concat([looper,tf.range(iter_val,negative_size)],0)

      negatives = tf.map_fn(Get_negatives, looper, dtype=tf.float32)
      size_negatives = smart_shape(negatives)[0]
      anchor_negative_repmat = tf.reshape(tf.tile(anchor, [size_negatives]), [size_negatives, -1])
      negatives_combined = tf.concat((anchor_negative_repmat,negatives),1)
      new_targets_negative = tf.zeros([smart_shape(negatives_combined)[0]],dtype=tf.int32)

      all_combined = tf.concat((positives_combined,negatives_combined),0)
      new_targets_combined = tf.concat((new_targets_positive,new_targets_negative),0)

      return all_combined, new_targets_combined

    expanded, new_targets = tf.map_fn(Expand, tf.range(0, size), dtype=(tf.float32, tf.int32))

    if merge_type == "concat":
      expanded = tf.reshape(expanded, [-1, n_features_inp * 2])
    elif merge_type == "add":
      part1 = expanded[::2, :]
      part2 = expanded[1::2, :]
      expanded = part1 + part2
    elif merge_type == "subtract":
      part1 = expanded[::2, :]
      part2 = expanded[1::2, :]
      expanded = part1 - part2
    elif merge_type == "abs_subtract":
      part1 = expanded[::2, :]
      part2 = expanded[1::2, :]
      expanded = tf.abs(part1 - part2)
    else:
      expanded = expanded

    new_targets = tf.reshape(new_targets, [-1])

    debug = 0
    if debug:
      # Print - debug example code
      def test(a):
        print(a)
        return numpy.array([5], dtype="int32")

      t, = tf.py_func(test, [smart_shape(new_targets)], [tf.int32])
      with tf.control_dependencies([t]):
        expanded = tf.identity(expanded)

    self.outputs = [expanded]
    self.out_labels = new_targets
예제 #16
0
    def create_input_tensors_dict(self, batch_size):

        ########################
        ####### TRAINING #######
        ########################
        if self.subset in "train":

            ####### Paired Batch-Mode #######
            if self.batching_mode in "pair":

                assert batch_size % 2 == 0
                batch_size /= 2

                rand = tf.random_uniform([5],
                                         maxval=tf.int32.max,
                                         dtype=tf.int32)
                sample_same_person = rand[0] % 2
                pers_id_1 = ((rand[1] - 1) % self.num_train_id) + 1
                pers_1_n_imgs = self.train_counts[pers_id_1 - 1]
                img_id_1 = ((rand[2] - 1) % pers_1_n_imgs) + 1

                def if_same_person():
                    pers_id_2 = pers_id_1
                    img_id_2 = ((rand[4] - 1) % (pers_1_n_imgs - 1)) + 1
                    img_id_2 = tf.cond(img_id_2 >= img_id_1,
                                       lambda: img_id_2 + 1, lambda: img_id_2)
                    return pers_id_2, img_id_2

                def if_not_same_person():
                    pers_id_2 = ((rand[3] - 1) % (self.num_train_id - 1)) + 1
                    pers_id_2 = tf.cond(pers_id_2 >= pers_id_1,
                                        lambda: pers_id_2 + 1,
                                        lambda: pers_id_2)
                    pers_2_n_imgs = self.train_counts[pers_id_2 - 1]
                    img_id_2 = ((rand[4] - 1) % pers_2_n_imgs) + 1
                    return pers_id_2, img_id_2

                pers_id_2, img_id_2 = tf.cond(
                    tf.cast(sample_same_person, tf.bool), if_same_person,
                    if_not_same_person)

                img1 = tf.as_string(pers_id_1, width=5,
                                    fill="0") + "_" + tf.as_string(
                                        img_id_1, width=4, fill="0") + ".png"
                img2 = tf.as_string(pers_id_2, width=5,
                                    fill="0") + "_" + tf.as_string(
                                        img_id_2, width=4, fill="0") + ".png"

                tag = img1 + " " + img2 + " " + tf.as_string(
                    sample_same_person)

                img1 = self.data_dir + self.train_folder + '/' + img1
                img2 = self.data_dir + self.train_folder + '/' + img2

                img_val1 = load_image_tensorflow(img1, jpg=False)
                img_val1.set_shape(self.input_size + (3, ))
                tensors = {"unnormalized_img": img_val1}
                tensors = apply_augmentors(tensors, self.augmentors)
                img_val1 = tensors["unnormalized_img"]
                img_val1 = normalize(img_val1)

                img_val2 = load_image_tensorflow(img2, jpg=False)
                img_val2.set_shape(self.input_size + (3, ))
                tensors = {"unnormalized_img": img_val2}
                tensors = apply_augmentors(tensors, self.augmentors)
                img_val2 = tensors["unnormalized_img"]
                img_val2 = normalize(img_val2)

                pair = tf.stack([img_val1, img_val2])
                label = sample_same_person

                imgs, labels, tags = tf.train.batch([pair, label, tag],
                                                    batch_size=batch_size)

                shape = smart_shape(imgs)
                shape2 = shape[1:]
                shape2[0] *= batch_size
                imgs = tf.reshape(imgs, shape2)

            ####### Group Batch-Mode #######
            elif self.batching_mode in "group":
                assert batch_size % self.group_size == 0
                batch_size /= self.group_size
                batch_size = int(batch_size)

                pers_ids = tf.random_shuffle(tf.range(
                    1, self.num_train_id))[0:batch_size]

                def for_each_identity(p_idx):
                    pers_id = pers_ids[p_idx]
                    img_ids = tf.tile(
                        tf.random_shuffle(
                            tf.range(1, self.train_counts[pers_id - 1])),
                        [4])[0:self.group_size]

                    def for_each_img(i_idx):
                        img_id = img_ids[i_idx]
                        tag = tf.as_string(
                            pers_id, width=5, fill="0") + "_" + tf.as_string(
                                img_id, width=4, fill="0") + ".png"

                        img = load_image_tensorflow(
                            self.data_dir + self.train_folder + '/' + tag,
                            jpg=False)
                        img.set_shape(self.input_size + (3, ))
                        tensors = {"unnormalized_img": img}
                        tensors = apply_augmentors(tensors, self.augmentors)
                        img = tensors["unnormalized_img"]
                        img = normalize(img)

                        label = p_idx
                        img.set_shape(self.input_size + (3, ))
                        return img, label, tag

                    imgs, labels, tags = tf.map_fn(
                        for_each_img,
                        tf.range(0, self.group_size),
                        dtype=(tf.float32, tf.int32, tf.string))
                    return imgs, labels, tags

                imgs, labels, tags = tf.map_fn(for_each_identity,
                                               tf.range(0, batch_size),
                                               dtype=(tf.float32, tf.int32,
                                                      tf.string))

                def reshape(x):
                    shape = smart_shape(x)
                    shape2 = shape[1:]
                    shape2[0] = self.group_size * batch_size
                    x = tf.reshape(x, shape2)
                    return x

                imgs = reshape(imgs)
                labels = reshape(labels)
                tags = reshape(tags)

            ####### Single Batch-Mode #######
            else:  # self.batching_mode in "single":

                rand = tf.random_uniform([2],
                                         maxval=tf.int32.max,
                                         dtype=tf.int32)
                pers_id_1 = ((rand[0] - 1) % self.num_train_id) + 1
                pers_1_n_imgs = self.train_counts[pers_id_1 - 1]
                img_id_1 = ((rand[1] - 1) % pers_1_n_imgs) + 1

                img1 = tf.as_string(pers_id_1, width=5,
                                    fill="0") + "_" + tf.as_string(
                                        img_id_1, width=4, fill="0") + ".png"

                tag = img1

                img1 = self.data_dir + self.train_folder + '/' + img1

                img_val1 = load_image_tensorflow(img1, jpg=False)
                img_val1.set_shape(self.input_size + (3, ))
                tensors = {"unnormalized_img": img_val1}
                tensors = apply_augmentors(tensors, self.augmentors)
                img_val1 = tensors["unnormalized_img"]
                img_val1 = normalize(img_val1)

                label = pers_id_1

                imgs, labels, tags = tf.train.batch([img_val1, label, tag],
                                                    batch_size=batch_size)

        ##########################
        ####### Validation #######
        ##########################
        else:  # self.subset in "valid":

            ####### Similarity Validation-Mode #######
            if self.validation_mode in "similarity":
                path = self.test_case + '/'
                start_idx = self.idx_placeholder[0]
                end_idx = self.idx_placeholder[1]
                end_net = self.use_end_network

                def if_end_net():
                    pdx = self.idx_placeholder[2]

                    def _load_imgs(idx):
                        img1_idx = pdx + 1
                        img2_idx = idx + 1
                        label = tf.cond(
                            abs(img1_idx - img2_idx) <= 0,
                            lambda: img1_idx * 0 + 1, lambda: img1_idx * 0)

                        img1 = path + tf.as_string(img1_idx, width=4,
                                                   fill="0") + "_1.png"
                        img2 = path + tf.as_string(img2_idx, width=4,
                                                   fill="0") + "_2.png"
                        tag = img1 + " " + img2 + " " + tf.as_string(label)

                        img_val1 = tf.zeros(self.input_size + (3, ))
                        img_val1.set_shape(self.input_size + (3, ))
                        img_val2 = tf.zeros(self.input_size + (3, ))
                        img_val2.set_shape(self.input_size + (3, ))
                        pair = tf.stack([img_val1, img_val2])

                        return pair, label, tag

                    imgs, labels, tags = tf.map_fn(
                        _load_imgs,
                        tf.range(start_idx, end_idx),
                        dtype=(tf.float32, tf.int32, tf.string))

                    shape = smart_shape(imgs)
                    shape2 = shape[1:]
                    shape2[0] *= end_idx - start_idx
                    imgs = tf.reshape(imgs, shape2)

                    return imgs, labels, tags

                def if_not_end_net():
                    test_size = self.idx_placeholder[2]
                    test_num = self.idx_placeholder[3]

                    def _load_imgs(idx):
                        label = 0
                        img = path + tf.as_string(
                            idx + 1, width=4,
                            fill="0") + "_" + tf.as_string(test_size +
                                                           test_num) + ".png"

                        tag = img
                        img = self.data_dir + img

                        img_val = load_normalized_image_tensorflow(img,
                                                                   jpg=False)
                        img_val.set_shape(self.input_size + (3, ))

                        return img_val, label, tag

                    imgs, labels, tags = tf.map_fn(
                        _load_imgs,
                        tf.range(start_idx, end_idx),
                        dtype=(tf.float32, tf.int32, tf.string))
                    shape = smart_shape(imgs)
                    imgs = tf.reshape(imgs, shape)
                    return imgs, labels, tags

                imgs, labels, tags = tf.cond(end_net, if_end_net,
                                             if_not_end_net)

            ####### Embedding Validation-Mode #######
            else:  # self.validation_mode in "embedding":
                path = self.test_case + '/'
                start_idx = self.idx_placeholder[0]
                end_idx = self.idx_placeholder[1]

                test_size = self.idx_placeholder[2]
                test_num = self.idx_placeholder[3]

                def _load_imgs(idx):

                    label = 0
                    img = path + tf.as_string(
                        test_size + 1, width=5, fill="0") + "_" + tf.as_string(
                            idx + 1, width=4, fill="0") + ".png"

                    tag = img
                    img = self.data_dir + img

                    img_val = load_normalized_image_tensorflow(img, jpg=False)
                    img_val.set_shape(self.input_size + (3, ))

                    return img_val, label, tag

                imgs, labels, tags = tf.map_fn(_load_imgs,
                                               tf.range(start_idx, end_idx),
                                               dtype=(tf.float32, tf.int32,
                                                      tf.string))
                shape = smart_shape(imgs)
                imgs = tf.reshape(imgs, shape)

        tensors = {"inputs": imgs, "labels": labels, "tags": tags}

        self.images = imgs
        return tensors
예제 #17
0
 def reshape(x):
     shape = smart_shape(x)
     shape2 = shape[1:]
     shape2[0] = self.group_size * batch_size
     x = tf.reshape(x, shape2)
     return x
예제 #18
0
    def __init__(self, name, inputs, targets, tower_setup):
        super(ExpandedSiameseConcat, self).__init__()
        curr, n_features_inp = prepare_input(inputs)
        size = smart_shape(curr)[0]

        def Expand(idx):
            anchor = curr[idx, :]
            anchor_class = targets[idx]
            classes, _ = tf.unique(targets)
            class_division = tf.cast(tf.equal(targets, anchor_class), tf.int32)
            partitioned_output = tf.dynamic_partition(curr, class_division, 2)
            partitioned_targets = tf.dynamic_partition(targets, class_division,
                                                       2)

            # Positives
            positives = partitioned_output[1]
            size_positives = smart_shape(positives)[0]
            anchor_positive_repmat = tf.reshape(
                tf.tile(anchor, [size_positives]), [size_positives, -1])
            positives_combined = tf.concat((anchor_positive_repmat, positives),
                                           1)
            new_targets_positive = tf.ones(
                [smart_shape(positives_combined)[0]], dtype=tf.int32)

            # Negatives
            negative_size = smart_shape(classes)[0]

            def Get_negatives(neg_idx):
                curr_neg_class = classes[neg_idx]
                neg_class_division = tf.cast(tf.equal(targets, curr_neg_class),
                                             tf.int32)
                neg_partitioned_output = tf.dynamic_partition(
                    curr, neg_class_division, 2)
                negative_set = neg_partitioned_output[1]
                size_negative_set = smart_shape(negative_set)[0]
                random_negative_idx = tf.random_shuffle(
                    tf.range(1, size_negative_set))[0]
                random_negative = negative_set[random_negative_idx, :]
                return random_negative

            looper = tf.range(0, anchor_class)
            iter_val = tf.minimum(anchor_class + 1, negative_size)
            looper = tf.concat([looper, tf.range(iter_val, negative_size)], 0)
            negatives = tf.map_fn(Get_negatives, looper, dtype=tf.float32)
            size_negatives = smart_shape(negatives)[0]
            anchor_negative_repmat = tf.reshape(
                tf.tile(anchor, [size_negatives]), [size_negatives, -1])
            negatives_combined = tf.concat((anchor_negative_repmat, negatives),
                                           1)
            new_targets_negative = tf.zeros(
                [smart_shape(negatives_combined)[0]], dtype=tf.int32)

            all_combined = tf.concat((positives_combined, negatives_combined),
                                     0)
            new_targets_combined = tf.concat(
                (new_targets_positive, new_targets_negative), 0)
            return all_combined, new_targets_combined

        expanded, new_targets = tf.map_fn(Expand,
                                          tf.range(0, size),
                                          dtype=(tf.float32, tf.int32))
        expanded = tf.reshape(expanded, [-1, n_features_inp * 2])
        new_targets = tf.reshape(new_targets, [-1])

        # new_shape = smart_shape(expanded)
        # tower_setup.is_training*860 + 100
        new_shape = [tower_setup.is_training * 896 + 64, 1000]
        new_targets.set_shape([new_shape[0]])
        expanded.set_shape(new_shape)

        # self.outputs = [expanded]
        # self.out_labels = new_targets

        def if_training():
            return new_targets, expanded

        def if_not_training():
            ahah = tf.concat([curr, curr], 1)
            ahah.set_shape([64, 1000])
            return targets, ahah

        self.out_labels, rar = tf.cond(
            tf.cast(tower_setup.is_training, tf.bool), if_training,
            if_not_training)
        self.outputs = [rar]
예제 #19
0
  def __init__(self, name, inputs, targets, n_classes, n_features, tower_setup, activation="linear", dropout=0.0,
               batch_norm=False,
               batch_norm_decay=BATCH_NORM_DECAY_DEFAULT, l2=L2_DEFAULT):
    super(FullyConnectedWithTripletLoss, self).__init__()
    self.measures = {}
    inp, n_features_inp = prepare_collapsed_input_and_dropout(inputs, dropout)
    with tf.variable_scope(name):
      if batch_norm:
        inp = tf.expand_dims(inp, axis=0)
        inp = tf.expand_dims(inp, axis=0)
        inp = self.create_and_apply_batch_norm(inp, n_features_inp, batch_norm_decay, tower_setup)
        inp = tf.squeeze(inp, axis=[0, 1])
      W = self.create_weight_variable("W", [n_features_inp, n_features], l2, tower_setup)
      b = self.create_bias_variable("b", [n_features], tower_setup)
      z = tf.matmul(inp, W) + b
      h = get_activation(activation)(z)
      self.outputs = [h]

      size = smart_shape(h)[0]

      def get_loss(idx):
        anchor = h[idx, :]
        anchor_class = targets[idx]
        class_division = tf.cast(tf.equal(targets, anchor_class), tf.int32)
        partitioned_output = tf.dynamic_partition(h, class_division, 2)

        # Positives
        positive_distances = tf.abs(anchor - partitioned_output[1])
        pos_dis_val = tf.norm(positive_distances,axis=1)
        hardest_positive_idx = tf.arg_max(pos_dis_val,0)
        pos_div_size = smart_shape(partitioned_output[1])[0]
        pos_divider = tf.one_hot(hardest_positive_idx,pos_div_size,dtype=tf.int32)
        hardest_positive = tf.dynamic_partition(positive_distances,pos_divider,2)[1]
        hardest_positive_class = tf.gather(targets, hardest_positive_idx)
        hardest_positive = tf.norm(hardest_positive, axis=1)

        # Negatives
        negative_distances = tf.abs(anchor - partitioned_output[0])
        neg_dis_val = tf.norm(negative_distances, axis=1)
        hardest_negative_idx = tf.arg_min(neg_dis_val,0)
        neg_div_size = smart_shape(partitioned_output[0])[0]
        neg_divider = tf.one_hot(hardest_negative_idx,neg_div_size,dtype=tf.int32)
        hardest_negative = tf.dynamic_partition(negative_distances,neg_divider,2)[1]
        hardest_negative_class = tf.gather(targets,hardest_negative_idx)
        hardest_negative = tf.norm(hardest_negative, axis=1)

        # margin = 1
        # loss = tf.maximum(0., margin + hardest_positive - hardest_negative)
        loss = tf.log1p(tf.exp(hardest_positive - hardest_negative))

        return loss

      loss = tf.map_fn(get_loss, tf.range(0, size), dtype=tf.float32)

      self.loss = tf.reduce_sum(loss)
      self.add_scalar_summary(self.loss, "loss")
      self.n_features = n_features

      ## Print - debug example code
      # def test(a):
      #   print(a)
      #   return numpy.array([5], dtype="int32")
      #
      # t, = tf.py_func(test, [WHATEVER YOU WANT TO PRINT], [tf.int32])
      # with tf.control_dependencies([t]):
      #   loss = tf.identity(loss)
예제 #20
0
    def __init__(self,
                 name,
                 inputs,
                 targets,
                 n_classes,
                 n_clusters,
                 tower_setup,
                 use_complete_batch,
                 use_SPN,
                 exclude_zeros_from_loss,
                 original_labels=None,
                 margin=2.0,
                 dropout=0.0,
                 l2=L2_DEFAULT):
        super(Clustering, self).__init__()
        self.measures = {}
        inp, n_features_inp = prepare_collapsed_input_and_dropout(
            inputs, dropout)

        with tf.variable_scope(name, reuse=tf.AUTO_REUSE):
            W = self.create_weight_variable("W", [n_features_inp, n_clusters],
                                            l2, tower_setup)
            b = self.create_bias_variable("b", [n_clusters], tower_setup)
            y_pred = tf.matmul(inp, W) + b
            y_pred = tf.nn.softmax(y_pred, -1, 'softmax')
            self.outputs = [y_pred]

            summ = tf.summary.histogram("softmax", y_pred)
            self.summaries.append(summ)

            if use_complete_batch:
                #original_labels = targets
                curr = y_pred
                batch_size = smart_shape(curr)[0]
                curr1 = curr[:, tf.newaxis, :]
                curr2 = curr[tf.newaxis, :, :]

                curr1 = tf.transpose(curr1, perm=[1, 0, 2])
                curr1_big = tf.tile(curr1, [batch_size, 1, 1])
                curr1_big = tf.transpose(curr1_big, perm=[1, 0, 2])
                curr2_big = tf.tile(curr2, [batch_size, 1, 1])

                boolean_target = tf.cast(tf.ones([batch_size, batch_size]),
                                         tf.bool)
                #### Following extracts one sided + diagonal, but for now we are using both sided as concat is non-symmetric
                #### In future may want to remove the diagonal
                # boolean_target = tf.matrix_band_part(boolean_target, -1, 0),tf.bool

                y_pred0 = tf.boolean_mask(curr1_big, boolean_target)
                y_pred1 = tf.boolean_mask(curr2_big, boolean_target)

                if not use_SPN:
                    targets1 = targets[:, tf.newaxis]
                    targets2 = targets[tf.newaxis, :]
                    whole_targets = tf.cast(tf.equal(targets1, targets2),
                                            tf.int32)
                    targets = tf.boolean_mask(whole_targets, boolean_target)
            else:
                y_pred0 = y_pred[0::2]
                y_pred1 = y_pred[1::2]
                targets = targets[::2]

            if original_labels is not None:
                cluster_ids = tf.argmax(y_pred, axis=-1)
                self.measures[Constants.CLUSTER_IDS] = [cluster_ids]
                self.measures[Constants.ORIGINAL_LABELS] = [original_labels]

            #y_pred0_stopped = tf.stop_gradient(y_pred0)
            #y_pred1_stopped = tf.stop_gradient(y_pred1)

            def kl(x, y):
                epsilon = tf.constant(1e-8, tf.float32)
                x += epsilon
                y += epsilon
                return tf.reduce_sum(x * tf.log(x / y), axis=-1)

            kl1 = kl(y_pred0, y_pred1)
            kl2 = kl(y_pred1, y_pred0)

            #kl1 = kl(y_pred0_stopped, y_pred1)
            #kl2 = kl(y_pred1_stopped, y_pred0)

            def Lh(x):
                return tf.nn.relu(margin - x)
                # return tf.nn.softplus(-x)

            pos_loss = kl1 + kl2
            neg_loss = Lh(kl1) + Lh(kl2)
            loss = tf.where(tf.cast(targets, tf.bool), pos_loss, neg_loss)
            if exclude_zeros_from_loss:
                norm_factor = tf.maximum(
                    tf.count_nonzero(loss, dtype=tf.float32), 1.0)
                loss /= norm_factor
                loss *= tf.cast(smart_shape(inp)[0], tf.float32)
            elif use_complete_batch:
                loss /= tf.cast(smart_shape(inp)[0], tf.float32)
            self.loss = tf.reduce_sum(loss)
            self.add_scalar_summary(self.loss, "loss")