예제 #1
0
    def generate_triplets(df, ps, num_triplets, features, preserved_features,
                          margin):
        def make_dictionary_for_face_class(df):
            '''
              - face_classes = {'class0': [class0_id0, ...], 'class1': [class1_id0, ...], ...}
            '''
            face_classes = dict()
            for idx, label in enumerate(df['class']):
                if label not in face_classes:
                    face_classes[label] = []
                face_classes[label].append(df.iloc[idx, 0])
            return face_classes

        triplets = []
        classes = ps['class'].unique()
        face_classes = make_dictionary_for_face_class(df)
        preserved_image = make_dictionary_for_face_class(ps)
        i = 0
        now_time = datetime.datetime.now()
        while i < num_triplets + 1:
            '''
              - all three image is selected from new train set
            '''

            pos_class = np.random.choice([7, 8, 9])
            neg_class = np.random.choice([7, 8, 9])
            while len(face_classes[pos_class]) < 2:
                pos_class = np.random.choice([7, 8, 9])
            while pos_class == neg_class:
                neg_class = np.random.choice([7, 8, 9])

            pos_name = df.loc[df['class'] == pos_class, 'name'].values[0]
            neg_name = df.loc[df['class'] == neg_class, 'name'].values[0]

            if len(face_classes[pos_class]) == 2:
                ianc, ipos = np.random.choice(2, size=2, replace=False)
            else:
                ianc = np.random.randint(0, len(face_classes[pos_class]))
                ipos = np.random.randint(0, len(face_classes[pos_class]))
                while ianc == ipos:
                    ipos = np.random.randint(0, len(face_classes[pos_class]))
            ineg = np.random.randint(0, len(face_classes[neg_class]))

            triplets.append([
                face_classes[pos_class][ianc], face_classes[pos_class][ipos],
                face_classes[neg_class][ineg], pos_class, neg_class, pos_name,
                neg_name, 1, 1, 1
            ])
            i += 1
        i = 0
        last_time = now_time
        now_time = datetime.datetime.now()
        print(now_time - last_time)
        while i < num_triplets + 1:
            '''
                - all three images are selected from preserved images
            '''
            pos_class = np.random.choice(classes)
            neg_class = np.random.choice(classes)
            while len(preserved_image[pos_class]) < 2:
                pos_class = np.random.choice(classes)
            while pos_class == neg_class:
                neg_class = np.random.choice(classes)

            pos_name = ps.loc[ps['class'] == pos_class, 'name'].values[0]
            neg_name = ps.loc[ps['class'] == neg_class, 'name'].values[0]

            if len(preserved_image[pos_class]) == 2:
                ianc, ipos = np.random.choice(2, size=2, replace=False)
            else:
                ianc = np.random.randint(0, len(preserved_image[pos_class]))
                ipos = np.random.randint(0, len(preserved_image[pos_class]))
                while ianc == ipos:
                    ipos = np.random.randint(0,
                                             len(preserved_image[pos_class]))
            ineg = np.random.randint(0, len(preserved_image[neg_class]))

            triplets.append([
                preserved_image[pos_class][ianc],
                preserved_image[pos_class][ipos],
                preserved_image[neg_class][ineg], pos_class, neg_class,
                pos_name, neg_name, 2, 2, 2
            ])
            i += 1
        i = 0
        last_time = now_time
        now_time = datetime.datetime.now()
        print(now_time - last_time)
        while i < num_triplets + 1:
            '''
                -a and p are from preserved images
                -n is from new train set
            '''
            pos_class = np.random.choice(classes)
            neg_class = np.random.choice([7, 8, 9])
            while len(preserved_image[pos_class]) < 2:
                pos_class = np.random.choice(classes)
            while pos_class == neg_class:
                neg_class = np.random.choice([7, 8, 9])

            pos_name = ps.loc[ps['class'] == pos_class, 'name'].values[0]
            neg_name = df.loc[df['class'] == neg_class, 'name'].values[0]

            if len(preserved_image[pos_class]) == 2:
                ianc, ipos = np.random.choice(2, size=2, replace=False)
            else:
                ianc = np.random.randint(0, len(preserved_image[pos_class]))
                ipos = np.random.randint(0, len(preserved_image[pos_class]))
                while ianc == ipos:
                    ipos = np.random.randint(0,
                                             len(preserved_image[pos_class]))
            ineg = np.random.randint(0, len(face_classes[neg_class]))

            a_position = pos_class * 3 + ianc
            p_position = pos_class * 3 + ipos
            n_position = \
                df.loc[df['class'] == neg_class, 'id'].ix[df['id'] == face_classes[neg_class][ineg]].index.values[0]

            l2_dist = PairwiseDistance(2)
            dp = l2_dist.forward_val(preserved_features[a_position],
                                     preserved_features[p_position])
            dn = l2_dist.forward_val(preserved_features[a_position],
                                     features[n_position])

            if dp - dn + margin > 0:
                triplets.append([
                    preserved_image[pos_class][ianc],
                    preserved_image[pos_class][ipos],
                    face_classes[neg_class][ineg], pos_class, neg_class,
                    pos_name, neg_name, 2, 2, 1
                ])
                i += 1
        i = 0
        last_time = now_time
        now_time = datetime.datetime.now()
        print(now_time - last_time)
        while i < num_triplets + 1:
            '''
                -a is from preserved images
                -p and n are from new train set
            '''

            pos_class = np.random.choice([7, 8, 9])
            neg_class = np.random.choice([7, 8, 9])
            while len(face_classes[pos_class]) < 2:
                pos_class = np.random.choice([7, 8, 9])
            while pos_class == neg_class:
                neg_class = np.random.choice([7, 8, 9])

            pos_name = ps.loc[ps['class'] == pos_class, 'name'].values[0]
            neg_name = df.loc[df['class'] == neg_class, 'name'].values[0]

            if len(face_classes[pos_class]) == 2:
                ianc, ipos = np.random.choice(2, size=2, replace=False)
            else:
                ianc = np.random.randint(0, len(preserved_image[pos_class]))
                ipos = np.random.randint(0, len(face_classes[pos_class]))
            ineg = np.random.randint(0, len(face_classes[neg_class]))

            a_position = \
                ps.loc[ps['class'] == pos_class, 'id'].ix[ps['id'] == preserved_image[pos_class][ianc]].index.values[0]
            p_position = \
                df.loc[df['class'] == pos_class, 'id'].ix[df['id'] == face_classes[pos_class][ipos]].index.values[0]
            n_position = \
                df.loc[df['class'] == neg_class, 'id'].ix[df['id'] == face_classes[neg_class][ineg]].index.values[0]

            l2_dist = PairwiseDistance(2)
            dp = l2_dist.forward_val(preserved_features[a_position],
                                     features[p_position])
            dn = l2_dist.forward_val(preserved_features[a_position],
                                     features[n_position])

            if dp - dn + margin > 0:
                triplets.append([
                    preserved_image[pos_class][ianc],
                    face_classes[pos_class][ipos],
                    face_classes[neg_class][ineg], pos_class, neg_class,
                    pos_name, neg_name, 2, 1, 1
                ])
                i += 1
        i = 0
        last_time = now_time
        now_time = datetime.datetime.now()
        print(now_time - last_time)
        while i < num_triplets:
            '''
                -a and p are from new train set
                -n is from pre 
            '''

            pos_class = np.random.choice([7, 8, 9])
            neg_class = np.random.choice(classes)
            while len(face_classes[pos_class]) < 2:
                pos_class = np.random.choice([7, 8, 9])
            while pos_class == neg_class:
                neg_class = np.random.choice(classes)

            pos_name = df.loc[df['class'] == pos_class, 'name'].values[0]
            neg_name = ps.loc[ps['class'] == neg_class, 'name'].values[0]

            if len(face_classes[pos_class]) == 2:
                ianc, ipos = np.random.choice(2, size=2, replace=False)
            else:
                ianc = np.random.randint(0, len(face_classes[pos_class]))
                ipos = np.random.randint(0, len(face_classes[pos_class]))
                while ianc == ipos:
                    ipos = np.random.randint(0, len(face_classes[pos_class]))
            ineg = np.random.randint(0, len(preserved_image[neg_class]))

            a_position = \
                df.loc[df['class'] == pos_class, 'id'].ix[df['id'] == face_classes[pos_class][ianc]].index.values[0]
            p_position = \
                df.loc[df['class'] == pos_class, 'id'].ix[df['id'] == face_classes[pos_class][ipos]].index.values[0]
            n_position = \
                ps.loc[ps['class'] == neg_class, 'id'].ix[ps['id'] == preserved_image[neg_class][ineg]].index.values[0]

            l2_dist = PairwiseDistance(2)
            dp = l2_dist.forward_val(features[a_position],
                                     features[p_position])
            dn = l2_dist.forward_val(features[a_position],
                                     preserved_features[n_position])

            if dp - dn + margin > 0:
                triplets.append([
                    face_classes[pos_class][ianc],
                    face_classes[pos_class][ipos],
                    preserved_image[neg_class][ineg], pos_class, neg_class,
                    pos_name, neg_name, 1, 1, 2
                ])
                i += 1
        i = 0
        last_time = now_time
        now_time = datetime.datetime.now()
        print(now_time - last_time)
        while i < num_triplets:
            '''
                -a is from new train set
                -p and n is from pre 
            '''

            pos_class = np.random.choice([7, 8, 9])
            neg_class = np.random.choice(classes)
            while len(face_classes[pos_class]) < 2:
                pos_class = np.random.choice([7, 8, 9])
            while pos_class == neg_class:
                neg_class = np.random.choice(classes)

            pos_name = df.loc[df['class'] == pos_class, 'name'].values[0]
            neg_name = ps.loc[ps['class'] == neg_class, 'name'].values[0]

            if len(face_classes[pos_class]) == 2:
                ianc, ipos = np.random.choice(2, size=2, replace=False)
            else:
                ianc = np.random.randint(0, len(face_classes[pos_class]))
                ipos = np.random.randint(0, len(preserved_image[pos_class]))
            ineg = np.random.randint(0, len(preserved_image[neg_class]))

            a_position = \
                df.loc[df['class'] == pos_class, 'id'].ix[df['id'] == face_classes[pos_class][ianc]].index.values[0]
            p_position = \
                ps.loc[ps['class'] == pos_class, 'id'].ix[ps['id'] == preserved_image[pos_class][ipos]].index.values[0]
            n_position = \
                ps.loc[ps['class'] == neg_class, 'id'].ix[ps['id'] == preserved_image[neg_class][ineg]].index.values[0]

            l2_dist = PairwiseDistance(2)
            dp = l2_dist.forward_val(features[a_position],
                                     preserved_features[p_position])
            dn = l2_dist.forward_val(features[a_position],
                                     preserved_features[n_position])

            if dp - dn + margin > 0:
                triplets.append([
                    face_classes[pos_class][ianc],
                    preserved_image[pos_class][ipos],
                    preserved_image[neg_class][ineg], pos_class, neg_class,
                    pos_name, neg_name, 1, 2, 2
                ])
                i += 1
        last_time = now_time
        now_time = datetime.datetime.now()
        print(now_time - last_time)
        return triplets
