diff --git a/data/dataset.py b/data/dataset.py new file mode 100644 index 0000000..2b961b6 --- /dev/null +++ b/data/dataset.py @@ -0,0 +1,312 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Distributed under terms of the MIT license. + +""" +Dataset preprocessing class for dataloader. +""" +from torch.utils import data +import torch +import os +from PIL import Image +from PIL import ImageChops, ImageEnhance +from random import shuffle +import os.path as osp +from torchvision import transforms as T +from torch.utils.data import DataLoader +import numpy as np +import random +import xml.etree.ElementTree as ET +import pdb + +def constrain(min_val, max_val, val): + return min(max_val, max(min_val, val)) + +class Pair_Dataset(data.Dataset): + + def __init__(self, im_root, scale_size=512, label_shape=(7, 14, 14), transforms=None, train=False, test=False): + """Get all images and spearate dataset to training and testing set.""" + self.test, self.train = test, train + self.im_root = im_root + self.imkey_list = self.get_imkeylist() + self.label_shape = label_shape + self.scale_size = scale_size + self.tensor2PIL = T.Compose([T.ToPILImage()]) + # Separate dataset + if self.test: + self.imkey_list = self.imkey_list + elif self.train: + self.imkey_list = self.imkey_list[:int(0.8*len(self.imkey_list))] + else: + self.imkey_list = self.imkey_list[int(0.8*len(self.imkey_list)):] + self.imnum = len(self.imkey_list) + + # Transform + if transforms is None: + # 在ToTensor这个类中已经实现了0~1的映射 + normalize = T.Normalize(mean=[0.485, 0.456, 0.406], + std =[0.229, 0.224, 0.225]) + # No enhancement on training and validating set + self.transforms = T.Compose([T.ToTensor()]) + #, normalize]) + + def __getitem__(self, index): + """ Return a pair of images. """ + ima_path = osp.join(self.im_root, self.imkey_list[index]+"_a.jpg") + imb_path = osp.join(self.im_root, self.imkey_list[index]+"_b.jpg") + im_a, im_b, flip, dx, dy, sx, sy = self.load_pair_im(ima_path, imb_path) + + + """ Return normalized groundtruth bboxes space. """ + labela_path = osp.join(self.im_root, self.imkey_list[index]+"_a.xml") + labelb_path = osp.join(self.im_root, self.imkey_list[index]+"_b.xml") + if random.uniform(0, 1) > 0.5 and self.train == True: + im_a, im_b = im_b, im_a + labela_path, labelb_path = labelb_path, labela_path + label = self.load_pair_label(labela_path, labelb_path, flip, dx, dy, sx, sy) + return index, im_a, im_b, label + + def load_pair_im(self, ima_path, imb_path): + """ Modify PAIR tagged code to make it to load single image """ + im_ori, impair_ori = Image.open(ima_path), Image.open(imb_path) #PAIR + ow, oh = im_ori.size[0], im_ori.size[1] + if self.train == True and self.test == False: + #随机crop和随机翻转 + jitter = 0.4 + dw, dh = int(ow*jitter), int(oh*jitter) + pleft, pright = random.randint(-dw, dw), random.randint(-dw, dw) + ptop, pbot = random.randint(-dh, dh), random.randint(-dh, dh) + swidth, sheight = ow-pleft-pright, oh-ptop-pbot # image size after random + sx, sy = float(swidth) / ow, float(sheight) / oh #random后相对于原图的比例 + im_cropped = im_ori.crop((pleft, ptop, ow-pright, oh-pbot)) # (left, upper, right, lower) + impair_cropped = impair_ori.crop((pleft, ptop, ow-pright, oh-pbot)) #PAIR + dx, dy = (float(pleft)/ow) / sx, (float(ptop)/oh) / sy #偏移量相对于random后的图像尺寸 + im_sized = im_cropped.resize((self.scale_size, self.scale_size)) #将crop后的图像resize成512 + impair_sized = impair_cropped.resize((self.scale_size, self.scale_size)) #PAIR + flip = (random.uniform(0, 1) > 0.5) + if flip: + im_sized = im_sized.transpose(Image.FLIP_LEFT_RIGHT) + impair_sized = impair_sized.transpose(Image.FLIP_LEFT_RIGHT) #PAIR + + #亮度 + bright_factor = random.uniform(0.8, 1.2) + im_sized = self.RandomBrightness(im_sized, bright_factor) + impair_sized = self.RandomBrightness(impair_sized, bright_factor) + + flag = (random.uniform(0, 1) > 0.5) + if flag: + #对比度 + contra_factor = random.uniform(0.5, 1.5) + im_sized = self.RandomContrast(im_sized, contra_factor) + impair_sized = self.RandomContrast(impair_sized, contra_factor) + else: + #对比度 + contra_factor = random.uniform(0.5, 1.5) + im_sized = self.RandomContrast(im_sized, contra_factor) + impair_sized = self.RandomContrast(impair_sized, contra_factor) + #饱和度 + satu_factor = random.uniform(0.5, 1.5) + im_sized = self.RandomSaturation(im_sized, satu_factor) + impair_sized = self.RandomSaturation(impair_sized, satu_factor) + #锐度 + shap_factor = random.uniform(0, 2.0) + im_sized = self.RandomSharp(im_sized, shap_factor) + impair_sized = self.RandomSharp(impair_sized, shap_factor) + #通道变换 + swap_flag = (random.uniform(0, 1) > 0.5) + if swap_flag: + swap_factor = random.randint(0, 5) + im_sized = self.RandomLightingNoise(im_sized, swap_factor) + impair_sized = self.RandomLightingNoise(impair_sized, swap_factor) + else: + dx = dy = 0 + flip = False + im_sized = im_ori.resize((self.scale_size, self.scale_size)) + impair_sized = impair_ori.resize((self.scale_size, self.scale_size)) #PAIR + sx, sy = 1, 1 # NOTE here this BUG + im = self.transforms(im_sized) # Normalize and adjust the mean and var + impair = self.transforms(impair_sized) #PAIR + + return im, impair, flip, dx, dy, sx, sy + + + def load_pair_label(self, labela_path, labelb_path, flip, dx, dy, sx, sy): + labela = self.get_label(labela_path, flip, dx, dy, sx, sy) + labelb = self.get_label(labelb_path, flip, dx, dy, sx, sy) + return self.mergelabel(labela, labelb) + + # GET LABEL TO STANDARD FORMAT, 5x14x14 + def get_label(self, label_path, flip, dx, dy, sx, sy): + ROW, COL = self.label_shape[1], self.label_shape[2] + label = np.zeros((5, self.label_shape[1], self.label_shape[2])) + if osp.exists(label_path): + tree = ET.parse(label_path) + im_size = tree.findall("size")[0] + ow, oh = int(im_size.find("width").text), int(im_size.find("height").text) #得到原图尺寸 + boxes = [] + for obj in tree.findall('object'): + bbox = obj.find('bndbox') + t_boxes = [int(bbox.find('xmin').text), int(bbox.find('ymin').text), + int(bbox.find('xmax').text), int(bbox.find('ymax').text)] #左上,右下,真实坐标 + boxes.append([1, + (t_boxes[0] + t_boxes[2])/(2.0*ow), # center x 归一化后 + (t_boxes[1] + t_boxes[3])/(2.0*oh), # center y + (t_boxes[2] - t_boxes[0])*1.0/ow, # w + (t_boxes[3] - t_boxes[1])*1.0/oh]) # h + ### Correct boxes ### + for i in range(len(boxes)): + left = (boxes[i][1] - boxes[i][3] / 2) * (1.0 / sx) - dx #crop后的左上 相对于crop后图片归一化后的坐标 + right = (boxes[i][1] + boxes[i][3] / 2) * (1.0 / sx) - dx + top = (boxes[i][2] - boxes[i][4] / 2) * (1.0 / sy) - dy + bottom = (boxes[i][2] + boxes[i][4] / 2) * (1.0 / sy) - dy + if flip: + swap = left + left = 1.0 - right + right = 1.0 - swap + + left = constrain(0, 1, left) + right = constrain(0, 1, right) + top = constrain(0, 1, top) + bottom = constrain(0, 1, bottom) + + boxes[i][1] = (left + right) / 2 + boxes[i][2] = (top + bottom) / 2 + boxes[i][3] = constrain(0, 1, right - left) + boxes[i][4] = constrain(0, 1, bottom - top) + + lst = list(range(len(boxes))) + shuffle(lst) + for i in lst: + x, y, w, h = boxes[i][1:] + x, y, w, h = constrain(0, 1, x), constrain(0, 1, y), constrain(0, 1, w), constrain(0, 1, h) + if (w < 0.01 or h < 0.01): + continue + col, row = int(x * self.label_shape[2]), int(y * self.label_shape[1]) + x, y = x * self.label_shape[2] - col, y * self.label_shape[1] - row #xy为相对于grid左上角的偏移量, wh为相对全图的归一化值 + if label[0, row, col] != 0: + continue + label[:, row, col] = 1, x, y, w, h + return label + + def mergelabel(self, labela, labelb): + label = np.zeros(self.label_shape) + for row in range(self.label_shape[1]): + for col in range(self.label_shape[2]): + """ + You should be aware of these code: + We can set _ 11 ____, the object are in the same position on image a and image b + """ + if labela[0, row, col] == 1 and label[1, row, col] == 0: + label[0, row, col] = 1 + label[1, row, col] = 1 + label[3:7, row, col] = labela[1:, row, col] + if labelb[0, row, col] == 1 and label[2, row, col] == 0: + label[0, row, col] = 1 + label[2, row, col] = 1 + label[3:7, row, col] = labelb[1:, row, col] + return label + + def get_imkeylist(self): + imkey_list = [] + for i in os.listdir(self.im_root): + if i[-3:] == "jpg" and (i[:-6] not in imkey_list): + imkey_list.append(i[:-6]) + return imkey_list + + def __len__(self): + """ Return image pair number of the dataset. """ + return self.imnum + + def RandomBrightness(self, img, brightness): + enh_bri = ImageEnhance.Brightness(img) + img_bri = enh_bri.enhance(brightness) + return img_bri + + def RandomContrast(self, img, contrast): + enh_con = ImageEnhance.Contrast(img) + img_con = enh_con.enhance(contrast) + return img_con + + def RandomSaturation(self, img, saturation): + enh_col = ImageEnhance.Color(img) + img_col = enh_col.enhance(saturation) + return img_col + + def RandomSharp(self, img, sharpness): + enh_sha = ImageEnhance.Sharpness(img) + img_sha = enh_sha.enhance(sharpness) + return img_sha + + def RandomLightingNoise(self, img, swap): + r, g, b = img.split() + perms = ((0, 1, 2), (0, 2, 1), + (1, 0, 2), (1, 2, 0), + (2, 0, 1), (2, 1, 0)) + if swap == 0: + return Image.merge('RGB', (r, g, b)) + elif swap == 1: + return Image.merge('RGB', (r, b, g)) + elif swap == 2: + return Image.merge('RGB', (g, r, b)) + elif swap == 3: + return Image.merge('RGB', (g, b, r)) + elif swap == 4: + return Image.merge('RGB', (b, r, g)) + elif swap == 5: + return Image.merge('RGB', (b, g, r)) + + + +if __name__ == "__main__": + train_dataset = Pair_Dataset("./diff_vending/test", test=True) + trainloader = DataLoader(train_dataset, + batch_size=1, + shuffle=True, + num_workers=0) + #print (np.sort(train_dataset.imkey_list)) + #print (len(train_dataset.imkey_list)) + #for ii, (im, label) in enumerate(trainloader): + imkeys = train_dataset.imkey_list + for ii, (index, im_a, im_b, label) in enumerate(trainloader): + #print (ii, im_a.size(), labela.shape, im_b.size(), labelb.shape) + #print (type(im_a), type(labela)) + #print (labela.shape[2]*labela.shape[3]) + #print (index[:], "-----", ii) + #print (imkeys[index[0]]) + #exit() + print (label) + exit() + pass + + """ + diff_ab = self.transforms(ImageChops.subtract(im_a, im_b)) + diff_ba = self.transforms(ImageChops.subtract(im_b, im_a)) + ### TEST ### + dab = diff_ab.numpy() + dba = diff_ba.numpy() + #dab[dab < 0.5] = 0 + dab = self.tensor2PIL(torch.from_numpy(dab)) + #draw_bbox(dab, ) + dab.save("/tmp/test/" + "{:05d}".format(index) + "_render_a.jpg") + t = ImageChops.subtract(im_a, im_b) + t.save("/tmp/ori/" + "{:05d}".format(index) + "_render_a.jpg") + #dba[dba < 0.5] = 0 + dba = self.tensor2PIL(torch.from_numpy(dba)) + dba.save("/tmp/test/" + "{:05d}".format(index) + "_render_b.jpg") + t = ImageChops.subtract(im_b, im_a) + t.save("/tmp/ori/" + "{:05d}".format(index) + "_render_b.jpg") + posa = np.where(labela[0] == 1) + posb = np.where(labelb[0] == 1) + bboxa = labela[1:, posa[0], posa[1]].transpose() + bboxb = labelb[1:, posb[0], posb[1]].transpose() + def r(bbox, im_size): + bbox[:, 0], bbox[:, 2] = bbox[:, 0]*im_size[0], bbox[:, 2]*im_size[0] + bbox[:, 1], bbox[:, 3] = bbox[:, 1]*im_size[1], bbox[:, 3]*im_size[1] + return bbox + bboxa = r(bboxa, im_a.size) + bboxb = r(bboxb, im_a.size) + labelrender("/tmp/ori", index, bboxa, bboxb) + return index, im_a, im_b, labela, labelb + """ diff --git a/data/test.txt b/data/test.txt new file mode 100644 index 0000000..a0f8d20 --- /dev/null +++ b/data/test.txt @@ -0,0 +1,258 @@ +20181127143631550-1_1 +00504 +2629 +00577 +20181119001553661-3_1 +2228 +2698 +00570 +00188 +01_20181129_171018 +2320 +20181127202128385-3_1 +01_20181129_164021 +00086 +00617 +2358 +20181127060659119-4_1 +20181127232730486-4_1 +01_20181129_170956 +20181126091925175-3_1 +20181119100953681-4_1 +01_20181129_163541 +2081 +2028 +00283 +00599 +00558 +00559 +00556 +01_20181130_114605 +1028 +2338 +20181119100206773-4_1 +01_20181130_112105 +00017 +1182 +2111 +00560 +20181128152958928-2_1 +00553 +00160 +00158 +20181119100858359-4_1 +20181128151525391-4_1 +01_20181129_163630 +00322 +00483 +00592 +00590 +1271 +20181127225130464-4_1 +00148 +1613 +00582 +00510 +20181128163141660-4_1 +20181127000608157-3_1 +00124 +1054 +01_20181129_163223 +1137 +2326 +20181127090731639-4_1 +01_20181130_114020 +20181127093927314-3_1 +2194 +1352 +1024 +2700 +00252 +00008 +20181119010249153-3_1 +01_20181129_162204 +01_20181130_113021 +00336 +00401 +2484 +00552 +20181127010400516-4_1 +2261 +2395 +01_20181129_163640 +2093 +1585 +00347 +1008 +00024 +20181119074740282-4_1 +20181127193609846-3_1 +20181119003056169-4_1 +20181119114015234-4_1 +00583 +20181121115305927-3_1 +2613 +00045 +20181127192007651-3_1 +00597 +00586 +01_20181130_114715 +00571 +00563 +20181128164851714-4_1 +01_20181129_165426 +1326 +01_20181130_114247 +01_20181130_113830 +20181121102433336-3_1 +00581 +2634 +00490 +1555 +20181127234818657-4_1 +20181122104751604-4_1 +20181127105031029-4_1 +1504 +20181122004912957-4_1 +20181127093602079-4_1 +01_20181129_162025 +20181119103806077-3_1 +00212 +20181119102338821-3_1 +20181126150842329-2_1 +20181127225809473-4_1 +01_20181130_111018 +1036 +1589 +01_20181130_112142 +2245 +00591 +1405 +00202 +2632 +01_20181129_164132 +00311 +20181127141135919-3_1 +00074 +00566 +20181119121522826-3_1 +00572 +00568 +01_20181129_164142 +00579 +00407 +2522 +00356 +00215 +00576 +00082 +1305 +1311 +00593 +00287 +1178 +20181127084731348-3_1 +20181121084515953-4_1 +20181127103440197-3_1 +20181127001835192-3_1 +00088 +20181121101328111-3_1 +01_20181130_112315 +20181127233255999-3_1 +20181119080141778-4_1 +00468 +00589 +2277 +00600 +00318 +00346 +01_20181129_164346 +20181127114334846-4_1 +20181127121810604-3_1 +00058 +20181119010329472-3_1 +2054 +2105 +01_20181130_114011 +00587 +20181127100750374-4_1 +00187 +2530 +20181127225724763-3_1 +20181119001030373-4_1 +1313 +20181128165006188-3_1 +20181127204409242-3_1 +20181127100750951-3_1 +20181119102025466-3_1 +00604 +01_20181130_112333 +1419 +01_20181129_164606 +20181121081825418-3_1 +00598 +2265 +00554 +20181127214530402-3_1 +00596 +01_20181130_113602 +00073 +00618 +2352 +1500 +20181119102432463-3_1 +00194 +00313 +20181127141824375-3_1 +00249 +00344 +00567 +2476 +00406 +20181119001731002-3_1 +00595 +2591 +1243 +01_20181129_170740 +01_20181130_113849 +2571 +00452 +1032 +20181127224549751-3_1 +1253 +00506 +20181127235907253-3_1 +00480 +01_20181130_111936 +20181127234023371-3_1 +01_20181129_164052 +20181122072800722-3_1 +20181119114834805-4_1 +00070 +20181128152958928-3_1 +20181127020840416-3_1 +2070 +00111 +00359 +20181127113242211-4_1 +20181127131102552-3_1 +00087 +00389 +1534 +20181121095648297-3_1 +00569 +01_20181130_114101 +1168 +2079 +00291 +20181119111250170-3_1 +20181127030527265-4_1 +2619 +1117 +20181119110615882-4_1 +20181127230447816-3_1 +20181119111839746-3_1 +00561 +01_20181130_114235 +00565 +1425 diff --git a/data/testa.txt b/data/testa.txt new file mode 100644 index 0000000..63f1eb7 --- /dev/null +++ b/data/testa.txt @@ -0,0 +1,258 @@ +20181127143631550-1_1_a +00504_a +2629_a +00577_a +20181119001553661-3_1_a +2228_a +2698_a +00570_a +00188_a +01_20181129_171018_a +2320_a +20181127202128385-3_1_a +01_20181129_164021_a +00086_a +00617_a +2358_a +20181127060659119-4_1_a +20181127232730486-4_1_a +01_20181129_170956_a +20181126091925175-3_1_a +20181119100953681-4_1_a +01_20181129_163541_a +2081_a +2028_a +00283_a +00599_a +00558_a +00559_a +00556_a +01_20181130_114605_a +1028_a +2338_a +20181119100206773-4_1_a +01_20181130_112105_a +00017_a +1182_a +2111_a +00560_a +20181128152958928-2_1_a +00553_a +00160_a +00158_a +20181119100858359-4_1_a +20181128151525391-4_1_a +01_20181129_163630_a +00322_a +00483_a +00592_a +00590_a +1271_a +20181127225130464-4_1_a +00148_a +1613_a +00582_a +00510_a +20181128163141660-4_1_a +20181127000608157-3_1_a +00124_a +1054_a +01_20181129_163223_a +1137_a +2326_a +20181127090731639-4_1_a +01_20181130_114020_a +20181127093927314-3_1_a +2194_a +1352_a +1024_a +2700_a +00252_a +00008_a +20181119010249153-3_1_a +01_20181129_162204_a +01_20181130_113021_a +00336_a +00401_a +2484_a +00552_a +20181127010400516-4_1_a +2261_a +2395_a +01_20181129_163640_a +2093_a +1585_a +00347_a +1008_a +00024_a +20181119074740282-4_1_a +20181127193609846-3_1_a +20181119003056169-4_1_a +20181119114015234-4_1_a +00583_a +20181121115305927-3_1_a +2613_a +00045_a +20181127192007651-3_1_a +00597_a +00586_a +01_20181130_114715_a +00571_a +00563_a +20181128164851714-4_1_a +01_20181129_165426_a +1326_a +01_20181130_114247_a +01_20181130_113830_a +20181121102433336-3_1_a +00581_a +2634_a +00490_a +1555_a +20181127234818657-4_1_a +20181122104751604-4_1_a +20181127105031029-4_1_a +1504_a +20181122004912957-4_1_a +20181127093602079-4_1_a +01_20181129_162025_a +20181119103806077-3_1_a +00212_a +20181119102338821-3_1_a +20181126150842329-2_1_a +20181127225809473-4_1_a +01_20181130_111018_a +1036_a +1589_a +01_20181130_112142_a +2245_a +00591_a +1405_a +00202_a +2632_a +01_20181129_164132_a +00311_a +20181127141135919-3_1_a +00074_a +00566_a +20181119121522826-3_1_a +00572_a +00568_a +01_20181129_164142_a +00579_a +00407_a +2522_a +00356_a +00215_a +00576_a +00082_a +1305_a +1311_a +00593_a +00287_a +1178_a +20181127084731348-3_1_a +20181121084515953-4_1_a +20181127103440197-3_1_a +20181127001835192-3_1_a +00088_a +20181121101328111-3_1_a +01_20181130_112315_a +20181127233255999-3_1_a +20181119080141778-4_1_a +00468_a +00589_a +2277_a +00600_a +00318_a +00346_a +01_20181129_164346_a +20181127114334846-4_1_a +20181127121810604-3_1_a +00058_a +20181119010329472-3_1_a +2054_a +2105_a +01_20181130_114011_a +00587_a +20181127100750374-4_1_a +00187_a +2530_a +20181127225724763-3_1_a +20181119001030373-4_1_a +1313_a +20181128165006188-3_1_a +20181127204409242-3_1_a +20181127100750951-3_1_a +20181119102025466-3_1_a +00604_a +01_20181130_112333_a +1419_a +01_20181129_164606_a +20181121081825418-3_1_a +00598_a +2265_a +00554_a +20181127214530402-3_1_a +00596_a +01_20181130_113602_a +00073_a +00618_a +2352_a +1500_a +20181119102432463-3_1_a +00194_a +00313_a +20181127141824375-3_1_a +00249_a +00344_a +00567_a +2476_a +00406_a +20181119001731002-3_1_a +00595_a +2591_a +1243_a +01_20181129_170740_a +01_20181130_113849_a +2571_a +00452_a +1032_a +20181127224549751-3_1_a +1253_a +00506_a +20181127235907253-3_1_a +00480_a +01_20181130_111936_a +20181127234023371-3_1_a +01_20181129_164052_a +20181122072800722-3_1_a +20181119114834805-4_1_a +00070_a +20181128152958928-3_1_a +20181127020840416-3_1_a +2070_a +00111_a +00359_a +20181127113242211-4_1_a +20181127131102552-3_1_a +00087_a +00389_a +1534_a +20181121095648297-3_1_a +00569_a +01_20181130_114101_a +1168_a +2079_a +00291_a +20181119111250170-3_1_a +20181127030527265-4_1_a +2619_a +1117_a +20181119110615882-4_1_a +20181127230447816-3_1_a +20181119111839746-3_1_a +00561_a +01_20181130_114235_a +00565_a +1425_a diff --git a/data/testb.txt b/data/testb.txt new file mode 100644 index 0000000..89cb991 --- /dev/null +++ b/data/testb.txt @@ -0,0 +1,258 @@ +20181127143631550-1_1_b +00504_b +2629_b +00577_b +20181119001553661-3_1_b +2228_b +2698_b +00570_b +00188_b +01_20181129_171018_b +2320_b +20181127202128385-3_1_b +01_20181129_164021_b +00086_b +00617_b +2358_b +20181127060659119-4_1_b +20181127232730486-4_1_b +01_20181129_170956_b +20181126091925175-3_1_b +20181119100953681-4_1_b +01_20181129_163541_b +2081_b +2028_b +00283_b +00599_b +00558_b +00559_b +00556_b +01_20181130_114605_b +1028_b +2338_b +20181119100206773-4_1_b +01_20181130_112105_b +00017_b +1182_b +2111_b +00560_b +20181128152958928-2_1_b +00553_b +00160_b +00158_b +20181119100858359-4_1_b +20181128151525391-4_1_b +01_20181129_163630_b +00322_b +00483_b +00592_b +00590_b +1271_b +20181127225130464-4_1_b +00148_b +1613_b +00582_b +00510_b +20181128163141660-4_1_b +20181127000608157-3_1_b +00124_b +1054_b +01_20181129_163223_b +1137_b +2326_b +20181127090731639-4_1_b +01_20181130_114020_b +20181127093927314-3_1_b +2194_b +1352_b +1024_b +2700_b +00252_b +00008_b +20181119010249153-3_1_b +01_20181129_162204_b +01_20181130_113021_b +00336_b +00401_b +2484_b +00552_b +20181127010400516-4_1_b +2261_b +2395_b +01_20181129_163640_b +2093_b +1585_b +00347_b +1008_b +00024_b +20181119074740282-4_1_b +20181127193609846-3_1_b +20181119003056169-4_1_b +20181119114015234-4_1_b +00583_b +20181121115305927-3_1_b +2613_b +00045_b +20181127192007651-3_1_b +00597_b +00586_b +01_20181130_114715_b +00571_b +00563_b +20181128164851714-4_1_b +01_20181129_165426_b +1326_b +01_20181130_114247_b +01_20181130_113830_b +20181121102433336-3_1_b +00581_b +2634_b +00490_b +1555_b +20181127234818657-4_1_b +20181122104751604-4_1_b +20181127105031029-4_1_b +1504_b +20181122004912957-4_1_b +20181127093602079-4_1_b +01_20181129_162025_b +20181119103806077-3_1_b +00212_b +20181119102338821-3_1_b +20181126150842329-2_1_b +20181127225809473-4_1_b +01_20181130_111018_b +1036_b +1589_b +01_20181130_112142_b +2245_b +00591_b +1405_b +00202_b +2632_b +01_20181129_164132_b +00311_b +20181127141135919-3_1_b +00074_b +00566_b +20181119121522826-3_1_b +00572_b +00568_b +01_20181129_164142_b +00579_b +00407_b +2522_b +00356_b +00215_b +00576_b +00082_b +1305_b +1311_b +00593_b +00287_b +1178_b +20181127084731348-3_1_b +20181121084515953-4_1_b +20181127103440197-3_1_b +20181127001835192-3_1_b +00088_b +20181121101328111-3_1_b +01_20181130_112315_b +20181127233255999-3_1_b +20181119080141778-4_1_b +00468_b +00589_b +2277_b +00600_b +00318_b +00346_b +01_20181129_164346_b +20181127114334846-4_1_b +20181127121810604-3_1_b +00058_b +20181119010329472-3_1_b +2054_b +2105_b +01_20181130_114011_b +00587_b +20181127100750374-4_1_b +00187_b +2530_b +20181127225724763-3_1_b +20181119001030373-4_1_b +1313_b +20181128165006188-3_1_b +20181127204409242-3_1_b +20181127100750951-3_1_b +20181119102025466-3_1_b +00604_b +01_20181130_112333_b +1419_b +01_20181129_164606_b +20181121081825418-3_1_b +00598_b +2265_b +00554_b +20181127214530402-3_1_b +00596_b +01_20181130_113602_b +00073_b +00618_b +2352_b +1500_b +20181119102432463-3_1_b +00194_b +00313_b +20181127141824375-3_1_b +00249_b +00344_b +00567_b +2476_b +00406_b +20181119001731002-3_1_b +00595_b +2591_b +1243_b +01_20181129_170740_b +01_20181130_113849_b +2571_b +00452_b +1032_b +20181127224549751-3_1_b +1253_b +00506_b +20181127235907253-3_1_b +00480_b +01_20181130_111936_b +20181127234023371-3_1_b +01_20181129_164052_b +20181122072800722-3_1_b +20181119114834805-4_1_b +00070_b +20181128152958928-3_1_b +20181127020840416-3_1_b +2070_b +00111_b +00359_b +20181127113242211-4_1_b +20181127131102552-3_1_b +00087_b +00389_b +1534_b +20181121095648297-3_1_b +00569_b +01_20181130_114101_b +1168_b +2079_b +00291_b +20181119111250170-3_1_b +20181127030527265-4_1_b +2619_b +1117_b +20181119110615882-4_1_b +20181127230447816-3_1_b +20181119111839746-3_1_b +00561_b +01_20181130_114235_b +00565_b +1425_b diff --git a/data/train.txt b/data/train.txt new file mode 100644 index 0000000..346588c --- /dev/null +++ b/data/train.txt @@ -0,0 +1,1638 @@ +20181127010247462-3_1 +00011 +00516 +00132 +1595 +20181121085448544-4_1 +20181119074028183-4_1 +2702 +2200 +1149 +01_20181130_113541 +01_20181129_162346 +1593 +20181119115008758-3_1 +00446 +20181127003722887-3_1 +20181127221349165-3_1 +2409 +01_20181129_163552 +2488 +00231 +2514 +20181127150405880-4_1 +1459 +1216 +20181119103101979-4_1 +1186 +1508 +1052 +00520 +1020 +20181119111453434-3_1 +20181122075850574-4_1 +00635 +1490 +2186 +1627 +2496 +1514 +2423 +1384 +2692 +20181119112737741-4_1 +20181122010220543-3_1 +2149 +01_20181129_165126 +00459 +01_20181129_153720 +00430 +1548 +2680 +01_20181129_165321 +2538 +2113 +1158 +2550 +2364 +00454 +01_20181129_165104 +20181121100636351-4_1 +00161 +00101 +00284 +00525 +00427 +01_20181129_165117 +2334 +00497 +20181127154558261-3_1 +00342 +2281 +20181127192043512-4_1 +00149 +00631 +2052 +01_20181130_111557 +00204 +01_20181130_113151 +20181127115337607-3_1 +00207 +00315 +1212 +00388 +01_20181129_170716 +00463 +00246 +2034 +20181122045305786-3_1 +00286 +1085 +20181128000818090-4_1 +01_20181130_114158 +00038 +1123 +1346 +1164 +20181127202741788-3_1 +1079 +00428 +20181122002040183-3_1 +2350 +00543 +00172 +2050 +2704 +20181127230517978-3_1 +20181127233732091-4_1 +00274 +1259 +1180 +1518 +01_20181129_154029 +20181127125137475-4_1 +00475 +01_20181130_112021 +1093 +01_20181130_111543 +20181122122255595-3_1 +2623 +2115 +01_20181130_114706 +20181127235306727-4_1 +01_20181130_113056 +00502 +20181127080139736-4_1 +20181122121858920-3_1 +00199 +00348 +2370 +01_20181130_111411 +2279 +2595 +20181127104655615-3_1 +20181128140520488-2_1 +20181127201412607-4_1 +20181122122020986-4_1 +20181127085647130-4_1 +20181127222919415-3_1 +00615 +20181127221349165-4_1 +2046 +2026 +00613 +00621 +01_20181129_164335 +20181119001011513-4_1 +1443 +20181121104728463-3_1 +00601 +1520 +20181127074831430-3_1 +00203 +1328 +01_20181130_112055 +00285 +20181128165955211-4_1 +00338 +2311 +20181119001011513-3_1 +01_20181130_112643 +2419 +01_20181129_162144 +00289 +2241 +00178 +00397 +2378 +20181127224908985-3_1 +00634 +2307 +1449 +2078 +20181127095859036-4_1 +20181122113820449-3_1 +1139 +2500 +2174 +1060 +20181122121356092-4_1 +00411 +01_20181129_163255 +00162 +20181127114239684-3_1 +01_20181130_113649 +1261 +00551 +20181119060033421-3_1 +1597 +2362 +00317 +1153 +01_20181130_114733 +00402 +00622 +20181121000045721-3_1 +00108 +2143 +00046 +2180 +20181127234639001-3_1 +20181119115433970-4_1 +2708 +20181127152826262-2_1 +01_20181129_170644 +2064 +00151 +1364 +2285 +00189 +00067 +00241 +20181127015943051-3_1 +00434 +01_20181130_112118 +00456 +2251 +2121 +20181127192905305-4_1 +2044 +1392 +20181127173424096-3_1 +2405 +1239 +00224 +2615 +1474 +00129 +01_20181130_113707 +01_20181129_163138 +01_20181129_153359 +00117 +2399 +1174 +20181119120354969-3_1 +1022 +2198 +1344 +20181127202435882-4_1 +1407 +01_20181130_114523 +1004 +00375 +20181119115611830-3_1 +2656 +1397 +2451 +01_20181129_164849 +00602 +2465 +00027 +2652 +2263 +1447 +20181127103320404-4_1 +2455 +1587 +20181127232458604-4_1 +2212 +2617 +20181126150842329-3_1 +1528 +1573 +01_20181129_162300 +20181127005623155-4_1 +00328 +1358 +00334 +2309 +00119 +00094 +2520 +20181119071505728-4_1 +20181127072627756-3_1 +2099 +01_20181130_112735 +20181127093942344-3_1 +00010 +2162 +00147 +01_20181129_165052 +2040 +00065 +01_20181129_170749 +20181128171016809-3_1 +2239 +2589 +20181119103516969-4_1 +2534 +20181119091827752-4_1 +20181122121516628-4_1 +2097 +20181127001649948-4_1 +01_20181130_114543 +00495 +20181126001318139-3_1 +00423 +00441 +00649 +00190 +00173 +00606 +20181119080906986-3_1 +00367 +2032 +01_20181129_165515 +1218 +1473 +1524 +1552 +20181127171206811-4_1 +20181127075635128-4_1 +00610 +20181127165217153-3_1 +1062 +00487 +20181127230259506-3_1 +20181127131645187-3_1 +1492 +1247 +00421 +1565 +2546 +20181122104920241-4_1 +01_20181129_164635 +20181127224815294-3_1 +00335 +00168 +1372 +20181119100357744-3_1 +00432 +2431 +1234 +20181127213320791-3_1 +2374 +20181122104622680-3_1 +01_20181130_111046 +00439 +01_20181130_112129 +20181127093926326-3_1 +2394 +2599 +2249 +1559 +2141 +00612 +2230 +2473 +20181126150446094-3_1 +00078 +20181119000956191-4_1 +1245 +2559 +1567 +00371 +20181119101555200-3_1 +00227 +00093 +20181122000053603-3_1 +20181121080900752-4_1 +01_20181130_112046 +2565 +1401 +00263 +00603 +20181127213344114-3_1 +01_20181130_113533 +2457 +01_20181130_113725 +20181127224241714-3_1 +1439 +1208 +2196 +2275 +20181122002525297-3_1 +2668 +2020 +1417 +20181119121606579-3_1 +00526 +2449 +20181127000049917-4_1 +00290 +01_20181130_111616 +2577 +00264 +2216 +1453 +00538 +20181121035640835-3_1 +1287 +1309 +1083 +1378 +01_20181129_163321 +01_20181129_163349 +00170 +2376 +20181121075447311-3_1 +2257 +00614 +01_20181129_170633 +20181127225041872-4_1 +00329 +1283 +1265 +01_20181129_164113 +2166 +2425 +2670 +00039 +01_20181130_114050 +00051 +2271 +00131 +20181127100731082-3_1 +00549 +00064 +00469 +20181121095446044-4_1 +2123 +1394 +1512 +20181121105152214-3_1 +2696 +00354 +2137 +00222 +01_20181129_153746 +1224 +2607 +20181127230923581-3_1 +2287 +2129 +20181127045208109-3_1 +2372 +20181122001044041-4_1 +1089 +2145 +20181127012107319-4_1 +2083 +01_20181130_114149 +20181128143035800-4_1 +00300 +20181127030027783-3_1 +1348 +00217 +2210 +01_20181129_164313 +1228 +2548 +1360 +01_20181130_112341 +1563 +20181127181546252-4_1 +00229 +00001 +2091 +2390 +20181127002601832-4_1 +2676 +00418 +20181127010743544-3_1 +2192 +01_20181130_114305 +20181127091225228-4_1 +1330 +00278 +1010 +01_20181129_164122 +20181127005001010-3_1 +2324 +20181122001241021-3_1 +2512 +00232 +00314 +00457 +1237 +1390 +1285 +2528 +2407 +1615 +00118 +20181127001707407-3_1 +1409 +20181127010230808-3_1 +20181127090657770-4_1 +20181119121530242-3_1 +01_20181129_165506 +20181126001317621-3_1 +2206 +1368 +00044 +00100 +20181127233501087-3_1 +20181127233131581-4_1 +00141 +1230 +00524 +00049 +20181127075252321-3_1 +00609 +2151 +2160 +1482 +2202 +1421 +1269 +20181127082310414-3_1 +00299 +20181126200827642-3_1 +00165 +20181126062910882-3_1 +20181122000556040-4_1 +1293 +2117 +00620 +20181127143631550-2_1 +20181122000052952-4_1 +00505 +2036 +00273 +20181122122756372-3_1 +1530 +00121 +20181127221911018-4_1 +2459 +20181128164601694-3_1 +1289 +20181128165928786-4_1 +2000 +2131 +2038 +1561 +20181122023138352-4_1 +1550 +20181119115019411-3_1 +20181121000545831-4_1 +2267 +2318 +00650 +20181119121131883-3_1 +1281 +00081 +20181126020158129-3_1 +20181127182642611-3_1 +20181119115203907-4_1 +2532 +20181127221233330-3_1 +20181119104035113-4_1 +01_20181130_111006 +01_20181130_113010 +2678 +00398 +00142 +20181119113804614-3_1 +01_20181129_162043 +20181122122804487-4_1 +2437 +00339 +00450 +2581 +2366 +20181127232323939-4_1 +20181128140520488-3_1 +20181127013430922-4_1 +01_20181130_110917 +1127 +00268 +20181127095243300-4_1 +00057 +1526 +00307 +00192 +20181121093030671-3_1 +2392 +00130 +00288 +01_20181130_114214 +00321 +20181127233103007-4_1 +00025 +01_20181129_163527 +20181127232033013-3_1 +20181127094245754-4_1 +1411 +1476 +20181127125614960-3_1 +1141 +1099 +01_20181130_112556 +1016 +1629 +20181122075223501-4_1 +01_20181130_110930 +00079 +20181122081312622-4_1 +1206 +1038 +1226 +1577 +00503 +20181119113432375-3_1 +20181127013631966-4_1 +2579 +20181119105413400-4_1 +20181119043830890-4_1 +00537 +20181119002009034-3_1 +20181126001713374-4_1 +00269 +1214 +2380 +1603 +00365 +00084 +01_20181129_164254 +01_20181130_114724 +20181127221136584-2_1 +2008 +1315 +20181121092636613-3_1 +2510 +00641 +20181126035620948-4_1 +00127 +2074 +00097 +01_20181130_113029 +20181122000745091-3_1 +20181127030623221-4_1 +20181126000705693-3_1 +1255 +20181119121233585-4_1 +20181127013205532-3_1 +00236 +00633 +2601 +00331 +00164 +00471 +20181119002047873-3_1 +2439 +1145 +20181127215011177-3_1 +20181127225246457-3_1 +01_20181130_113839 +2474 +2016 +01_20181129_163949 +00080 +1445 +2095 +20181119115509287-3_1 +20181119101555200-4_1 +20181127074902009-4_1 +2273 +20181119111505568-4_1 +1162 +01_20181129_170606 +1431 +1273 +20181127003156459-3_1 +00125 +20181127014217867-4_1 +1395 +2660 +00632 +00013 +2397 +00611 +2666 +1488 +1510 +2243 +00254 +2068 +00358 +1484 +00616 +2506 +00373 +01_20181130_111532 +01_20181129_155810 +2524 +2597 +00177 +20181119111548548-3_1 +2006 +00403 +20181127154558624-3_1 +20181119005355036-3_1 +1295 +00448 +00489 +2322 +00006 +20181127175956914-3_1 +2674 +1303 +20181127093911883-3_1 +00377 +00445 +1196 +01_20181130_113200 +00098 +01_20181129_164625 +00544 +00384 +20181128132919701-2_1 +1435 +01_20181129_164615 +00201 +20181126150558628-2_1 +2672 +01_20181130_114654 +00063 +20181128164630165-4_1 +00619 +00153 +20181127100718633-3_1 +20181121110151434-4_1 +20181126152954169-2_1 +01_20181130_112744 +2461 +00419 +00120 +01_20181129_170944 +00133 +20181127170245383-4_1 +00640 +20181119075122755-4_1 +20181127220108359-4_1 +20181121113230538-4_1 +01_20181130_112715 +20181128000541194-3_1 +00512 +00301 +20181119103334351-4_1 +01_20181129_162250 +00390 +00174 +00305 +01_20181129_165045 +00638 +1609 +00062 +1423 +1467 +20181119110753201-4_1 +1111 +00466 +2283 +20181127075324924-4_1 +2062 +20181127154558624-4_1 +20181127194320187-2_1 +20181119105542999-4_1 +2253 +00015 +01_20181130_114616 +2119 +00186 +01_20181130_111503 +00298 +20181127092635045-3_1 +2190 +01_20181129_160809 +1601 +00145 +00214 +2435 +00636 +00637 +00357 +2060 +00433 +20181127224934339-4_1 +00250 +1619 +20181127204432329-3_1 +20181127101615633-4_1 +20181122020249975-3_1 +00330 +1320 +20181122080948511-3_1 +01_20181130_112956 +20181119103840446-4_1 +00259 +20181122032956669-3_1 +01_20181129_165416 +01_20181129_164030 +00341 +00156 +20181121110705119-3_1 +1251 +2401 +1469 +1200 +01_20181129_164645 +00184 +2147 +2542 +1184 +20181127092539655-4_1 +20181127075635128-3_1 +00355 +00037 +20181127222745426-4_1 +20181126004807199-3_1 +2710 +1103 +20181128130740139-3_1 +2508 +1299 +00422 +20181127123808454-3_1 +00023 +1538 +00102 +20181125100419346-4_1 +00060 +1374 +2467 +1465 +00206 +01_20181130_113715 +20181122073750667-3_1 +01_20181130_112034 +1121 +20181119092254236-3_1 +2072 +00208 +01_20181129_161900 +20181128132919701-1_1 +2642 +1605 +20181126014538184-4_1 +01_20181130_111925 +1018 +20181126181859959-2_1 +01_20181129_164836 +20181119105121435-3_1 +01_20181129_164900 +00253 +01_20181129_163123 +1076 +00521 +20181122020715219-3_1 +01_20181129_163334 +1297 +00107 +2332 +20181121114153157-4_1 +01_20181130_111114 +00368 +2164 +2010 +2101 +00643 +1427 +00316 +00191 +2561 +2328 +1316 +1494 +20181127072414460-4_1 +00332 +00484 +20181119112437378-4_1 +1030 +01_20181130_114639 +2178 +20181122010220543-4_1 +00447 +2153 +2336 +20181127230251206-3_1 +1332 +00461 +00089 +00485 +1166 +00180 +1540 +2557 +00295 +2403 +20181122080944034-4_1 +00522 +1220 +1631 +01_20181130_112010 +01_20181129_162225 +00550 +00053 +01_20181129_163155 +20181119094454220-3_1 +20181128105623531-2_1 +00104 +20181127095602614-4_1 +2638 +20181127013425289-3_1 +1623 +00429 +01_20181129_170833 +1621 +2644 +1249 +20181121072412351-3_1 +20181128165303879-3_1 +1210 +1522 +1078 +2413 +01_20181129_165526 +1376 +01_20181130_111031 +2305 +20181119121233585-3_1 +20181122005531396-3_1 +00527 +00021 +00069 +20181128163524688-3_1 +00605 +20181127144552058-3_1 +01_20181129_165134 +2076 +20181119013228333-4_1 +2609 +00181 +1257 +20181127004618957-3_1 +2486 +20181119114018628-3_1 +20181126003200345-3_1 +2567 +2214 +20181127163654619-4_1 +2498 +20181121112838990-4_1 +20181127121113397-4_1 +20181121104030474-3_1 +1338 +2585 +00042 +01_20181130_114534 +1502 +00496 +2415 +01_20181130_112323 +20181127004525695-3_1 +00352 +2605 +2139 +2492 +20181128000756689-4_1 +01_20181129_165404 +20181127010556106-4_1 +1072 +2184 +2621 +20181127115516857-3_1 +20181128111521435-1_1 +20181126013939987-3_1 +1611 +20181126015606934-4_1 +01_20181130_111433 +00416 +20181127230657705-3_1 +01_20181129_170655 +01_20181130_114036 +2107 +00221 +00626 +20181127215616945-4_1 +1236 +1291 +01_20181129_163507 +20181127234432832-3_1 +01_20181130_112417 +00247 +1050 +01_20181129_163602 +00498 +00122 +01_20181129_170759 +00323 +2330 +20181126200758882-2_1 +2316 +20181127220608827-4_1 +20181127003156459-4_1 +1241 +00360 +01_20181130_111957 +1279 +2208 +1267 +20181126185253527-2_1 +01_20181129_162103 +20181119112645446-3_1 +01_20181129_162121 +00491 +20181121080441207-3_1 +2648 +2014 +00509 +20181119121627237-3_1 +01_20181129_165452 +20181127000650698-3_1 +20181127000616541-4_1 +2575 +00340 +1002 +2188 +00378 +20181127113906983-4_1 +00210 +20181128164710878-3_1 +20181122104448601-4_1 +20181127093743341-4_1 +00435 +00624 +2259 +00195 +20181127234720221-3_1 +2135 +20181122041209218-3_1 +00541 +01_20181129_161828 +20181119004342745-3_1 +00137 +1068 +00256 +00144 +01_20181130_113210 +01_20181129_164153 +1012 +1048 +01_20181130_111059 +20181127055123153-3_1 +00395 +20181119004427545-3_1 +1143 +2297 +00477 +00417 +01_20181129_170811 +00143 +2611 +1119 +00018 +00425 +01_20181129_164039 +20181127232447851-3_1 +00175 +1451 +00266 +20181127101816754-4_1 +2469 +1058 +20181122002241659-4_1 +20181127002233018-4_1 +2354 +2417 +2516 +2536 +20181122003752841-3_1 +1334 +2301 +2563 +2636 +2127 +20181122001534897-4_1 +1553 +1277 +00095 +1105 +1064 +2640 +1441 +1575 +20181128164429752-3_1 +01_20181129_171009 +00379 +01_20181129_170729 +00531 +20181122002710407-4_1 +20181119115021579-4_1 +20181121000545831-3_1 +20181122002946945-3_1 +2089 +2224 +01_20181130_111947 +1115 +00200 +1125 +2482 +20181127010839884-3_1 +2441 +20181127092942460-4_1 +00412 +2631 +1044 +01_20181130_114553 +1607 +01_20181129_163616 +20181122004346347-4_1 +00333 +1354 +2157 +01_20181129_154119 +01_20181129_161819 +20181119002925693-3_1 +00228 +20181122122034042-3_1 +00464 +00140 +1040 +00628 +00090 +00326 +20181119100357744-4_1 +20181127075957107-4_1 +2356 +1599 +2125 +2463 +01_20181129_162410 +2443 +01_20181130_112625 +1356 +00262 +2247 +00488 +1147 +1222 +00139 +20181127233116905-4_1 +2348 +1198 +2471 +20181122001534897-3_1 +20181126004807199-4_1 +20181119091657430-3_1 +20181127075252570-3_1 +00393 +01_20181129_164000 +20181119010304348-4_1 +1170 +00380 +00022 +20181122122332937-3_1 +00630 +20181122104747521-4_1 +00061 +00319 +00364 +00392 +1437 +2289 +20181122121406951-3_1 +00005 +20181127121643578-4_1 +01_20181129_164322 +01_20181130_110853 +1591 +2103 +2237 +00444 +00400 +1026 +1194 +00243 +01_20181130_114627 +2236 +01_20181129_170704 +20181126124416178-2_1 +1536 +1362 +20181126004308657-3_1 +01_20181130_110948 +20181122000543299-3_1 +00109 +00276 +1097 +00179 +1546 +20181127003819487-4_1 +2388 +2109 +20181127074053174-4_1 +00157 +01_20181130_112610 +20181121000443354-4_1 +2650 +20181127115321277-3_1 +20181119101759756-4_1 +1087 +00443 +01_20181129_165440 +2690 +01_20181129_162320 +2340 +20181127201050621-3_1 +00216 +20181127085734111-3_1 +20181127001001394-3_1 +20181119114352534-3_1 +2303 +20181122122100546-3_1 +2176 +20181127202435882-3_1 +1160 +1557 +00451 +1006 +01_20181130_113038 +1370 +2222 +20181127224452979-4_1 +00493 +00096 +20181119115045863-4_1 +01_20181130_113659 +20181127101152231-4_1 +20181127220311359-3_1 +2684 +00361 +20181127230142599-4_1 +1579 +2706 +20181127100731082-4_1 +20181127013225881-3_1 +20181121095615900-3_1 +20181119075231628-3_1 +20181119115524143-3_1 +00507 +2445 +1336 +00076 +00128 +2480 +00440 +01_20181130_111446 +00293 +20181127023043594-3_1 +20181126201109427-4_1 +1340 +20181126152954169-3_1 +2447 +1095 +01_20181130_113525 +01_20181130_113917 +00020 +20181127010515454-4_1 +1070 +01_20181130_111133 +2293 +1091 +1046 +00211 +20181127135456736-4_1 +00310 +20181121075250891-4_1 +1202 +01_20181130_112634 +00534 +2646 +2048 +00155 +1471 +00647 +00114 +1380 +2427 +01_20181130_112725 +1382 +00312 +00297 +00230 +1263 +01_20181130_111517 +2299 +1415 +1101 +00474 +2024 +00106 +20181127221742713-4_1 +00218 +1486 +2658 +20181126035620948-3_1 +00345 +1433 +01_20181130_112250 +2587 +2627 +1429 +00099 +20181122121700635-4_1 +1301 +20181128150040768-1_1 +00404 +00607 +1350 +00048 +00414 +00546 +00366 +20181128145516880-2_1 +2182 +1188 +20181127090432846-4_1 +1322 +00075 +1342 +2066 +1583 +20181119103334351-3_1 +2421 +00436 +00415 +00213 +01_20181130_111423 +2573 +20181119100813942-4_1 +00382 +01_20181129_163104 +1081 +00410 +2526 +20181126000515692-4_1 +00280 +2433 +2540 +2625 +00257 +20181119112047550-3_1 +20181119003727619-4_1 +20181127080126870-3_1 +20181127201050621-4_1 +01_20181130_114207 +00234 +1461 +00494 +1498 +20181119103749511-4_1 +00016 +1318 +1625 +20181128122439345-2_1 +20181127113843708-3_1 +00539 +20181128174127699-4_1 +00369 +20181127224851174-3_1 +01_20181130_113733 +01_20181129_170623 +20181127043505302-3_1 +2662 +01_20181130_113909 +2553 +2269 +01_20181130_113623 +20181127212223489-4_1 +1324 +2172 +2603 +2158 +00529 +1463 +01_20181130_113512 +20181127161250784-4_1 +1066 +00625 +2504 +2315 +00248 +00146 +2234 +2291 +1388 +20181127173424096-4_1 +20181127010119487-3_1 +2694 +1399 +20181128143936956-1_1 +2204 +2518 +00004 +00154 +20181121100230103-3_1 +20181127034632957-4_1 +2170 +20181119120520492-3_1 +01_20181129_163210 +1034 +00515 +20181122013832268-4_1 +20181119113722754-3_1 +2686 +00324 +00639 +01_20181129_165335 +1232 +2220 +01_20181130_113900 +00026 +00302 +20181128163429487-4_1 +01_20181129_163307 +00482 +2664 +20181127220847854-3_1 +20181127143458813-3_1 +1172 +00396 +20181119115926168-3_1 +00438 +2226 +00386 +1617 +20181122001044041-3_1 +2682 +2654 +2342 +20181119011543507-3_1 +20181127150519069-4_1 +01_20181129_163940 +00113 +00028 +2544 +1192 +1403 +20181127113612183-3_1 +00103 +00478 +20181122121313891-3_1 +20181127225414390-4_1 +01_20181130_113459 +20181122073716737-3_1 +20181127012258051-4_1 +1133 +20181127010427774-3_1 +1155 +20181127074751792-3_1 +01_20181129_170841 +20181127133311293-2_1 +20181125123315158-3_1 +00009 +1478 +1386 +20181119033219588-4_1 +00455 +20181122000444538-4_1 +00492 +01_20181129_165345 +01_20181129_164303 +2502 +20181119092207198-4_1 +2593 +00007 +01_20181129_164009 +00629 +2002 +1455 +20181128150040768-4_1 +01_20181129_154055 +2155 +20181127235646080-3_1 +2552 +1056 +20181121091731738-3_1 +2368 +2344 +20181119091827752-3_1 +1000 +2360 +00240 +20181127095726262-3_1 +20181121083238283-3_1 +20181127222704454-3_1 +1113 +01_20181130_112300 +20181119112056294-4_1 +2018 +20181128161101275-2_1 +20181126165018850-1_1 +20181127223614758-3_1 +01_20181130_114741 +20181119121807941-4_1 +1571 +00183 +00071 +00220 +2490 +1366 +01_20181129_153655 +1151 +00652 +00012 +1496 +00408 +20181119091811374-3_1 +00251 +2346 +1014 +20181127232358578-4_1 +01_20181130_113219 +00350 +00383 +2478 +00072 +2384 +2030 +00486 +20181127023842660-4_1 +20181127004815087-3_1 +20181126004830616-3_1 +00092 +1457 +2411 +2232 +1157 +01_20181129_164556 +1107 +20181121112441752-3_1 +20181122080021057-3_1 +1176 +00002 +00116 +2085 +1275 +1532 +1413 +01_20181130_113550 +2555 +2087 +00066 +00308 +20181122052625519-3_1 +20181127195406672-4_1 +20181121083959600-4_1 +1135 +20181127230609226-3_1 +20181121110151434-3_1 +1042 +20181128134632228-2_1 +20181127090432846-3_1 +00166 +2255 +01_20181129_165353 +1480 +2058 +2295 +2583 +1307 +2056 +20181127224934339-3_1 +00372 +1131 +20181122000632255-4_1 +00325 +2004 +1204 +1129 +00035 +20181127055427470-3_1 +20181127233420161-3_1 +00083 +2429 +20181119003621701-3_1 +2688 +00648 +1544 +00514 +01_20181130_114803 +00110 +2386 +00472 +1506 +20181127014451922-3_1 +00138 +20181127202210901-3_1 +2133 +00363 +20181126200758882-1_1 +2168 +20181128164136413-3_1 +01_20181130_114256 +2569 +1542 +00167 +20181127113452893-4_1 +2012 +00136 +00460 +1569 +2042 +20181121100936635-3_1 +2494 +00235 +00277 +2313 +01_20181130_114223 +00134 +20181127044902570-3_1 +20181122003853982-4_1 +20181122004611642-4_1 +20181119110620276-3_1 +2453 +20181127100354947-4_1 +00304 +1074 +1581 +20181127005001010-4_1 +00608 +20181119020405719-3_1 +00040 +01_20181130_112307 +1109 +2218 +01_20181130_114028 +00513 +20181127034632957-3_1 +1516 +00271 +1190 +2382 +2022 +01_20181129_155709 +20181122080222799-4_1 +00242 diff --git a/data/traina.txt b/data/traina.txt new file mode 100644 index 0000000..c31e2e9 --- /dev/null +++ b/data/traina.txt @@ -0,0 +1,1638 @@ +20181127010247462-3_1_a +00011_a +00516_a +00132_a +1595_a +20181121085448544-4_1_a +20181119074028183-4_1_a +2702_a +2200_a +1149_a +01_20181130_113541_a +01_20181129_162346_a +1593_a +20181119115008758-3_1_a +00446_a +20181127003722887-3_1_a +20181127221349165-3_1_a +2409_a +01_20181129_163552_a +2488_a +00231_a +2514_a +20181127150405880-4_1_a +1459_a +1216_a +20181119103101979-4_1_a +1186_a +1508_a +1052_a +00520_a +1020_a +20181119111453434-3_1_a +20181122075850574-4_1_a +00635_a +1490_a +2186_a +1627_a +2496_a +1514_a +2423_a +1384_a +2692_a +20181119112737741-4_1_a +20181122010220543-3_1_a +2149_a +01_20181129_165126_a +00459_a +01_20181129_153720_a +00430_a +1548_a +2680_a +01_20181129_165321_a +2538_a +2113_a +1158_a +2550_a +2364_a +00454_a +01_20181129_165104_a +20181121100636351-4_1_a +00161_a +00101_a +00284_a +00525_a +00427_a +01_20181129_165117_a +2334_a +00497_a +20181127154558261-3_1_a +00342_a +2281_a +20181127192043512-4_1_a +00149_a +00631_a +2052_a +01_20181130_111557_a +00204_a +01_20181130_113151_a +20181127115337607-3_1_a +00207_a +00315_a +1212_a +00388_a +01_20181129_170716_a +00463_a +00246_a +2034_a +20181122045305786-3_1_a +00286_a +1085_a +20181128000818090-4_1_a +01_20181130_114158_a +00038_a +1123_a +1346_a +1164_a +20181127202741788-3_1_a +1079_a +00428_a +20181122002040183-3_1_a +2350_a +00543_a +00172_a +2050_a +2704_a +20181127230517978-3_1_a +20181127233732091-4_1_a +00274_a +1259_a +1180_a +1518_a +01_20181129_154029_a +20181127125137475-4_1_a +00475_a +01_20181130_112021_a +1093_a +01_20181130_111543_a +20181122122255595-3_1_a +2623_a +2115_a +01_20181130_114706_a +20181127235306727-4_1_a +01_20181130_113056_a +00502_a +20181127080139736-4_1_a +20181122121858920-3_1_a +00199_a +00348_a +2370_a +01_20181130_111411_a +2279_a +2595_a +20181127104655615-3_1_a +20181128140520488-2_1_a +20181127201412607-4_1_a +20181122122020986-4_1_a +20181127085647130-4_1_a +20181127222919415-3_1_a +00615_a +20181127221349165-4_1_a +2046_a +2026_a +00613_a +00621_a +01_20181129_164335_a +20181119001011513-4_1_a +1443_a +20181121104728463-3_1_a +00601_a +1520_a +20181127074831430-3_1_a +00203_a +1328_a +01_20181130_112055_a +00285_a +20181128165955211-4_1_a +00338_a +2311_a +20181119001011513-3_1_a +01_20181130_112643_a +2419_a +01_20181129_162144_a +00289_a +2241_a +00178_a +00397_a +2378_a +20181127224908985-3_1_a +00634_a +2307_a +1449_a +2078_a +20181127095859036-4_1_a +20181122113820449-3_1_a +1139_a +2500_a +2174_a +1060_a +20181122121356092-4_1_a +00411_a +01_20181129_163255_a +00162_a +20181127114239684-3_1_a +01_20181130_113649_a +1261_a +00551_a +20181119060033421-3_1_a +1597_a +2362_a +00317_a +1153_a +01_20181130_114733_a +00402_a +00622_a +20181121000045721-3_1_a +00108_a +2143_a +00046_a +2180_a +20181127234639001-3_1_a +20181119115433970-4_1_a +2708_a +20181127152826262-2_1_a +01_20181129_170644_a +2064_a +00151_a +1364_a +2285_a +00189_a +00067_a +00241_a +20181127015943051-3_1_a +00434_a +01_20181130_112118_a +00456_a +2251_a +2121_a +20181127192905305-4_1_a +2044_a +1392_a +20181127173424096-3_1_a +2405_a +1239_a +00224_a +2615_a +1474_a +00129_a +01_20181130_113707_a +01_20181129_163138_a +01_20181129_153359_a +00117_a +2399_a +1174_a +20181119120354969-3_1_a +1022_a +2198_a +1344_a +20181127202435882-4_1_a +1407_a +01_20181130_114523_a +1004_a +00375_a +20181119115611830-3_1_a +2656_a +1397_a +2451_a +01_20181129_164849_a +00602_a +2465_a +00027_a +2652_a +2263_a +1447_a +20181127103320404-4_1_a +2455_a +1587_a +20181127232458604-4_1_a +2212_a +2617_a +20181126150842329-3_1_a +1528_a +1573_a +01_20181129_162300_a +20181127005623155-4_1_a +00328_a +1358_a +00334_a +2309_a +00119_a +00094_a +2520_a +20181119071505728-4_1_a +20181127072627756-3_1_a +2099_a +01_20181130_112735_a +20181127093942344-3_1_a +00010_a +2162_a +00147_a +01_20181129_165052_a +2040_a +00065_a +01_20181129_170749_a +20181128171016809-3_1_a +2239_a +2589_a +20181119103516969-4_1_a +2534_a +20181119091827752-4_1_a +20181122121516628-4_1_a +2097_a +20181127001649948-4_1_a +01_20181130_114543_a +00495_a +20181126001318139-3_1_a +00423_a +00441_a +00649_a +00190_a +00173_a +00606_a +20181119080906986-3_1_a +00367_a +2032_a +01_20181129_165515_a +1218_a +1473_a +1524_a +1552_a +20181127171206811-4_1_a +20181127075635128-4_1_a +00610_a +20181127165217153-3_1_a +1062_a +00487_a +20181127230259506-3_1_a +20181127131645187-3_1_a +1492_a +1247_a +00421_a +1565_a +2546_a +20181122104920241-4_1_a +01_20181129_164635_a +20181127224815294-3_1_a +00335_a +00168_a +1372_a +20181119100357744-3_1_a +00432_a +2431_a +1234_a +20181127213320791-3_1_a +2374_a +20181122104622680-3_1_a +01_20181130_111046_a +00439_a +01_20181130_112129_a +20181127093926326-3_1_a +2394_a +2599_a +2249_a +1559_a +2141_a +00612_a +2230_a +2473_a +20181126150446094-3_1_a +00078_a +20181119000956191-4_1_a +1245_a +2559_a +1567_a +00371_a +20181119101555200-3_1_a +00227_a +00093_a +20181122000053603-3_1_a +20181121080900752-4_1_a +01_20181130_112046_a +2565_a +1401_a +00263_a +00603_a +20181127213344114-3_1_a +01_20181130_113533_a +2457_a +01_20181130_113725_a +20181127224241714-3_1_a +1439_a +1208_a +2196_a +2275_a +20181122002525297-3_1_a +2668_a +2020_a +1417_a +20181119121606579-3_1_a +00526_a +2449_a +20181127000049917-4_1_a +00290_a +01_20181130_111616_a +2577_a +00264_a +2216_a +1453_a +00538_a +20181121035640835-3_1_a +1287_a +1309_a +1083_a +1378_a +01_20181129_163321_a +01_20181129_163349_a +00170_a +2376_a +20181121075447311-3_1_a +2257_a +00614_a +01_20181129_170633_a +20181127225041872-4_1_a +00329_a +1283_a +1265_a +01_20181129_164113_a +2166_a +2425_a +2670_a +00039_a +01_20181130_114050_a +00051_a +2271_a +00131_a +20181127100731082-3_1_a +00549_a +00064_a +00469_a +20181121095446044-4_1_a +2123_a +1394_a +1512_a +20181121105152214-3_1_a +2696_a +00354_a +2137_a +00222_a +01_20181129_153746_a +1224_a +2607_a +20181127230923581-3_1_a +2287_a +2129_a +20181127045208109-3_1_a +2372_a +20181122001044041-4_1_a +1089_a +2145_a +20181127012107319-4_1_a +2083_a +01_20181130_114149_a +20181128143035800-4_1_a +00300_a +20181127030027783-3_1_a +1348_a +00217_a +2210_a +01_20181129_164313_a +1228_a +2548_a +1360_a +01_20181130_112341_a +1563_a +20181127181546252-4_1_a +00229_a +00001_a +2091_a +2390_a +20181127002601832-4_1_a +2676_a +00418_a +20181127010743544-3_1_a +2192_a +01_20181130_114305_a +20181127091225228-4_1_a +1330_a +00278_a +1010_a +01_20181129_164122_a +20181127005001010-3_1_a +2324_a +20181122001241021-3_1_a +2512_a +00232_a +00314_a +00457_a +1237_a +1390_a +1285_a +2528_a +2407_a +1615_a +00118_a +20181127001707407-3_1_a +1409_a +20181127010230808-3_1_a +20181127090657770-4_1_a +20181119121530242-3_1_a +01_20181129_165506_a +20181126001317621-3_1_a +2206_a +1368_a +00044_a +00100_a +20181127233501087-3_1_a +20181127233131581-4_1_a +00141_a +1230_a +00524_a +00049_a +20181127075252321-3_1_a +00609_a +2151_a +2160_a +1482_a +2202_a +1421_a +1269_a +20181127082310414-3_1_a +00299_a +20181126200827642-3_1_a +00165_a +20181126062910882-3_1_a +20181122000556040-4_1_a +1293_a +2117_a +00620_a +20181127143631550-2_1_a +20181122000052952-4_1_a +00505_a +2036_a +00273_a +20181122122756372-3_1_a +1530_a +00121_a +20181127221911018-4_1_a +2459_a +20181128164601694-3_1_a +1289_a +20181128165928786-4_1_a +2000_a +2131_a +2038_a +1561_a +20181122023138352-4_1_a +1550_a +20181119115019411-3_1_a +20181121000545831-4_1_a +2267_a +2318_a +00650_a +20181119121131883-3_1_a +1281_a +00081_a +20181126020158129-3_1_a +20181127182642611-3_1_a +20181119115203907-4_1_a +2532_a +20181127221233330-3_1_a +20181119104035113-4_1_a +01_20181130_111006_a +01_20181130_113010_a +2678_a +00398_a +00142_a +20181119113804614-3_1_a +01_20181129_162043_a +20181122122804487-4_1_a +2437_a +00339_a +00450_a +2581_a +2366_a +20181127232323939-4_1_a +20181128140520488-3_1_a +20181127013430922-4_1_a +01_20181130_110917_a +1127_a +00268_a +20181127095243300-4_1_a +00057_a +1526_a +00307_a +00192_a +20181121093030671-3_1_a +2392_a +00130_a +00288_a +01_20181130_114214_a +00321_a +20181127233103007-4_1_a +00025_a +01_20181129_163527_a +20181127232033013-3_1_a +20181127094245754-4_1_a +1411_a +1476_a +20181127125614960-3_1_a +1141_a +1099_a +01_20181130_112556_a +1016_a +1629_a +20181122075223501-4_1_a +01_20181130_110930_a +00079_a +20181122081312622-4_1_a +1206_a +1038_a +1226_a +1577_a +00503_a +20181119113432375-3_1_a +20181127013631966-4_1_a +2579_a +20181119105413400-4_1_a +20181119043830890-4_1_a +00537_a +20181119002009034-3_1_a +20181126001713374-4_1_a +00269_a +1214_a +2380_a +1603_a +00365_a +00084_a +01_20181129_164254_a +01_20181130_114724_a +20181127221136584-2_1_a +2008_a +1315_a +20181121092636613-3_1_a +2510_a +00641_a +20181126035620948-4_1_a +00127_a +2074_a +00097_a +01_20181130_113029_a +20181122000745091-3_1_a +20181127030623221-4_1_a +20181126000705693-3_1_a +1255_a +20181119121233585-4_1_a +20181127013205532-3_1_a +00236_a +00633_a +2601_a +00331_a +00164_a +00471_a +20181119002047873-3_1_a +2439_a +1145_a +20181127215011177-3_1_a +20181127225246457-3_1_a +01_20181130_113839_a +2474_a +2016_a +01_20181129_163949_a +00080_a +1445_a +2095_a +20181119115509287-3_1_a +20181119101555200-4_1_a +20181127074902009-4_1_a +2273_a +20181119111505568-4_1_a +1162_a +01_20181129_170606_a +1431_a +1273_a +20181127003156459-3_1_a +00125_a +20181127014217867-4_1_a +1395_a +2660_a +00632_a +00013_a +2397_a +00611_a +2666_a +1488_a +1510_a +2243_a +00254_a +2068_a +00358_a +1484_a +00616_a +2506_a +00373_a +01_20181130_111532_a +01_20181129_155810_a +2524_a +2597_a +00177_a +20181119111548548-3_1_a +2006_a +00403_a +20181127154558624-3_1_a +20181119005355036-3_1_a +1295_a +00448_a +00489_a +2322_a +00006_a +20181127175956914-3_1_a +2674_a +1303_a +20181127093911883-3_1_a +00377_a +00445_a +1196_a +01_20181130_113200_a +00098_a +01_20181129_164625_a +00544_a +00384_a +20181128132919701-2_1_a +1435_a +01_20181129_164615_a +00201_a +20181126150558628-2_1_a +2672_a +01_20181130_114654_a +00063_a +20181128164630165-4_1_a +00619_a +00153_a +20181127100718633-3_1_a +20181121110151434-4_1_a +20181126152954169-2_1_a +01_20181130_112744_a +2461_a +00419_a +00120_a +01_20181129_170944_a +00133_a +20181127170245383-4_1_a +00640_a +20181119075122755-4_1_a +20181127220108359-4_1_a +20181121113230538-4_1_a +01_20181130_112715_a +20181128000541194-3_1_a +00512_a +00301_a +20181119103334351-4_1_a +01_20181129_162250_a +00390_a +00174_a +00305_a +01_20181129_165045_a +00638_a +1609_a +00062_a +1423_a +1467_a +20181119110753201-4_1_a +1111_a +00466_a +2283_a +20181127075324924-4_1_a +2062_a +20181127154558624-4_1_a +20181127194320187-2_1_a +20181119105542999-4_1_a +2253_a +00015_a +01_20181130_114616_a +2119_a +00186_a +01_20181130_111503_a +00298_a +20181127092635045-3_1_a +2190_a +01_20181129_160809_a +1601_a +00145_a +00214_a +2435_a +00636_a +00637_a +00357_a +2060_a +00433_a +20181127224934339-4_1_a +00250_a +1619_a +20181127204432329-3_1_a +20181127101615633-4_1_a +20181122020249975-3_1_a +00330_a +1320_a +20181122080948511-3_1_a +01_20181130_112956_a +20181119103840446-4_1_a +00259_a +20181122032956669-3_1_a +01_20181129_165416_a +01_20181129_164030_a +00341_a +00156_a +20181121110705119-3_1_a +1251_a +2401_a +1469_a +1200_a +01_20181129_164645_a +00184_a +2147_a +2542_a +1184_a +20181127092539655-4_1_a +20181127075635128-3_1_a +00355_a +00037_a +20181127222745426-4_1_a +20181126004807199-3_1_a +2710_a +1103_a +20181128130740139-3_1_a +2508_a +1299_a +00422_a +20181127123808454-3_1_a +00023_a +1538_a +00102_a +20181125100419346-4_1_a +00060_a +1374_a +2467_a +1465_a +00206_a +01_20181130_113715_a +20181122073750667-3_1_a +01_20181130_112034_a +1121_a +20181119092254236-3_1_a +2072_a +00208_a +01_20181129_161900_a +20181128132919701-1_1_a +2642_a +1605_a +20181126014538184-4_1_a +01_20181130_111925_a +1018_a +20181126181859959-2_1_a +01_20181129_164836_a +20181119105121435-3_1_a +01_20181129_164900_a +00253_a +01_20181129_163123_a +1076_a +00521_a +20181122020715219-3_1_a +01_20181129_163334_a +1297_a +00107_a +2332_a +20181121114153157-4_1_a +01_20181130_111114_a +00368_a +2164_a +2010_a +2101_a +00643_a +1427_a +00316_a +00191_a +2561_a +2328_a +1316_a +1494_a +20181127072414460-4_1_a +00332_a +00484_a +20181119112437378-4_1_a +1030_a +01_20181130_114639_a +2178_a +20181122010220543-4_1_a +00447_a +2153_a +2336_a +20181127230251206-3_1_a +1332_a +00461_a +00089_a +00485_a +1166_a +00180_a +1540_a +2557_a +00295_a +2403_a +20181122080944034-4_1_a +00522_a +1220_a +1631_a +01_20181130_112010_a +01_20181129_162225_a +00550_a +00053_a +01_20181129_163155_a +20181119094454220-3_1_a +20181128105623531-2_1_a +00104_a +20181127095602614-4_1_a +2638_a +20181127013425289-3_1_a +1623_a +00429_a +01_20181129_170833_a +1621_a +2644_a +1249_a +20181121072412351-3_1_a +20181128165303879-3_1_a +1210_a +1522_a +1078_a +2413_a +01_20181129_165526_a +1376_a +01_20181130_111031_a +2305_a +20181119121233585-3_1_a +20181122005531396-3_1_a +00527_a +00021_a +00069_a +20181128163524688-3_1_a +00605_a +20181127144552058-3_1_a +01_20181129_165134_a +2076_a +20181119013228333-4_1_a +2609_a +00181_a +1257_a +20181127004618957-3_1_a +2486_a +20181119114018628-3_1_a +20181126003200345-3_1_a +2567_a +2214_a +20181127163654619-4_1_a +2498_a +20181121112838990-4_1_a +20181127121113397-4_1_a +20181121104030474-3_1_a +1338_a +2585_a +00042_a +01_20181130_114534_a +1502_a +00496_a +2415_a +01_20181130_112323_a +20181127004525695-3_1_a +00352_a +2605_a +2139_a +2492_a +20181128000756689-4_1_a +01_20181129_165404_a +20181127010556106-4_1_a +1072_a +2184_a +2621_a +20181127115516857-3_1_a +20181128111521435-1_1_a +20181126013939987-3_1_a +1611_a +20181126015606934-4_1_a +01_20181130_111433_a +00416_a +20181127230657705-3_1_a +01_20181129_170655_a +01_20181130_114036_a +2107_a +00221_a +00626_a +20181127215616945-4_1_a +1236_a +1291_a +01_20181129_163507_a +20181127234432832-3_1_a +01_20181130_112417_a +00247_a +1050_a +01_20181129_163602_a +00498_a +00122_a +01_20181129_170759_a +00323_a +2330_a +20181126200758882-2_1_a +2316_a +20181127220608827-4_1_a +20181127003156459-4_1_a +1241_a +00360_a +01_20181130_111957_a +1279_a +2208_a +1267_a +20181126185253527-2_1_a +01_20181129_162103_a +20181119112645446-3_1_a +01_20181129_162121_a +00491_a +20181121080441207-3_1_a +2648_a +2014_a +00509_a +20181119121627237-3_1_a +01_20181129_165452_a +20181127000650698-3_1_a +20181127000616541-4_1_a +2575_a +00340_a +1002_a +2188_a +00378_a +20181127113906983-4_1_a +00210_a +20181128164710878-3_1_a +20181122104448601-4_1_a +20181127093743341-4_1_a +00435_a +00624_a +2259_a +00195_a +20181127234720221-3_1_a +2135_a +20181122041209218-3_1_a +00541_a +01_20181129_161828_a +20181119004342745-3_1_a +00137_a +1068_a +00256_a +00144_a +01_20181130_113210_a +01_20181129_164153_a +1012_a +1048_a +01_20181130_111059_a +20181127055123153-3_1_a +00395_a +20181119004427545-3_1_a +1143_a +2297_a +00477_a +00417_a +01_20181129_170811_a +00143_a +2611_a +1119_a +00018_a +00425_a +01_20181129_164039_a +20181127232447851-3_1_a +00175_a +1451_a +00266_a +20181127101816754-4_1_a +2469_a +1058_a +20181122002241659-4_1_a +20181127002233018-4_1_a +2354_a +2417_a +2516_a +2536_a +20181122003752841-3_1_a +1334_a +2301_a +2563_a +2636_a +2127_a +20181122001534897-4_1_a +1553_a +1277_a +00095_a +1105_a +1064_a +2640_a +1441_a +1575_a +20181128164429752-3_1_a +01_20181129_171009_a +00379_a +01_20181129_170729_a +00531_a +20181122002710407-4_1_a +20181119115021579-4_1_a +20181121000545831-3_1_a +20181122002946945-3_1_a +2089_a +2224_a +01_20181130_111947_a +1115_a +00200_a +1125_a +2482_a +20181127010839884-3_1_a +2441_a +20181127092942460-4_1_a +00412_a +2631_a +1044_a +01_20181130_114553_a +1607_a +01_20181129_163616_a +20181122004346347-4_1_a +00333_a +1354_a +2157_a +01_20181129_154119_a +01_20181129_161819_a +20181119002925693-3_1_a +00228_a +20181122122034042-3_1_a +00464_a +00140_a +1040_a +00628_a +00090_a +00326_a +20181119100357744-4_1_a +20181127075957107-4_1_a +2356_a +1599_a +2125_a +2463_a +01_20181129_162410_a +2443_a +01_20181130_112625_a +1356_a +00262_a +2247_a +00488_a +1147_a +1222_a +00139_a +20181127233116905-4_1_a +2348_a +1198_a +2471_a +20181122001534897-3_1_a +20181126004807199-4_1_a +20181119091657430-3_1_a +20181127075252570-3_1_a +00393_a +01_20181129_164000_a +20181119010304348-4_1_a +1170_a +00380_a +00022_a +20181122122332937-3_1_a +00630_a +20181122104747521-4_1_a +00061_a +00319_a +00364_a +00392_a +1437_a +2289_a +20181122121406951-3_1_a +00005_a +20181127121643578-4_1_a +01_20181129_164322_a +01_20181130_110853_a +1591_a +2103_a +2237_a +00444_a +00400_a +1026_a +1194_a +00243_a +01_20181130_114627_a +2236_a +01_20181129_170704_a +20181126124416178-2_1_a +1536_a +1362_a +20181126004308657-3_1_a +01_20181130_110948_a +20181122000543299-3_1_a +00109_a +00276_a +1097_a +00179_a +1546_a +20181127003819487-4_1_a +2388_a +2109_a +20181127074053174-4_1_a +00157_a +01_20181130_112610_a +20181121000443354-4_1_a +2650_a +20181127115321277-3_1_a +20181119101759756-4_1_a +1087_a +00443_a +01_20181129_165440_a +2690_a +01_20181129_162320_a +2340_a +20181127201050621-3_1_a +00216_a +20181127085734111-3_1_a +20181127001001394-3_1_a +20181119114352534-3_1_a +2303_a +20181122122100546-3_1_a +2176_a +20181127202435882-3_1_a +1160_a +1557_a +00451_a +1006_a +01_20181130_113038_a +1370_a +2222_a +20181127224452979-4_1_a +00493_a +00096_a +20181119115045863-4_1_a +01_20181130_113659_a +20181127101152231-4_1_a +20181127220311359-3_1_a +2684_a +00361_a +20181127230142599-4_1_a +1579_a +2706_a +20181127100731082-4_1_a +20181127013225881-3_1_a +20181121095615900-3_1_a +20181119075231628-3_1_a +20181119115524143-3_1_a +00507_a +2445_a +1336_a +00076_a +00128_a +2480_a +00440_a +01_20181130_111446_a +00293_a +20181127023043594-3_1_a +20181126201109427-4_1_a +1340_a +20181126152954169-3_1_a +2447_a +1095_a +01_20181130_113525_a +01_20181130_113917_a +00020_a +20181127010515454-4_1_a +1070_a +01_20181130_111133_a +2293_a +1091_a +1046_a +00211_a +20181127135456736-4_1_a +00310_a +20181121075250891-4_1_a +1202_a +01_20181130_112634_a +00534_a +2646_a +2048_a +00155_a +1471_a +00647_a +00114_a +1380_a +2427_a +01_20181130_112725_a +1382_a +00312_a +00297_a +00230_a +1263_a +01_20181130_111517_a +2299_a +1415_a +1101_a +00474_a +2024_a +00106_a +20181127221742713-4_1_a +00218_a +1486_a +2658_a +20181126035620948-3_1_a +00345_a +1433_a +01_20181130_112250_a +2587_a +2627_a +1429_a +00099_a +20181122121700635-4_1_a +1301_a +20181128150040768-1_1_a +00404_a +00607_a +1350_a +00048_a +00414_a +00546_a +00366_a +20181128145516880-2_1_a +2182_a +1188_a +20181127090432846-4_1_a +1322_a +00075_a +1342_a +2066_a +1583_a +20181119103334351-3_1_a +2421_a +00436_a +00415_a +00213_a +01_20181130_111423_a +2573_a +20181119100813942-4_1_a +00382_a +01_20181129_163104_a +1081_a +00410_a +2526_a +20181126000515692-4_1_a +00280_a +2433_a +2540_a +2625_a +00257_a +20181119112047550-3_1_a +20181119003727619-4_1_a +20181127080126870-3_1_a +20181127201050621-4_1_a +01_20181130_114207_a +00234_a +1461_a +00494_a +1498_a +20181119103749511-4_1_a +00016_a +1318_a +1625_a +20181128122439345-2_1_a +20181127113843708-3_1_a +00539_a +20181128174127699-4_1_a +00369_a +20181127224851174-3_1_a +01_20181130_113733_a +01_20181129_170623_a +20181127043505302-3_1_a +2662_a +01_20181130_113909_a +2553_a +2269_a +01_20181130_113623_a +20181127212223489-4_1_a +1324_a +2172_a +2603_a +2158_a +00529_a +1463_a +01_20181130_113512_a +20181127161250784-4_1_a +1066_a +00625_a +2504_a +2315_a +00248_a +00146_a +2234_a +2291_a +1388_a +20181127173424096-4_1_a +20181127010119487-3_1_a +2694_a +1399_a +20181128143936956-1_1_a +2204_a +2518_a +00004_a +00154_a +20181121100230103-3_1_a +20181127034632957-4_1_a +2170_a +20181119120520492-3_1_a +01_20181129_163210_a +1034_a +00515_a +20181122013832268-4_1_a +20181119113722754-3_1_a +2686_a +00324_a +00639_a +01_20181129_165335_a +1232_a +2220_a +01_20181130_113900_a +00026_a +00302_a +20181128163429487-4_1_a +01_20181129_163307_a +00482_a +2664_a +20181127220847854-3_1_a +20181127143458813-3_1_a +1172_a +00396_a +20181119115926168-3_1_a +00438_a +2226_a +00386_a +1617_a +20181122001044041-3_1_a +2682_a +2654_a +2342_a +20181119011543507-3_1_a +20181127150519069-4_1_a +01_20181129_163940_a +00113_a +00028_a +2544_a +1192_a +1403_a +20181127113612183-3_1_a +00103_a +00478_a +20181122121313891-3_1_a +20181127225414390-4_1_a +01_20181130_113459_a +20181122073716737-3_1_a +20181127012258051-4_1_a +1133_a +20181127010427774-3_1_a +1155_a +20181127074751792-3_1_a +01_20181129_170841_a +20181127133311293-2_1_a +20181125123315158-3_1_a +00009_a +1478_a +1386_a +20181119033219588-4_1_a +00455_a +20181122000444538-4_1_a +00492_a +01_20181129_165345_a +01_20181129_164303_a +2502_a +20181119092207198-4_1_a +2593_a +00007_a +01_20181129_164009_a +00629_a +2002_a +1455_a +20181128150040768-4_1_a +01_20181129_154055_a +2155_a +20181127235646080-3_1_a +2552_a +1056_a +20181121091731738-3_1_a +2368_a +2344_a +20181119091827752-3_1_a +1000_a +2360_a +00240_a +20181127095726262-3_1_a +20181121083238283-3_1_a +20181127222704454-3_1_a +1113_a +01_20181130_112300_a +20181119112056294-4_1_a +2018_a +20181128161101275-2_1_a +20181126165018850-1_1_a +20181127223614758-3_1_a +01_20181130_114741_a +20181119121807941-4_1_a +1571_a +00183_a +00071_a +00220_a +2490_a +1366_a +01_20181129_153655_a +1151_a +00652_a +00012_a +1496_a +00408_a +20181119091811374-3_1_a +00251_a +2346_a +1014_a +20181127232358578-4_1_a +01_20181130_113219_a +00350_a +00383_a +2478_a +00072_a +2384_a +2030_a +00486_a +20181127023842660-4_1_a +20181127004815087-3_1_a +20181126004830616-3_1_a +00092_a +1457_a +2411_a +2232_a +1157_a +01_20181129_164556_a +1107_a +20181121112441752-3_1_a +20181122080021057-3_1_a +1176_a +00002_a +00116_a +2085_a +1275_a +1532_a +1413_a +01_20181130_113550_a +2555_a +2087_a +00066_a +00308_a +20181122052625519-3_1_a +20181127195406672-4_1_a +20181121083959600-4_1_a +1135_a +20181127230609226-3_1_a +20181121110151434-3_1_a +1042_a +20181128134632228-2_1_a +20181127090432846-3_1_a +00166_a +2255_a +01_20181129_165353_a +1480_a +2058_a +2295_a +2583_a +1307_a +2056_a +20181127224934339-3_1_a +00372_a +1131_a +20181122000632255-4_1_a +00325_a +2004_a +1204_a +1129_a +00035_a +20181127055427470-3_1_a +20181127233420161-3_1_a +00083_a +2429_a +20181119003621701-3_1_a +2688_a +00648_a +1544_a +00514_a +01_20181130_114803_a +00110_a +2386_a +00472_a +1506_a +20181127014451922-3_1_a +00138_a +20181127202210901-3_1_a +2133_a +00363_a +20181126200758882-1_1_a +2168_a +20181128164136413-3_1_a +01_20181130_114256_a +2569_a +1542_a +00167_a +20181127113452893-4_1_a +2012_a +00136_a +00460_a +1569_a +2042_a +20181121100936635-3_1_a +2494_a +00235_a +00277_a +2313_a +01_20181130_114223_a +00134_a +20181127044902570-3_1_a +20181122003853982-4_1_a +20181122004611642-4_1_a +20181119110620276-3_1_a +2453_a +20181127100354947-4_1_a +00304_a +1074_a +1581_a +20181127005001010-4_1_a +00608_a +20181119020405719-3_1_a +00040_a +01_20181130_112307_a +1109_a +2218_a +01_20181130_114028_a +00513_a +20181127034632957-3_1_a +1516_a +00271_a +1190_a +2382_a +2022_a +01_20181129_155709_a +20181122080222799-4_1_a +00242_a diff --git a/data/trainb.txt b/data/trainb.txt new file mode 100644 index 0000000..3255281 --- /dev/null +++ b/data/trainb.txt @@ -0,0 +1,1638 @@ +20181127010247462-3_1_b +00011_b +00516_b +00132_b +1595_b +20181121085448544-4_1_b +20181119074028183-4_1_b +2702_b +2200_b +1149_b +01_20181130_113541_b +01_20181129_162346_b +1593_b +20181119115008758-3_1_b +00446_b +20181127003722887-3_1_b +20181127221349165-3_1_b +2409_b +01_20181129_163552_b +2488_b +00231_b +2514_b +20181127150405880-4_1_b +1459_b +1216_b +20181119103101979-4_1_b +1186_b +1508_b +1052_b +00520_b +1020_b +20181119111453434-3_1_b +20181122075850574-4_1_b +00635_b +1490_b +2186_b +1627_b +2496_b +1514_b +2423_b +1384_b +2692_b +20181119112737741-4_1_b +20181122010220543-3_1_b +2149_b +01_20181129_165126_b +00459_b +01_20181129_153720_b +00430_b +1548_b +2680_b +01_20181129_165321_b +2538_b +2113_b +1158_b +2550_b +2364_b +00454_b +01_20181129_165104_b +20181121100636351-4_1_b +00161_b +00101_b +00284_b +00525_b +00427_b +01_20181129_165117_b +2334_b +00497_b +20181127154558261-3_1_b +00342_b +2281_b +20181127192043512-4_1_b +00149_b +00631_b +2052_b +01_20181130_111557_b +00204_b +01_20181130_113151_b +20181127115337607-3_1_b +00207_b +00315_b +1212_b +00388_b +01_20181129_170716_b +00463_b +00246_b +2034_b +20181122045305786-3_1_b +00286_b +1085_b +20181128000818090-4_1_b +01_20181130_114158_b +00038_b +1123_b +1346_b +1164_b +20181127202741788-3_1_b +1079_b +00428_b +20181122002040183-3_1_b +2350_b +00543_b +00172_b +2050_b +2704_b +20181127230517978-3_1_b +20181127233732091-4_1_b +00274_b +1259_b +1180_b +1518_b +01_20181129_154029_b +20181127125137475-4_1_b +00475_b +01_20181130_112021_b +1093_b +01_20181130_111543_b +20181122122255595-3_1_b +2623_b +2115_b +01_20181130_114706_b +20181127235306727-4_1_b +01_20181130_113056_b +00502_b +20181127080139736-4_1_b +20181122121858920-3_1_b +00199_b +00348_b +2370_b +01_20181130_111411_b +2279_b +2595_b +20181127104655615-3_1_b +20181128140520488-2_1_b +20181127201412607-4_1_b +20181122122020986-4_1_b +20181127085647130-4_1_b +20181127222919415-3_1_b +00615_b +20181127221349165-4_1_b +2046_b +2026_b +00613_b +00621_b +01_20181129_164335_b +20181119001011513-4_1_b +1443_b +20181121104728463-3_1_b +00601_b +1520_b +20181127074831430-3_1_b +00203_b +1328_b +01_20181130_112055_b +00285_b +20181128165955211-4_1_b +00338_b +2311_b +20181119001011513-3_1_b +01_20181130_112643_b +2419_b +01_20181129_162144_b +00289_b +2241_b +00178_b +00397_b +2378_b +20181127224908985-3_1_b +00634_b +2307_b +1449_b +2078_b +20181127095859036-4_1_b +20181122113820449-3_1_b +1139_b +2500_b +2174_b +1060_b +20181122121356092-4_1_b +00411_b +01_20181129_163255_b +00162_b +20181127114239684-3_1_b +01_20181130_113649_b +1261_b +00551_b +20181119060033421-3_1_b +1597_b +2362_b +00317_b +1153_b +01_20181130_114733_b +00402_b +00622_b +20181121000045721-3_1_b +00108_b +2143_b +00046_b +2180_b +20181127234639001-3_1_b +20181119115433970-4_1_b +2708_b +20181127152826262-2_1_b +01_20181129_170644_b +2064_b +00151_b +1364_b +2285_b +00189_b +00067_b +00241_b +20181127015943051-3_1_b +00434_b +01_20181130_112118_b +00456_b +2251_b +2121_b +20181127192905305-4_1_b +2044_b +1392_b +20181127173424096-3_1_b +2405_b +1239_b +00224_b +2615_b +1474_b +00129_b +01_20181130_113707_b +01_20181129_163138_b +01_20181129_153359_b +00117_b +2399_b +1174_b +20181119120354969-3_1_b +1022_b +2198_b +1344_b +20181127202435882-4_1_b +1407_b +01_20181130_114523_b +1004_b +00375_b +20181119115611830-3_1_b +2656_b +1397_b +2451_b +01_20181129_164849_b +00602_b +2465_b +00027_b +2652_b +2263_b +1447_b +20181127103320404-4_1_b +2455_b +1587_b +20181127232458604-4_1_b +2212_b +2617_b +20181126150842329-3_1_b +1528_b +1573_b +01_20181129_162300_b +20181127005623155-4_1_b +00328_b +1358_b +00334_b +2309_b +00119_b +00094_b +2520_b +20181119071505728-4_1_b +20181127072627756-3_1_b +2099_b +01_20181130_112735_b +20181127093942344-3_1_b +00010_b +2162_b +00147_b +01_20181129_165052_b +2040_b +00065_b +01_20181129_170749_b +20181128171016809-3_1_b +2239_b +2589_b +20181119103516969-4_1_b +2534_b +20181119091827752-4_1_b +20181122121516628-4_1_b +2097_b +20181127001649948-4_1_b +01_20181130_114543_b +00495_b +20181126001318139-3_1_b +00423_b +00441_b +00649_b +00190_b +00173_b +00606_b +20181119080906986-3_1_b +00367_b +2032_b +01_20181129_165515_b +1218_b +1473_b +1524_b +1552_b +20181127171206811-4_1_b +20181127075635128-4_1_b +00610_b +20181127165217153-3_1_b +1062_b +00487_b +20181127230259506-3_1_b +20181127131645187-3_1_b +1492_b +1247_b +00421_b +1565_b +2546_b +20181122104920241-4_1_b +01_20181129_164635_b +20181127224815294-3_1_b +00335_b +00168_b +1372_b +20181119100357744-3_1_b +00432_b +2431_b +1234_b +20181127213320791-3_1_b +2374_b +20181122104622680-3_1_b +01_20181130_111046_b +00439_b +01_20181130_112129_b +20181127093926326-3_1_b +2394_b +2599_b +2249_b +1559_b +2141_b +00612_b +2230_b +2473_b +20181126150446094-3_1_b +00078_b +20181119000956191-4_1_b +1245_b +2559_b +1567_b +00371_b +20181119101555200-3_1_b +00227_b +00093_b +20181122000053603-3_1_b +20181121080900752-4_1_b +01_20181130_112046_b +2565_b +1401_b +00263_b +00603_b +20181127213344114-3_1_b +01_20181130_113533_b +2457_b +01_20181130_113725_b +20181127224241714-3_1_b +1439_b +1208_b +2196_b +2275_b +20181122002525297-3_1_b +2668_b +2020_b +1417_b +20181119121606579-3_1_b +00526_b +2449_b +20181127000049917-4_1_b +00290_b +01_20181130_111616_b +2577_b +00264_b +2216_b +1453_b +00538_b +20181121035640835-3_1_b +1287_b +1309_b +1083_b +1378_b +01_20181129_163321_b +01_20181129_163349_b +00170_b +2376_b +20181121075447311-3_1_b +2257_b +00614_b +01_20181129_170633_b +20181127225041872-4_1_b +00329_b +1283_b +1265_b +01_20181129_164113_b +2166_b +2425_b +2670_b +00039_b +01_20181130_114050_b +00051_b +2271_b +00131_b +20181127100731082-3_1_b +00549_b +00064_b +00469_b +20181121095446044-4_1_b +2123_b +1394_b +1512_b +20181121105152214-3_1_b +2696_b +00354_b +2137_b +00222_b +01_20181129_153746_b +1224_b +2607_b +20181127230923581-3_1_b +2287_b +2129_b +20181127045208109-3_1_b +2372_b +20181122001044041-4_1_b +1089_b +2145_b +20181127012107319-4_1_b +2083_b +01_20181130_114149_b +20181128143035800-4_1_b +00300_b +20181127030027783-3_1_b +1348_b +00217_b +2210_b +01_20181129_164313_b +1228_b +2548_b +1360_b +01_20181130_112341_b +1563_b +20181127181546252-4_1_b +00229_b +00001_b +2091_b +2390_b +20181127002601832-4_1_b +2676_b +00418_b +20181127010743544-3_1_b +2192_b +01_20181130_114305_b +20181127091225228-4_1_b +1330_b +00278_b +1010_b +01_20181129_164122_b +20181127005001010-3_1_b +2324_b +20181122001241021-3_1_b +2512_b +00232_b +00314_b +00457_b +1237_b +1390_b +1285_b +2528_b +2407_b +1615_b +00118_b +20181127001707407-3_1_b +1409_b +20181127010230808-3_1_b +20181127090657770-4_1_b +20181119121530242-3_1_b +01_20181129_165506_b +20181126001317621-3_1_b +2206_b +1368_b +00044_b +00100_b +20181127233501087-3_1_b +20181127233131581-4_1_b +00141_b +1230_b +00524_b +00049_b +20181127075252321-3_1_b +00609_b +2151_b +2160_b +1482_b +2202_b +1421_b +1269_b +20181127082310414-3_1_b +00299_b +20181126200827642-3_1_b +00165_b +20181126062910882-3_1_b +20181122000556040-4_1_b +1293_b +2117_b +00620_b +20181127143631550-2_1_b +20181122000052952-4_1_b +00505_b +2036_b +00273_b +20181122122756372-3_1_b +1530_b +00121_b +20181127221911018-4_1_b +2459_b +20181128164601694-3_1_b +1289_b +20181128165928786-4_1_b +2000_b +2131_b +2038_b +1561_b +20181122023138352-4_1_b +1550_b +20181119115019411-3_1_b +20181121000545831-4_1_b +2267_b +2318_b +00650_b +20181119121131883-3_1_b +1281_b +00081_b +20181126020158129-3_1_b +20181127182642611-3_1_b +20181119115203907-4_1_b +2532_b +20181127221233330-3_1_b +20181119104035113-4_1_b +01_20181130_111006_b +01_20181130_113010_b +2678_b +00398_b +00142_b +20181119113804614-3_1_b +01_20181129_162043_b +20181122122804487-4_1_b +2437_b +00339_b +00450_b +2581_b +2366_b +20181127232323939-4_1_b +20181128140520488-3_1_b +20181127013430922-4_1_b +01_20181130_110917_b +1127_b +00268_b +20181127095243300-4_1_b +00057_b +1526_b +00307_b +00192_b +20181121093030671-3_1_b +2392_b +00130_b +00288_b +01_20181130_114214_b +00321_b +20181127233103007-4_1_b +00025_b +01_20181129_163527_b +20181127232033013-3_1_b +20181127094245754-4_1_b +1411_b +1476_b +20181127125614960-3_1_b +1141_b +1099_b +01_20181130_112556_b +1016_b +1629_b +20181122075223501-4_1_b +01_20181130_110930_b +00079_b +20181122081312622-4_1_b +1206_b +1038_b +1226_b +1577_b +00503_b +20181119113432375-3_1_b +20181127013631966-4_1_b +2579_b +20181119105413400-4_1_b +20181119043830890-4_1_b +00537_b +20181119002009034-3_1_b +20181126001713374-4_1_b +00269_b +1214_b +2380_b +1603_b +00365_b +00084_b +01_20181129_164254_b +01_20181130_114724_b +20181127221136584-2_1_b +2008_b +1315_b +20181121092636613-3_1_b +2510_b +00641_b +20181126035620948-4_1_b +00127_b +2074_b +00097_b +01_20181130_113029_b +20181122000745091-3_1_b +20181127030623221-4_1_b +20181126000705693-3_1_b +1255_b +20181119121233585-4_1_b +20181127013205532-3_1_b +00236_b +00633_b +2601_b +00331_b +00164_b +00471_b +20181119002047873-3_1_b +2439_b +1145_b +20181127215011177-3_1_b +20181127225246457-3_1_b +01_20181130_113839_b +2474_b +2016_b +01_20181129_163949_b +00080_b +1445_b +2095_b +20181119115509287-3_1_b +20181119101555200-4_1_b +20181127074902009-4_1_b +2273_b +20181119111505568-4_1_b +1162_b +01_20181129_170606_b +1431_b +1273_b +20181127003156459-3_1_b +00125_b +20181127014217867-4_1_b +1395_b +2660_b +00632_b +00013_b +2397_b +00611_b +2666_b +1488_b +1510_b +2243_b +00254_b +2068_b +00358_b +1484_b +00616_b +2506_b +00373_b +01_20181130_111532_b +01_20181129_155810_b +2524_b +2597_b +00177_b +20181119111548548-3_1_b +2006_b +00403_b +20181127154558624-3_1_b +20181119005355036-3_1_b +1295_b +00448_b +00489_b +2322_b +00006_b +20181127175956914-3_1_b +2674_b +1303_b +20181127093911883-3_1_b +00377_b +00445_b +1196_b +01_20181130_113200_b +00098_b +01_20181129_164625_b +00544_b +00384_b +20181128132919701-2_1_b +1435_b +01_20181129_164615_b +00201_b +20181126150558628-2_1_b +2672_b +01_20181130_114654_b +00063_b +20181128164630165-4_1_b +00619_b +00153_b +20181127100718633-3_1_b +20181121110151434-4_1_b +20181126152954169-2_1_b +01_20181130_112744_b +2461_b +00419_b +00120_b +01_20181129_170944_b +00133_b +20181127170245383-4_1_b +00640_b +20181119075122755-4_1_b +20181127220108359-4_1_b +20181121113230538-4_1_b +01_20181130_112715_b +20181128000541194-3_1_b +00512_b +00301_b +20181119103334351-4_1_b +01_20181129_162250_b +00390_b +00174_b +00305_b +01_20181129_165045_b +00638_b +1609_b +00062_b +1423_b +1467_b +20181119110753201-4_1_b +1111_b +00466_b +2283_b +20181127075324924-4_1_b +2062_b +20181127154558624-4_1_b +20181127194320187-2_1_b +20181119105542999-4_1_b +2253_b +00015_b +01_20181130_114616_b +2119_b +00186_b +01_20181130_111503_b +00298_b +20181127092635045-3_1_b +2190_b +01_20181129_160809_b +1601_b +00145_b +00214_b +2435_b +00636_b +00637_b +00357_b +2060_b +00433_b +20181127224934339-4_1_b +00250_b +1619_b +20181127204432329-3_1_b +20181127101615633-4_1_b +20181122020249975-3_1_b +00330_b +1320_b +20181122080948511-3_1_b +01_20181130_112956_b +20181119103840446-4_1_b +00259_b +20181122032956669-3_1_b +01_20181129_165416_b +01_20181129_164030_b +00341_b +00156_b +20181121110705119-3_1_b +1251_b +2401_b +1469_b +1200_b +01_20181129_164645_b +00184_b +2147_b +2542_b +1184_b +20181127092539655-4_1_b +20181127075635128-3_1_b +00355_b +00037_b +20181127222745426-4_1_b +20181126004807199-3_1_b +2710_b +1103_b +20181128130740139-3_1_b +2508_b +1299_b +00422_b +20181127123808454-3_1_b +00023_b +1538_b +00102_b +20181125100419346-4_1_b +00060_b +1374_b +2467_b +1465_b +00206_b +01_20181130_113715_b +20181122073750667-3_1_b +01_20181130_112034_b +1121_b +20181119092254236-3_1_b +2072_b +00208_b +01_20181129_161900_b +20181128132919701-1_1_b +2642_b +1605_b +20181126014538184-4_1_b +01_20181130_111925_b +1018_b +20181126181859959-2_1_b +01_20181129_164836_b +20181119105121435-3_1_b +01_20181129_164900_b +00253_b +01_20181129_163123_b +1076_b +00521_b +20181122020715219-3_1_b +01_20181129_163334_b +1297_b +00107_b +2332_b +20181121114153157-4_1_b +01_20181130_111114_b +00368_b +2164_b +2010_b +2101_b +00643_b +1427_b +00316_b +00191_b +2561_b +2328_b +1316_b +1494_b +20181127072414460-4_1_b +00332_b +00484_b +20181119112437378-4_1_b +1030_b +01_20181130_114639_b +2178_b +20181122010220543-4_1_b +00447_b +2153_b +2336_b +20181127230251206-3_1_b +1332_b +00461_b +00089_b +00485_b +1166_b +00180_b +1540_b +2557_b +00295_b +2403_b +20181122080944034-4_1_b +00522_b +1220_b +1631_b +01_20181130_112010_b +01_20181129_162225_b +00550_b +00053_b +01_20181129_163155_b +20181119094454220-3_1_b +20181128105623531-2_1_b +00104_b +20181127095602614-4_1_b +2638_b +20181127013425289-3_1_b +1623_b +00429_b +01_20181129_170833_b +1621_b +2644_b +1249_b +20181121072412351-3_1_b +20181128165303879-3_1_b +1210_b +1522_b +1078_b +2413_b +01_20181129_165526_b +1376_b +01_20181130_111031_b +2305_b +20181119121233585-3_1_b +20181122005531396-3_1_b +00527_b +00021_b +00069_b +20181128163524688-3_1_b +00605_b +20181127144552058-3_1_b +01_20181129_165134_b +2076_b +20181119013228333-4_1_b +2609_b +00181_b +1257_b +20181127004618957-3_1_b +2486_b +20181119114018628-3_1_b +20181126003200345-3_1_b +2567_b +2214_b +20181127163654619-4_1_b +2498_b +20181121112838990-4_1_b +20181127121113397-4_1_b +20181121104030474-3_1_b +1338_b +2585_b +00042_b +01_20181130_114534_b +1502_b +00496_b +2415_b +01_20181130_112323_b +20181127004525695-3_1_b +00352_b +2605_b +2139_b +2492_b +20181128000756689-4_1_b +01_20181129_165404_b +20181127010556106-4_1_b +1072_b +2184_b +2621_b +20181127115516857-3_1_b +20181128111521435-1_1_b +20181126013939987-3_1_b +1611_b +20181126015606934-4_1_b +01_20181130_111433_b +00416_b +20181127230657705-3_1_b +01_20181129_170655_b +01_20181130_114036_b +2107_b +00221_b +00626_b +20181127215616945-4_1_b +1236_b +1291_b +01_20181129_163507_b +20181127234432832-3_1_b +01_20181130_112417_b +00247_b +1050_b +01_20181129_163602_b +00498_b +00122_b +01_20181129_170759_b +00323_b +2330_b +20181126200758882-2_1_b +2316_b +20181127220608827-4_1_b +20181127003156459-4_1_b +1241_b +00360_b +01_20181130_111957_b +1279_b +2208_b +1267_b +20181126185253527-2_1_b +01_20181129_162103_b +20181119112645446-3_1_b +01_20181129_162121_b +00491_b +20181121080441207-3_1_b +2648_b +2014_b +00509_b +20181119121627237-3_1_b +01_20181129_165452_b +20181127000650698-3_1_b +20181127000616541-4_1_b +2575_b +00340_b +1002_b +2188_b +00378_b +20181127113906983-4_1_b +00210_b +20181128164710878-3_1_b +20181122104448601-4_1_b +20181127093743341-4_1_b +00435_b +00624_b +2259_b +00195_b +20181127234720221-3_1_b +2135_b +20181122041209218-3_1_b +00541_b +01_20181129_161828_b +20181119004342745-3_1_b +00137_b +1068_b +00256_b +00144_b +01_20181130_113210_b +01_20181129_164153_b +1012_b +1048_b +01_20181130_111059_b +20181127055123153-3_1_b +00395_b +20181119004427545-3_1_b +1143_b +2297_b +00477_b +00417_b +01_20181129_170811_b +00143_b +2611_b +1119_b +00018_b +00425_b +01_20181129_164039_b +20181127232447851-3_1_b +00175_b +1451_b +00266_b +20181127101816754-4_1_b +2469_b +1058_b +20181122002241659-4_1_b +20181127002233018-4_1_b +2354_b +2417_b +2516_b +2536_b +20181122003752841-3_1_b +1334_b +2301_b +2563_b +2636_b +2127_b +20181122001534897-4_1_b +1553_b +1277_b +00095_b +1105_b +1064_b +2640_b +1441_b +1575_b +20181128164429752-3_1_b +01_20181129_171009_b +00379_b +01_20181129_170729_b +00531_b +20181122002710407-4_1_b +20181119115021579-4_1_b +20181121000545831-3_1_b +20181122002946945-3_1_b +2089_b +2224_b +01_20181130_111947_b +1115_b +00200_b +1125_b +2482_b +20181127010839884-3_1_b +2441_b +20181127092942460-4_1_b +00412_b +2631_b +1044_b +01_20181130_114553_b +1607_b +01_20181129_163616_b +20181122004346347-4_1_b +00333_b +1354_b +2157_b +01_20181129_154119_b +01_20181129_161819_b +20181119002925693-3_1_b +00228_b +20181122122034042-3_1_b +00464_b +00140_b +1040_b +00628_b +00090_b +00326_b +20181119100357744-4_1_b +20181127075957107-4_1_b +2356_b +1599_b +2125_b +2463_b +01_20181129_162410_b +2443_b +01_20181130_112625_b +1356_b +00262_b +2247_b +00488_b +1147_b +1222_b +00139_b +20181127233116905-4_1_b +2348_b +1198_b +2471_b +20181122001534897-3_1_b +20181126004807199-4_1_b +20181119091657430-3_1_b +20181127075252570-3_1_b +00393_b +01_20181129_164000_b +20181119010304348-4_1_b +1170_b +00380_b +00022_b +20181122122332937-3_1_b +00630_b +20181122104747521-4_1_b +00061_b +00319_b +00364_b +00392_b +1437_b +2289_b +20181122121406951-3_1_b +00005_b +20181127121643578-4_1_b +01_20181129_164322_b +01_20181130_110853_b +1591_b +2103_b +2237_b +00444_b +00400_b +1026_b +1194_b +00243_b +01_20181130_114627_b +2236_b +01_20181129_170704_b +20181126124416178-2_1_b +1536_b +1362_b +20181126004308657-3_1_b +01_20181130_110948_b +20181122000543299-3_1_b +00109_b +00276_b +1097_b +00179_b +1546_b +20181127003819487-4_1_b +2388_b +2109_b +20181127074053174-4_1_b +00157_b +01_20181130_112610_b +20181121000443354-4_1_b +2650_b +20181127115321277-3_1_b +20181119101759756-4_1_b +1087_b +00443_b +01_20181129_165440_b +2690_b +01_20181129_162320_b +2340_b +20181127201050621-3_1_b +00216_b +20181127085734111-3_1_b +20181127001001394-3_1_b +20181119114352534-3_1_b +2303_b +20181122122100546-3_1_b +2176_b +20181127202435882-3_1_b +1160_b +1557_b +00451_b +1006_b +01_20181130_113038_b +1370_b +2222_b +20181127224452979-4_1_b +00493_b +00096_b +20181119115045863-4_1_b +01_20181130_113659_b +20181127101152231-4_1_b +20181127220311359-3_1_b +2684_b +00361_b +20181127230142599-4_1_b +1579_b +2706_b +20181127100731082-4_1_b +20181127013225881-3_1_b +20181121095615900-3_1_b +20181119075231628-3_1_b +20181119115524143-3_1_b +00507_b +2445_b +1336_b +00076_b +00128_b +2480_b +00440_b +01_20181130_111446_b +00293_b +20181127023043594-3_1_b +20181126201109427-4_1_b +1340_b +20181126152954169-3_1_b +2447_b +1095_b +01_20181130_113525_b +01_20181130_113917_b +00020_b +20181127010515454-4_1_b +1070_b +01_20181130_111133_b +2293_b +1091_b +1046_b +00211_b +20181127135456736-4_1_b +00310_b +20181121075250891-4_1_b +1202_b +01_20181130_112634_b +00534_b +2646_b +2048_b +00155_b +1471_b +00647_b +00114_b +1380_b +2427_b +01_20181130_112725_b +1382_b +00312_b +00297_b +00230_b +1263_b +01_20181130_111517_b +2299_b +1415_b +1101_b +00474_b +2024_b +00106_b +20181127221742713-4_1_b +00218_b +1486_b +2658_b +20181126035620948-3_1_b +00345_b +1433_b +01_20181130_112250_b +2587_b +2627_b +1429_b +00099_b +20181122121700635-4_1_b +1301_b +20181128150040768-1_1_b +00404_b +00607_b +1350_b +00048_b +00414_b +00546_b +00366_b +20181128145516880-2_1_b +2182_b +1188_b +20181127090432846-4_1_b +1322_b +00075_b +1342_b +2066_b +1583_b +20181119103334351-3_1_b +2421_b +00436_b +00415_b +00213_b +01_20181130_111423_b +2573_b +20181119100813942-4_1_b +00382_b +01_20181129_163104_b +1081_b +00410_b +2526_b +20181126000515692-4_1_b +00280_b +2433_b +2540_b +2625_b +00257_b +20181119112047550-3_1_b +20181119003727619-4_1_b +20181127080126870-3_1_b +20181127201050621-4_1_b +01_20181130_114207_b +00234_b +1461_b +00494_b +1498_b +20181119103749511-4_1_b +00016_b +1318_b +1625_b +20181128122439345-2_1_b +20181127113843708-3_1_b +00539_b +20181128174127699-4_1_b +00369_b +20181127224851174-3_1_b +01_20181130_113733_b +01_20181129_170623_b +20181127043505302-3_1_b +2662_b +01_20181130_113909_b +2553_b +2269_b +01_20181130_113623_b +20181127212223489-4_1_b +1324_b +2172_b +2603_b +2158_b +00529_b +1463_b +01_20181130_113512_b +20181127161250784-4_1_b +1066_b +00625_b +2504_b +2315_b +00248_b +00146_b +2234_b +2291_b +1388_b +20181127173424096-4_1_b +20181127010119487-3_1_b +2694_b +1399_b +20181128143936956-1_1_b +2204_b +2518_b +00004_b +00154_b +20181121100230103-3_1_b +20181127034632957-4_1_b +2170_b +20181119120520492-3_1_b +01_20181129_163210_b +1034_b +00515_b +20181122013832268-4_1_b +20181119113722754-3_1_b +2686_b +00324_b +00639_b +01_20181129_165335_b +1232_b +2220_b +01_20181130_113900_b +00026_b +00302_b +20181128163429487-4_1_b +01_20181129_163307_b +00482_b +2664_b +20181127220847854-3_1_b +20181127143458813-3_1_b +1172_b +00396_b +20181119115926168-3_1_b +00438_b +2226_b +00386_b +1617_b +20181122001044041-3_1_b +2682_b +2654_b +2342_b +20181119011543507-3_1_b +20181127150519069-4_1_b +01_20181129_163940_b +00113_b +00028_b +2544_b +1192_b +1403_b +20181127113612183-3_1_b +00103_b +00478_b +20181122121313891-3_1_b +20181127225414390-4_1_b +01_20181130_113459_b +20181122073716737-3_1_b +20181127012258051-4_1_b +1133_b +20181127010427774-3_1_b +1155_b +20181127074751792-3_1_b +01_20181129_170841_b +20181127133311293-2_1_b +20181125123315158-3_1_b +00009_b +1478_b +1386_b +20181119033219588-4_1_b +00455_b +20181122000444538-4_1_b +00492_b +01_20181129_165345_b +01_20181129_164303_b +2502_b +20181119092207198-4_1_b +2593_b +00007_b +01_20181129_164009_b +00629_b +2002_b +1455_b +20181128150040768-4_1_b +01_20181129_154055_b +2155_b +20181127235646080-3_1_b +2552_b +1056_b +20181121091731738-3_1_b +2368_b +2344_b +20181119091827752-3_1_b +1000_b +2360_b +00240_b +20181127095726262-3_1_b +20181121083238283-3_1_b +20181127222704454-3_1_b +1113_b +01_20181130_112300_b +20181119112056294-4_1_b +2018_b +20181128161101275-2_1_b +20181126165018850-1_1_b +20181127223614758-3_1_b +01_20181130_114741_b +20181119121807941-4_1_b +1571_b +00183_b +00071_b +00220_b +2490_b +1366_b +01_20181129_153655_b +1151_b +00652_b +00012_b +1496_b +00408_b +20181119091811374-3_1_b +00251_b +2346_b +1014_b +20181127232358578-4_1_b +01_20181130_113219_b +00350_b +00383_b +2478_b +00072_b +2384_b +2030_b +00486_b +20181127023842660-4_1_b +20181127004815087-3_1_b +20181126004830616-3_1_b +00092_b +1457_b +2411_b +2232_b +1157_b +01_20181129_164556_b +1107_b +20181121112441752-3_1_b +20181122080021057-3_1_b +1176_b +00002_b +00116_b +2085_b +1275_b +1532_b +1413_b +01_20181130_113550_b +2555_b +2087_b +00066_b +00308_b +20181122052625519-3_1_b +20181127195406672-4_1_b +20181121083959600-4_1_b +1135_b +20181127230609226-3_1_b +20181121110151434-3_1_b +1042_b +20181128134632228-2_1_b +20181127090432846-3_1_b +00166_b +2255_b +01_20181129_165353_b +1480_b +2058_b +2295_b +2583_b +1307_b +2056_b +20181127224934339-3_1_b +00372_b +1131_b +20181122000632255-4_1_b +00325_b +2004_b +1204_b +1129_b +00035_b +20181127055427470-3_1_b +20181127233420161-3_1_b +00083_b +2429_b +20181119003621701-3_1_b +2688_b +00648_b +1544_b +00514_b +01_20181130_114803_b +00110_b +2386_b +00472_b +1506_b +20181127014451922-3_1_b +00138_b +20181127202210901-3_1_b +2133_b +00363_b +20181126200758882-1_1_b +2168_b +20181128164136413-3_1_b +01_20181130_114256_b +2569_b +1542_b +00167_b +20181127113452893-4_1_b +2012_b +00136_b +00460_b +1569_b +2042_b +20181121100936635-3_1_b +2494_b +00235_b +00277_b +2313_b +01_20181130_114223_b +00134_b +20181127044902570-3_1_b +20181122003853982-4_1_b +20181122004611642-4_1_b +20181119110620276-3_1_b +2453_b +20181127100354947-4_1_b +00304_b +1074_b +1581_b +20181127005001010-4_1_b +00608_b +20181119020405719-3_1_b +00040_b +01_20181130_112307_b +1109_b +2218_b +01_20181130_114028_b +00513_b +20181127034632957-3_1_b +1516_b +00271_b +1190_b +2382_b +2022_b +01_20181129_155709_b +20181122080222799-4_1_b +00242_b diff --git a/eval_wo_gd.py b/eval_wo_gd.py new file mode 100644 index 0000000..587982b --- /dev/null +++ b/eval_wo_gd.py @@ -0,0 +1,100 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Copyright © 2017-10-25 21:09 zq +# +# Distributed under terms of the MIT license. + +""" +Evaluate our best model without groundtruth. +""" + +import argparse +import torch +import numpy as np +import time +import importlib + +from torch.autograd import Variable +from torchvision import transforms +from torch.utils.data import DataLoader + +from data.dataset import Pair_Dataset +from loss.v2loss import v2loss +import os +import os.path as osp +from utils import render_v2wo_gd + + +def evaluate(args): + ### DATA ### + dataclass = Pair_Dataset(args.test_dir, test=True) + imkey_list = dataclass.imkey_list + dataloader = {} + dataloader["test"] = DataLoader(dataclass, + 1, + shuffle=False, + num_workers=args.num_workers) + if not osp.exists(args.desdir): + os.makedirs(args.desdir) + fa, fb = open(args.deta_fn, "w"), open(args.detb_fn, "w") + anchors = [(41.4514,52.2819), (63.2610,59.1658), (52.3392,76.1706), (94.5413,77.2516), (71.5646,108.9415)] + criterion = v2loss(anchors=anchors, coord_scale=2) + ### LOAD MODEL ### + if osp.exists(args.model_fn): + model_weights = torch.load(args.model_fn) + model = importlib.import_module("model." + args.model).DiffNetwork() + model.load_state_dict(model_weights) + if args.cuda: + model = model.cuda() + else: + raise IOError + + ### START TO EUALUATE ### + tic = time.time() + running_loss = 0 + + for ii, (index, im_a, im_b, label) in enumerate(dataloader["test"]): + inp_a, inp_b = Variable(im_a), Variable(im_b) + if args.cuda: + inp_a, inp_b = inp_a.cuda(), inp_b.cuda() + pred = model(inp_a, inp_b) + imkey = imkey_list[index[0]] + + deta_str, detb_str = render_v2wo_gd(args, imkey, pred, anchors=anchors) + fa.write(deta_str), fb.write(detb_str) + + fa.close(), fb.close() + + print (" | Time consuming: {:.2f}s".format(time.time()-tic)) + +def parse(): + parser = argparse.ArgumentParser() + parser.add_argument('--test_dir', type=str, default="./data/cdata/test") + parser.add_argument('--num_workers', type=int, default=1, + help="Number of data loading threads.") + parser.add_argument('--no_cuda', action='store_true', default=False, + help="Disable CUDA training.") + parser.add_argument('--model', type=str, default="subv2", + help="A model name to generate network.") + parser.add_argument('--model_fn', type=str, default="./default.pth.tar", + help="A model tar file to test.") + parser.add_argument('--deta_fn', type=str, default="./result_wo/det_a.txt", + help="Detection result filename of image a.") + parser.add_argument('--detb_fn', type=str, default="./result_wo/det_b.txt", + help="Detection result filename of image b.") + parser.add_argument('--desdir', type=str, default="./result_wo", + help="Rendered image directory.") + parser.add_argument('--fontfn', type=str, default="./srcs/droid-sans-mono.ttf", + help="Font filename when rendering.") + parser.add_argument('--render', type=int, default=0, + help="Output rendered files to result directory") + + args = parser.parse_args() + args.cuda = not args.no_cuda and torch.cuda.is_available() + return args + +if __name__ == "__main__": + args = parse() + evaluate(args) diff --git a/evalv1.py b/evalv1.py new file mode 100644 index 0000000..f6879e1 --- /dev/null +++ b/evalv1.py @@ -0,0 +1,113 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Distributed under terms of the MIT license. + +""" +Evaluate our best model. +""" + +import argparse +import torch +import time +import os +import os.path as osp +import importlib + +from torch.autograd import Variable +from torchvision import transforms +from torch.utils.data import DataLoader +from torch.optim import lr_scheduler + +from data.dataset import Pair_Dataset +from loss.loss import criterion +import os.path as osp +from utils import render_orim + +tensor2PIL = lambda x: transforms.ToPILImage()(x.view(-1, 512, 512)) + +def evaluate(args): + ### DATA ### + dataclass = Pair_Dataset(args.test_dir, test=True) + imkey_list = dataclass.imkey_list + dataloader = {} + dataloader["test"] = DataLoader(dataclass, + 1, + shuffle=False, + num_workers=args.num_workers) + if not osp.exists(args.desdir): + os.makedirs(args.desdir) + fa, fb = open(args.deta_fn, "w"), open(args.detb_fn, "w") + + ### LOAD MODEL ### + if osp.exists(args.model_fn): + model_weights = torch.load(args.model_fn) + model = importlib.import_module("model." + args.model).DiffNetwork() + model.load_state_dict(model_weights) + if args.cuda: + model = model.eval().cuda() + else: + raise IOError + + ### START TO EUALUATE ### + tic = time.time() + running_loss = 0 + + cnt = 0 + allt = 0 + for ii, (index, im_a, im_b, label) in enumerate(dataloader["test"]): + cnt += 1 + inp_a, inp_b = Variable(im_a), Variable(im_b) + label = Variable(label) + if args.cuda: + inp_a, inp_b = inp_a.cuda(), inp_b.cuda() + label = label.cuda() + ta = time.time() + pred = model(inp_a, inp_b) + tb = time.time() + dt = tb - ta + allt += dt + loss = criterion(label, pred) + running_loss += loss.data[0] + imkey = imkey_list[index[0]] + + deta_str, detb_str = render_orim(args, imkey, label, pred) + fa.write(deta_str), fb.write(detb_str) + + fa.close(), fb.close() + + print (" | -- Eval Ave Loss {:.2f}".format(running_loss/(ii+1))) + print (" | Time consuming: {:.2f}s".format(time.time()-tic)) + print('count: %d' % cnt) + print('all infer time: {:.2f}s, avg infer time: {:.2f}ms'.format(allt, 1000*allt/cnt)) + +def parse(): + parser = argparse.ArgumentParser() + parser.add_argument('--test_dir', type=str, default="./data/cdata/test") + parser.add_argument('--num_workers', type=int, default=4, + help="Number of data loading threads.") + parser.add_argument('--no_cuda', action='store_true', default=False, + help="Disable CUDA training.") + parser.add_argument('--model', type=str, default="base", + help="A model name to generate network.") + parser.add_argument('--model_fn', type=str, default="./default.pth.tar", + help="A model tar file to test.") + parser.add_argument('--deta_fn', type=str, default="./result/v120/det_a.txt", + help="Detection result filename of image a.") + parser.add_argument('--detb_fn', type=str, default="./result/v120/det_b.txt", + help="Detection result filename of image b.") + parser.add_argument('--desdir', type=str, default="./result/v120", + help="Rendered image directory.") + parser.add_argument('--fontfn', type=str, default="./srcs/droid-sans-mono.ttf", + help="Font filename when rendering.") + parser.add_argument('--render', type=int, default=0, + help="Output rendered files to result directory") + + args = parser.parse_args() + args.cuda = not args.no_cuda and torch.cuda.is_available() + return args + +if __name__ == "__main__": + args = parse() + evaluate(args) diff --git a/evalv2.py b/evalv2.py new file mode 100644 index 0000000..37b0d49 --- /dev/null +++ b/evalv2.py @@ -0,0 +1,90 @@ +import argparse +import torch +import numpy as np +import time +import importlib + +from torch.autograd import Variable +from torchvision import transforms +from torch.utils.data import DataLoader + +import xml.etree.ElementTree as ET +from data.d14 import Pair_Dataset +from loss.v2loss import v2loss +import os +import os.path as osp +from utils import render_v2orim +import pdb + +def evaluate(args): + dataclass = Pair_Dataset(args.test_dir, test=True) + imkey_list = dataclass.imkey_list + dataloader = DataLoader(dataclass, 1, shuffle=False, num_workers=args.num_workers) + if osp.exists(args.model_fn): + model_weights = torch.load(args.model_fn) + model = importlib.import_module('model.' + args.model).DiffNetwork() + model.load_state_dict(model_weights) + model = model.cuda().eval() + else: + raise IOError + + if not osp.exists(args.desdir): + os.makedirs(args.desdir) + fa, fb = open(args.deta_fn, "w"), open(args.detb_fn, "w") + + anchors = [(41.4514,52.2819), (63.2610,59.1658), (52.3392,76.1706), (94.5413,77.2516), (71.5646,108.9415)] + + print(' | Start evaluating...') + tic = time.time() + criterion = v2loss(anchors=anchors, coord_scale=2) + running_loss= 0 + + cnt = 0 + allt = 0 + for ii, (index, im_a, im_b, label) in enumerate(dataloader): + cnt += 1 + inp_a, inp_b = Variable(im_a).cuda(), Variable(im_b).cuda() + label = Variable(label).cuda() + ta = time.time() + pred = model(inp_a, inp_b) + tb = time.time() + dt = tb - ta + allt += dt + loss = criterion(pred.float(), label.float(), ii) + running_loss += loss.data[0] + imkey = imkey_list[index[0]] + + deta_str, detb_str = render_v2orim(args, imkey, label, pred, anchors=anchors) + fa.write(deta_str), fb.write(detb_str) + fa.close(), fb.close() + + print (" | -- Eval Ave Loss {:.4f}".format(running_loss/(ii+1))) + print (" | Time consuming: {:.2f}s".format(time.time()-tic)) + print('count: %d' % cnt) + print('all infer time: {:.2f}s, avg infer time: {:.2f}ms'.format(allt, 1000*allt/cnt)) + +def parse(): + parser = argparse.ArgumentParser() + parser.add_argument('--test_dir', type=str, default='./data/cdata/test') + parser.add_argument('--num_workers', type=int, default=1, + help="Number of data loading threads.") + parser.add_argument('--model', type=str, default="base", + help="A model name to generate network.") + parser.add_argument('--model_fn', type=str, default="./base_2019-01-07.pth.tar", + help="A model tar file to test.") + parser.add_argument('--deta_fn', type=str, default="./result/v2/det_a.txt", + help="Detection result filename of image a.") + parser.add_argument('--detb_fn', type=str, default="./result/v2/det_b.txt", + help="Detection result filename of image b.") + parser.add_argument('--desdir', type=str, default="./result/v2", + help="Rendered image directory.") + parser.add_argument('--fontfn', type=str, default="./srcs/droid-sans-mono.ttf", + help="Font filename when rendering.") + parser.add_argument('--render', type=int, default=0, + help="Output rendered files to result directory") + args = parser.parse_args() + return args + +if __name__ == "__main__": + args = parse() + evaluate(args) diff --git a/loss/__init__.py b/loss/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/loss/__pycache__/__init__.cpython-36.pyc b/loss/__pycache__/__init__.cpython-36.pyc new file mode 100644 index 0000000..c04bc46 Binary files /dev/null and b/loss/__pycache__/__init__.cpython-36.pyc differ diff --git a/loss/__pycache__/loss.cpython-36.pyc b/loss/__pycache__/loss.cpython-36.pyc new file mode 100644 index 0000000..8c2178f Binary files /dev/null and b/loss/__pycache__/loss.cpython-36.pyc differ diff --git a/loss/__pycache__/v2loss.cpython-36.pyc b/loss/__pycache__/v2loss.cpython-36.pyc new file mode 100644 index 0000000..03c801c Binary files /dev/null and b/loss/__pycache__/v2loss.cpython-36.pyc differ diff --git a/loss/loss.py b/loss/loss.py new file mode 100644 index 0000000..5d4fb6c --- /dev/null +++ b/loss/loss.py @@ -0,0 +1,118 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Copyright © 2017-10-26 22:09 zq +# +# Distributed under terms of the MIT license. + +import torch +import numpy as np +import time +import matplotlib.pyplot as plt + +from torch.autograd import Variable +import pdb + + +__all__ = ['criterion'] + +""" +How to get value from GPU RAM + You first need to get tensor out of the variable using .data + Then you need to move the tensor to cpu using .cpu() + After that you can convert tensor to numpy using .numpy() + And you probably know the rest... So basically a.data.cpu().numpy()[0] will give you just the value +""" + +def criterion(label, pred, object_scale=1, noobject_scale=0.1, class_scale=0.3, coord_scale=5, num_class=2): + ### INIT ### + pred = pred.type('torch.cuda.DoubleTensor') + loss = Variable(torch.zeros((1)), requires_grad=True).cuda().type('torch.cuda.DoubleTensor') + BS, ROW, COL = pred.size()[0], pred.size()[2], pred.size()[3] + avg_iou, avg_cat, avg_allcat, avg_obj, avg_anyobj, count = 0, 0, 0, 0, 0, 0 + delta = pred[:, 0, :, :] + loss += noobject_scale * torch.sum(torch.mul(delta, delta)) + + for i_pair in range(BS): + count_obj = 0 + for row in range(ROW): + for col in range(COL): + ### Compute match bounding box of groundtruth + if label[i_pair, 0, row, col].data[0]: + """ + Label semantic: + _ __ ____ + 0 12 3456 + + + +> bbox + + ++> Which obj + ++> Object + """ + + # Forward and backward of category(2) + delta = pred[i_pair, 1:1+num_class, row, col] - label[i_pair, 1:1+num_class, row, col] + loss += class_scale * torch.sum(torch.mul(delta, delta)) + +# print ("Loss stage 1, class: {:.5f}".format(loss.data[0])) + + # Forward and backward of prob of obj + delta = pred[i_pair, 0, row, col] - 1.0 + loss -= noobject_scale * (torch.mul(pred[i_pair, 0, row, col], pred[i_pair, 0, row, col])) + loss += object_scale * (delta ** 2) + +# print ("Loss stage 2, obj: {:.5f}".format(loss.data[0])) + + # Forward and backward of coordinates + tx, ty, tw, th = label[i_pair, 1+num_class:, row, col].data + #tx = tx / ROW + #ty = ty / psz[1] + ox, oy, ow, oh = pred[i_pair, 1+num_class:num_class+1+4, row, col].data + # ox /= psz[2] + # oy /= psz[1] + iou = box_iou([(ox+col)/COL, (oy+row)/ROW, ow, oh], [(tx+col)/COL, (ty+row)/ROW, tw, th]) +# print('iou: {:.5f}'.format(iou)) + loss += (iou - 1.0) *(iou - 1.0) +# print ("Loss stage 3, iou: {:.5f}".format(loss.data[0])) + + delta = pred[i_pair, 1+num_class:, row, col] - label[i_pair, 1+num_class:, row, col] + loss += coord_scale * torch.sum(torch.mul(delta, delta)) +# print ("Loss stage 4, coord: {:.5f}\n".format(loss.data[0])) + loss = loss / BS + + return loss + + +### UTILS FOR IOU ### + +def box_iou(a, b): + return box_intersection(a, b) / box_union(a, b) + +def box_intersection(a, b): + def overlap(mida, wa, midb, wb): + l1, l2 = mida - wa/2, midb - wb/2 + left = max(l1, l2) + r1, r2 = mida + wa/2, midb + wb/2 + right = min(r1, r2) + return right - left + w = overlap(a[0], a[2], b[0], b[2]) + h = overlap(a[1], a[3], b[1], b[3]) + if (w <= 0 or h <= 0): + return 0 + area = w * h + return area + +def box_union(a, b): + i = box_intersection(a, b) + u = a[2] * a[3] + b[2] * b[3] - i + return u + +# 均方根误差 root-mean-square error +def box_rmse(a, b): + res = (a[0] - b[0]) ** 2 + res += (a[1] - b[1]) ** 2 + res += (a[2] - b[2]) ** 2 + res += (a[3] - b[3]) ** 2 + return sqrt(res) + + + diff --git a/loss/v2giou.py b/loss/v2giou.py new file mode 100644 index 0000000..e9f37f6 --- /dev/null +++ b/loss/v2giou.py @@ -0,0 +1,233 @@ +# -*- coding: utf-8 -*- +import torch +import torch.nn as nn +import torch.nn.functional as F +import numpy as np +from torch.autograd import Variable +import itertools +import pdb + +class v2loss(nn.Module): + + def __init__(self, anchors, + obj_scale=5, noobj_scale=0.5, class_scale=1, coord_scale=1, num_class=2): + super(v2loss, self).__init__() + self.num_class = num_class + self.num_anchors = len(anchors) + self.anchors = torch.Tensor(anchors) / (512/14.0) + #anchor化为相对于grid的w和h + + self.coord_scale = coord_scale + self.noobj_scale = noobj_scale + self.obj_scale = obj_scale + self.class_scale = class_scale + + self.size = 1 + num_class + 4 + + def forward(self, pred, label, seen): + ''' + pred: bsx35x14x14 + label: bsx 7x14x14 + ''' + BS = pred.data.size(0) + H = pred.data.size(2) + W = pred.data.size(3) + + wh = Variable(torch.from_numpy(np.reshape([W, H], [1, 1, 1, 1, 2]))).float().cuda() + #anchor_bias = Variable(self.anchors.view(1, 1, 1, self.num_anchors, 2)).cuda() + anchor_bias = Variable(self.anchors.view(1, 1, 1, self.num_anchors, 2)).cuda() / wh + w_list = np.array(list(range(W)), np.float32) + wh_ids = Variable(torch.from_numpy(np.array(list(map(lambda x: np.array(list(itertools.product(w_list, [x]))), range(H)))).reshape(1, H, W, 1, 2))).float().cuda() + + loss = Variable(torch.zeros((1)), requires_grad=True).cuda() + class_zeros = Variable(torch.zeros(self.num_class)).cuda() + mask_loss = Variable(torch.zeros(H*W*self.num_anchors*5).contiguous().view(H, W, self.num_anchors, 5)).cuda() + zero_coords_loss = Variable(torch.zeros(H*W*self.num_anchors*4).contiguous().view(H, W, self.num_anchors, 4)).cuda() + zero_coords_obj_loss = Variable(torch.zeros(H*W*self.num_anchors*5).contiguous().view(H, W, self.num_anchors, 5)).cuda() + + zero_pad = Variable(torch.zeros(2).contiguous().view(1, 2)).cuda() + pad_var = Variable(torch.zeros(2*self.num_anchors).contiguous().view(self.num_anchors, 2)).cuda() + anchor_padded = torch.cat([pad_var, anchor_bias.contiguous().view(self.num_anchors, 2)], 1) + + pred = pred.permute(0, 2, 3, 1) + pred = pred.contiguous().view(-1, H, W, self.num_anchors, self.size) + + adjust_xy = pred[:, :, :, :, 1+self.num_class:1+self.num_class+2].sigmoid() + adjust_coords = (adjust_xy + wh_ids) / wh + #adjust_coords = adjust_xy + wh_ids + adjust_wh = torch.exp(pred[:, :, :, :, 1+self.num_class+2:1+self.num_class+4]) * anchor_bias + + for b in range(BS): + gtb = parse_label(label[b]) + if not len(gtb): + continue + gt = Variable(torch.zeros((len(gtb), 4))).cuda() + for i, anno in enumerate(gtb): + #gt[i,0] = anno[0] + #gt[i,1] = anno[1] + #gt[i,2] = anno[2] * W + #gt[i,3] = anno[3] * H + gt[i,0] = anno[0] / W + gt[i,1] = anno[1] / H + gt[i,2] = anno[2] + gt[i,3] = anno[3] + pred_outputs = torch.cat([adjust_coords[b], adjust_wh[b]], 3) + bboxes_iou = bbox_ious(pred_outputs, gt, False) + + boxes_max_iou = torch.max(bboxes_iou, -1)[0] + all_obj_mask = boxes_max_iou.le(0.6) + #all_obj_loss = all_obj_mask.float() *(self.noobj_scale * (-1 * pred[b, :, :, :, 0])) + all_obj_loss = all_obj_mask.float() *(self.noobj_scale * (pred[b, :, :, :, 0])) + #所有iou<0.6的计为noobj,计算noobj loss + + all_coords_loss = zero_coords_loss.clone() + if seen < 12800: + #all_coords_loss = 0.01 * torch.cat([(0.5 - adjust_xy[b]), (0 - pred[b, :, :, :, 1+self.num_class+2:1+self.num_class+4])], -1) + all_coords_loss = 0.01 * torch.cat([(adjust_xy[b]-0.5), (pred[b, :, :, :, 1+self.num_class+2:1+self.num_class+4]-0)], -1) + #训练图片<12800张时,计算框的形状loss + coord_obj_loss = torch.cat([all_coords_loss, all_obj_loss.unsqueeze(-1)], -1) + + batch_mask = mask_loss.clone() + truth_coord_obj_loss = zero_coords_obj_loss.clone() + for truth_iter in torch.arange(len(gtb)): + truth_iter = int(truth_iter) + truth_box = gt[truth_iter] + anchor_select = bbox_ious(torch.cat([zero_pad.t(), truth_box[2:].view(1,2).t()], 0).t(), anchor_padded, True) + anchor_id = torch.max(anchor_select, 1)[1] + + truth_i = truth_box[0] * W + w_i = truth_i.int() + truth_x = truth_i - w_i.float() + #w_i = truth_box[0].int() + #truth_x = truth_box[0] - w_i.float() + truth_j = truth_box[1] * H + h_j = truth_j.int() + truth_y = truth_j - h_j.float() + #h_j = truth_box[1].int() + #truth_y = truth_box[1] - h_j.float() + truth_wh = (truth_box[2:] / anchor_bias.contiguous().view(self.num_anchors, 2).index_select(0, anchor_id.long())).log() + if (truth_wh[0] == Variable( - torch.cuda.FloatTensor([float('inf')]))).data[0] == 1: + pdb.set_trace() + truth_coords = torch.cat([truth_x.unsqueeze(0), truth_y.unsqueeze(0), truth_wh], 1) + pred_output = pred[b].index_select(0, h_j.long()).index_select(1, w_i.long()).index_select(2, anchor_id.long())[0][0][0] + pred_xy = adjust_xy[b].index_select(0, h_j.long()).index_select(1, w_i.long()).index_select(2, anchor_id.long())[0][0][0] + pred_wh = pred_output[1+self.num_class+2:1+self.num_class+4] + pred_coords = torch.cat([pred_xy, pred_wh], 0) + #coords_loss = self.coord_scale * (truth_coords - pred_coords.unsqueeze(0)) + #coords_loss = self.coord_scale * (pred_coords.unsqueeze(0) - truth_coords) + coords_loss_scale = 2 - truth_x.data[0] * truth_y.data[0] + coords_loss = self.coord_scale * coords_loss_scale * (pred_coords.unsqueeze(0) - truth_coords) + #coords_loss = self.coord_scale * (2 - truth_x.data[0]*truth_y.data[0]) *(pred_coords.unsqueeze(0) - truth_coords) + #坐标回归损失,选中的那个anchor的预测结果和真实坐标的损失 + iou = bboxes_iou.index_select(0, h_j.long()).index_select(1, w_i.long()).index_select(2, anchor_id.long())[0][0][0][truth_iter] + + #print(iou, h_j.data[0], w_i.data[0], label[b, :, h_j.data[0], w_i.data[0]]) + + obj_loss = self.obj_scale * (pred_output[0] - iou) + #obj_loss = self.obj_scale * (pred_output[0] - 1) + #obj loss 选中的anchor的iou loss + truth_co_obj = torch.cat([coords_loss, obj_loss.view(1, 1)], 1) + + class_vec = class_zeros.clone() + class_vec[0] = label[b, 1, int(h_j), int(w_i)] + class_vec[1] = label[b, 2, int(h_j), int(w_i)] + #class_loss = self.class_scale * (class_vec - pred_output[1:1+self.num_class]) + class_loss = self.class_scale * (pred_output[1:1+self.num_class] - class_vec) + #分类损失,选中的那个anchor的分类损失 + + mask_ones = Variable(torch.ones(5)).cuda() + batch_mask[h_j.long(), w_i.long(), anchor_id.long()] = mask_ones + truth_coord_obj_loss[h_j.long(), w_i.long(), anchor_id.long()] = truth_co_obj + loss += class_loss.pow(2).sum() + batch_coord_obj_loss = batch_mask * truth_coord_obj_loss + (1 - batch_mask) * coord_obj_loss + #只计算选中anchor对应的坐标和obj loss,别的框的置0忽略 + loss += batch_coord_obj_loss.pow(2).sum() + if loss.data[0] > 10000: + print('loss(%d) is too high'%(loss.data[0])) + print(pred[b,:,:,:,0].pow(2).sum()) + pdb.set_trace() + + return loss/BS + + +def bbox_ious(bboxes1, bboxes2, is_anchor): + x1, y1, w1, h1 = bboxes1.chunk(4, dim=-1) #把tensor按顺序分成4块 + x2, y2, w2, h2 = bboxes2.chunk(4, dim=-1) + x11 = x1 - 0.5*w1#预测框左上x + y11 = y1 - 0.5*h1#预测框左上y + x12 = x1 + 0.5*w1#预测框右下x + y12 = y1 + 0.5*h1#预测框右下y + x21 = x2 - 0.5*w2#(1,1) + y21 = y2 - 0.5*h2 + x22 = x2 + 0.5*w2 + y22 = y2 + 0.5*h2 + xI1 = torch.max(x11, x21.transpose(1, 0))#所有预测框左上角与gt左上角 最大值 + yI1 = torch.max(y11, y21.transpose(1, 0)) + + xI2 = torch.min(x12, x22.transpose(1, 0))#所有预测框右下角与gt右下角 最小值 + yI2 = torch.min(y12, y22.transpose(1, 0)) + + #[xI1, yI1, xI2, yI2] 交并框 + + inner_box_w = torch.clamp((xI2 - xI1), min=0) + inner_box_h = torch.clamp((yI2 - yI1), min=0) + inter_area = inner_box_w * inner_box_h + + bboxes1_area = (x12 - x11) * (y12 - y11) + bboxes2_area = (x22 - x21) * (y22 - y21) + + union = (bboxes1_area + bboxes2_area.transpose(1, 0)) - inter_area + + return torch.clamp(inter_area / union, min=0) + +def bbox_gious(bboxes1, bboxes2): + x1, y1, w1, h1 = bboxes1.chunk(4, dim=-1) + x2, y2, w2, h2 = bboxes2.chunk(4, dim=-1) + x11 = x1 - 0.5*w1 + y11 = y1 - 0.5*h1 + x12 = x1 + 0.5*w1 + y12 = y1 + 0.5*h1 + x21 = x2 - 0.5*w2 + y21 = y2 - 0.5*h2 + x22 = x2 + 0.5*w2 + y22 = y2 + 0.5*h2 + + bboxes1_area = (x12 - x11) * (y12 - y11) + bboxes2_area = (x22 - x21) * (y22 - y21) + + xI1 = torch.max(x11, x21.transpose(1, 0)) + yI1 = torch.max(y11, y21.transpose(1, 0)) + xI2 = torch.min(x12, x22.transpose(1, 0)) + yI2 = torch.min(y12, y22.transpose(1, 0)) + inter_box_w = torch.clamp((xI2 - xI1), min=0) + inter_box_h = torch.clamp((yI2 - yI1), min=0) + inter_area = inner_box_w * inner_box_h + + union = bboxea1_area + bboxes2_area.transpose(1, 0) - inter_area + iou = torch.clamp(inter_area / union, min=0) + + xE1 = torch.min(x11, x21.transpose(1, 0)) + yE1 = torch.min(y11, y21.transpose(1, 0)) + xE2 = torch.max(x12, x22.transpose(1, 0)) + yE2 = torch.max(y12, y22.transpose(1, 0)) + enclose_w = torch.clamp((xE2 - xE1), min=0) + enclose_h = torch.clamp((yE2 - yE1), min=0) + enclose_area = enclose_w * enclose_h + + giou = iou - (enclose_area - union_area) / enclose_area + + return giou + + + +def parse_label(label): + _, h, w = label.size() + gts = [] + for r in range(h): + for c in range(w): + if label[0, r, c].data[0]: + tx, ty, tw, th = label[1+2:, r, c].data + tx, ty = tx+c, ty+r + gts.append([tx,ty,tw,th]) + return gts + diff --git a/loss/v2loss.py b/loss/v2loss.py new file mode 100644 index 0000000..65499aa --- /dev/null +++ b/loss/v2loss.py @@ -0,0 +1,185 @@ +# -*- coding: utf-8 -*- +import torch +import torch.nn as nn +import torch.nn.functional as F +import numpy as np +from torch.autograd import Variable +import itertools +import pdb + +class v2loss(nn.Module): + + def __init__(self, anchors, + obj_scale=5, noobj_scale=0.5, class_scale=1, coord_scale=1, num_class=2): + super(v2loss, self).__init__() + self.num_class = num_class + self.num_anchors = len(anchors) + self.anchors = torch.Tensor(anchors) / (512/14.0) + #anchor化为相对于grid的w和h + + self.coord_scale = coord_scale + self.noobj_scale = noobj_scale + self.obj_scale = obj_scale + self.class_scale = class_scale + + self.size = 1 + num_class + 4 + + def forward(self, pred, label, seen): + ''' + pred: bsx35x14x14 + label: bsx 7x14x14 + ''' + BS = pred.data.size(0) + H = pred.data.size(2) + W = pred.data.size(3) + + wh = Variable(torch.from_numpy(np.reshape([W, H], [1, 1, 1, 1, 2]))).float().cuda() + #anchor_bias = Variable(self.anchors.view(1, 1, 1, self.num_anchors, 2)).cuda() + anchor_bias = Variable(self.anchors.view(1, 1, 1, self.num_anchors, 2)).cuda() / wh + w_list = np.array(list(range(W)), np.float32) + wh_ids = Variable(torch.from_numpy(np.array(list(map(lambda x: np.array(list(itertools.product(w_list, [x]))), range(H)))).reshape(1, H, W, 1, 2))).float().cuda() + + loss = Variable(torch.zeros((1)), requires_grad=True).cuda() + class_zeros = Variable(torch.zeros(self.num_class)).cuda() + mask_loss = Variable(torch.zeros(H*W*self.num_anchors*5).contiguous().view(H, W, self.num_anchors, 5)).cuda() + zero_coords_loss = Variable(torch.zeros(H*W*self.num_anchors*4).contiguous().view(H, W, self.num_anchors, 4)).cuda() + zero_coords_obj_loss = Variable(torch.zeros(H*W*self.num_anchors*5).contiguous().view(H, W, self.num_anchors, 5)).cuda() + + zero_pad = Variable(torch.zeros(2).contiguous().view(1, 2)).cuda() + pad_var = Variable(torch.zeros(2*self.num_anchors).contiguous().view(self.num_anchors, 2)).cuda() + anchor_padded = torch.cat([pad_var, anchor_bias.contiguous().view(self.num_anchors, 2)], 1) + + pred = pred.permute(0, 2, 3, 1) + pred = pred.contiguous().view(-1, H, W, self.num_anchors, self.size) + + adjust_xy = pred[:, :, :, :, 1+self.num_class:1+self.num_class+2].sigmoid() + adjust_coords = (adjust_xy + wh_ids) / wh + #adjust_coords = adjust_xy + wh_ids + adjust_wh = torch.exp(pred[:, :, :, :, 1+self.num_class+2:1+self.num_class+4]) * anchor_bias + + for b in range(BS): + gtb = parse_label(label[b]) + if not len(gtb): + continue + gt = Variable(torch.zeros((len(gtb), 4))).cuda() + for i, anno in enumerate(gtb): + #gt[i,0] = anno[0] + #gt[i,1] = anno[1] + #gt[i,2] = anno[2] * W + #gt[i,3] = anno[3] * H + gt[i,0] = anno[0] / W + gt[i,1] = anno[1] / H + gt[i,2] = anno[2] + gt[i,3] = anno[3] + pred_outputs = torch.cat([adjust_coords[b], adjust_wh[b]], 3) + bboxes_iou = bbox_ious(pred_outputs, gt, False) + + boxes_max_iou = torch.max(bboxes_iou, -1)[0] + all_obj_mask = boxes_max_iou.le(0.6) + #all_obj_loss = all_obj_mask.float() *(self.noobj_scale * (-1 * pred[b, :, :, :, 0])) + all_obj_loss = all_obj_mask.float() *(self.noobj_scale * (pred[b, :, :, :, 0])) + #所有iou<0.6的计为noobj,计算noobj loss + + all_coords_loss = zero_coords_loss.clone() + if seen < 12800: + #all_coords_loss = 0.01 * torch.cat([(0.5 - adjust_xy[b]), (0 - pred[b, :, :, :, 1+self.num_class+2:1+self.num_class+4])], -1) + all_coords_loss = 0.01 * torch.cat([(adjust_xy[b]-0.5), (pred[b, :, :, :, 1+self.num_class+2:1+self.num_class+4]-0)], -1) + #训练图片<12800张时,计算框的形状loss + coord_obj_loss = torch.cat([all_coords_loss, all_obj_loss.unsqueeze(-1)], -1) + + batch_mask = mask_loss.clone() + truth_coord_obj_loss = zero_coords_obj_loss.clone() + for truth_iter in torch.arange(len(gtb)): + truth_iter = int(truth_iter) + truth_box = gt[truth_iter] + anchor_select = bbox_ious(torch.cat([zero_pad.t(), truth_box[2:].view(1,2).t()], 0).t(), anchor_padded, True) + anchor_id = torch.max(anchor_select, 1)[1] + + truth_i = truth_box[0] * W + w_i = truth_i.int() + truth_x = truth_i - w_i.float() + #w_i = truth_box[0].int() + #truth_x = truth_box[0] - w_i.float() + truth_j = truth_box[1] * H + h_j = truth_j.int() + truth_y = truth_j - h_j.float() + #h_j = truth_box[1].int() + #truth_y = truth_box[1] - h_j.float() + truth_wh = (truth_box[2:] / anchor_bias.contiguous().view(self.num_anchors, 2).index_select(0, anchor_id.long())).log() + if (truth_wh[0] == Variable( - torch.cuda.FloatTensor([float('inf')]))).data[0] == 1: + pdb.set_trace() + truth_coords = torch.cat([truth_x.unsqueeze(0), truth_y.unsqueeze(0), truth_wh], 1) + pred_output = pred[b].index_select(0, h_j.long()).index_select(1, w_i.long()).index_select(2, anchor_id.long())[0][0][0] + pred_xy = adjust_xy[b].index_select(0, h_j.long()).index_select(1, w_i.long()).index_select(2, anchor_id.long())[0][0][0] + pred_wh = pred_output[1+self.num_class+2:1+self.num_class+4] + pred_coords = torch.cat([pred_xy, pred_wh], 0) + #coords_loss = self.coord_scale * (truth_coords - pred_coords.unsqueeze(0)) + #coords_loss = self.coord_scale * (pred_coords.unsqueeze(0) - truth_coords) + coords_loss = self.coord_scale * (2 - truth_x.data[0]*truth_y.data[0]) *(pred_coords.unsqueeze(0) - truth_coords) + #坐标回归损失,选中的那个anchor的预测结果和真实坐标的损失 + iou = bboxes_iou.index_select(0, h_j.long()).index_select(1, w_i.long()).index_select(2, anchor_id.long())[0][0][0][truth_iter] + + #print(iou, h_j.data[0], w_i.data[0], label[b, :, h_j.data[0], w_i.data[0]]) + + obj_loss = self.obj_scale * (pred_output[0] - iou) + #obj_loss = self.obj_scale * (pred_output[0] - 1) + #obj loss 选中的anchor的iou loss + truth_co_obj = torch.cat([coords_loss, obj_loss.view(1, 1)], 1) + + class_vec = class_zeros.clone() + class_vec[0] = label[b, 1, int(h_j), int(w_i)] + class_vec[1] = label[b, 2, int(h_j), int(w_i)] + #class_loss = self.class_scale * (class_vec - pred_output[1:1+self.num_class]) + class_loss = self.class_scale * (pred_output[1:1+self.num_class] - class_vec) + #分类损失,选中的那个anchor的分类损失 + + mask_ones = Variable(torch.ones(5)).cuda() + batch_mask[h_j.long(), w_i.long(), anchor_id.long()] = mask_ones + truth_coord_obj_loss[h_j.long(), w_i.long(), anchor_id.long()] = truth_co_obj + loss += class_loss.pow(2).sum() + batch_coord_obj_loss = batch_mask * truth_coord_obj_loss + (1 - batch_mask) * coord_obj_loss + #只计算选中anchor对应的坐标和obj loss,别的框的置0忽略 + loss += batch_coord_obj_loss.pow(2).sum() + if loss.data[0] > 10000: + print('loss(%d) is too high'%(loss.data[0])) + print(pred[b,:,:,:,0].pow(2).sum()) + pdb.set_trace() + + return loss/BS + + +def bbox_ious(bboxes1, bboxes2, is_anchor): + x1, y1, w1, h1 = bboxes1.chunk(4, dim=-1) + x2, y2, w2, h2 = bboxes2.chunk(4, dim=-1) + x11 = x1 - 0.5*w1 + y11 = y1 - 0.5*h1 + x12 = x1 + 0.5*w1 + y12 = y1 + 0.5*h1 + x21 = x2 - 0.5*w2 + y21 = y2 - 0.5*h2 + x22 = x2 + 0.5*w2 + y22 = y2 + 0.5*h2 + xI1 = torch.max(x11, x21.transpose(1, 0)) + yI1 = torch.max(y11, y21.transpose(1, 0)) + + xI2 = torch.min(x12, x22.transpose(1, 0)) + yI2 = torch.min(y12, y22.transpose(1, 0)) + inner_box_w = torch.clamp((xI2 - xI1), min=0) + inner_box_h = torch.clamp((yI2 - yI1), min=0) + inter_area = inner_box_w * inner_box_h + bboxes1_area = (x12 - x11) * (y12 - y11) + bboxes2_area = (x22 - x21) * (y22 - y21) + union = (bboxes1_area + bboxes2_area.transpose(1, 0)) - inter_area + return torch.clamp(inter_area / union, min=0) + +def parse_label(label): + _, h, w = label.size() + gts = [] + for r in range(h): + for c in range(w): + if label[0, r, c].data[0]: + tx, ty, tw, th = label[1+2:, r, c].data + tx, ty = tx+c, ty+r + gts.append([tx,ty,tw,th]) + return gts + diff --git a/loss/v2loss15.py b/loss/v2loss15.py new file mode 100644 index 0000000..33feffc --- /dev/null +++ b/loss/v2loss15.py @@ -0,0 +1,179 @@ +# -*- coding: utf-8 -*- +import torch +import torch.nn as nn +import torch.nn.functional as F +import numpy as np +from torch.autograd import Variable +import itertools +import pdb + +class v2loss(nn.Module): + + def __init__(self, anchors, + obj_scale=5, noobj_scale=0.5, class_scale=1, coord_scale=1, num_class=2): + super(v2loss, self).__init__() + self.num_class = num_class + self.num_anchors = len(anchors) + self.anchors = torch.Tensor(anchors) / (512/15.0) + #anchor化为相对于grid的w和h + + self.coord_scale = coord_scale + self.noobj_scale = noobj_scale + self.obj_scale = obj_scale + self.class_scale = class_scale + + self.size = 1 + num_class + 4 + + def forward(self, pred, label, seen): + ''' + pred: bsx35x14x14 + label: bsx 7x14x14 + ''' + BS = pred.data.size(0) + H = pred.data.size(2) + W = pred.data.size(3) + + wh = Variable(torch.from_numpy(np.reshape([W, H], [1, 1, 1, 1, 2]))).float().cuda() + #anchor_bias = Variable(self.anchors.view(1, 1, 1, self.num_anchors, 2)).cuda() + anchor_bias = Variable(self.anchors.view(1, 1, 1, self.num_anchors, 2)).cuda() / wh + w_list = np.array(list(range(W)), np.float32) + wh_ids = Variable(torch.from_numpy(np.array(list(map(lambda x: np.array(list(itertools.product(w_list, [x]))), range(H)))).reshape(1, H, W, 1, 2))).float().cuda() + + loss = Variable(torch.zeros((1)), requires_grad=True).cuda() + class_zeros = Variable(torch.zeros(self.num_class)).cuda() + mask_loss = Variable(torch.zeros(H*W*self.num_anchors*5).contiguous().view(H, W, self.num_anchors, 5)).cuda() + zero_coords_loss = Variable(torch.zeros(H*W*self.num_anchors*4).contiguous().view(H, W, self.num_anchors, 4)).cuda() + zero_coords_obj_loss = Variable(torch.zeros(H*W*self.num_anchors*5).contiguous().view(H, W, self.num_anchors, 5)).cuda() + + zero_pad = Variable(torch.zeros(2).contiguous().view(1, 2)).cuda() + pad_var = Variable(torch.zeros(2*self.num_anchors).contiguous().view(self.num_anchors, 2)).cuda() + anchor_padded = torch.cat([pad_var, anchor_bias.contiguous().view(self.num_anchors, 2)], 1) + + pred = pred.permute(0, 2, 3, 1) + pred = pred.contiguous().view(-1, H, W, self.num_anchors, self.size) + + adjust_xy = pred[:, :, :, :, 1+self.num_class:1+self.num_class+2].sigmoid() + adjust_coords = (adjust_xy + wh_ids) / wh + #adjust_coords = adjust_xy + wh_ids + adjust_wh = torch.exp(pred[:, :, :, :, 1+self.num_class+2:1+self.num_class+4]) * anchor_bias + + for b in range(BS): + gtb = parse_label(label[b]) + if not len(gtb): + continue + gt = Variable(torch.zeros((len(gtb), 4))).cuda() + for i, anno in enumerate(gtb): + #gt[i,0] = anno[0] + #gt[i,1] = anno[1] + #gt[i,2] = anno[2] * W + #gt[i,3] = anno[3] * H + gt[i,0] = anno[0] / W + gt[i,1] = anno[1] / H + gt[i,2] = anno[2] + gt[i,3] = anno[3] + pred_outputs = torch.cat([adjust_coords[b], adjust_wh[b]], 3) + bboxes_iou = bbox_ious(pred_outputs, gt, False) + + boxes_max_iou = torch.max(bboxes_iou, -1)[0] + all_obj_mask = boxes_max_iou.le(0.6) + #all_obj_loss = all_obj_mask.float() *(self.noobj_scale * (-1 * pred[b, :, :, :, 0])) + all_obj_loss = all_obj_mask.float() *(self.noobj_scale * (pred[b, :, :, :, 0])) + + all_coords_loss = zero_coords_loss.clone() + if seen < 12800: + #all_coords_loss = 0.01 * torch.cat([(0.5 - adjust_xy[b]), (0 - pred[b, :, :, :, 1+self.num_class+2:1+self.num_class+4])], -1) + all_coords_loss = 0.01 * torch.cat([(adjust_xy[b]-0.5), (pred[b, :, :, :, 1+self.num_class+2:1+self.num_class+4]-0)], -1) + coord_obj_loss = torch.cat([all_coords_loss, all_obj_loss.unsqueeze(-1)], -1) + + batch_mask = mask_loss.clone() + truth_coord_obj_loss = zero_coords_obj_loss.clone() + for truth_iter in torch.arange(len(gtb)): + truth_iter = int(truth_iter) + truth_box = gt[truth_iter] + anchor_select = bbox_ious(torch.cat([zero_pad.t(), truth_box[2:].view(1,2).t()], 0).t(), anchor_padded, True) + anchor_id = torch.max(anchor_select, 1)[1] + + truth_i = truth_box[0] * W + w_i = truth_i.int() + truth_x = truth_i - w_i.float() + #w_i = truth_box[0].int() + #truth_x = truth_box[0] - w_i.float() + truth_j = truth_box[1] * H + h_j = truth_j.int() + truth_y = truth_j - h_j.float() + #h_j = truth_box[1].int() + #truth_y = truth_box[1] - h_j.float() + truth_wh = (truth_box[2:] / anchor_bias.contiguous().view(self.num_anchors, 2).index_select(0, anchor_id.long())).log() + if (truth_wh[0] == Variable( - torch.cuda.FloatTensor([float('inf')]))).data[0] == 1: + pdb.set_trace() + truth_coords = torch.cat([truth_x.unsqueeze(0), truth_y.unsqueeze(0), truth_wh], 1) + pred_output = pred[b].index_select(0, h_j.long()).index_select(1, w_i.long()).index_select(2, anchor_id.long())[0][0][0] + pred_xy = adjust_xy[b].index_select(0, h_j.long()).index_select(1, w_i.long()).index_select(2, anchor_id.long())[0][0][0] + pred_wh = pred_output[1+self.num_class+2:1+self.num_class+4] + pred_coords = torch.cat([pred_xy, pred_wh], 0) + #coords_loss = self.coord_scale * (truth_coords - pred_coords.unsqueeze(0)) + #coords_loss = self.coord_scale * (pred_coords.unsqueeze(0) - truth_coords) + coords_loss = self.coord_scale * (2 - truth_x.data[0]*truth_y.data[0]) *(pred_coords.unsqueeze(0) - truth_coords) + iou = bboxes_iou.index_select(0, h_j.long()).index_select(1, w_i.long()).index_select(2, anchor_id.long())[0][0][0][truth_iter] + + #print(iou, h_j.data[0], w_i.data[0], label[b, :, h_j.data[0], w_i.data[0]]) + + obj_loss = self.obj_scale * (pred_output[0] - iou) + #obj_loss = self.obj_scale * (pred_output[0] - 1) + truth_co_obj = torch.cat([coords_loss, obj_loss.view(1, 1)], 1) + + class_vec = class_zeros.clone() + class_vec[0] = label[b, 1, int(h_j), int(w_i)] + class_vec[1] = label[b, 2, int(h_j), int(w_i)] + #class_loss = self.class_scale * (class_vec - pred_output[1:1+self.num_class]) + class_loss = self.class_scale * (pred_output[1:1+self.num_class] - class_vec) + + mask_ones = Variable(torch.ones(5)).cuda() + batch_mask[h_j.long(), w_i.long(), anchor_id.long()] = mask_ones + truth_coord_obj_loss[h_j.long(), w_i.long(), anchor_id.long()] = truth_co_obj + loss += class_loss.pow(2).sum() + batch_coord_obj_loss = batch_mask * truth_coord_obj_loss + (1 - batch_mask) * coord_obj_loss + loss += batch_coord_obj_loss.pow(2).sum() + if loss.data[0] > 10000: + print('loss(%d) is too high'%(loss.data[0])) + print(pred[b,:,:,:,0].pow(2).sum()) + pdb.set_trace() + + return loss/BS + + +def bbox_ious(bboxes1, bboxes2, is_anchor): + x1, y1, w1, h1 = bboxes1.chunk(4, dim=-1) + x2, y2, w2, h2 = bboxes2.chunk(4, dim=-1) + x11 = x1 - 0.5*w1 + y11 = y1 - 0.5*h1 + x12 = x1 + 0.5*w1 + y12 = y1 + 0.5*h1 + x21 = x2 - 0.5*w2 + y21 = y2 - 0.5*h2 + x22 = x2 + 0.5*w2 + y22 = y2 + 0.5*h2 + xI1 = torch.max(x11, x21.transpose(1, 0)) + yI1 = torch.max(y11, y21.transpose(1, 0)) + + xI2 = torch.min(x12, x22.transpose(1, 0)) + yI2 = torch.min(y12, y22.transpose(1, 0)) + inner_box_w = torch.clamp((xI2 - xI1), min=0) + inner_box_h = torch.clamp((yI2 - yI1), min=0) + inter_area = inner_box_w * inner_box_h + bboxes1_area = (x12 - x11) * (y12 - y11) + bboxes2_area = (x22 - x21) * (y22 - y21) + union = (bboxes1_area + bboxes2_area.transpose(1, 0)) - inter_area + return torch.clamp(inter_area / union, min=0) + +def parse_label(label): + _, h, w = label.size() + gts = [] + for r in range(h): + for c in range(w): + if label[0, r, c].data[0]: + tx, ty, tw, th = label[1+2:, r, c].data + tx, ty = tx+c, ty+r + gts.append([tx,ty,tw,th]) + return gts + diff --git a/mAP/compute_mAP.py b/mAP/compute_mAP.py new file mode 100644 index 0000000..863a421 --- /dev/null +++ b/mAP/compute_mAP.py @@ -0,0 +1,232 @@ +#!/usr/bin/env python3 +# This file was modified from +# https://raw.githubusercontent.com/rbgirshick/py-faster-rcnn/master/lib/datasets/voc_eval.py +# -------------------------------------------------------- +# Faster R-CNN +# Licensed under The MIT License [see LICENSE for details] +# Written by Bharath Hariharan +# -------------------------------------------------------- + +import gflags +import xml.etree.ElementTree as ET +import os, sys +import pickle +import time +import numpy as np +import os.path as osp +import math +import matplotlib.pyplot as plt +import pdb + +floor = lambda x: math.floor(float(x)) + + +CLASSES = ["a", "b"] + +def parse_rec(filename): + """ Parse a PASCAL VOC xml file """ + if osp.exists(filename): + tree = ET.parse(filename) + objects = [] + for obj in tree.findall('object'): + obj_struct = {} + #obj_struct['name'] = tree.findall('filename')[0].text[-5:-4] + obj_struct['name'] = filename[-5:-4] + obj_struct['difficult'] = 0 + bbox = obj.find('bndbox') + obj_struct['bbox'] = [floor(bbox.find('xmin').text), + floor(bbox.find('ymin').text), + floor(bbox.find('xmax').text), + floor(bbox.find('ymax').text)] + objects.append(obj_struct) + else: + objects = [] + + return objects + +def voc_ap(rec, prec, use_07_metric=False): + """ ap = voc_ap(rec, prec, [use_07_metric]) + Compute VOC AP given precision and recall. + If use_07_metric is true, uses the VOC 07 11 point method (default:False). + """ + if use_07_metric: + # 11 point metric + ap = 0. + for t in np.arange(0., 1.1, 0.1): + if np.sum(rec >= t) == 0: + p = 0 + else: + p = np.max(prec[rec >= t]) + ap = ap + p / 11. + else: + # correct AP calculation + # first append sentinel values at the end + mrec = np.concatenate(([0.], rec, [1.])) + mpre = np.concatenate(([0.], prec, [0.])) + + # compute the precision envelope + for i in range(mpre.size - 1, 0, -1): + mpre[i - 1] = np.maximum(mpre[i - 1], mpre[i]) + + # to calculate area under PR curve, look for points + # where X axis (recall) changes value + i = np.where(mrec[1:] != mrec[:-1])[0] + + # and sum (\Delta recall) * prec + ap = np.sum((mrec[i + 1] - mrec[i]) * mpre[i + 1]) + return ap + +def voc_eval(detpath, annopath, imagesetfile, classname, ovthresh=0.5, use_07_metric=False): + with open(imagesetfile, 'r') as f: + lines = f.readlines() + imagenames = [x.strip() for x in lines] + + # load annots == records + recs = {} + for i, imagename in enumerate(imagenames): + recs[imagename] = parse_rec(annopath.format(imagename)) + + # extract gt objects for this class + class_recs = {} + npos = 0 + for imagename in imagenames: + R = [obj for obj in recs[imagename] if obj['name'] == classname] + bbox = np.array([x['bbox'] for x in R]) + difficult = np.array([x['difficult'] for x in R]).astype(np.bool) + det = [False] * len(R) + npos = npos + sum(~difficult) + class_recs[imagename] = {'bbox': bbox, + 'difficult': difficult, + 'det': det} + + # read dets + detfile = detpath.format(classname) + with open(detfile, 'r') as f: + lines = f.readlines() + + splitlines = [x.strip().split(' ') for x in lines] + image_ids = [x[0] for x in splitlines] + confidence = np.array([float(x[1]) for x in splitlines]) + BB = np.array([[float(z) for z in x[2:]] for x in splitlines]) + + if confidence.shape[0] == 0: # None this class + return 0, 0, 0 + + # sort by confidence + sorted_ind = np.argsort(-confidence) # gen a sort index + sorted_scores = np.sort(-confidence) + BB = BB[sorted_ind, :] + image_ids = [image_ids[x] for x in sorted_ind] + + # go down dets and mark TPs and FPs + nd = len(image_ids) + tp = np.zeros(nd) + fp = np.zeros(nd) + for d in range(nd): + R = class_recs[image_ids[d]] + bb = BB[d, :].astype(float) + ovmax = -np.inf + BBGT = R['bbox'].astype(float) + + if BBGT.size > 0: + ixmin = np.maximum(BBGT[:, 0], bb[0]) + iymin = np.maximum(BBGT[:, 1], bb[1]) + ixmax = np.minimum(BBGT[:, 2], bb[2]) + iymax = np.minimum(BBGT[:, 3], bb[3]) + iw = np.maximum(ixmax - ixmin + 1., 0.) + ih = np.maximum(iymax - iymin + 1., 0.) + inters = iw * ih + + uni = ((bb[2] - bb[0] + 1.) * (bb[3] - bb[1] + 1.) + + (BBGT[:, 2] - BBGT[:, 0] + 1.) * + (BBGT[:, 3] - BBGT[:, 1] + 1.) - inters) + + overlaps = inters / uni + ovmax = np.max(overlaps) + jmax = np.argmax(overlaps) + + if ovmax > ovthresh: + if not R['difficult'][jmax]: + if not R['det'][jmax]: + tp[d] = 1. + R['det'][jmax] = 1 + else: + fp[d] = 1. + else: + fp[d] = 1. + + # compute precision recall + fp = np.cumsum(fp) + tp = np.cumsum(tp) + rec = tp / float(npos) + # avoid divide by zero in case the first detection matches a difficult + # ground truth + prec = tp / np.maximum(tp + fp, np.finfo(np.float64).eps) + ap = voc_ap(rec, prec, use_07_metric) + + return rec, prec, ap + +def assistor(detpath, annopath, imagesetfile, classname): + rec, prec, ap = voc_eval(detpath, annopath, imagesetfile, classname, ovthresh=0.5, use_07_metric=False) + print (' | {}--------------'.format(classname)) + print (' | --ap: {}'.format(ap)) + print (' | --max prec: {}'.format(max(prec))) + print (' | --max rec: {}'.format(max(rec))) + print (" | ") + return rec, prec, ap + +def pr(prec, rec, ap, classname, use_07_metric=False): + xs = np.arange(0, 1.1, 0.1) + name = classname + plt.figure() + plt.title('AP(%s)=%.4f' %(name, ap)) + plt.xlabel('Recall') + plt.ylabel('Precision') + plt.axis([0, 1, 0, 1.05]) + plt.xticks(xs) + plt.yticks(xs) + if use_07_metric: + ps = [] + for x in xs: + if np.sum(rec>=x) == 0: + ps.append(0) + else: + np.append(np.max(np.nan_to_num(prec)[rec>=x])) + plt.plot(xs, ps) + plt.savefig('%s.png' % (name)) + plt.close() + else: + mpre = np.concatenate(([0], np.nan_to_num(prec), [0])) + mrec = np.concatenate(([0], rec, [1])) + mpre = np.maximum.accumulate(mpre[::-1])[::-1] + i = np.where(mrec[1:] != mrec[:-1])[0] + ts = mrec[i+1] + ps = mpre[i+1] + plt.plot(ts, ps) + plt.savefig('%s.png' % (name)) + plt.close() + +if __name__ == '__main__': + """ + det_a_path = "./cache/det_a.txt" + det_b_path = "./cache/det_b.txt" + annopath = "/home/zq/diff_resnet/data/test/{}.xml" + im_a_txt = "./cache/testa.txt" + im_b_txt = "./cache/testb.txt" + """ + det_a_path, det_b_path = sys.argv[1], sys.argv[2] + annopath = sys.argv[3] + im_a_txt, im_b_txt = sys.argv[4], sys.argv[5] + + mAP = 0.0 + tic = time.time() + rec_a, prec_a, ap_a = assistor(det_a_path, annopath, im_a_txt, "a") + rec_b, prec_b, ap_b = assistor(det_b_path, annopath, im_b_txt, "b") + #pr(prec_a, rec_a, ap_a, 'a') + #pr(prec_b, rec_b, ap_b, 'b') + mAP += ap_a/2.0 + mAP += ap_b/2.0 + print (' | mAP: {}'.format(mAP)) + print (" | This evalution consumes {0:.1f}s".format(time.time()-tic)) + print (" | Done!") + diff --git a/mAP/test_mAP.sh b/mAP/test_mAP.sh new file mode 100644 index 0000000..92809c5 --- /dev/null +++ b/mAP/test_mAP.sh @@ -0,0 +1,12 @@ +#! /bin/sh +# +# init.sh +# +# Distributed under terms of the MIT license. + + +python compute_mAP.py ../result/v2/det_a.txt \ + ../result/v2/det_b.txt \ + '../data/test/{}.xml' \ + ../data/testa.txt \ + ../data/testb.txt diff --git a/model/__init__.py b/model/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/model/base.py b/model/base.py new file mode 100644 index 0000000..ddb7753 --- /dev/null +++ b/model/base.py @@ -0,0 +1,40 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Copyright © 2017-10-25 20:42 zq +# +# Distributed under terms of the MIT license. + +""" +Find difference of two similar image through learning in pytorch. +""" + +import torch.nn as nn +import torchvision +import torch +from torchvision import datasets, models, transforms + +class DiffNetwork(nn.Module): + def __init__(self): + super(DiffNetwork, self).__init__() + # 16x16 and 512 channels + self.resnet18 = nn.Sequential(*list(models.resnet18(pretrained=True).children())[:-2]) + self.regression = nn.Sequential( + # To 14x14 + nn.Conv2d(1024, 512, kernel_size=4, stride=1, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(512, 512, kernel_size=4, stride=1, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(512, 35, kernel_size=3, stride=1, padding=1)) + + def forward(self, inputa, inputb): + outputa = self.resnet18(inputa) + outputb = self.resnet18(inputb) + concated_fea = torch.cat([outputa, outputb], dim=1) # [batch_size, 1024, 16, 16] + output = self.regression(concated_fea) + return output diff --git a/model/cbam.py b/model/cbam.py new file mode 100644 index 0000000..f414727 --- /dev/null +++ b/model/cbam.py @@ -0,0 +1,75 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Copyright © 2017-10-25 20:42 zq +# +# Distributed under terms of the MIT license. + +""" +Find difference of two similar image through learning in pytorch. +""" + +import torch.nn as nn +import torchvision +import torch +from torchvision import datasets, models, transforms +import pdb + +class ChannelAttention(nn.Module): + def __init__(self, in_plane, ratio=16): + super(ChannelAttention, self).__init__() + self.avg_pool = nn.AdaptiveAvgPool2d(1) + self.max_pool = nn.AdaptiveMaxPool2d(1) + self.fc1 = nn.Conv2d(in_plane, in_plane//ratio, 1, bias=False) + self.relu1 = nn.ReLU() + self.fc2 = nn.Conv2d(in_plane//ratio, in_plane, 1, bias=False) + self.sigmoid = nn.Sigmoid() + + def forward(self, x): + avg_out = self.fc2(self.relu1(self.fc1(self.avg_pool(x)))) + max_out = self.fc2(self.relu1(self.fc1(self.max_pool(x)))) + out = avg_out + max_out + return self.sigmoid(out) + + +class SpatialAttention(nn.Module): + def __init__(self): + super(SpatialAttention, self).__init__() + self.conv1 = nn.Conv2d(2, 1, kernel_size=7, padding=3, bias=False) + self.sigmoid = nn.Sigmoid() + + def forward(self, x): + avg_out = torch.mean(x, dim=1, keepdim=True) + max_out, _ = torch.max(x, dim=1, keepdim=True) + x = torch.cat([avg_out, max_out], dim=1) + x = self.conv1(x) + return self.sigmoid(x) + +class DiffNetwork(nn.Module): + def __init__(self): + super(DiffNetwork, self).__init__() + # 16x16 and 512 channels + self.sa = SpatialAttention() + self.ca = ChannelAttention(512) + self.resnet18 = nn.Sequential(*list(models.resnet18(pretrained=True).children())[:-2]) + self.regression = nn.Sequential( + # To 14x14 + nn.Conv2d(512, 512, kernel_size=4, stride=1, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(512, 512, kernel_size=4, stride=1, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(512, 35, kernel_size=3, stride=1, padding=1)) # (5x7)x14x14 + + def forward(self, inputa, inputb): + outputa = self.resnet18(inputa) + outputb = self.resnet18(inputb) + sub_fea = outputa - outputb + + ### + sub_fea = self.ca(sub_fea) * sub_fea + sub_fea = self.sa(sub_fea) * sub_fea + output = self.regression(sub_fea) + return output diff --git a/model/da.py b/model/da.py new file mode 100644 index 0000000..39ef604 --- /dev/null +++ b/model/da.py @@ -0,0 +1,90 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Copyright © 2017-10-25 20:42 zq +# +# Distributed under terms of the MIT license. + +""" +Find difference of two similar image through learning in pytorch. +""" + +import torch.nn as nn +import torchvision +import torch +from torchvision import datasets, models, transforms +import pdb + +class PAM(nn.Module): + def __init__(self, in_plane): + super(PAM, self).__init__() + + self.query_conv = nn.Conv2d(in_plane, in_plane//8, 1, bias=False) + self.key_conv = nn.Conv2d(in_plane, in_plane//8, 1, bias=False) + self.value_conv = nn.Conv2d(in_plane, in_plane, 1, bias=False) + self.gamma = nn.Parameter(torch.zeros(1)) + self.softmax = nn.Softmax(dim=-1) + + def forward(self, x): + b, C, h, w = x.size() + proj_query = self.query_conv(x).view(b, -1, w*h).permute(0, 2, 1) + proj_key = self.key_conv(x).view(b, -1, w*h) + energy = torch.bmm(proj_query, proj_key) + att = self.softmax(energy) + proj_value = self.value_conv(x).view(b, -1, w*h) + + out = torch.bmm(proj_value, att.permute(0, 2, 1)) + out = out.view(b, C, h, w) + out = self.gamma*out + x + return out + + +class CAM(nn.Module): + def __init__(self, in_plane): + super(CAM, self).__init__() + self.gamma = nn.Parameter(torch.zeros(1)) + self.softmax = nn.Softmax(dim=-1) + + def forward(self,x): + b, C, h, w = x.size() + proj_query = x.view(b, C, -1) + proj_key = x.view(b, C, -1).permute(0, 2, 1) + energy = torch.bmm(proj_query, proj_key) + energy_new = torch.max(energy, -1, keepdim=True)[0].expand_as(energy) - energy + att = self.softmax(energy_new) + proj_value = x.view(b, C, -1) + + out = torch.bmm(att, proj_value) + out = out.view(b, C, h, w) + out = self.gamma*out + x + return out + + +class DiffNetwork(nn.Module): + def __init__(self): + super(DiffNetwork, self).__init__() + # 16x16 and 512 channels + self.ca = CAM(512) + self.sa = PAM(512) + self.resnet18 = nn.Sequential(*list(models.resnet18(pretrained=True).children())[:-2]) + self.regression = nn.Sequential( + # To 14x14 + nn.Conv2d(512, 512, kernel_size=4, stride=1, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(512, 512, kernel_size=4, stride=1, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(512, 35, kernel_size=3, stride=1, padding=1)) # (5x7)x14x14 + + def forward(self, inputa, inputb): + outputa = self.resnet18(inputa) + outputb = self.resnet18(inputb) + sub_fea = outputa - outputb + + ### + sub_ca = self.ca(sub_fea) + sub_sa = self.sa(sub_fea) + output = self.regression(sub_ca+sub_sa) + return output diff --git a/model/sub.py b/model/sub.py new file mode 100644 index 0000000..61e895b --- /dev/null +++ b/model/sub.py @@ -0,0 +1,38 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Copyright © 2017-10-25 20:42 zq +# +# Distributed under terms of the MIT license. + +""" +Find difference of two similar image through learning in pytorch. +""" + +import torch.nn as nn +import torchvision +import torch +from torchvision import datasets, models, transforms + +class DiffNetwork(nn.Module): + def __init__(self): + super(DiffNetwork, self).__init__() + # 16x16 and 512 channels + self.resnet18 = nn.Sequential(*list(models.resnet18(pretrained=True).children())[:-2]) + self.regression = nn.Sequential( + # To 14x14 + nn.Conv2d(512, 512, kernel_size=4, stride=1, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(512, 512, kernel_size=4, stride=1, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(512, 7, kernel_size=3, stride=1, padding=1)) # 7x14x14 + + def forward(self, inputa, inputb): + outputa = self.resnet18(inputa) + outputb = self.resnet18(inputb) + sub_fea = outputa - outputb + output = self.regression(sub_fea) + return output diff --git a/model/subv2.py b/model/subv2.py new file mode 100644 index 0000000..11436ef --- /dev/null +++ b/model/subv2.py @@ -0,0 +1,38 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Copyright © 2017-10-25 20:42 zq +# +# Distributed under terms of the MIT license. + +""" +Find difference of two similar image through learning in pytorch. +""" + +import torch.nn as nn +import torchvision +import torch +from torchvision import datasets, models, transforms + +class DiffNetwork(nn.Module): + def __init__(self): + super(DiffNetwork, self).__init__() + # 16x16 and 512 channels + self.resnet18 = nn.Sequential(*list(models.resnet18(pretrained=True).children())[:-2]) + self.regression = nn.Sequential( + # To 14x14 + nn.Conv2d(512, 512, kernel_size=4, stride=1, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(512, 512, kernel_size=4, stride=1, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(512, 512, kernel_size=3, stride=1, padding=1), + nn.ReLU(inplace=True), + nn.Conv2d(512, 35, kernel_size=3, stride=1, padding=1)) # 7x14x14 + + def forward(self, inputa, inputb): + outputa = self.resnet18(inputa) + outputb = self.resnet18(inputb) + sub_fea = outputa - outputb + output = self.regression(sub_fea) + return output diff --git a/nms.py b/nms.py new file mode 100644 index 0000000..c1ded71 --- /dev/null +++ b/nms.py @@ -0,0 +1,56 @@ +# -------------------------------------------------------- +# Fast R-CNN +# Copyright (c) 2015 Microsoft +# Licensed under The MIT License [see LICENSE for details] +# Written by Ross Girshick +# -------------------------------------------------------- + +import numpy as np +np.seterr(divide='ignore', invalid='ignore') + +def nms(dets, thresh=0.2, score_thresh=0.22): + """Pure Python NMS baseline.""" + scores = dets[:, 0] + s_idx = np.where(scores >= score_thresh)[0] + scores = dets[s_idx, 0] + x1 = dets[s_idx, 1] + y1 = dets[s_idx, 2] + x2 = dets[s_idx, 3] + y2 = dets[s_idx, 4] + + areas = (x2 - x1 + 1) * (y2 - y1 + 1) + order = scores.argsort()[::-1] + + keep = [] + while order.size > 0: + i = order[0] + keep.append(i) + xx1 = np.maximum(x1[i], x1[order[1:]]) + yy1 = np.maximum(y1[i], y1[order[1:]]) + xx2 = np.minimum(x2[i], x2[order[1:]]) + yy2 = np.minimum(y2[i], y2[order[1:]]) + + w = np.maximum(0.0, xx2 - xx1 + 1) + h = np.maximum(0.0, yy2 - yy1 + 1) + inter = w * h + ovr = inter / (areas[i] + areas[order[1:]] - inter) + + inds = np.where(ovr <= thresh)[0] + order = order[inds + 1] + + #print (keep) + #print (x1, y1, x2, y2) + res = np.zeros((len(keep), 5)) + for ii, idx in enumerate(keep): + res[ii, :] = scores[idx], x1[idx], y1[idx], x2[idx], y2[idx] + #print (res) + #print ("-----------------------") + return res + +if __name__ == "__main__": + dets = np.array( [[ 1.00442088 , 313 , 301 , 60 , 63 ], + [ 0.61739206 , 341 , 302 , 45 , 56 ], + [1.029, 169, 346, 46, 66]]) + print (dets) + print (dets.shape) + print (nms(dets)) diff --git a/score_mAP.sh b/score_mAP.sh new file mode 100644 index 0000000..4517fda --- /dev/null +++ b/score_mAP.sh @@ -0,0 +1,7 @@ +#! /bin/sh +# +# cal_mAP.sh +# +# Distributed under terms of the MIT license. + +cd ./mAP && bash test_mAP.sh diff --git a/srcs/droid-sans-mono.ttf b/srcs/droid-sans-mono.ttf new file mode 100644 index 0000000..b985926 Binary files /dev/null and b/srcs/droid-sans-mono.ttf differ diff --git a/trainv1.py b/trainv1.py new file mode 100644 index 0000000..7807c2b --- /dev/null +++ b/trainv1.py @@ -0,0 +1,150 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Copyright © 2017-10-25 21:09 zq +# +# Distributed under terms of the MIT license. + +""" Training learning difference of two similar images network. """ + +import argparse +import torch +from torch.autograd import Variable +from torchvision import transforms +from torch.utils.data import DataLoader +from torch.optim import lr_scheduler + +import time +import importlib + +from data.dataset import Pair_Dataset +from loss.loss import criterion + +def train(args): + ### DATA ### + dataloader = {} + dataloader["train"] = DataLoader(Pair_Dataset(args.trainval_dir, train=True), + args.batch_size, + shuffle=True, + num_workers=args.num_workers) + dataloader["valid"] = DataLoader(Pair_Dataset(args.trainval_dir, train=False), + args.batch_size, + shuffle=False, + num_workers=args.num_workers) + + ### MODEL and METHOD ### + model = importlib.import_module("model." + args.model).DiffNetwork() + if args.cuda: + model.cuda() + + optimizer = torch.optim.SGD(model.parameters(), + lr = args.lr, + momentum=0.9, + weight_decay = args.weight_decay) + if args.lr_policy == "exp": + exp_lr_scheduler = lr_scheduler.StepLR(optimizer, step_size=args.lr_stepsize, gamma=0.9) + + ### START TO MACHINE LEARNING ### + tic = time.time() + best_model_wts = model.state_dict() + best_loss = float('inf') + for epoch in range(args.nepochs): + print (" | Epoch {}/{}".format(epoch, args.nepochs-1)) + print (" | " + "-" * 20) + + # Each epoch has a training and validation phase + for phase in ['train', 'valid']: + if phase == 'train': + if args.lr_policy == "exp": + exp_lr_scheduler.step() + elif args.lr_policy == "custom": + custom_lr_scheduler(optimizer, epoch) + model.train(True) # Set model in training mode + else: + model.train(False) + + running_loss = 0 + for ii, (index, im_a, im_b, label) in enumerate(dataloader[phase]): + inp_a, inp_b = Variable(im_a), Variable(im_b) + label = Variable(label) + if args.cuda: + inp_a, inp_b = inp_a.cuda(), inp_b.cuda() + label = label.cuda() + optimizer.zero_grad() + pred = model(inp_a, inp_b) + + loss = criterion(label, pred) + if phase == "train": + loss.backward() + optimizer.step() + + if ii % args.log_freq == 0 and phase == "train": + print (" | Epoch{}: {}, Loss {:.2f}".format(epoch, ii, loss.data[0])) + running_loss += loss.data[0] + epoch_loss = running_loss / (ii+1) + print (" | Epoch {} {} Loss {:.4f}".format(epoch, phase, epoch_loss)) + + # Deep copy of the model + if phase == 'valid' and best_loss >= epoch_loss: + best_loss = epoch_loss + best_model_wts = model.state_dict() + torch.save(best_model_wts, args.model_fn) + print (" | Epoch {} state saved, now loss reaches {}...".format(epoch, best_loss)) + print (" | Time consuming: {:.4f}s".format(time.time()-tic)) + print (" | ") + +def custom_lr_scheduler(optimizer, epoch): + if 0 <= epoch < 20: + lr = (epoch / 5.0)*0.001 + 0.0001 + elif epoch < 75: + lr = 1e-3 + elif epoch < 105: + lr = 1e-4 + elif 105 <= epoch: + lr = 1e-5 + for param_group in optimizer.param_groups: + param_group['lr'] = lr + + +def parse(): + parser = argparse.ArgumentParser() + date = time.strftime("%Y-%m-%d", time.localtime()) + ### DATA ### + parser.add_argument('--trainval_dir', type=str, default="./data/cdata/train") + parser.add_argument('--nepochs', type=int, default=800, + help="Number of sweeps over the dataset to train.") + parser.add_argument('--batch_size', type=int, default=8, + help="Number of images in each mini-batch.") + parser.add_argument('--num_workers', type=int, default=4, + help="Number of data loading threads.") + parser.add_argument('--lr', type=float, default=1e-3) + parser.add_argument('--no_cuda', action='store_true', default=False, + help="Disable CUDA training.") + parser.add_argument('--model', type=str, default="sub", + help="Model module name in model dir and I will save best model the same name.") + parser.add_argument('--model_fn', type=str, default="", + help="Model filename to save.") + parser.add_argument('--lr_policy', type=str, default="exp", + help="Policy of learning rate change.") + parser.add_argument('--lr_stepsize', type=int, default=100, + help="Control exponent learning rate decay.") + parser.add_argument('--log_freq', type=int, default=10) + # As a rule of thumb, the more training examples you have, the weaker this term should be. + # The more parameters you have the higher this term should be. + parser.add_argument('--weight_decay', type=float, default=5e-4, + help="Goven the regularization term of the neural net.") + + args = parser.parse_args() + args.cuda = not args.no_cuda and torch.cuda.is_available() + if args.model_fn == "": + args.model_fn = args.model + "_" + date + ".pth.tar" + return args + + +if __name__ == "__main__": + args = parse() + print (args) + train(args) + print (args) + diff --git a/trainv2.py b/trainv2.py new file mode 100644 index 0000000..3e44e08 --- /dev/null +++ b/trainv2.py @@ -0,0 +1,159 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Distributed under terms of the MIT license. + +""" Training learning difference of two similar images network. """ + +import argparse +import torch +from torch.autograd import Variable +from torchvision import transforms +from torch.utils.data import DataLoader +from torch.optim import lr_scheduler + +import time +import importlib + +from data.dataset import Pair_Dataset +from loss.v2loss import v2loss + +def train(args): + ### DATA ### + traindata = Pair_Dataset(args.trainval_dir, train=True) + train_list = traindata.imkey_list + validdata = Pair_Dataset(args.trainval_dir, train=False) + valid_list = validdata.imkey_list + dataloader = {} + dataloader["train"] = DataLoader(traindata, + args.batch_size, + shuffle=True, + num_workers=args.num_workers) + dataloader["valid"] = DataLoader(validdata, + args.batch_size, + shuffle=False, + num_workers=args.num_workers) + + ### MODEL and METHOD ### + model = importlib.import_module("model." + args.model).DiffNetwork() + if args.cuda: + model.cuda() + + optimizer = torch.optim.SGD(model.parameters(), + lr = args.lr, + momentum=0.9, + weight_decay = args.weight_decay) + if args.lr_policy == "exp": + exp_lr_scheduler = lr_scheduler.StepLR(optimizer, step_size=args.lr_stepsize, gamma=0.9) + + anchors = [(41.4514,52.2819), (63.2610,59.1658), (52.3392,76.1706), (94.5413,77.2516), (71.5646,108.9415)] + ### START TO MACHINE LEARNING ### + criterion = v2loss(anchors=anchors, coord_scale=2) + tic = time.time() + best_model_wts = model.state_dict() + best_loss = float('inf') + iters = 0 + for epoch in range(args.nepochs): + print (" | Seen %d" %iters) + print (" | Epoch {}/{}".format(epoch, args.nepochs-1)) + print (" | " + "-" * 20) + + # Each epoch has a training and validation phase + for phase in ['train', 'valid']: + if phase == 'train': + if args.lr_policy == "exp": + exp_lr_scheduler.step() + elif args.lr_policy == "custom": + custom_lr_scheduler(optimizer, epoch) + model.train(True) # Set model in training mode + else: + model.train(False) + + running_loss = 0 + for ii, (index, im_a, im_b, label) in enumerate(dataloader[phase]): + inp_a, inp_b = Variable(im_a), Variable(im_b) + label = Variable(label) + if args.cuda: + inp_a, inp_b = inp_a.cuda(), inp_b.cuda() + label = label.cuda() + optimizer.zero_grad() + #pdb.set_trace() + pred = model(inp_a, inp_b) + + loss = criterion(pred.float(), label.float(), iters) + if phase == "train": + loss.backward() + optimizer.step() + iters += args.batch_size + + if ii % args.log_freq == 0 and phase == "train": + print (" | Epoch{}: {}, Loss {:.4f}".format(epoch, ii, loss.data[0])) + running_loss += loss.data[0] + epoch_loss = running_loss / (ii+1) + print (" | Epoch {} {} Loss {:.4f}".format(epoch, phase, epoch_loss)) + + # Deep copy of the model + if phase == 'valid' and best_loss >= epoch_loss: + best_loss = epoch_loss + best_model_wts = model.state_dict() + torch.save(best_model_wts, args.model_fn) + print (" | Epoch {} state saved, now loss reaches {}...".format(epoch, best_loss)) + print (" | Time consuming: {:.4f}s".format(time.time()-tic)) + print (" | ") + +def custom_lr_scheduler(optimizer, epoch): + if 0 <= epoch < 20: + lr = (epoch / 5.0)*0.001 + 0.0001 + elif epoch < 75: + lr = 1e-3 + elif epoch < 105: + lr = 1e-4 + elif 105 <= epoch: + lr = 1e-5 + for param_group in optimizer.param_groups: + param_group['lr'] = lr + + +def parse(): + parser = argparse.ArgumentParser() + date = time.strftime("%Y-%m-%d", time.localtime()) + ### DATA ### + parser.add_argument('--trainval_dir', type=str, default="./data/cdata/train") + parser.add_argument('--nepochs', type=int, default=800, + help="Number of sweeps over the dataset to train.") + parser.add_argument('--batch_size', type=int, default=8, + help="Number of images in each mini-batch.") + parser.add_argument('--num_workers', type=int, default=4, + help="Number of data loading threads.") + parser.add_argument('--no_cuda', action='store_true', default=False, + help="Disable CUDA training.") + parser.add_argument('--model', type=str, default="sub", + help="Model module name in model dir and I will save best model the same name.") + parser.add_argument('--model_fn', type=str, default="", + help="Model filename to save.") + parser.add_argument('--lr_policy', type=str, default="exp", + help="Policy of learning rate change.") + parser.add_argument('--lr_stepsize', type=int, default=100, + help="Control exponent learning rate decay.") + parser.add_argument('--log_freq', type=int, default=10) + # As a rule of thumb, the more training examples you have, the weaker this term should be. + # The more parameters you have the higher this term should be. + parser.add_argument('--weight_decay', type=float, default=5e-4, + help="Goven the regularization term of the neural net.") + parser.add_argument('--lr', type=float, default=1e-3, + help="Goven the learning rate of the neural net.") + + args = parser.parse_args() + args.cuda = not args.no_cuda and torch.cuda.is_available() + if args.model_fn == "": + args.model_fn = args.model + "_" + date + ".pth.tar" + return args + + +if __name__ == "__main__": + args = parse() + print (args) + train(args) + print (args) + diff --git a/trainv2_log.py b/trainv2_log.py new file mode 100644 index 0000000..97021d3 --- /dev/null +++ b/trainv2_log.py @@ -0,0 +1,171 @@ +#! /usr/bin/env python3 +# -*- coding: utf-8 -*- +# vim:fenc=utf-8 +# +# Distributed under terms of the MIT license. + +""" Training learning difference of two similar images network. """ + +import argparse +import torch +from torch.autograd import Variable +from torchvision import transforms +from torch.utils.data import DataLoader +from torch.optim import lr_scheduler + +import time +import importlib + +from data.dataset import Pair_Dataset +from loss.v2loss import v2loss + +from tensorboardX import SummaryWriter +writer = SummaryWriter('./log') + +def train(args): + ### DATA ### + traindata = Pair_Dataset(args.trainval_dir, train=True) + train_list = traindata.imkey_list + validdata = Pair_Dataset(args.trainval_dir, train=False) + valid_list = validdata.imkey_list + dataloader = {} + dataloader["train"] = DataLoader(traindata, + args.batch_size, + shuffle=True, + num_workers=args.num_workers) + dataloader["valid"] = DataLoader(validdata, + args.batch_size, + shuffle=False, + num_workers=args.num_workers) + + ### MODEL and METHOD ### + model = importlib.import_module("model." + args.model).DiffNetwork() + if args.cuda: + model.cuda() + + optimizer = torch.optim.SGD(model.parameters(), + lr = args.lr, + momentum=0.9, + weight_decay = args.weight_decay) + if args.lr_policy == "exp": + exp_lr_scheduler = lr_scheduler.StepLR(optimizer, step_size=args.lr_stepsize, gamma=0.9) + + anchors = [(41.4514,52.2819), (63.2610,59.1658), (52.3392,76.1706), (94.5413,77.2516), (71.5646,108.9415)] + ### START TO MACHINE LEARNING ### + criterion = v2loss(anchors=anchors, coord_scale=2) + tic = time.time() + best_model_wts = model.state_dict() + best_loss = float('inf') + iters = 0 + for epoch in range(args.nepochs): + print (" | Seen %d" %iters) + print (" | Epoch {}/{}".format(epoch, args.nepochs-1)) + print (" | " + "-" * 20) + + # Each epoch has a training and validation phase + for phase in ['train', 'valid']: + if phase == 'train': + if args.lr_policy == "exp": + exp_lr_scheduler.step() + elif args.lr_policy == "custom": + custom_lr_scheduler(optimizer, epoch) + model.train(True) # Set model in training mode + else: + model.train(False) + + running_loss = 0 + for ii, (index, im_a, im_b, label) in enumerate(dataloader[phase]): + inp_a, inp_b = Variable(im_a), Variable(im_b) + label = Variable(label) + if args.cuda: + inp_a, inp_b = inp_a.cuda(), inp_b.cuda() + label = label.cuda() + optimizer.zero_grad() + #pdb.set_trace() + pred = model(inp_a, inp_b) + + loss = criterion(pred.float(), label.float(), iters) + if phase == "train": + loss.backward() + optimizer.step() + iters += args.batch_size + + if ii % args.log_freq == 0 and phase == "train": + niter = epoch * len(dataloader[phase]) + ii + writer.add_scalars('Train_val_loss', {'train_loss': loss.data[0]}, niter) + print (" | Epoch{}: {}, Loss {:.4f}".format(epoch, ii, loss.data[0])) + running_loss += loss.data[0] + epoch_loss = running_loss / (ii+1) + if phase == 'train': + nitem = (epoch+1) * (len(dataloader['train'])) + writer.add_scalars('Train_val_loss', {'train_loss': loss.data[0]}, nitem) + if phase == 'valid': + nitem = (epoch+1) * (len(dataloader['train'])) + writer.add_scalars('Train_val_loss', {'val_loss': epoch_loss}, nitem) + print (" | Epoch {} {} Loss {:.4f}".format(epoch, phase, epoch_loss)) + + # Deep copy of the model + if phase == 'valid' and best_loss >= epoch_loss: + best_loss = epoch_loss + best_model_wts = model.state_dict() + torch.save(best_model_wts, args.model_fn) + print (" | Epoch {} state saved, now loss reaches {}...".format(epoch, best_loss)) + print (" | Time consuming: {:.4f}s".format(time.time()-tic)) + print (" | ") + writer.close() + +def custom_lr_scheduler(optimizer, epoch): + if 0 <= epoch < 20: + lr = (epoch / 5.0)*0.001 + 0.0001 + elif epoch < 75: + lr = 1e-3 + elif epoch < 105: + lr = 1e-4 + elif 105 <= epoch: + lr = 1e-5 + for param_group in optimizer.param_groups: + param_group['lr'] = lr + + +def parse(): + parser = argparse.ArgumentParser() + date = time.strftime("%Y-%m-%d", time.localtime()) + ### DATA ### + parser.add_argument('--trainval_dir', type=str, default="./data/cdata/train") + parser.add_argument('--nepochs', type=int, default=800, + help="Number of sweeps over the dataset to train.") + parser.add_argument('--batch_size', type=int, default=8, + help="Number of images in each mini-batch.") + parser.add_argument('--num_workers', type=int, default=4, + help="Number of data loading threads.") + parser.add_argument('--no_cuda', action='store_true', default=False, + help="Disable CUDA training.") + parser.add_argument('--model', type=str, default="sub", + help="Model module name in model dir and I will save best model the same name.") + parser.add_argument('--model_fn', type=str, default="", + help="Model filename to save.") + parser.add_argument('--lr_policy', type=str, default="exp", + help="Policy of learning rate change.") + parser.add_argument('--lr_stepsize', type=int, default=100, + help="Control exponent learning rate decay.") + parser.add_argument('--log_freq', type=int, default=10) + # As a rule of thumb, the more training examples you have, the weaker this term should be. + # The more parameters you have the higher this term should be. + parser.add_argument('--weight_decay', type=float, default=5e-4, + help="Goven the regularization term of the neural net.") + parser.add_argument('--lr', type=float, default=1e-3, + help="Goven the learning rate of the neural net.") + + args = parser.parse_args() + args.cuda = not args.no_cuda and torch.cuda.is_available() + if args.model_fn == "": + args.model_fn = args.model + "_" + date + ".pth.tar" + return args + + +if __name__ == "__main__": + args = parse() + print (args) + train(args) + print (args) + diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..56dc20c --- /dev/null +++ b/utils.py @@ -0,0 +1,353 @@ +import PIL +from PIL import Image, ImageFont, ImageDraw +import math +import numpy as np +import os +import os.path as osp +import xml.etree.ElementTree as ET +from nms import nms +import pdb +import torch + +floor = lambda x: math.floor(float(x)) +f2s = lambda x: str(float(x)) + +def render_orim(args, imkey, label, pred): + font = ImageFont.truetype(args.fontfn, 12) + imsize = getimsize(args.test_dir, imkey) + # deta_crd and gda_crd are both (midx, midy, w, h) on scaled images + gda_crd, gdb_crd = parse_gd(label, imsize, 1), parse_gd(label, imsize, 2) + deta_crd = parse_det(pred, imkey, imsize, 1) + detb_crd = parse_det(pred, imkey, imsize, 2) + + # Scale bbox + gda_crd, gdb_crd = scale_trans(gda_crd, imsize), scale_trans(gdb_crd, imsize) + deta_crd, detb_crd = scale_trans(deta_crd, imsize), scale_trans(detb_crd, imsize) + deta_str, detb_str = bbox2str(deta_crd, imkey, 1), bbox2str(detb_crd, imkey, 2) + + # Render on images + if args.render == 1: + im_a_path = osp.join(args.test_dir, imkey + "_a.jpg") + im_b_path = osp.join(args.test_dir, imkey + "_b.jpg") + im_a, im_b = Image.open(im_a_path), Image.open(im_b_path) + labelrender_t(im_a, im_b, args.desdir, imkey, gda_crd, gdb_crd) + detrender_t(im_a, im_b, args.desdir, imkey, deta_crd, detb_crd, font) + return deta_str, detb_str + +def render_v2orim(args, imkey, label, pred, anchors): + font = ImageFont.truetype(args.fontfn, 12) + imsize = getimsize(args.test_dir, imkey) + # deta_crd and gda_crd are both (midx, midy, w, h) on scaled images + gda_crd, gdb_crd = parse_gd(label, imsize, 1), parse_gd(label, imsize, 2) + deta_crd = parse_v2det(pred, imkey, imsize, 1, scale_size=512, anchors=anchors) + detb_crd = parse_v2det(pred, imkey, imsize, 2, scale_size=512, anchors=anchors) + + # Scale bbox + gda_crd, gdb_crd = scale_trans(gda_crd, imsize), scale_trans(gdb_crd, imsize) + deta_crd, detb_crd = scale_trans(deta_crd, imsize), scale_trans(detb_crd, imsize) + deta_str, detb_str = bbox2str(deta_crd, imkey, 1), bbox2str(detb_crd, imkey, 2) + + # Render on images + if args.render == 1: + im_a_path = osp.join(args.test_dir, imkey + "_a.jpg") + im_b_path = osp.join(args.test_dir, imkey + "_b.jpg") + im_a, im_b = Image.open(im_a_path), Image.open(im_b_path) + labelrender_t(im_a, im_b, args.desdir, imkey, gda_crd, gdb_crd) + detrender_t(im_a, im_b, args.desdir, imkey, deta_crd, detb_crd, font) + return deta_str, detb_str + +def render_wo_gd(args, imkey, pred): + font = ImageFont.truetype(args.fontfn, 12) + imsize = getimsize(args.test_dir, imkey) + # deta_crd and gda_crd are both (midx, midy, w, h) on scaled images + deta_crd = parse_det(pred, imkey, imsize, 1) + detb_crd = parse_det(pred, imkey, imsize, 2) + + # Scale bbox + deta_crd, detb_crd = scale_trans(deta_crd, imsize), scale_trans(detb_crd, imsize) + deta_str, detb_str = bbox2str(deta_crd, imkey, 1), bbox2str(detb_crd, imkey, 2) + + # Render on images + if args.render == 1: + im_a_path = osp.join(args.test_dir, imkey + "_a.jpg") + im_b_path = osp.join(args.test_dir, imkey + "_b.jpg") + #im_a_path = osp.join(args.test_dir, imkey + "_o.jpg") + #im_b_path = osp.join(args.test_dir, imkey + "_c.jpg") + im_a, im_b = Image.open(im_a_path), Image.open(im_b_path) + detrender_t(im_a, im_b, args.desdir, imkey, deta_crd, detb_crd, font) + return deta_str, detb_str + +def render_v2wo_gd(args, imkey, pred, anchors): + font = ImageFont.truetype(args.fontfn, 12) + imsize = get_ocimsize(args.test_dir, imkey) + # deta_crd and gda_crd are both (midx, midy, w, h) on scaled images + deta_crd = parse_v2det(pred, imkey, imsize, 1, scale_size=512, anchors=anchors) + detb_crd = parse_v2det(pred, imkey, imsize, 2, scale_size=512, anchors=anchors) + + # Scale bbox + deta_crd, detb_crd = scale_trans(deta_crd, imsize), scale_trans(detb_crd, imsize) + deta_str, detb_str = bbox2str(deta_crd, imkey, 1), bbox2str(detb_crd, imkey, 2) + + # Render on images + if args.render == 1: + im_a_path = osp.join(args.test_dir, imkey + "_a.jpg") + im_b_path = osp.join(args.test_dir, imkey + "_b.jpg") + #im_a_path = osp.join(args.test_dir, imkey + "_o.jpg") + #im_b_path = osp.join(args.test_dir, imkey + "_c.jpg") + im_a, im_b = Image.open(im_a_path), Image.open(im_b_path) + detrender_t(im_a, im_b, args.desdir, imkey, deta_crd, detb_crd, font) + return deta_str, detb_str + + + +""" NOTE sx and sy is 1 and 1 """ +def parse_gd(label, imsize, pairwise, scale_size=512): + ROW, COL = label.size()[2:] + gd_list = [] + n_bbox = 0 + ow, oh = imsize + label = label.data.cpu().numpy() + sx, sy = 1, 1 + + for row in range(ROW): + for col in range(COL): + # We only have one instance each time at evalution stage + if label[0, pairwise, row, col]: + n_bbox += 1 + x = (label[0, 3, row, col] + col) / COL + y = (label[0, 4, row, col] + row) / ROW + w, h = label[0, 5:, row, col] + gd_list.append([x, y, w, h]) + + for i in range(n_bbox): + gdx, gdy, gdw, gdh = gd_list[i][:] + ### USE FOLLOW CODE TO RECOVER TO ORIGIN SIZE, WITH BUGGY### + gdx, gdy = scale_size*gdx*sx, scale_size*gdy*sy + gdw, gdh = scale_size*gdw*sx, scale_size*gdh*sy + gd_list[i][:] = 1, gdx, gdy, gdw, gdh + + return gd_list + +def parse_det(pred, imkey, imsize, pairwise, scale_size=512): + #det result: prob_obj, pa, pb, x, y, w, h -- normalized + ROW, COL = pred.size()[2:] + det = np.zeros((1, 5)) + ow, oh = imsize + sx, sy = 1, 1 + + pred = pred.data.cpu().numpy() + for row in range(ROW): + for col in range(COL): + if row == 0 and col == 0: + det[0, 0] = pred[0, 0, row, col] * pred[0, pairwise, row, col] + det[0, 1] = (pred[0, 3, row, col] + col) / COL + det[0, 2] = (pred[0, 4, row, col] + row) / ROW + det[0, 3:] = pred[0, 5:, row, col] + det = det.reshape(1, 5) + else: + temp = np.zeros((1, 5)) + temp[0, 0] = pred[0, 0, row, col] * pred[0, pairwise, row, col] + temp[0, 1] = (pred[0, 3, row, col] + col) / COL + temp[0, 2] = (pred[0, 4, row, col] + row) / ROW + temp[0, 3:] = pred[0, 5:, row, col] + temp = temp.reshape(1, 5) + det = np.vstack((det, temp)) + + for i in range(det.shape[0]): + # detx means det_midx; dety means det_midy + detx, dety, detw, deth = det[i, 1:] + """USE THE FOLLOW CODE TO RECOVER FROM ORIGIN IMAGES, WITH BUGGY""" + orix, oriy = int(detx*scale_size*sx), int(dety*scale_size*sy) + oriw, orih = int(detw*scale_size*sx), int(deth*scale_size*sy) + det[i, 1:] = orix, oriy, oriw, orih + + # NOTE: We need to nms + det_mm = np.array(mid2mm(det)) + #det_list = mm2mid( nms(det_mm) ) + #det_list = mm2mid( nms(det_mm, 0.3, 0.3) ) + + #mAP + #det_list = det + #det_list = mm2mid(nms(det_mm, 0.6, 0.001)) + det_list = mm2mid(nms(det_mm, 0.45, 0.001)) + #det_list = mm2mid(nms(det_mm, 0.3, 0.001)) # + if len(det_list)>100: + det_list = det_list[:100] + return det_list + + +def parse_v2det(pred, imkey, imsize, pairwise, anchors, scale_size=512): + ROW, COL = pred.size()[2:] + det = np.zeros((1, 5)) + ow, oh = imsize + sy, sx = 1, 1 + size = 1+2+4 + anchors = np.array(anchors) / scale_size + anchor_w = anchors[:, 0] + anchor_h = anchors[:, 1] + pred = pred.permute(0, 2, 3, 1) + pred = pred.contiguous().view(-1, ROW, COL, len(anchors), size) + pred = pred.data.cpu().numpy() + for row in range(ROW): + for col in range(COL): + for n in range(len(anchors)): + if row == 0 and col == 0 and n == 0: + det[0, 0] = pred[0, row, col, n, 0] * pred[0, row, col, n, pairwise] + det[0, 1] = (sigmoid(pred[0, row, col, n, 3]) + col) / COL + det[0, 2] = (sigmoid(pred[0, row, col, n, 4]) + row) / ROW + det[0, 3] = np.exp(pred[0, row, col, n, 5]) * anchor_w[n] + det[0, 4] = np.exp(pred[0, row, col, n, 6]) * anchor_h[n] + det = det.reshape(1, 5) + else: + tmp = np.zeros((1, 5)) + tmp[0, 0] = pred[0, row, col, n, 0] * pred[0, row, col, n, pairwise] + tmp[0, 1] = (sigmoid(pred[0, row, col, n, 3]) + col) / COL + tmp[0, 2] = (sigmoid(pred[0, row, col, n, 4]) + row) / ROW + tmp[0, 3] = np.exp(pred[0, row, col, n, 5]) * anchor_w[n] + tmp[0, 4] = np.exp(pred[0, row, col, n, 6]) * anchor_h[n] + tmp = tmp.reshape(1, 5) + det = np.vstack((det, tmp)) + + + for i in range(det.shape[0]): + detx, dety, detw, deth = det[i, 1:] + orix, oriy = int(detx*scale_size*sx), int(dety*scale_size*sy) + oriw, orih = int(detw*scale_size*sx), int(deth*scale_size*sy) + det[i, 1:] = orix, oriy, oriw, orih + + det_mm = np.array(mid2mm(det)) + #det_list = mm2mid(nms(det_mm, 0.45, 0.4)) + #det_list = mm2mid(nms(det_mm, 0.3, 0.3)) + det_list = mm2mid(nms(det_mm, 0.22, 0.3)) #93.41 + #det_list = mm2mid(nms(det_mm, 0.22, 0.3)) #no nms + #det_list = mm2mid(nms(det_mm)) + + ##for mAP + ##det_list = mm2mid(nms(det_mm, 0.6, 0.001)) + #det_list = mm2mid(nms(det_mm, 0.45, 0.001)) + ##det_list = mm2mid(nms(det_mm, 0.3, 0.001)) # + #if len(det_list)>100: + # det_list = det_list[:100] + + return det_list + + +def sigmoid(x): + return 1/(1+np.exp(-x)) + +def softmax(x): + x = x - np.max(x) + return np.exp(x) / np.sum(x) + +def mid2mm(midlist): + mid_np = np.array(midlist) + if len(midlist) != 0: + midx, midy, w, h = mid_np[:, 1], mid_np[:, 2], mid_np[:, 3], mid_np[:, 4] + minx, miny, maxx, maxy = midx - w/2.0, midy - h/2.0, midx + w/2.0, midy + h/2.0 + mid_np[:, 1], mid_np[:, 2], mid_np[:, 3], mid_np[:, 4] = minx, miny, maxx, maxy + return mid_np.tolist() + +def mm2mid(mmlist): + mm_np = np.array(mmlist) + if len(mmlist) != 0: + minx, miny, maxx, maxy = mm_np[:, 1], mm_np[:, 2], mm_np[:, 3], mm_np[:, 4] + midx, midy, w, h = (minx+maxx)/2.0, (miny+maxy)/2.0, (maxx-minx), (maxy-miny) + mm_np[:, 1], mm_np[:, 2], mm_np[:, 3], mm_np[:, 4] = midx, midy, w, h + return mm_np.tolist() + +def scale_trans(bbox, imsize, scale_size=512): + # gd and det should be Nx5 format + ow, oh = imsize + sx, sy = ow*1.0/scale_size, oh*1.0/scale_size + bbox_np = np.array(bbox) + if len(bbox) != 0: + bbox_np[:, 1] = bbox_np[:, 1] * sx + bbox_np[:, 3] = bbox_np[:, 3] * sx + bbox_np[:, 2] = bbox_np[:, 2] * sy + bbox_np[:, 4] = bbox_np[:, 4] * sy + return bbox_np.tolist() + +def bbox2str(det_list, imkey, pairwise): + # det_list in the format of midx, midy, w, h + det_str = "" + det_len = len(det_list) + det = mid2mm(det_list) + for i in range(det_len): + det_str += imkey + "_" + chr(ord('a')+pairwise-1) + " " + for j in range(5): + det_str += f2s(det[i][j]) + " " + det_str += "\n" + return det_str + +def labelrender_t(im_ra, im_rb, desdir, imkey, gda_crd, gdb_crd, color="#ff0000"): + for i_gd in gda_crd: + draw_bbox(im_ra, i_gd[1:], color) + for i_gd in gdb_crd: + draw_bbox(im_rb, i_gd[1:], color) + im_ra.save(osp.join(desdir, imkey+"_render_a.jpg")) + im_rb.save(osp.join(desdir, imkey+"_render_b.jpg")) + +def detrender_t(im_a, im_b, desdir, imkey, deta_crd, detb_crd, font, color="#00ff00"): + for i_det in deta_crd: + draw_bbox(im_a, i_det[1:], color) + #draw_prob(im_a, i_det, font, color) + for i_det in detb_crd: + draw_bbox(im_b, i_det[1:], color) + #draw_prob(im_b, i_det, font, color) + im_a.save(osp.join(desdir, imkey+"_render_a.jpg")) + im_b.save(osp.join(desdir, imkey+"_render_b.jpg")) + +def draw_bbox(im, bbox, color="#00ff00"): + # bbox should in midx, midy, w, h list format + draw_im = ImageDraw.Draw(im) + midx, midy, w, h = bbox[:] + xmin, ymin = floor(midx - w/2.0), floor(midy - h/2.0) + xmax, ymax = floor(midx + w/2.0), floor(midy + h/2.0) + draw_im.line([xmin, ymin, xmax, ymin], width=4, fill=color) + draw_im.line([xmin, ymin, xmin, ymax], width=4, fill=color) + draw_im.line([xmax, ymin, xmax, ymax], width=4, fill=color) + draw_im.line([xmin, ymax, xmax, ymax], width=4, fill=color) + del draw_im + +def draw_prob(im, bbox, font, color="#00ff00"): + im_draw = ImageDraw.Draw(im) + prob_str = "{:.3f}".format(float(bbox[0])) + topleftx = bbox[1] - bbox[3]/2.0 + toplefty = bbox[2] - bbox[4]/2.0 + im_draw.text((topleftx, toplefty), prob_str, font=font, fill=color) + del im_draw + +def getimsize(im_root, imkey): + assert (type(imkey) == type("")), " | Error: imkey shold be string type..." + xmlpath = "" + if osp.exists(osp.join(im_root, imkey+"_a.xml")): + xmlpath = osp.join(im_root, imkey+"_a.xml") + elif osp.exists(osp.join(im_root, imkey+"_b.xml")): + xmlpath = osp.join(im_root, imkey+"_b.xml") + if xmlpath != "": + tree = ET.parse(xmlpath) + im_size = tree.findall("size")[0] + ow = int(im_size.find("width").text) + oh = int(im_size.find("height").text) + else: + im = Image.open(osp.join(im_root, imkey+"_a.jpg")) + ow, oh = im.size + return (ow, oh) + +def get_ocimsize(im_root, imkey): + assert (type(imkey) == type("")), " | Error: imkey shold be string type..." + xmlpath = "" + if osp.exists(osp.join(im_root, imkey+"_a.xml")): + xmlpath = osp.join(im_root, imkey+"_a.xml") + elif osp.exists(osp.join(im_root, imkey+"_b.xml")): + xmlpath = osp.join(im_root, imkey+"_b.xml") + if xmlpath != "": + tree = ET.parse(xmlpath) + im_size = tree.findall("size")[0] + ow = int(im_size.find("width").text) + oh = int(im_size.find("height").text) + else: + im = Image.open(osp.join(im_root, imkey+"_o.jpg")) + ow, oh = im.size + return (ow, oh) +