예제 #2
0
def select_three_sample(model, args, epoch, writer):
    model.eval()
    num_each_class = [500, 500, 500, 500, 500, 500, 500, 50, 50, 50]
    # num_each_class = [500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500, 500]
    transform = transforms.Compose([
        transforms.Resize(32),
        transforms.ToTensor(),
        transforms.Normalize(mean=np.array([0.485, 0.456, 0.406]),
                             std=np.array([0.229, 0.224, 0.225])),
    ])
    train_set = torchvision.datasets.ImageFolder(root=args.train_set,
                                                 transform=transform)
    train_loader = torch.utils.data.DataLoader(train_set,
                                               batch_size=args.test_batch_size,
                                               shuffle=False)

    NearestCentroid, KNeighbors, features, label, labels = [], [], [], [], []
    for i, (data, target) in enumerate(train_loader):
        data, target = data.cuda(), target.cuda()
        data, target = Variable(data), Variable(target)
        output = model(data)
        features.extend(output.data)
        KNeighbors.extend(output.data.cpu().numpy())
        labels.extend(target.data.cpu().numpy())

    count = 0
    l2_dist = PairwiseDistance(2)
    destination = os.path.join(args.check_path, 'epoch' + str(epoch))
    if not os.path.exists(destination):
        os.mkdir(destination)
    for i in range(len(num_each_class)):
        num_sample = features[count:count + num_each_class[i]]
        m = torch.tensor(np.zeros(args.embedding_size)).float().cuda()
        for x in num_sample:
            m += x
        m /= num_each_class[i]

        sample1 = min(num_sample, key=lambda x: l2_dist.forward_val(x, m))
        sample2 = max(num_sample,
                      key=lambda x: l2_dist.forward_val(x, sample1))
        sample3 = max(num_sample,
                      key=lambda x: l2_dist.forward_val(x, sample2))
        NearestCentroid.append(sample1.cpu().numpy())
        label.append(i)

        sample1_loc, sample2_loc, sample3_loc = -1, -1, -1
        for j in range(num_sample.__len__()):
            if (num_sample[j] == sample1).all():
                sample1_loc = j
            if (num_sample[j] == sample2).all():
                sample2_loc = j
            if (num_sample[j] == sample3).all():
                sample3_loc = j

        frame = pd.read_csv(args.train_set_csv)
        destination_class = os.path.join(
            destination, str(frame['name'][count + sample1_loc]))
        if not os.path.exists(destination_class):
            os.mkdir(destination_class)
        sample1_source = os.path.join(
            args.train_set, str(frame['name'][count + sample1_loc]),
            str(frame['id'][count + sample1_loc]) + '.png')
        sample2_source = os.path.join(
            args.train_set, str(frame['name'][count + sample2_loc]),
            str(frame['id'][count + sample2_loc]) + '.png')
        sample3_source = os.path.join(
            args.train_set, str(frame['name'][count + sample3_loc]),
            str(frame['id'][count + sample3_loc]) + '.png')
        shutil.copy(sample1_source, destination_class + '/sample1.png')
        shutil.copy(sample2_source, destination_class + '/sample2.png')
        shutil.copy(sample3_source, destination_class + '/sample3.png')
        count += num_each_class[i]

    clf = neighbors.NearestCentroid()
    clf.fit(NearestCentroid, label)

    return features, labels, clf, destination
예제 #3
0
    def generate_triplets(df, num_triplets, features, margin):
        def make_dictionary_for_face_class(df):
            '''
              - face_classes = {'class0': [class0_id0, ...], 'class1': [class1_id0, ...], ...}
            '''
            face_classes = dict()
            for idx, label in enumerate(df['class']):
                if label not in face_classes:
                    face_classes[label] = []
                face_classes[label].append(df.iloc[idx, 0])
            return face_classes

        triplets = []
        classes = df['class'].unique()
        face_classes = make_dictionary_for_face_class(df)
        i = 0
        while i < num_triplets:
            '''
              - randomly choose anchor, positive and negative images for triplet loss
              - anchor and positive images in pos_class
              - negative image in neg_class
              - at least, two images needed for anchor and positive images in pos_class
              - negative image should have different class as anchor and positive images by definition
            '''

            pos_class = np.random.choice(classes)
            neg_class = np.random.choice(classes)
            while len(face_classes[pos_class]) < 2:
                pos_class = np.random.choice(classes)
            while pos_class == neg_class:
                neg_class = np.random.choice(classes)

            pos_name = df.loc[df['class'] == pos_class, 'name'].values[0]
            neg_name = df.loc[df['class'] == neg_class, 'name'].values[0]
            if len(face_classes[pos_class]) == 2:
                ianc, ipos = np.random.choice(2, size=2, replace=False)
            else:
                ianc = np.random.randint(0, len(face_classes[pos_class]))
                ipos = np.random.randint(0, len(face_classes[pos_class]))
                while ianc == ipos:
                    ipos = np.random.randint(0, len(face_classes[pos_class]))
            ineg = np.random.randint(0, len(face_classes[neg_class]))

            a_position = df.loc[df['class'] == pos_class, 'id'].ix[
                df['id'] == face_classes[pos_class][ianc]].index.values[0]
            p_position = df.loc[df['class'] == pos_class, 'id'].ix[
                df['id'] == face_classes[pos_class][ipos]].index.values[0]
            n_position = df.loc[df['class'] == neg_class, 'id'].ix[
                df['id'] == face_classes[neg_class][ineg]].index.values[0]

            l2_dist = PairwiseDistance(2)
            dp = l2_dist.forward_val(features[a_position],
                                     features[p_position])
            dn = l2_dist.forward_val(features[a_position],
                                     features[n_position])

            if dp - dn + margin > 0:
                triplets.append([
                    face_classes[pos_class][ianc],
                    face_classes[pos_class][ipos],
                    face_classes[neg_class][ineg], pos_class, neg_class,
                    pos_name, neg_name
                ])
                i += 1

        return triplets