if __name__ == '__main__': args = get_args() writer = SummaryWriter(log_dir=args.log_dir) cuda_device = args.cuda with torch.cuda.device(int(cuda_device[-1])): # 设置随机种子 torch.manual_seed(args.seed) torch.cuda.manual_seed(args.seed) random.seed(args.seed) if args.model == 'resnet34': model = resnet34(pretrained=args.pretrain).cuda() elif args.model == 'resnet18': model = resnet18(pretrained=args.pretrain).cuda() elif args.model == 'resnet50': model = resnet50(pretrained=args.pretrain).cuda() print('use model', args.model) elif args.model == 'resnet101': model = resnet101(pretrained=args.pretrain).cuda() elif args.model == 'resnet152': model = resnet152(pretrained=args.pretrain).cuda() elif args.model == 'resnext50_32x4d': model = resnext50_32x4d(pretrained=args.pretrain).cuda() elif args.model == 'resnext101_32x8d': model = resnext101_32x8d(pretrained=args.pretrain).cuda() elif args.model == 'wide_resnet50_2': model = wide_resnet50_2(pretrained=args.pretrain).cuda() elif args.model == 'wide_resnet101_2': model = wide_resnet101_2(pretrained=args.pretrain).cuda() elif 'efficientnet' in args.model: model = EfficientNet.from_name(args.model, num_classes=100).cuda()
def main(args=None): parser = argparse.ArgumentParser( description='Simple training script for training a RetinaNet network.') parser.add_argument('--dataset', help='Dataset type, must be one of csv or coco.') parser.add_argument('--coco_path', help='Path to COCO directory') parser.add_argument( '--csv_train', help='Path to file containing training annotations (see readme)') parser.add_argument('--csv_classes', help='Path to file containing class list (see readme)') parser.add_argument( '--csv_val', help= 'Path to file containing validation annotations (optional, see readme)' ) parser.add_argument( '--depth', help='Resnet depth, must be one of 18, 34, 50, 101, 152', type=int, default=50) parser.add_argument('--epochs', help='Number of epochs', type=int, default=100) parser = parser.parse_args(args) # Create the data loaders if parser.dataset == 'coco': if parser.coco_path is None: raise ValueError('Must provide --coco_path when training on COCO,') # dataset_train = CocoDataset(parser.coco_path, set_name='trainval35k', transform=transforms.Compose([Normalizer(), Augmenter(), Resizer()])) dataset_val = CocoDataset(parser.coco_path, set_name='val5k', transform=transforms.Compose( [Normalizer(), Resizer()])) elif parser.dataset == 'csv': if parser.csv_train is None: raise ValueError('Must provide --csv_train when training on COCO,') if parser.csv_classes is None: raise ValueError( 'Must provide --csv_classes when training on COCO,') dataset_train = CSVDataset(train_file=parser.csv_train, class_list=parser.csv_classes, transform=transforms.Compose( [Normalizer(), Augmenter(), Resizer()])) if parser.csv_val is None: dataset_val = None print('No validation annotations provided.') else: dataset_val = CSVDataset(train_file=parser.csv_val, class_list=parser.csv_classes, transform=transforms.Compose( [Normalizer(), Resizer()])) else: raise ValueError( 'Dataset type not understood (must be csv or coco), exiting.') #sampler = AspectRatioBasedSampler(dataset_train, batch_size=16, drop_last=False) #dataloader_train = DataLoader(dataset_train, num_workers=3, collate_fn=collater, batch_sampler=sampler) if dataset_val is not None: sampler_val = AspectRatioBasedSampler(dataset_val, batch_size=1, drop_last=False) dataloader_val = DataLoader(dataset_val, num_workers=3, collate_fn=collater, batch_sampler=sampler_val) # Create the model if parser.depth == 18: retinanet = model.resnet18(num_classes=dataset_val.num_classes(), pretrained=True) elif parser.depth == 34: retinanet = model.resnet34(num_classes=dataset_val.num_classes(), pretrained=True) elif parser.depth == 50: retinanet = model.resnet50(num_classes=dataset_val.num_classes(), pretrained=True) elif parser.depth == 101: retinanet = model.resnet101(num_classes=dataset_val.num_classes(), pretrained=True) elif parser.depth == 152: retinanet = model.resnet152(num_classes=dataset_val.num_classes(), pretrained=True) else: raise ValueError( 'Unsupported model depth, must be one of 18, 34, 50, 101, 152') use_gpu = True retinanet.load_state_dict( torch.load("coco_resnet_50_map_0_335_state_dict.pt", encoding='latin1')) if use_gpu: retinanet = retinanet.cuda() # retinanet = torch.nn.DataParallel(retinanet).cuda() #retinanet.training = True #optimizer = optim.Adam(retinanet.parameters(), lr=1e-5) #scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, patience=3, verbose=True) #loss_hist = collections.deque(maxlen=500) retinanet.eval() #retinanet.module.freeze_bn() # print('Num training images: {}'.format(len(dataset_train))) if parser.dataset == 'coco': print('Evaluating dataset') coco_eval.evaluate_coco(dataset_val, retinanet) elif parser.dataset == 'csv' and parser.csv_val is not None: print('Evaluating dataset') mAP = csv_eval.evaluate(dataset_val, retinanet)
use_gpu = torch.cuda.is_available() # inputs, classes = next(iter(dataloaders)) inputs = next(iter(dataloaders)) ###################################################################### class_names = 128 # # step3: Finetuning the convnet # Load a pretrainied model and reset final fully connected layer. if opt.use_dense: # model = ft_net_dense(len(class_names)) model = ft_net_dense(class_names) print('********************ft_net_dense******************') else: # model = ft_net(len(class_names)) # model = resnet50(len(class_names)) model = resnet50(class_names) # model = resnet50(751) print('********************ft_net************************') print(model) if use_gpu: model = model.cuda() if opt.load_flag: save_path = os.path.join('./model', opt.load_name, 'net_%s.pth' % opt.which_epoch) model.load_state_dict(torch.load(save_path)) ###################################################################### # step 4: setting and train # criterion = nn.CrossEntropyLoss()
import tensorflow as tf import data import model print("Loading data...") x_train, y_train, x_test, y_test = data.load() if args.new == True: if args.model == "diyModel": model = model.diyModel() elif args.model == "VGG16": model = model.vgg16() elif args.model == "VGG19": model = model.vgg19() elif args.model == "ResNet50": model = model.resnet50() elif args.model == "ResNet101": model = model.resnet101() else: model = tf.keras.models.load_model("./" + str(args.model) + ".h5") model.fit(x_train, y_train, validation_data=(x_test, y_test), epochs=args.epochs, batch_size=args.batch_size) model.save("./" + str(args.model) + ".h5") print("Saved")
def main(config): np.random.seed(0) random.seed(0) torch.manual_seed(0) model_path = './models/' + config.model_date + '/best_retinanet.pt' val_dataset = datasets.ImageFolder(os.path.join(config.data_dir, 'test')) dataset_val = GetDataset(train_file=config.csv_val, class_list=config.csv_classes, transform=transforms.Compose([Resizer()]), dataset=val_dataset, seed=0) dataloader_val = DataLoader(dataset_val, batch_size=1, num_workers=1, collate_fn=collater) # Create the model if config.depth == 18: retinanet = model.resnet18(num_classes=dataset_val.num_classes(), pretrained=True) elif config.depth == 34: retinanet = model.resnet34(num_classes=dataset_val.num_classes(), pretrained=True) elif config.depth == 50: retinanet = model.resnet50(num_classes=dataset_val.num_classes(), pretrained=True) elif config.depth == 101: retinanet = model.resnet101(num_classes=dataset_val.num_classes(), pretrained=True) elif config.depth == 152: retinanet = model.resnet152(num_classes=dataset_val.num_classes(), pretrained=True) else: raise ValueError( 'Unsupported model depth, must be one of 18, 34, 50, 101, 152') use_gpu = True if use_gpu: retinanet = torch.nn.DataParallel(retinanet).cuda() retinanet.load_state_dict(torch.load(model_path)) retinanet.eval() correct = 0 if config.eval_map: mAP = eval_new.evaluate(dataset_val, retinanet, iou_threshold=config.thres) avg_time = AverageMeter() for idx, data in enumerate(dataloader_val): with torch.no_grad(): st = time.time() scores, classification, transformed_anchors, similarity = retinanet( [data['img'].cuda().float(), data['pair'].float()]) avg_time.update(time.time() - st) scores = scores.cpu().numpy() idxs = np.where(scores > 0.5) img = np.array(255 * data['img'][0, :, :, :]).copy() img[img < 0] = 0 img[img > 255] = 255 img = np.transpose(img, (1, 2, 0)) pair = np.array(255 * data['pair'][0, :, :, :]).copy() pair[pair < 0] = 0 pair[pair > 255] = 255 pair = np.transpose(pair, (1, 2, 0)) if config.plot: img = cv2.cvtColor(img.astype(np.uint8), cv2.COLOR_BGR2RGB) pair = cv2.cvtColor(pair.astype(np.uint8), cv2.COLOR_BGR2RGB) max_sim = 0.0 annot = dataset_val.get_annot(idx) annot = annot['annot'] bbox_true = annot[annot[:, 5] == 1, :4] for j in range(idxs[0].shape[0]): bbox = transformed_anchors[idxs[0][j], :] x1 = int(bbox[0]) y1 = int(bbox[1]) x2 = int(bbox[2]) y2 = int(bbox[3]) sim = similarity[j, 0].item() if sim > max_sim: max_sim = sim bbox_est = np.asarray([[x1, y1, x2, y2]]) if config.plot: draw_caption(img, (x1, y1, x2, y2), str(round(sim, 2))) cv2.rectangle(img, (x1, y1), (x2, y2), color=(0, 0, 255), thickness=2) iou = compute_overlap(bbox_true, bbox_est / data['scale'][0]) if iou.any() > config.thres and max_sim > config.sim_thres: correct += 1 max_sim = 0 # print('Iter = {}, number correct = {}'.format(idx+1, correct)) if config.plot: cv2.imshow('pair', pair) cv2.imshow('img', img) cv2.waitKey(0) # press q to quit, any other to view next image print('Final Accuracy is {}'.format(correct / config.test_trials)) print('Average time: {}'.format(avg_time.val))
def main(args=None): parser = argparse.ArgumentParser(description='Simple training script for training a RetinaNet network.') parser.add_argument('--dataset', default="csv",help='Dataset type, must be one of csv or coco.') parser.add_argument('--coco_path', help='Path to COCO directory') parser.add_argument('--csv_train', default = "./data/train_only.csv",help='Path to file containing training annotations (see readme)') parser.add_argument('--csv_classes', default = "./data/classes.csv",help='Path to file containing class list (see readme)') parser.add_argument('--csv_val', default = "./data/train_only.csv",help='Path to file containing validation annotations (optional, see readme)') parser.add_argument('--depth', help='Resnet depth, must be one of 18, 34, 50, 101, 152', type=int, default=101) parser.add_argument('--epochs', help='Number of epochs', type=int, default=40) parser = parser.parse_args(args) # Create the data loaders if parser.dataset == 'coco': if parser.coco_path is None: raise ValueError('Must provide --coco_path when training on COCO,') dataset_train = CocoDataset(parser.coco_path, set_name='train2017', transform=transforms.Compose([Normalizer(), Augmenter(), Resizer()])) dataset_val = CocoDataset(parser.coco_path, set_name='val2017', transform=transforms.Compose([Normalizer(), Resizer()])) elif parser.dataset == 'csv': if parser.csv_train is None: raise ValueError('Must provide --csv_train when training on COCO,') if parser.csv_classes is None: raise ValueError('Must provide --csv_classes when training on COCO,') dataset_train = CSVDataset(train_file=parser.csv_train, class_list=parser.csv_classes, transform=transforms.Compose([Normalizer(), Augmenter(), Resizer()])) if parser.csv_val is None: dataset_val = None print('No validation annotations provided.') else: dataset_val = CSVDataset(train_file=parser.csv_val, class_list=parser.csv_classes, transform=transforms.Compose([Normalizer(), Resizer()])) else: raise ValueError('Dataset type not understood (must be csv or coco), exiting.') sampler = AspectRatioBasedSampler(dataset_train, batch_size=1, drop_last=False) dataloader_train = DataLoader(dataset_train, num_workers=3, collate_fn=collater, batch_sampler=sampler) if dataset_val is not None: sampler_val = AspectRatioBasedSampler(dataset_val, batch_size=1, drop_last=False) dataloader_val = DataLoader(dataset_val, num_workers=3, collate_fn=collater, batch_sampler=sampler_val) # Create the model if parser.depth == 18: retinanet = model.resnet18(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 34: retinanet = model.resnet34(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 50: retinanet = model.resnet50(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 101: retinanet = model.resnet101(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 152: retinanet = model.resnet152(num_classes=dataset_train.num_classes(), pretrained=True) else: raise ValueError('Unsupported model depth, must be one of 18, 34, 50, 101, 152') use_gpu = True if use_gpu: retinanet = retinanet.cuda() retinanet = torch.nn.DataParallel(retinanet).cuda() retinanet.training = True optimizer = optim.Adam(retinanet.parameters(), lr=1e-5) scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, patience=5, verbose=True,mode="max") #scheduler = optim.lr_scheduler.StepLR(optimizer,8) loss_hist = collections.deque(maxlen=500) retinanet.train() retinanet.module.freeze_bn() if not os.path.exists("./logs"): os.mkdir("./logs") if not os.path.exists('best_models'): os.makedirs('best_models') log_file = open("./logs/log.txt","w") print('Num training images: {}'.format(len(dataset_train))) best_map = 0 print("Training models...") for epoch_num in range(parser.epochs): #scheduler.step(epoch_num) retinanet.train() retinanet.module.freeze_bn() epoch_loss = [] for iter_num, data in enumerate(dataloader_train): try: #print(csv_eval.evaluate(dataset_val[:20], retinanet)[0]) #print(type(csv_eval.evaluate(dataset_val, retinanet))) optimizer.zero_grad() classification_loss, regression_loss = retinanet([data['img'].cuda().float(), data['annot']]) classification_loss = classification_loss.mean() regression_loss = regression_loss.mean() loss = classification_loss + regression_loss if bool(loss == 0): continue loss.backward() torch.nn.utils.clip_grad_norm_(retinanet.parameters(), 0.1) optimizer.step() loss_hist.append(float(loss)) epoch_loss.append(float(loss)) if iter_num % 50 == 0: print('Epoch: {} | Iteration: {} | Classification loss: {:1.5f} | Regression loss: {:1.5f} | Running loss: {:1.5f}'.format(epoch_num, iter_num, float(classification_loss), float(regression_loss), np.mean(loss_hist))) log_file.write('Epoch: {} | Iteration: {} | Classification loss: {:1.5f} | Regression loss: {:1.5f} | Running loss: {:1.5f} \n'.format(epoch_num, iter_num, float(classification_loss), float(regression_loss), np.mean(loss_hist))) del classification_loss del regression_loss except Exception as e: print(e) continue if parser.dataset == 'coco': print('Evaluating dataset') coco_eval.evaluate_coco(dataset_val, retinanet) elif parser.dataset == 'csv' and parser.csv_val is not None: print('Evaluating dataset') mAP = csv_eval.evaluate(dataset_val, retinanet) try: is_best_map = mAP[0][0] > best_map best_map = max(mAP[0][0],best_map) except: pass if is_best_map: print("Get better map: ",best_map) torch.save(retinanet.module, './logs/{}_scale15_{}.pt'.format(epoch_num,best_map)) shutil.copyfile('./logs/{}_scale15_{}.pt'.format(epoch_num,best_map),"./best_models/model.pt") else: print("Current map: ",best_map) scheduler.step(best_map) retinanet.eval() torch.save(retinanet, './logs/model_final.pt')
def main(args=None): parser = argparse.ArgumentParser( description='Simple training script for training a RetinaNet network.') parser.add_argument('--dataset', help='Dataset type, must be one of csv or coco.') parser.add_argument('--coco_path', help='Path to COCO directory') parser.add_argument('--csv_classes', help='Path to file containing class list (see readme)') parser.add_argument( '--csv_val', help= 'Path to file containing validation annotations (optional, see readme)' ) parser.add_argument('--model', help='Path to model (.pt) file.') parser = parser.parse_args(args) if parser.dataset == 'coco': dataset_val = CocoDataset(parser.coco_path, set_name='val2014', transform=transforms.Compose( [Normalizer(), Resizer()])) elif parser.dataset == 'csv': dataset_val = CSVDataset(train_file=parser.csv_train, class_list=parser.csv_classes, transform=transforms.Compose( [Normalizer(), Resizer()])) else: raise ValueError( 'Dataset type not understood (must be csv or coco), exiting.') sampler_val = AspectRatioBasedSampler(dataset_val, batch_size=1, drop_last=False) dataloader_val = DataLoader(dataset_val, num_workers=1, collate_fn=collater, batch_sampler=sampler_val) # retinanet = torch.load(parser.model) retinanet = model.resnet50(num_classes=80) retinanet.load_state_dict(torch.load(parser.model)) use_gpu = True if use_gpu: retinanet = retinanet.cuda() retinanet.eval() unnormalize = UnNormalizer() def draw_caption(image, box, caption): b = np.array(box).astype(int) cv2.putText(image, caption, (b[0], b[1] - 10), cv2.FONT_HERSHEY_PLAIN, 1, (0, 0, 0), 2) cv2.putText(image, caption, (b[0], b[1] - 10), cv2.FONT_HERSHEY_PLAIN, 1, (255, 255, 255), 1) for idx, data in enumerate(dataloader_val): with torch.no_grad(): st = time.time() scores, classification, transformed_anchors = retinanet( data['img'].cuda().float()) print('Elapsed time: {}'.format(time.time() - st)) idxs = np.where(scores > 0.5) img = np.array(255 * unnormalize(data['img'][0, :, :, :])).copy() img[img < 0] = 0 img[img > 255] = 255 img = np.transpose(img, (1, 2, 0)) img = cv2.cvtColor(img.astype(np.uint8), cv2.COLOR_BGR2RGB) for j in range(idxs[0].shape[0]): bbox = transformed_anchors[idxs[0][j], :] x1 = int(bbox[0]) y1 = int(bbox[1]) x2 = int(bbox[2]) y2 = int(bbox[3]) label_name = dataset_val.labels[int( classification[idxs[0][j]])] draw_caption(img, (x1, y1, x2, y2), label_name) cv2.rectangle(img, (x1, y1), (x2, y2), color=(0, 0, 255), thickness=2) # print(label_name) # cv2.imshow('img', img) plt.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) plt.show()
def main(): data_root = os.path.abspath(os.path.join(os.getcwd(), "../")) # get data root path image_path = os.path.join(data_root, "dataset", "data") # flower data set path train_dir = os.path.join(image_path, "train") validation_dir = os.path.join(image_path, "val") assert os.path.exists(train_dir), "cannot find {}".format(train_dir) assert os.path.exists(validation_dir), "cannot find {}".format( validation_dir) # create direction for saving weights if not os.path.exists("save_weights"): os.makedirs("save_weights") im_height = 224 im_width = 224 batch_size = 16 epochs = 50 num_classes = 20 _R_MEAN = 123.68 _G_MEAN = 116.78 _B_MEAN = 103.94 def pre_function(img): img = img - [_R_MEAN, _G_MEAN, _B_MEAN] return img train_image_generator = ImageDataGenerator( horizontal_flip=True, preprocessing_function=pre_function) validation_image_generator = ImageDataGenerator( preprocessing_function=pre_function) train_data_gen = train_image_generator.flow_from_directory( directory=train_dir, batch_size=batch_size, shuffle=True, target_size=(im_height, im_width), class_mode='categorical') total_train = train_data_gen.n # get class dict class_indices = train_data_gen.class_indices # transform value and key of dict inverse_dict = dict((val, key) for key, val in class_indices.items()) # write dict into json file json_str = json.dumps(inverse_dict, indent=4) with open('class_indices.json', 'w') as json_file: json_file.write(json_str) val_data_gen = validation_image_generator.flow_from_directory( directory=validation_dir, batch_size=batch_size, shuffle=False, target_size=(im_height, im_width), class_mode='categorical') # img, _ = next(train_data_gen) total_val = val_data_gen.n print("using {} images for training, {} images for validation.".format( total_train, total_val)) feature = resnet50(num_classes=num_classes, include_top=False) # 加载权重 pre_weights_path = './pretrain_weights.ckpt' assert len(glob.glob(pre_weights_path + "*")), "cannot find {}".format(pre_weights_path) feature.load_weights(pre_weights_path) feature.trainable = False feature.summary() model = tf.keras.Sequential([ feature, tf.keras.layers.GlobalAvgPool2D(), tf.keras.layers.Dropout(rate=0.5), tf.keras.layers.Dense(1024, activation="relu"), tf.keras.layers.Dropout(rate=0.5), tf.keras.layers.Dense(num_classes), tf.keras.layers.Softmax() ]) model.summary() callback_list = [ callbacks.ReduceLROnPlateau( monitor='val_loss', factor=0.1, patience=3, verbose=1, ), callbacks.ModelCheckpoint(filepath='./save_weights/ResNet50.h5', monitor='val_acc', save_best_only=True, save_weights_only=True, verbose=1) ] model.compile(loss='categorical_crossentropy', optimizer=optimizers.Adam(lr=0.0002), metrics=['acc']) history = model.fit_generator(train_data_gen, steps_per_epoch=64, epochs=epochs, validation_data=val_data_gen, callbacks=callback_list, verbose=1) showTable(history)
def main(args=None): parser = argparse.ArgumentParser( description='Simple training script for training a RetinaNet network.') parser.add_argument('--dataset', help='Dataset type, must be one of csv or coco.') parser.add_argument('--coco_path', help='Path to COCO directory') parser.add_argument( '--csv_train', help='Path to file containing training annotations (see readme)') parser.add_argument('--csv_classes', help='Path to file containing class list (see readme)') parser.add_argument( '--csv_val', help= 'Path to file containing validation annotations (optional, see readme)' ) parser.add_argument( '--depth', help='Resnet depth, must be one of 18, 34, 50, 101, 152', type=int, default=50) parser.add_argument('--epochs', help='Number of epochs', type=int, default=20) parser.add_argument('--resume', '-r', action='store_true', help='resume from checkpoint') parser.add_argument('--batch_size', type=int, default=4, help='set the batch size') parser.add_argument('--learning_rate', '-lr', type=float, default=1e-3, help='set the learning rate') parser = parser.parse_args(args) batch_size = parser.batch_size learning_rate = parser.learning_rate start_epoch = 0 device = 'cuda' if torch.cuda.is_available() else 'cpu' best_acc = 0 # best test accuracy # mean & std for ROI extraction #mean = (0.1146, 0.1147, 0.1148) #std = (0.1089, 0.1090, 0.1090) # mean & std for QRCode extraction mean = (0.2405, 0.2416, 0.2427) std = (0.2194, 0.2208, 0.2223) # Create the data loaders if parser.dataset == 'coco': if parser.coco_path is None: raise ValueError('Must provide --coco_path when training on COCO,') dataset_train = CocoDataset(parser.coco_path, set_name='train2017', transform=transforms.Compose( [Normalizer(), Augmenter(), Resizer()])) dataset_val = CocoDataset(parser.coco_path, set_name='val2017', transform=transforms.Compose( [Normalizer(), Resizer()])) elif parser.dataset == 'csv': if parser.csv_train is None: raise ValueError('Must provide --csv_train when training on COCO,') if parser.csv_classes is None: raise ValueError( 'Must provide --csv_classes when training on COCO,') dataset_train = CSVDataset( train_file=parser.csv_train, class_list=parser.csv_classes, transform=transforms.Compose([ Normalizer(mean=mean, std=std), Augmenter(), #YFlipAugmenter(), #CropAugmenter(), #Rot180Augmenter(), Resizer() ])) if parser.csv_val is None: dataset_val = None print('No validation annotations provided.') else: dataset_val = CSVDataset(train_file=parser.csv_val, class_list=parser.csv_classes, transform=transforms.Compose([ Normalizer(mean=mean, std=std), Resizer() ])) else: raise ValueError( 'Dataset type not understood (must be csv or coco), exiting.') sampler = AspectRatioBasedSampler(dataset_train, batch_size=batch_size, drop_last=False) dataloader_train = DataLoader(dataset_train, num_workers=4, collate_fn=collater, batch_sampler=sampler) if dataset_val is not None: sampler_val = AspectRatioBasedSampler(dataset_val, batch_size=1, drop_last=False) dataloader_val = DataLoader(dataset_val, num_workers=4, collate_fn=collater, batch_sampler=sampler_val) # Create the model if parser.depth == 18: retinanet = model.resnet18(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 34: retinanet = model.resnet34(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 50: retinanet = model.resnet50(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 101: retinanet = model.resnet101(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 152: retinanet = model.resnet152(num_classes=dataset_train.num_classes(), pretrained=True) else: raise ValueError( 'Unsupported model depth, must be one of 18, 34, 50, 101, 152') use_gpu = True if use_gpu: retinanet = retinanet.to(device) retinanet = torch.nn.DataParallel(retinanet) if parser.resume: # Load checkpoint print("==> Resuming from checkpoint") checkpoint = torch.load('./checkpoint/ckpt.pth') retinanet.load_state_dict(checkpoint['net']) best_acc = checkpoint['acc'] start_epoch = checkpoint['epoch'] print('resume training from epoch:', start_epoch, " with accuracy:", best_acc) retinanet.training = True #optimizer = optim.Adam(retinanet.parameters(), lr=1e-3) optimizer = optim.SGD(retinanet.parameters(), lr=learning_rate, momentum=0.9) scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, patience=3, verbose=True) loss_hist = collections.deque(maxlen=500) retinanet.train() retinanet.module.freeze_bn() print('Num training images: {}'.format(len(dataset_train))) for epoch_num in range(start_epoch, start_epoch + parser.epochs): retinanet.train() retinanet.module.freeze_bn() epoch_loss = [] for iter_num, data in enumerate(dataloader_train): try: optimizer.zero_grad() classification_loss, regression_loss = retinanet( [data['img'].cuda().float(), data['annot']]) classification_loss = classification_loss.mean() regression_loss = regression_loss.mean() loss = classification_loss + regression_loss if bool(loss == 0): continue loss.backward() torch.nn.utils.clip_grad_norm_(retinanet.parameters(), 0.1) optimizer.step() loss_hist.append(float(loss)) epoch_loss.append(float(loss)) print( 'Epoch: {} | Iteration: {} | Classification loss: {:1.5f} | Regression loss: {:1.5f} | Running loss: {:1.5f}' .format(epoch_num, iter_num, float(classification_loss), float(regression_loss), np.mean(loss_hist))) del classification_loss del regression_loss except Exception as e: print(e) continue writer.add_scalar('train_loss', np.mean(epoch_loss), epoch_num) if parser.dataset == 'coco': print('Evaluating dataset') coco_eval.evaluate_coco(dataset_val, retinanet) elif parser.dataset == 'csv' and parser.csv_val is not None: print('Evaluating dataset') mAP = csv_eval.evaluate(dataset_val, retinanet, iou_threshold=0.7, max_detections=5, score_threshold=0.2, epoch=epoch_num) print('mapROI:', mAP[0]) AP, num_annotations = mAP[0] acc = 100. * AP if acc > best_acc: print('Saving... acc:', acc) state = { 'net': retinanet.state_dict(), 'acc': acc, 'epoch': epoch_num, } if not os.path.isdir('checkpoint'): os.mkdir('checkpoint') torch.save(state, './checkpoint/ckpt.pth') torch.save(retinanet, './checkpoint/best.pth') best_acc = acc writer.add_scalar('test_acc', acc, epoch_num) scheduler.step(np.mean(epoch_loss)) #torch.save(retinanet.module, osp.join('checkpoints','{}_retinanet_{}.pt'.format(parser.dataset, epoch_num))) retinanet.eval() torch.save(retinanet, 'model_final.pt'.format(epoch_num)) writer.close()
sampler = AspectRatioBasedSampler(dataset_train, batch_size=2, drop_last=False) dataloader_train = DataLoader(dataset_train, num_workers=3, collate_fn=collater, batch_sampler=sampler) if dataset_val is not None: sampler_val = AspectRatioBasedSampler(dataset_val, batch_size=1, drop_last=False) dataloader_val = DataLoader(dataset_val, num_workers=3, collate_fn=collater, batch_sampler=sampler_val) retinanet = model.resnet50(num_classes=dataset_train.num_classes(), pretrained=True) retinanet.load_state_dict(state_dict, strict=False) use_gpu = True if use_gpu: retinanet = retinanet.cuda() retinanet = torch.nn.DataParallel(retinanet).cuda() retinanet.training = True optimizer = optim.Adam(retinanet.parameters(), lr=1e-5) scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, patience=3,
inverse_dict = dict((val, key) for key, val in class_indices.items()) # write dict into json file json_str = json.dumps(inverse_dict, indent=4) with open('class_indices.json', 'w') as json_file: json_file.write(json_str) val_data_gen = validation_image_generator.flow_from_directory( directory=validation_dir, batch_size=batch_size, shuffle=False, target_size=(im_height, im_width), class_mode='categorical') # img, _ = next(train_data_gen) total_val = val_data_gen.n feature = resnet50(num_classes=5, include_top=False) # feature.build((None, 224, 224, 3)) # when using subclass model # feature.load_weights('pretrain_weights.ckpt') # feature.trainable = False feature.summary() model = tf.keras.Sequential([ feature, tf.keras.layers.GlobalAvgPool2D(), tf.keras.layers.Dropout(rate=0.5), tf.keras.layers.Dense(1024), tf.keras.layers.Dropout(rate=0.5), tf.keras.layers.Dense(5), tf.keras.layers.Softmax() ]) # model.build((None, 224, 224, 3))
def main(): """ --------------------------------------------- MAIN -------------------------------------------------------- Instantiates the model plus loss function and defines the dataloaders for several datasets including some data augmentation. Defines the grid for a grid search on lambda_max_divrs and initial_centroid_value_multipliers which both have a big influence on the sparsity (and respectively accuracy) of the resulting ternary networks. Starts grid search. """ # Manual seed for reproducibility torch.manual_seed(363636) # Global instances global args, use_cuda, device # Instantiating the parser args = parser.parse_args() # Global CUDA flag use_cuda = args.cuda and torch.cuda.is_available() # Defining device and device's map locationo device = torch.device("cuda" if use_cuda else "cpu") print('chosen device: ', device) # Building the model if args.model == 'cifar_micronet': print( 'Building MicroNet for CIFAR with depth multiplier {} and width multiplier {} ...' .format(args.dw_multps[0]**args.phi, args.dw_multps[1]**args.phi)) if args.dataset == 'CIFAR100': num_classes = 100 elif args.dataset == 'CIFAR10': num_classes = 10 model = micronet(args.dw_multps[0]**args.phi, args.dw_multps[1]**args.phi, num_classes) elif args.model == 'image_micronet': print( 'Building MicroNet for ImageNet with depth multiplier {} and width multiplier {} ...' .format(args.dw_multps[0]**args.phi, args.dw_multps[1]**args.phi)) model = image_micronet(args.dw_multps[0]**args.phi, args.dw_multps[1]**args.phi) elif args.model == 'efficientnet-b1': print('Building EfficientNet-B1 ...') model = EfficientNet.efficientnet_b1() elif args.model == 'efficientnet-b2': print('Building EfficientNet-B2 ...') model = EfficientNet.efficientnet_b2() elif args.model == 'efficientnet-b3': print('Building EfficientNet-B3 ...') model = EfficientNet.efficientnet_b3() elif args.model == 'efficientnet-b4': print('Building EfficientNet-B4 ...') model = EfficientNet.efficientnet_b4() elif args.model == 'lenet-5': print( 'Building LeNet-5 with depth multiplier {} and width multiplier {} ...' .format(args.dw_multps[0]**args.phi, args.dw_multps[1]**args.phi)) model = lenet5(d_multiplier=args.dw_multps[0]**args.phi, w_multiplier=args.dw_multps[1]**args.phi) elif args.model == "resnet18": model = resnet18() elif args.model == 'resnet20': model = resnet20() elif args.model == 'resnet50': model = resnet50() for name, param in model.named_parameters(): print('\n', name) # Transfers model to device (GPU/CPU). model.to(device) # Defining loss function and printing CUDA information (if available) if use_cuda: print("PyTorch version: ") print(torch.__version__) print("CUDA Version: ") print(torch.version.cuda) print("cuDNN version is: ") print(cudnn.version()) cudnn.benchmark = True loss_fct = nn.CrossEntropyLoss().cuda() else: loss_fct = nn.CrossEntropyLoss() # Dataloaders for CIFAR, ImageNet and MNIST if args.dataset == 'CIFAR100': print('Loading CIFAR-100 data ...') normalize = transforms.Normalize( mean=[x / 255.0 for x in [125.3, 123.0, 113.9]], std=[x / 255.0 for x in [63.0, 62.1, 66.7]]) kwargs = { 'num_workers': args.workers, 'pin_memory': True } if use_cuda else {} train_loader = torch.utils.data.DataLoader(datasets.CIFAR100( root=args.data_path, train=True, transform=transforms.Compose([ transforms.RandomHorizontalFlip(), transforms.RandomCrop(32, 4), transforms.ColorJitter(brightness=0.3, contrast=0.3, saturation=0.3, hue=0.075), transforms.ToTensor(), normalize, Cutout(n_holes=1, length=16), ]), download=True), batch_size=args.batch_size, shuffle=True, **kwargs) val_loader = torch.utils.data.DataLoader( datasets.CIFAR100(root=args.data_path, train=False, transform=transforms.Compose([ transforms.ToTensor(), normalize, ])), batch_size=args.val_batch_size, shuffle=False, **kwargs) elif args.dataset == 'ImageNet': print('Loading ImageNet data ...') traindir = os.path.join(args.data_path, 'train') valdir = os.path.join(args.data_path, 'val') normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) train_dataset = datasets.ImageFolder( traindir, transforms.Compose([ transforms.RandomResizedCrop(args.image_size), transforms.RandomHorizontalFlip(), transforms.ToTensor(), normalize, ])) train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=args.batch_size, shuffle=True, num_workers=args.workers, pin_memory=True) if model.__class__.__name__ == 'EfficientNet' or 'efficientnet' in str( args.model): image_size = EfficientNet.get_image_size(args.model) val_dataset = datasets.ImageFolder( valdir, transforms.Compose([ transforms.Resize(image_size, interpolation=PIL.Image.BICUBIC), transforms.CenterCrop(image_size), transforms.ToTensor(), normalize, ])) else: val_dataset = datasets.ImageFolder( valdir, transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), normalize, ])) val_loader = torch.utils.data.DataLoader( val_dataset, batch_size=args.val_batch_size, shuffle=False, num_workers=args.workers, pin_memory=True) elif args.dataset == 'MNIST': kwargs = { 'num_workers': args.workers, 'pin_memory': True } if use_cuda else {} train_loader = torch.utils.data.DataLoader(datasets.MNIST( args.data_path, train=True, download=True, transform=transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307, ), (0.3081, )) ])), batch_size=args.batch_size, shuffle=True, **kwargs) val_loader = torch.utils.data.DataLoader( datasets.MNIST(args.data_path, train=False, transform=transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.1307, ), (0.3081, )) ])), batch_size=args.val_batch_size, shuffle=True, **kwargs) elif args.dataset == 'CIFAR10': print('Loading CIFAR-10 data ...') normalize = transforms.Normalize( mean=[x / 255.0 for x in [125.3, 123.0, 113.9]], std=[x / 255.0 for x in [63.0, 62.1, 66.7]]) kwargs = { 'num_workers': args.workers, 'pin_memory': True } if use_cuda else {} train_loader = torch.utils.data.DataLoader(datasets.CIFAR10( root=args.data_path, train=True, transform=transforms.Compose([ transforms.RandomHorizontalFlip(), transforms.RandomCrop(32, 4), transforms.ColorJitter(brightness=0.3, contrast=0.3, saturation=0.3, hue=0.075), transforms.ToTensor(), normalize, Cutout(n_holes=1, length=16), ]), download=True), batch_size=args.batch_size, shuffle=True, **kwargs) val_loader = torch.utils.data.DataLoader( datasets.CIFAR10(root=args.data_path, train=False, transform=transforms.Compose([ transforms.ToTensor(), normalize, ])), batch_size=args.val_batch_size, shuffle=False, **kwargs) else: raise NotImplementedError('Undefined dataset name %s' % args.dataset) # Gridsearch on dividers for lambda_max and initial cluster center values for initial_c_divr in args.ini_c_divrs: for lambda_max_divr in args.lambda_max_divrs: print('lambda_max_divr: {}, initial_c_divr: {}'.format( lambda_max_divr, initial_c_divr)) if args.slurm_save == None: logfile = open('./model_quantization/logfiles/logfile.txt', 'a+') else: logfile = open(args.slurm_save + '/logfile.txt', 'a+') logfile.write('lambda_max_divr: {}, initial_c_divr: {}'.format( lambda_max_divr, initial_c_divr)) grid_search(train_loader, val_loader, model, loss_fct, lambda_max_divr, initial_c_divr)
def main(args=None): parser = argparse.ArgumentParser( description='Simple training script for training a RetinaNet network.') parser.add_argument('--dataset', help='Dataset type, must be one of csv or coco.') parser.add_argument('--csv_classes', help='Path to file containing class list (see readme)') parser.add_argument( '--csv_val', help= 'Path to file containing validation annotations (optional, see readme)' ) parser.add_argument( '--depth', help='Resnet depth, must be one of 18, 34, 50, 101, 152', type=int, default=50) parser.add_argument('--epochs', help='Number of epochs', type=int, default=100) parser.add_argument('--title', type=str, default='') parser.add_argument("--resume_model", type=str, default="") parser.add_argument("--resume_epoch", type=int, default=0) parser = parser.parse_args(args) title = parser.resume_model.split('.')[0] log_dir = "./runs/" + title writer = SummaryWriter(log_dir) if not os.path.isdir(log_dir + "/checkpoints"): os.makedirs(log_dir + "/checkpoints") if not os.path.isdir(log_dir + '/map_files'): os.makedirs(log_dir + '/map_files') if parser.dataset == 'csv': if parser.csv_val is None: dataset_val = None print('No validation annotations provided.') else: dataset_val = CSVDataset(train_file=parser.csv_val, class_list=parser.csv_classes, transform=transforms.Compose( [Normalizer(), Resizer()])) else: raise ValueError( 'Dataset type not understood (must be csv or coco), exiting.') if dataset_val is not None: sampler_val = AspectRatioBasedSampler(dataset_val, batch_size=1, drop_last=False) dataloader_val = DataLoader(dataset_val, num_workers=0, collate_fn=collater, batch_sampler=sampler_val) # Create the model if parser.depth == 18: retinanet = model.resnet18(num_classes=dataset_val.num_classes(), pretrained=True) elif parser.depth == 34: retinanet = model.resnet34(num_classes=dataset_val.num_classes(), pretrained=True) elif parser.depth == 50: retinanet = model.resnet50(num_classes=dataset_val.num_classes(), pretrained=True) elif parser.depth == 101: retinanet = model.resnet101(num_classes=dataset_val.num_classes(), pretrained=True) elif parser.depth == 152: retinanet = model.resnet152(num_classes=dataset_val.num_classes(), pretrained=True) else: raise ValueError( 'Unsupported model depth, must be one of 18, 34, 50, 101, 152') if parser.resume_model: retinanet.load_state_dict(torch.load(parser.resume_model)) use_gpu = True if use_gpu: retinanet = retinanet.cuda() theshes = [.05, 0.1, 0.2, 0.3] i = 0 for thresh in theshes: i = i + 1 retinanet.eval() print('Evaluating dataset') mAP, AP_string = csv_eval.evaluate(dataset_val, retinanet, score_threshold=thresh) with open( log_dir + '/map_files/{}_retinanet_{}.txt'.format( parser.dataset, thresh), 'w') as f: f.write(AP_string) total = 0.0 all = 0.0 total_unweighted = 0.0 for c in mAP: total += mAP[c][0] * mAP[c][1] total_unweighted += mAP[c][0] all += mAP[c][1] writer.add_scalar("thresh_finder/mAP", total / all, i) writer.add_scalar("thresh_finder/mAP_unweighted", total_unweighted / len(mAP), i)
def main(): device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") print("using {} device.".format(device)) data_transform = { "train": transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]), "val": transforms.Compose([ transforms.Resize(256), transforms.CenterCrop(224), transforms.ToTensor(), transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]) } data_root = os.path.abspath(os.path.join(os.getcwd(), "../..")) # get data root path image_path = os.path.join(data_root, "data_set", "industry_data") # flower data set path assert os.path.exists(image_path), "{} path does not exist.".format( image_path) train_dataset = datasets.ImageFolder(root=os.path.join( image_path, "train"), transform=data_transform["train"]) for img in train_dataset.imgs: Image.open(img[0]).convert('RGB') train_num = len(train_dataset) # {'daisy':0, 'dandelion':1, 'roses':2, 'sunflower':3, 'tulips':4} flower_list = train_dataset.class_to_idx cla_dict = dict((val, key) for key, val in flower_list.items()) # write dict into json file json_str = json.dumps(cla_dict, indent=4) with open('class_indices.json', 'w') as json_file: json_file.write(json_str) # 需修改 batch_size = 64 nw = min([os.cpu_count(), batch_size if batch_size > 1 else 0, 8]) # number of workers print('Using {} dataloader workers every process'.format(nw)) train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=nw) validate_dataset = datasets.ImageFolder(root=os.path.join( image_path, "val"), transform=data_transform["val"]) for img in validate_dataset.imgs: Image.open(img[0]).convert('RGB') val_num = len(validate_dataset) validate_loader = torch.utils.data.DataLoader(validate_dataset, batch_size=batch_size, shuffle=False, num_workers=nw) print("using {} images for training, {} images for validation.".format( train_num, val_num)) # 实例化resnet34, 默认num_classes=1000, 可以根据自己需要指定分类类别 # net = resnet34(num_classes=num_class) net = resnet50(num_classes=num_class) # load pretrain weights 载入官方的权重预处理, 1000种与要分类的数目不匹配 # download url: https://download.pytorch.org/models/resnet34-333f7ec4.pth # model_weight_path = "./resnet34-pre.pth" # model_weight_path = "./resnet50-pre.pth" # assert os.path.exists(model_weight_path), "file {} does not exist.".format(model_weight_path) # net.load_state_dict(torch.load(model_weight_path, map_location=device)) # 载入模型权重 # for param in net.parameters(): # param.requires_grad = False # change fc layer structure in_channel = net.fc.in_features # net.fc = nn.Linear(in_channel, 5) # 5 表示分类类别个数 需要修改 net.fc = nn.Linear(in_channel, num_class) # 需修改 net.to(device) # define loss function loss_function = nn.CrossEntropyLoss() # construct an optimizer params = [p for p in net.parameters() if p.requires_grad] optimizer = optim.Adam(params, lr=0.0001) # 训练次数,需修改 epochs = 100 best_acc = 0.0 # save_path = './resNet34.pth' save_path = './resNet50.pth' train_steps = len(train_loader) for epoch in range(epochs): # train net.train() running_loss = 0.0 train_bar = tqdm(train_loader) for step, data in enumerate(train_bar): images, labels = data optimizer.zero_grad() logits = net(images.to(device)) loss = loss_function(logits, labels.to(device)) loss.backward() optimizer.step() # print statistics running_loss += loss.item() train_bar.desc = "train epoch[{}/{}] loss:{:.3f}".format( epoch + 1, epochs, loss) # validate net.eval() acc = 0.0 # accumulate accurate number / epoch with torch.no_grad(): val_bar = tqdm(validate_loader) for val_data in val_bar: val_images, val_labels = val_data outputs = net(val_images.to(device)) # loss = loss_function(outputs, test_labels) predict_y = torch.max(outputs, dim=1)[1] acc += torch.eq(predict_y, val_labels.to(device)).sum().item() val_bar.desc = "valid epoch[{}/{}]".format(epoch + 1, epochs) val_accurate = acc / val_num print('[epoch %d] train_loss: %.3f val_accuracy: %.3f' % (epoch + 1, running_loss / train_steps, val_accurate)) if val_accurate > best_acc: best_acc = val_accurate torch.save(net.state_dict(), save_path) print('Finished Training')
def main(): data_root = os.path.abspath(os.path.join(os.getcwd(), '../')) # get data root path print("data_root:" + str(data_root)) image_path = os.path.join(data_root, "flower_data") # flower data set path train_dir = os.path.join(image_path, "train") validation_dir = os.path.join(image_path, "val") assert os.path.exists(train_dir), "cannot find {}".format(train_dir) assert os.path.exists(validation_dir), "cannot find {}".format(validation_dir) # crate direction for saving weights if not os.path.exists("save_weights"): os.makedirs("save_weights") im_height = 224 im_width = 224 batch_size = 16 epochs = 20 num_classes = 5 _R_MEAN = 123.68 _G_MEAN = 116.78 _B_MEAN = 103.94 def pre_function(img): img = img - [_R_MEAN, _G_MEAN, _B_MEAN] return img # data generator with data augmentation """ The ImageDataGenerator API reference here https://keras.io/api/preprocessing/image/ 1.训练集增加翻转操作是为了提高数据集的多样性,从而提高模型的泛化能力 2.pre_function; 减去数据集中的均值 3.shuffle;是否启用翻转功能 """ train_image_generator = ImageDataGenerator(horizontal_flip=True, preprocessing_function=pre_function) validation_image_generator = ImageDataGenerator(preprocessing_function=pre_function) train_data_gen = train_image_generator.flow_from_directory(directory=train_dir, batch_size=batch_size, shuffle=True, target_size=(im_height, im_width), class_mode='categorical') total_train = train_data_gen.n # get class dict class_indices = train_data_gen.class_indices # transform value and key of dict inverse_dict = dict((val, key) for key, val in class_indices.items()) # write dict into json file json_str = json.dumps(inverse_dict, indent=4) with open('class_indices.json', 'w') as json_file: json_file.write(json_str) val_data_gen = validation_image_generator.flow_from_directory(directory=validation_dir, batch_size=batch_size, shuffle=False, target_size=(im_height, im_width), class_mode='categorical') # img,_=next(train_data_gen) total_val = val_data_gen.n print('using{}image for training, {} images for validation.'.format(total_train, total_val)) feature = resnet50(num_classes=5, include_top=False) """ 迁移学习:使用预训练模型可以加快训练速度 """ pre_weights_path = './pretrain_weights.ckpt' assert len(glob.glob(pre_weights_path + "*")), "cannot find {}".format(pre_weights_path) feature.load_weights(pre_weights_path) feature.trainable = False feature.summary() model = tf.keras.Sequential([ feature, tf.keras.layers.GlobalAvgPool2D(), tf.keras.layers.Dropout(rate=0.5), tf.keras.layers.Dense(1024, activation='relu'), tf.keras.layers.Dropout(rate=0.5), tf.keras.layers.Dense(num_classes), tf.keras.layers.Softmax() ]) model.summary() # using keras low level api for training loss_object = tf.keras.losses.CategoricalCrossentropy(from_logits=False) optimizer = tf.keras.optimizers.Adam(learning_rate=0.0005) train_loss = tf.keras.metrics.Mean(name='train_loss') train_accuracy = tf.keras.metrics.CategoricalAccuracy(name='train_accruacy') val_loss = tf.keras.metrics.Mean(name='val_loss') val_accruacy = tf.keras.metrics.CategoricalAccuracy(name='val_accuracy') @tf.function def train_step(images, labels): with tf.GradientTape() as tape: output = model(images, training=True) loss = loss_object(labels, output) gradients = tape.gradient(loss, model.trainable_variables) optimizer.apply_gradients(zip(gradients, model.trainable_variables)) train_loss(loss) train_accuracy(labels, output) @tf.function def val_step(images, labels): output = model(images, training=False) loss = loss_object(labels, output) val_loss(loss) val_accruacy(labels, output) best_val_acc = 0. for epoch in range(epochs): train_loss.reset_states() # clear histroy info train_accuracy.reset_states() val_loss.reset_states() val_accruacy.reset_states() # train train_bar = tqdm(range(total_train // batch_size)) for step in train_bar: images, labels = next(train_data_gen) train_step(images, labels) # print train process train_bar.desc = "train epoch[{}/{}] loss:{:.3f}, acc:{:.3f}".format(epoch + 1, epochs, train_loss.result(), train_accuracy.result()) # validate val_bar = tqdm(range(total_val // batch_size)) for step in val_bar: test_images, test_labels = next(val_data_gen) val_step(test_images, test_labels) # print val process val_bar.desc = "valid epoch[{}'{}] loss:{:.3f}, acc:{:.3f}".format(epoch + 1, epochs, val_loss.result(), val_accruacy.result() ) # only save weights if val_accruacy.result() > best_val_acc: best_val_acc = val_accruacy.result() model.save_weights("./save_weights/resnet50.ckpt", save_format="tf")
dataloader = data_.DataLoader(dataset, \ batch_size=opt.batch_size, \ shuffle=True, \ # pin_memory=True, num_workers=opt.num_workers) testset = TestDataset(opt) test_dataloader = data_.DataLoader(testset, batch_size=opt.batch_size, num_workers=opt.test_num_workers, shuffle=False, \ pin_memory=True ) resnet = model.resnet50(20, True) resnet = resnet.cuda() resnet = torch.nn.DataParallel(resnet).cuda() resnet.load_state_dict(torch.load('resnet_6.pt')) optimizer = optim.Adam(resnet.parameters(), lr=opt.lr) scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, patience=3, verbose=True) loss_hist = collections.deque(maxlen=500) resnet.train() resnet.module.freeze_bn() #resnet.freeze_bn()
def train(csv_train=None, csv_classes=None, csv_val=None, epochs=12, depth=50, batch_size=2): dataset = "csv" # Create the data loaders if dataset == 'csv': if csv_train is None: raise ValueError('Must provide --csv_train when training on COCO,') if csv_classes is None: raise ValueError('Must provide --csv_classes when training on COCO,') dataset_train = CSVDataset(train_file=csv_train, class_list=csv_classes, transform=transforms.Compose([RandomHorizontalFlip(0.3),RandomRotation(6),Gamma_Correction(0.2), Image_Noise(0.2), Blur(0.2) , Normalizer(), Augmenter(), Resizer()])) if csv_val is None: dataset_val = None print('No validation annotations provided.') else: dataset_val = CSVDataset(train_file=csv_val, class_list=csv_classes, transform=transforms.Compose([Normalizer(), Resizer()])) else: raise ValueError('Dataset type not understood (must be csv or coco), exiting.') sampler = AspectRatioBasedSampler(dataset_train, batch_size=batch_size, drop_last=False) dataloader_train = DataLoader(dataset_train, num_workers=3, collate_fn=collater, batch_sampler=sampler) if dataset_val is not None: sampler_val = AspectRatioBasedSampler(dataset_val, batch_size=1, drop_last=False) dataloader_val = DataLoader(dataset_val, num_workers=3, collate_fn=collater, batch_sampler=sampler_val) # Create the model if depth == 18: retinanet = model.resnet18(num_classes=dataset_train.num_classes(), pretrained=True) elif depth == 34: retinanet = model.resnet34(num_classes=dataset_train.num_classes(), pretrained=True) elif depth == 50: retinanet = model.resnet50(num_classes=dataset_train.num_classes(), pretrained=True) elif depth == 101: retinanet = model.resnet101(num_classes=dataset_train.num_classes(), pretrained=True) elif depth == 152: retinanet = model.resnet152(num_classes=dataset_train.num_classes(), pretrained=True) else: raise ValueError('Unsupported model depth, must be one of 18, 34, 50, 101, 152') use_gpu = True if use_gpu: retinanet = retinanet.cuda() retinanet = torch.nn.DataParallel(retinanet).cuda() retinanet.training = True optimizer = optim.Adam(retinanet.parameters(), lr=1e-5) scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, patience=3, verbose=True) loss_hist = collections.deque(maxlen=500) retinanet.train() retinanet.module.freeze_bn() print('Num training images: {}'.format(len(dataset_train))) # Change total_loss_data = [] class_loss_data = [] reg_loss_data = [] # Change for epoch_num in range(epochs): retinanet.train() retinanet.module.freeze_bn() epoch_loss = [] # Change epoch_reg_loss = [] epoch_class_loss = [] # Change for iter_num, data in enumerate(dataloader_train): try: optimizer.zero_grad() classification_loss, regression_loss = retinanet([data['img'].cuda().float(), data['annot']]) classification_loss = classification_loss.mean() regression_loss = regression_loss.mean() loss = classification_loss + regression_loss if bool(loss == 0): continue loss.backward() torch.nn.utils.clip_grad_norm_(retinanet.parameters(), 0.1) optimizer.step() loss_hist.append(float(loss)) epoch_loss.append(float(loss)) # Change epoch_reg_loss.append(float(regression_loss)) epoch_class_loss.append(float(classification_loss)) # Change print('Epoch: {} | Iteration: {} | Classification loss: {:1.5f} | Regression loss: {:1.5f} | Running loss: {:1.5f}'.format(epoch_num, iter_num, float(classification_loss), float(regression_loss), np.mean(loss_hist))) del classification_loss del regression_loss except Exception as e: print(e) continue if dataset == 'csv' and csv_val is not None: print('Evaluating dataset') mAP = csv_eval.evaluate(dataset_val, retinanet) # Change total_loss_data.append(np.mean(epoch_loss)) class_loss_data.append(np.mean(epoch_class_loss)) reg_loss_data.append(np.mean(epoch_reg_loss)) print("Epoch loss", total_loss_data) print("Epoch loss - classification", class_loss_data) print("Epoch loss - Regression", reg_loss_data) # Change scheduler.step(np.mean(epoch_loss)) torch.save(retinanet.module, '{}_retinanet_{}.pt'.format(dataset, epoch_num)) retinanet.eval() torch.save(retinanet, 'model_final.pt'.format(epoch_num)) # Change import matplotlib.pyplot as plt plt.plot(total_loss_data, label='Total loss') plt.plot(class_loss_data, label='Classification loss') plt.plot(reg_loss_data, label='Regression loss') plt.ylabel("Loss") plt.xlabel("Epoch") plt.title("Epoch losses") plt.legend() plt.show()
import torchsummary if __name__ == '__main__': """ python grad_cam.py <path_to_image> 1. Loads an image with opencv. 2. Preprocesses it for VGG19 and converts to a pytorch variable. 3. Makes a forward pass to find the category index with the highest score, and computes intermediate activations. Makes the visualization. """ args = get_args() # Can work with any model, but it assumes that the model has a # feature method, and a classifier method, # as in the VGG models in torchvision. model = model.resnet50(pretrained=False) model.load_state_dict(torch.load('resnet50_flower_real.pth', map_location=torch.device('cpu'))) # checkpoint = torch.load('resnet50_flower_real.pth', map_location=torch.device('cpu')) # model = checkpoint['model'] # model.load_state_dict(checkpoint['state_dict']) # torchsummary.summary(model,(3,128,128)) grad_cam = GradCam(model=model, feature_module=model.layer4, \ target_layer_names=["2"], use_cuda=args.use_cuda) # khoi sequence thu 4 #0 1 2 # print(grad_cam) # img = cv2.imread('image_05636.jpg', 1) # img = np.float32(cv2.resize(img, (224, 224))) / 255 # input = preprocess_image(img) transform = transforms.Compose([transforms.Resize((128, 128)),
network.cuda(gpu_ids[0]) ###################################################################### # Finetuning the convnet # ---------------------- # # Load a pretrainied model and reset final fully connected layer. # if opt.use_dense: model = ft_net_dense(len(class_names)) print('*****************************ft_net_dense*************************') else: # model = ft_net(len(class_names)) model = resnet50(len(class_names)) print( '***************************ft_net**********************************') print(model) if use_gpu: model = model.cuda() criterion = nn.CrossEntropyLoss() # ignored_params = list(map(id, model.model.fc.parameters() )) + list(map(id, model.classifier.parameters() )) ignored_params = list(map(id, model.fc1.parameters())) + list( map(id, model.fc2.parameters())) # base_params = filter(lambda p: id(p) not in ignored_params, model.parameters()) base_params = filter(lambda p: id(p) not in ignored_params, model.parameters())
def main(args=None): parser = argparse.ArgumentParser( description='Simple training script for training a RetinaNet network.') parser.add_argument( '--train-file', help='Path to file containing training annotations (see readme)') parser.add_argument('--classes-file', help='Path to file containing class list (see readme)') parser.add_argument( '--val-file', help= 'Path to file containing validation annotations (optional, see readme)' ) parser.add_argument( '--depth', help='Resnet depth, must be one of 18, 34, 50, 101, 152', type=int, default=50) parser.add_argument('--epochs', help='Number of epochs', type=int, default=100) parser.add_argument('--title', type=str, default='') parser.add_argument("--resume_model", type=str, default="") parser.add_argument("--resume_epoch", type=int, default=0) parser.add_argument("--reinit-classifier", action="store_true", default=False) parser.add_argument("--lr", type=float, default=.00001) parser.add_argument("--all-box-regression", action="store_true", default=False) parser.add_argument("--batch-size", type=int, default=16) parser = parser.parse_args(args) log_dir = "./runs/" + parser.title writer = SummaryWriter(log_dir) #pdb.set_trace() with open(log_dir + '/config.csv', 'w') as f: for item in vars(parser): print(item + ',' + str(getattr(parser, item))) f.write(item + ',' + str(getattr(parser, item)) + '\n') if not os.path.isdir(log_dir + "/checkpoints"): os.makedirs(log_dir + "/checkpoints") if not os.path.isdir(log_dir + '/map_files'): os.makedirs(log_dir + '/map_files') dataset_train = CSVDataset(train_file=parser.train_file, class_list=parser.classes_file, transform=transforms.Compose( [Normalizer(), Augmenter(), Resizer()])) if parser.val_file is None: dataset_val = None print('No validation annotations provided.') else: dataset_val = CSVDataset(train_file=parser.val_file, class_list=parser.classes_file, transform=transforms.Compose( [Normalizer(), Resizer()])) sampler = AspectRatioBasedSampler(dataset_train, batch_size=parser.batch_size, drop_last=True) dataloader_train = DataLoader(dataset_train, num_workers=8, collate_fn=collater, batch_sampler=sampler) if dataset_val is not None: sampler_val = AspectRatioBasedSampler(dataset_val, batch_size=parser.batch_size, drop_last=False) dataloader_val = DataLoader(dataset_val, num_workers=8, collate_fn=collater, batch_sampler=sampler_val) # Create the model if parser.depth == 18: retinanet = model.resnet18(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 34: retinanet = model.resnet34(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 50: retinanet = model.resnet50(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 101: retinanet = model.resnet101(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 152: retinanet = model.resnet152(num_classes=dataset_train.num_classes(), pretrained=True) else: raise ValueError( 'Unsupported model depth, must be one of 18, 34, 50, 101, 152') if parser.resume_model: x = torch.load(parser.resume_model) if parser.reinit_classifier: dummy = nn.Conv2d(256, 9 * dataset_train.num_classes(), kernel_size=3, padding=1) x['classificationModel.output.weight'] = dummy.weight.clone() x['classificationModel.output.bias'] = dummy.bias.clone() prior = 0.01 x['classificationModel.output.weight'].data.fill_(0) x['classificationModel.output.bias'].data.fill_(-math.log( (1.0 - prior) / prior)) retinanet.load_state_dict(x) use_gpu = True if use_gpu: retinanet = retinanet.cuda() retinanet = torch.nn.DataParallel(retinanet).cuda() #torch.nn.DataParallel(retinanet).cuda() retinanet.training = True optimizer = optim.Adam(retinanet.parameters(), lr=parser.lr) scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, patience=3, verbose=True) loss_hist = collections.deque(maxlen=500) retinanet.train() retinanet.module.freeze_bn() # x = torch.load('./csv_retinanet_20.pth') # retinanet.module.load_state_dict(x) print('Num training images: {}'.format(len(dataset_train))) for epoch_num in range(parser.resume_epoch, parser.epochs): retinanet.train() retinanet.module.freeze_bn() epoch_loss = [] i = 0 avg_class_loss = 0.0 avg_reg_loss = 0.0 for iter_num, data in enumerate(dataloader_train): i += 1 try: optimizer.zero_grad() #pdb.set_trace() shape = data['img'].shape[2] * data['img'].shape[3] writer.add_scalar("train/image_shape", shape, epoch_num * (len(dataloader_train)) + i) classification_loss, regression_loss = retinanet( [data['img'].cuda().float(), data['annot'].cuda().float()]) classification_loss = classification_loss.mean() regression_loss = regression_loss.mean() avg_class_loss += classification_loss avg_reg_loss += regression_loss if i % 100 == 0: writer.add_scalar("train/classification_loss", avg_class_loss / 100, epoch_num * (len(dataloader_train)) + i) writer.add_scalar("train/regression_loss", avg_reg_loss / 100, epoch_num * (len(dataloader_train)) + i) avg_class_loss = 0.0 avg_reg_loss = 0.0 loss = classification_loss + regression_loss if bool(loss == 0): continue loss.backward() torch.nn.utils.clip_grad_norm_(retinanet.parameters(), 0.1) optimizer.step() loss_hist.append(float(loss)) epoch_loss.append(float(loss)) print( 'Epoch: {} | Iteration: {} | Classification loss: {:1.5f} | Regression loss: {:1.5f} | Running loss: {:1.5f}' .format(epoch_num, iter_num, float(classification_loss), float(regression_loss), np.mean(loss_hist))) del classification_loss del regression_loss except Exception as e: print(e) continue if epoch_num % 2 == 0: print('Evaluating dataset') retinanet.eval() mAP, AP_string = csv_eval.evaluate(dataset_val, retinanet.module, score_threshold=0.1) with open( log_dir + '/map_files/retinanet_{}.txt'.format(epoch_num), 'w') as f: f.write(AP_string) total = 0.0 all = 0.0 total_unweighted = 0.0 for c in mAP: total += mAP[c][0] * mAP[c][1] total_unweighted += mAP[c][0] all += mAP[c][1] writer.add_scalar("val/mAP", total / all, epoch_num) writer.add_scalar("val/mAP_unweighted", total_unweighted / len(mAP), epoch_num) scheduler.step(np.mean(epoch_loss)) torch.save(retinanet.module.state_dict(), log_dir + '/checkpoints/retinanet_{}.pth'.format(epoch_num)) retinanet.eval() torch.save(retinanet.module.state_dict(), log_dir + '/checkpoints/model_final.pth'.format(epoch_num))
video_category = label_df['Video_category'][idx] video_name = label_df['Video_name'][idx] rescale_factor = 1 frames = readShortVideo(video_path, video_category, video_name, downsample_factor=12, rescale_factor=rescale_factor) frame_tensor_list = [] for frame in frames: frame_tensor_transform = transform(frame) frame_tensor_list.append(frame_tensor_transform) frames_tensor = torch.stack(frame_tensor_list).cuda() resnet_out = resnet50(frames_tensor) # feature_np = np.load(feature_path+video_name+'.npy') # resnet_out = torch.tensor(feature_np).cuda() hidden = model.init_hidden() for i in range(resnet_out.size()[0]): classifier_out, hidden = model(resnet_out[i].view(1, 1, -1), hidden) pred_seq.append(int(classifier_out.topk(1)[1])) with open(output_path + '/p2_result.txt', 'w') as f: for i, pred in enumerate(pred_seq): f.write(str(pred)) if i + 1 != len(pred_seq):
target_size=(im_height, im_width), class_mode='categorical') # img, _ = next(train_data_gen) total_val = val_data_gen.n # shuffle false->true test_data_gen = test_image_generator.flow_from_directory( directory=test_dir, batch_size=batch_size, shuffle=True, target_size=(im_height, im_width), class_mode='categorical') # img, _ = next(train_data_gen) total_test = test_data_gen.n model = resnet50(num_classes=2, include_top=True) # transfer时加载已训练参数 # model.load_weights(filepath="D:/machine_learning/Resnet/resnet50_new/save_weights/resNet50_OUBAO_01.ckpt") model.summary() # using keras low level api for training loss_object = tf.keras.losses.CategoricalCrossentropy(from_logits=False) optimizer = tf.keras.optimizers.Adam(learning_rate=0.0002) train_loss = tf.keras.metrics.Mean(name='train_loss') train_accuracy = tf.keras.metrics.CategoricalAccuracy(name='train_accuracy') # train_auc = tf.keras.metrics.Mean(name='train_auc') valid_loss = tf.keras.metrics.Mean(name='valid_loss') valid_accuracy = tf.keras.metrics.CategoricalAccuracy(name='valid_accuracy') # test_auc = tf.keras.metrics.Mean(name='test_tp')
def train(): if not os.path.exists(save_path): os.makedirs(save_path) device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") print("Device being used:", device) ############### 모델 생성 net = model.resnet50(class_num=4) # (앵커, 기자, 인터뷰, 자료화면) 에 클래스일 확률 print('Total params: %.2fM' % (sum(p.numel() for p in net.parameters()) / 1000000.0)) # Loss Function softmax = nn.Softmax(dim=1) criterion = nn.CrossEntropyLoss() # Optimizer optimizer = optim.Adam(net.parameters(), lr=lr, weight_decay=5e-4) # Scheduler scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.5) net.to(device) criterion.to(device) writer = SummaryWriter(log_dir=log_dir) ############### Dataset, DataLoader 생성 # dataset = TimeStampDataset(xlsx_path=xlsx_path, root_path=dataset_path, sigma=3.0, image_size=(180,120)) # dataset = ClassDataset(xlsx_path=xlsx_path, root_path=dataset_path, sigma=6.0, spacing=8, image_size=(180,120)) dataset = ClassDataset(xlsx_path=xlsx_path, root_path=dataset_path, spacing=8, seed=420, image_size=(180, 120)) train_size = int(len(dataset) * 0.8) val_size = int(len(dataset) * 0.2) train_dataset, val_dataset = random_split(dataset, [train_size, val_size], generator=torch.Generator().manual_seed(0)) print(f"Total number of train datas : {len(train_dataset)}") print(f"Total number of validation datas : {len(val_dataset)}") train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True) val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=True) print(f"Total number of train batches : {len(train_loader)}") print(f"Total number of train batches : {len(val_loader)}") ############### 학습 시작 best_acc_on_train = 0.0 best_acc_on_test = 0.0 for epoch in range(0, nEpochs): ############### Train net.train() running_loss = 0.0 # 한 epoch 동안의 loss running_corrects = 0.0 # 한 epoch 동안의 corrects start_time = timeit.default_timer() for inputs, labels in tqdm(train_loader): inputs = inputs.to(device=device, dtype=torch.float32) labels = labels.to(device=device, dtype=torch.int64) optimizer.zero_grad() outputs = net(inputs) # --> 4 개의 Class 에 대한 확률값. (4) ################## Loss 측정 loss = criterion(outputs, labels) running_loss += loss.item() * inputs.size(0) ################## Accuracy 측정 probs = softmax(outputs) pred_labels = torch.max(probs, 1)[1] running_corrects += torch.sum(pred_labels == labels) loss.backward() optimizer.step() epoch_loss = running_loss / len(train_loader.dataset) epoch_acc = running_corrects.double() / len(train_loader.dataset) writer.add_scalar('data/train_loss_epoch', epoch_loss, epoch) writer.add_scalar('data/train_acc_epoch', epoch_acc, epoch) writer.add_scalar('data/learning_rate', lr, epoch) if epoch_acc > best_acc_on_train: torch.save({ 'epoch': epoch + 1, 'state_dict': net.state_dict(), 'opt_dict': optimizer.state_dict(), }, os.path.join(save_path, 'train_epoch-' + str(epoch) + '-best_model.pth')) best_acc_on_train = epoch_acc print("[Train] Epoch: {}/{} Loss: {} Acc: {}".format(epoch+1, nEpochs, epoch_loss, epoch_acc)) stop_time = timeit.default_timer() print("Execution time: " + str(stop_time - start_time) + "\n") ############### validation net.eval() running_loss = 0.0 running_corrects = 0.0 start_time = timeit.default_timer() for inputs, labels in tqdm(val_loader): inputs = inputs.to(device=device, dtype=torch.float32) labels = labels.to(device=device, dtype=torch.int64) with torch.no_grad(): outputs = net(inputs) ################## Loss 측정 loss = criterion(outputs, labels) running_loss += loss.item() * inputs.size(0) ################## Accuracy 측정 probs = softmax(outputs) pred_labels = torch.max(probs, 1)[1] running_corrects += torch.sum(pred_labels == labels) epoch_loss = running_loss / len(val_loader.dataset) epoch_acc = running_corrects.double() / len(val_loader.dataset) writer.add_scalar('data/test_loss_epoch', epoch_loss, epoch) writer.add_scalar('data/test_acc_epoch', epoch_acc, epoch) if epoch_acc > best_acc_on_test: torch.save({ 'epoch': epoch + 1, 'state_dict': net.state_dict(), 'opt_dict': optimizer.state_dict(), }, os.path.join(save_path, 'test_epoch-' + str(epoch) + '-best_model.pth')) best_acc_on_test = epoch_acc print("[test] Epoch: {}/{} Loss: {} Acc: {}".format(epoch+1, nEpochs, epoch_loss, epoch_acc)) stop_time = timeit.default_timer() print("Execution time: " + str(stop_time - start_time) + "\n") scheduler.step() writer.close()
def main(): parser = argparse.ArgumentParser() parser.add_argument('--epochs', default=50, type=int, help='epoch number') parser.add_argument('-b', '--batch_size', default=256, type=int, help='mini-batch size') parser.add_argument('--lr', '--learning_rate', default=1e-3, type=float, help='initial learning rate') parser.add_argument('-c', '--continue', dest='continue_path', type=str, required=False) parser.add_argument('--exp_name', default=config.exp_name, type=str, required=False) parser.add_argument('--drop_rate', default=0, type=float, required=False) parser.add_argument('--only_fc', action='store_true', help='only train fc layers') parser.add_argument('--net', default='densenet169', type=str, required=False) parser.add_argument('--local', action='store_true', help='train local branch') args = parser.parse_args() args.batch_size = 16 args.epochs = 120 args.lr = 1e-3 args.net = 'resnet101' print(args) config.exp_name = args.exp_name config.make_dir() save_args(args, config.log_dir) # get network if args.net == 'resnet50': net = resnet50(pretrained=True, drop_rate=args.drop_rate) elif args.net == 'resnet101': net = resnet101(pretrained=True, drop_rate=args.drop_rate) elif args.net == 'densenet121': net = models.densenet121(pretrained=True) net.classifier = nn.Sequential(nn.Linear(1024, 1), nn.Sigmoid()) elif args.net == 'densenet169': net = densenet169(pretrained=True, drop_rate=args.drop_rate) elif args.net == 'fusenet': global_branch = torch.load(GLOBAL_BRANCH_DIR)['net'] local_branch = torch.load(LOCAL_BRANCH_DIR)['net'] net = fusenet(global_branch, local_branch) del global_branch, local_branch elif args.net == 'attention_resnet': net = Attentionnet() elif args.net == 'effnet-b3': net = EfficientNet.from_name('efficientnet-b3', n_classes=1, pretrained=False) elif args.net == 'effnet-b5': net = EfficientNet.from_name('efficientnet-b5', n_classes=1, pretrained=False) elif args.net == 'effnet-b7': net = EfficientNet.from_name('efficientnet-b7', n_classes=1, pretrained=False) else: raise NameError net = net.cuda() sess = Session(config, net=net) # get dataloader # train_loader = get_dataloaders('train', batch_size=args.batch_size, # shuffle=True, is_local=args.local) # # valid_loader = get_dataloaders('valid', batch_size=args.batch_size, # shuffle=False, is_local=args.local) train_loader = get_dataloaders('train', batch_size=args.batch_size, num_workers=4, shuffle=True) valid_loader = get_dataloaders('valid', batch_size=args.batch_size, shuffle=False) if args.continue_path and os.path.exists(args.continue_path): sess.load_checkpoint(args.continue_path) # start session clock = sess.clock tb_writer = sess.tb_writer sess.save_checkpoint('start.pth.tar') # set criterion, optimizer and scheduler criterion = nn.BCELoss().cuda() # not used if args.only_fc: optimizer = optim.Adam(sess.net.module.classifier.parameters(), args.lr) else: optimizer = optim.Adam(sess.net.parameters(), args.lr) scheduler = ReduceLROnPlateau(optimizer, 'max', factor=0.5, patience=6, verbose=True) # scheduler = CosineAnnealingWarmUpRestarts(optimizer, T_0=10, T_mult=2, eta_max=1e-2, T_up=2, gamma=0.7) # start training for e in range(args.epochs): for para in optimizer.param_groups: print('LR', para['lr']) train_out = train_model(train_loader, sess.net, criterion, optimizer, clock.epoch) valid_out = valid_model(valid_loader, sess.net, criterion, optimizer, clock.epoch) tb_writer.add_scalars('loss', { 'train': train_out['epoch_loss'], 'valid': valid_out['epoch_loss'] }, clock.epoch) tb_writer.add_scalars('acc', { 'train': train_out['epoch_acc'], 'valid': valid_out['epoch_acc'] }, clock.epoch) tb_writer.add_scalar('auc', valid_out['epoch_auc'], clock.epoch) tb_writer.add_scalar('learning_rate', optimizer.param_groups[-1]['lr'], clock.epoch) scheduler.step(valid_out['epoch_auc']) # scheduler.step() if valid_out['epoch_acc'] > sess.best_val_acc: sess.best_val_acc = valid_out['epoch_acc'] print('best_acc:', sess.best_val_acc, '_@_', e) sess.save_checkpoint('best_model.pth.tar') if clock.epoch % 10 == 0: sess.save_checkpoint('epoch{}.pth.tar'.format(clock.epoch)) sess.save_checkpoint('latest.pth.tar') clock.tock()
def main(args=None): #def main(epoch): parser = argparse.ArgumentParser( description='Simple training script for training a RetinaNet network.') parser.add_argument('--dataset', help='Dataset type, must be one of csv or coco.') parser.add_argument('--coco_path', help='Path to COCO directory') parser.add_argument( '--csv_train', help='Path to file containing training annotations (see readme)') parser.add_argument('--csv_classes', help='Path to file containing class list (see readme)') parser.add_argument( '--csv_val', help= 'Path to file containing validation annotations (optional, see readme)' ) parser.add_argument( '--depth', help='Resnet depth, must be one of 18, 34, 50, 101, 152', type=int, default=50) parser.add_argument('--epochs', help='Number of epochs', type=int, default=100) #parser.add_argument('--resume', '-r', action='store_true', help='resume from checkpoint') parser.add_argument('--start-epoch', default=0, type=int, help='manual epoch number (useful on restarts)') parser.add_argument('--resume', default='', type=str, metavar='PATH', help='path to latest checkpoint (default: none)') parser = parser.parse_args(args) #args = parser.parse_args() #parser = parser.parse_args(epoch) # Create the data loaders if parser.dataset == 'coco': if parser.coco_path is None: raise ValueError('Must provide --coco_path when training on COCO,') dataset_train = CocoDataset(parser.coco_path, set_name='train2017', transform=transforms.Compose( [Normalizer(), Augmenter(), Resizer()])) dataset_val = CocoDataset(parser.coco_path, set_name='val2017', transform=transforms.Compose( [Normalizer(), Resizer()])) elif parser.dataset == 'csv': if parser.csv_train is None: raise ValueError('Must provide --csv_train when training on COCO,') if parser.csv_classes is None: raise ValueError( 'Must provide --csv_classes when training on COCO,') dataset_train = CSVDataset(train_file=parser.csv_train, class_list=parser.csv_classes, transform=transforms.Compose( [Normalizer(), Augmenter(), Resizer()])) if parser.csv_val is None: dataset_val = None print('No validation annotations provided.') else: dataset_val = CSVDataset(train_file=parser.csv_val, class_list=parser.csv_classes, transform=transforms.Compose( [Normalizer(), Resizer()])) else: raise ValueError( 'Dataset type not understood (must be csv or coco), exiting.') sampler = AspectRatioBasedSampler(dataset_train, batch_size=4, drop_last=False) dataloader_train = DataLoader(dataset_train, num_workers=3, collate_fn=collater, batch_sampler=sampler) if dataset_val is not None: sampler_val = AspectRatioBasedSampler(dataset_val, batch_size=1, drop_last=False) dataloader_val = DataLoader(dataset_val, num_workers=3, collate_fn=collater, batch_sampler=sampler_val) # Create the model if parser.depth == 18: retinanet = model.resnet18(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 34: retinanet = model.resnet34(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 50: retinanet = model.resnet50(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 101: retinanet = model.resnet101(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 152: retinanet = model.resnet152(num_classes=dataset_train.num_classes(), pretrained=True) else: raise ValueError( 'Unsupported model depth, must be one of 18, 34, 50, 101, 152') use_gpu = True if use_gpu: retinanet = retinanet.cuda() #retinanet().load_state_dict(torch.load('/users/wenchi/ghwwc/Pytorch-retinanet-master/resnet50-19c8e357.pth')) #if True: #print('==> Resuming from checkpoint..') #checkpoint = torch.load('/users/wenchi/ghwwc/Pytorch-retinanet-master/coco_retinanet_2.pt') #retinanet().load_state_dict(checkpoint) #best_loss = checkpoint['loss'] #start_epoch = checkpoint['epoch'] retinanet = torch.nn.DataParallel(retinanet).cuda() retinanet.training = True #optimizer = optim.Adam(retinanet.parameters(), lr=1e-5) optimizer = optim.SGD(retinanet.parameters(), lr=1e-5) scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, patience=3, verbose=True) loss_hist = collections.deque(maxlen=500) retinanet.train() #retinanet.freeze_bn() #for train from a middle state retinanet.module.freeze_bn() #for train from the very beginning print('Num training images: {}'.format(len(dataset_train))) for epoch_num in range(parser.start_epoch, parser.epochs): if parser.resume: if os.path.isfile(parser.resume): print("=>loading checkpoint '{}'".format(parser.resume)) checkpoint = torch.load(parser.resume) print(parser.start_epoch) #parser.start_epoch = checkpoint['epoch'] #retinanet.load_state_dict(checkpoint['state_dict']) retinanet = checkpoint #retinanet.load_state_dict(checkpoint) print(retinanet) #optimizer.load_state_dict(checkpoint) print("=> loaded checkpoint '{}' (epoch {})".format( parser.resume, checkpoint)) else: print("=> no checkpoint found at '{}'".format(parser.resume)) retinanet.train() retinanet.freeze_bn() #retinanet.module.freeze_bn() epoch_loss = [] for iter_num, data in enumerate(dataloader_train): try: optimizer.zero_grad() classification_loss, regression_loss = retinanet( [data['img'].cuda().float(), data['annot'].cuda()]) classification_loss = classification_loss.mean() regression_loss = regression_loss.mean() loss = classification_loss + regression_loss if bool(loss == 0): continue loss.backward() torch.nn.utils.clip_grad_norm_(retinanet.parameters(), 0.1) optimizer.step() loss_hist.append(float(loss)) epoch_loss.append(float(loss)) print( 'Epoch: {} | Iteration: {} | Classification loss: {:1.5f} | Regression loss: {:1.5f} | Running loss: {:1.5f}' .format(epoch_num, iter_num, float(classification_loss), float(regression_loss), np.mean(loss_hist))) del classification_loss del regression_loss except Exception as e: print(e) continue if parser.dataset == 'coco': print('Evaluating dataset') coco_eval.evaluate_coco(dataset_val, retinanet) elif parser.dataset == 'csv' and parser.csv_val is not None: print('Evaluating dataset') mAP = csv_eval.evaluate(dataset_val, retinanet) scheduler.step(np.mean(epoch_loss)) #torch.save(retinanet.module, '{}_retinanet_101_{}.pt'.format(parser.dataset, epoch_num)) torch.save( retinanet, '{}_retinanet_dilation_experiment_{}.pt'.format( parser.dataset, epoch_num)) name = '{}_retinanet_dilation_experiment_{}.pt'.format( parser.dataset, epoch_num) parser.resume = '/users/wenchi/ghwwc/pytorch-retinanet-master_new/name' retinanet.eval() torch.save(retinanet, 'model_final_dilation_experiment.pt'.format(epoch_num))
def __init__(self, PRETRAINED): super(Deblur, self).__init__() self.exec = resnet50(pretrained=PRETRAINED) self.classifier = nn.Linear(2048, 2)
batch_size = 16 train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=batch_size, shuffle=True, num_workers=0) validate_dataset = datasets.ImageFolder(root=image_path + "_val", transform=data_transform["_val"]) val_num = len(validate_dataset) validate_loader = torch.utils.data.DataLoader(validate_dataset, batch_size=batch_size, shuffle=False, num_workers=0) net = resnet50() # load pretrain weights model_weight_path = "./resnet50_qy.pth" missing_keys, unexpected_keys = net.load_state_dict( torch.load(model_weight_path), strict=False) # for param in net.parameters(): # param.requires_grad = False # change fc layer structure inchannel = net.fc.in_features net.fc = nn.Linear(inchannel, 51) net.to(device) loss_function = nn.CrossEntropyLoss() optimizer = optim.Adam(net.parameters(), lr=0.0001) best_acc = 0.0
def main(): data_root = os.path.abspath(os.path.join(os.getcwd(), "../..")) # get data root path image_path = data_root + "/data_set/flower_data/" # flower data set path train_dir = image_path + "train" validation_dir = image_path + "val" im_height = 224 im_width = 224 batch_size = 16 epochs = 20 _R_MEAN = 123.68 _G_MEAN = 116.78 _B_MEAN = 103.94 def pre_function(img): # img = im.open('test.jpg') # img = np.array(img).astype(np.float32) img = img - [_R_MEAN, _G_MEAN, _B_MEAN] return img # data generator with data augmentation train_image_generator = ImageDataGenerator( horizontal_flip=True, preprocessing_function=pre_function) validation_image_generator = ImageDataGenerator( preprocessing_function=pre_function) train_data_gen = train_image_generator.flow_from_directory( directory=train_dir, batch_size=batch_size, shuffle=True, target_size=(im_height, im_width), class_mode='categorical') total_train = train_data_gen.n # get class dict class_indices = train_data_gen.class_indices # transform value and key of dict inverse_dict = dict((val, key) for key, val in class_indices.items()) # write dict into json file json_str = json.dumps(inverse_dict, indent=4) with open('class_indices.json', 'w') as json_file: json_file.write(json_str) val_data_gen = validation_image_generator.flow_from_directory( directory=validation_dir, batch_size=batch_size, shuffle=False, target_size=(im_height, im_width), class_mode='categorical') # img, _ = next(train_data_gen) total_val = val_data_gen.n feature = resnet50(num_classes=5, include_top=False) # feature.build((None, 224, 224, 3)) # when using subclass model feature.load_weights('pretrain_weights.ckpt') feature.trainable = False feature.summary() model = tf.keras.Sequential([ feature, tf.keras.layers.GlobalAvgPool2D(), tf.keras.layers.Dropout(rate=0.5), tf.keras.layers.Dense(1024, activation="relu"), tf.keras.layers.Dropout(rate=0.5), tf.keras.layers.Dense(5), tf.keras.layers.Softmax() ]) # model.build((None, 224, 224, 3)) model.summary() # using keras low level api for training loss_object = tf.keras.losses.CategoricalCrossentropy(from_logits=False) optimizer = tf.keras.optimizers.Adam(learning_rate=0.0002) train_loss = tf.keras.metrics.Mean(name='train_loss') train_accuracy = tf.keras.metrics.CategoricalAccuracy( name='train_accuracy') test_loss = tf.keras.metrics.Mean(name='test_loss') test_accuracy = tf.keras.metrics.CategoricalAccuracy(name='test_accuracy') @tf.function def train_step(images, labels): with tf.GradientTape() as tape: output = model(images, training=True) loss = loss_object(labels, output) gradients = tape.gradient(loss, model.trainable_variables) optimizer.apply_gradients(zip(gradients, model.trainable_variables)) train_loss(loss) train_accuracy(labels, output) @tf.function def test_step(images, labels): output = model(images, training=False) t_loss = loss_object(labels, output) test_loss(t_loss) test_accuracy(labels, output) best_test_loss = float('inf') for epoch in range(1, epochs + 1): train_loss.reset_states() # clear history info train_accuracy.reset_states() # clear history info test_loss.reset_states() # clear history info test_accuracy.reset_states() # clear history info # train for step in range(total_train // batch_size): images, labels = next(train_data_gen) train_step(images, labels) # print train process rate = (step + 1) / (total_train // batch_size) a = "*" * int(rate * 50) b = "." * int((1 - rate) * 50) acc = train_accuracy.result().numpy() print("\r[{}]train acc: {:^3.0f}%[{}->{}]{:.4f}".format( epoch, int(rate * 100), a, b, acc), end="") print() # validate for step in range(total_val // batch_size): test_images, test_labels = next(val_data_gen) test_step(test_images, test_labels) template = 'Epoch {}, Loss: {}, Accuracy: {}, Test Loss: {}, Test Accuracy: {}' print( template.format(epoch, train_loss.result(), train_accuracy.result() * 100, test_loss.result(), test_accuracy.result() * 100)) if test_loss.result() < best_test_loss: best_test_loss = test_loss.result() model.save_weights("./save_weights/resNet_50.ckpt", save_format="tf")
def main(args=None): parser = argparse.ArgumentParser( description='Simple training script for training a RetinaNet network.') parser.add_argument('--dataset', help='Dataset type, must be one of csv or coco.') parser.add_argument('--coco_path', help='Path to COCO directory') parser.add_argument( '--csv_train', help='Path to file containing training annotations (see readme)') parser.add_argument('--csv_classes_general', help='Path to file containing class list (see readme)') parser.add_argument('--csv_features', help='Path to dir containing features csv files') parser.add_argument('--csv_colors', help='Path to file containing color classes') parser.add_argument('--csv_types', help='Path to file containing type classes') parser.add_argument( '--csv_val', help= 'Path to file containing validation annotations (optional, see readme)' ) parser.add_argument( '--image_dir', help='Path to file containing images (optional, see readme)') parser.add_argument('--pretrain_model', help='Path to model (.pt) file.') parser.add_argument( '--depth', help='Resnet depth, must be one of 18, 34, 50, 101, 152', type=int, default=50) parser.add_argument('--epochs', help='Number of epochs', type=int, default=100) parser = parser.parse_args(args) # Create the data loaders if parser.dataset == 'csv': if parser.csv_train is None: raise ValueError('Must provide --csv_train when training on COCO,') if parser.csv_classes_general is None: raise ValueError( 'Must provide --csv_classes_general when training on COCO,') dataset_train = CSVDataset(train_file=parser.csv_train, class_list=parser.csv_classes_general, color_classes=parser.csv_colors, type_classes=parser.csv_types, feature_class_dir=parser.csv_features, image_dir=parser.image_dir, transform=transforms.Compose( [Normalizer(), Augmenter(), Resizer()])) if parser.csv_val is None: dataset_val = None print('No validation annotations provided.') else: dataset_val = CSVDataset(train_file=parser.csv_val, class_list=parser.csv_classes_general, transform=transforms.Compose( [Normalizer(), Resizer()])) else: raise ValueError( 'Dataset type not understood (must be csv or coco), exiting.') sampler = AspectRatioBasedSampler(dataset_train, batch_size=2, drop_last=False) dataloader_train = DataLoader(dataset_train, num_workers=3, collate_fn=collater, batch_sampler=sampler) if dataset_val is not None: sampler_val = AspectRatioBasedSampler(dataset_val, batch_size=1, drop_last=False) dataloader_val = DataLoader(dataset_val, num_workers=3, collate_fn=collater, batch_sampler=sampler_val) # Create the model if parser.depth == 18: retinanet = model.resnet18(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 34: retinanet = model.resnet34(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 50: retinanet = model.resnet50(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 101: retinanet = model.resnet101(num_classes=dataset_train.num_classes(), pretrained=True) elif parser.depth == 152: retinanet = model.resnet152(num_classes=dataset_train.num_classes(), pretrained=True) else: raise ValueError( 'Unsupported model depth, must be one of 18, 34, 50, 101, 152') use_gpu = True if use_gpu: # retinanet = nn.DataParallel(retinanet) # torch.cuda.set_device(0) retinanet = retinanet.cuda() retinanet = torch.nn.DataParallel(retinanet).cuda() retinanet.training = True if parser.pretrain_model is not None: retinanet = torch.load(parser.pretrain_model) print('load model: ' + str(parser.pretrain_model)) optimizer = optim.Adam(retinanet.parameters(), lr=1e-5) scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, patience=3, verbose=True) loss_hist = collections.deque(maxlen=500) retinanet.train() retinanet.module.freeze_bn() print('Num training images: {}'.format(len(dataset_train))) for epoch_num in range(parser.epochs): retinanet.train() retinanet.module.freeze_bn() epoch_loss = [] for iter_num, data in enumerate(dataloader_train): try: optimizer.zero_grad() classification_loss, regression_loss = retinanet( [data['img'].cuda().float(), data['annot']]) classification_loss = classification_loss.mean() regression_loss = regression_loss.mean() loss = classification_loss + regression_loss if bool(loss == 0): continue loss.backward() torch.nn.utils.clip_grad_norm_(retinanet.parameters(), 0.1) optimizer.step() loss_hist.append(float(loss)) epoch_loss.append(float(loss)) print( 'Epoch: {} | Iteration: {} | Classification loss: {:1.5f} | Regression loss: {:1.5f} | Running loss: {:1.5f}' .format(epoch_num, iter_num, float(classification_loss), float(regression_loss), np.mean(loss_hist))) del classification_loss del regression_loss except Exception as e: print(e) continue if parser.dataset == 'coco': print('Evaluating dataset') coco_eval.evaluate_coco(dataset_val, retinanet) elif parser.dataset == 'csv' and parser.csv_val is not None: print('Evaluating dataset') mAP = csv_eval.evaluate(dataset_val, retinanet) scheduler.step(np.mean(epoch_loss)) torch.save(retinanet.module, '{}_retinanet_{}.pt'.format(parser.dataset, epoch_num)) retinanet.eval() torch.save(retinanet, 'model_final.pt'.format(epoch_num))
def main(args=None): parser = argparse.ArgumentParser( description='Simple training script for training a RetinaNet network.') parser.add_argument( '--csv_train', help='Path to file containing training annotations (see readme)') parser.add_argument('--csv_classes', help='Path to file containing class list (see readme)') parser.add_argument( '--csv_val', help= 'Path to file containing validation annotations (optional, see readme)' ) parser.add_argument( '--depth', help='Resnet depth, must be one of 18, 34, 50, 101, 152', type=int, default=50) parser.add_argument('--epochs', help='Number of epochs', type=int, default=50) parser.add_argument('--model_name', help='name of the model to save') parser.add_argument('--pretrained', help='pretrained model name') parser = parser.parse_args(args) # Create the data loaders dataset_train = CSVDataset(train_file=parser.csv_train, class_list=parser.csv_classes, transform=transforms.Compose( [Resizer(), Augmenter(), Normalizer()])) if parser.csv_val is None: dataset_val = None print('No validation annotations provided.') else: dataset_val = CSVDataset(train_file=parser.csv_val, class_list=parser.csv_classes, transform=transforms.Compose( [Resizer(), Normalizer()])) sampler = AspectRatioBasedSampler(dataset_train, batch_size=2, drop_last=False) dataloader_train = DataLoader(dataset_train, num_workers=16, collate_fn=collater, batch_sampler=sampler) #dataloader_train = DataLoader(dataset_train, num_workers=16, collate_fn=collater, batch_size=8, shuffle=True) if dataset_val is not None: sampler_val = AspectRatioBasedSampler(dataset_val, batch_size=2, drop_last=False) dataloader_val = DataLoader(dataset_val, num_workers=16, collate_fn=collater, batch_sampler=sampler_val) #dataloader_val = DataLoader(dataset_train, num_workers=16, collate_fn=collater, batch_size=8, shuffle=True) # Create the model_pose_level_attention if parser.depth == 18: retinanet = model.resnet18(num_classes=dataset_train.num_classes()) elif parser.depth == 34: retinanet = model.resnet34(num_classes=dataset_train.num_classes()) elif parser.depth == 50: retinanet = model.resnet50(num_classes=dataset_train.num_classes()) elif parser.depth == 101: retinanet = model.resnet101(num_classes=dataset_train.num_classes()) elif parser.depth == 152: retinanet = model.resnet152(num_classes=dataset_train.num_classes()) else: raise ValueError( 'Unsupported model depth, must be one of 18, 34, 50, 101, 152') if ckpt: retinanet = torch.load('') print('load ckpt') else: retinanet_dict = retinanet.state_dict() pretrained_dict = torch.load('./weight/' + parser.pretrained) pretrained_dict = { k: v for k, v in pretrained_dict.items() if k in retinanet_dict } retinanet_dict.update(pretrained_dict) retinanet.load_state_dict(retinanet_dict) print('load pretrained backbone') print(retinanet) retinanet = torch.nn.DataParallel(retinanet, device_ids=[0]) retinanet.cuda() retinanet.training = True optimizer = optim.Adam(retinanet.parameters(), lr=1e-5) #optimizer = optim.SGD(retinanet.parameters(), lr=1e-3, momentum=0.9, weight_decay=1e-4) scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, patience=3, verbose=True) #scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=20, gamma=0.1) loss_hist = collections.deque(maxlen=500) retinanet.train() retinanet.module.freeze_bn() print('Num training images: {}'.format(len(dataset_train))) f_map = open('./mAP_txt/' + parser.model_name + '.txt', 'a') writer = SummaryWriter(log_dir='./summary') iters = 0 for epoch_num in range(0, parser.epochs): retinanet.train() retinanet.module.freeze_bn() epoch_loss = [] #scheduler.step() for iter_num, data in enumerate(dataloader_train): iters += 1 optimizer.zero_grad() classification_loss, regression_loss, repgt_loss, repbox_loss = retinanet( [data['img'].cuda().float(), data['annot'], data['ignore']]) classification_loss = classification_loss.mean() regression_loss = regression_loss.mean() repgt_loss = repgt_loss.mean() repbox_loss = repbox_loss.mean() loss = classification_loss + regression_loss + 0.5 * repgt_loss + 0.5 * repbox_loss if bool(loss == 0): continue loss.backward() torch.nn.utils.clip_grad_norm_(retinanet.parameters(), 0.1) optimizer.step() loss_hist.append(float(loss)) epoch_loss.append(float(loss)) print( 'Epoch: {} | Iteration: {} | Classification loss: {:1.5f} | Regression loss: {:1.5f} | RepGT loss {:1.5f} | RepBox loss {:1.5f} | Running loss: {:1.5f}' .format(epoch_num, iter_num, float(classification_loss), float(regression_loss), float(repgt_loss), float(repbox_loss), np.mean(loss_hist))) writer.add_scalar('classification_loss', classification_loss, iters) writer.add_scalar('regression_loss', regression_loss, iters) writer.add_scalar('loss', loss, iters) del classification_loss del regression_loss if parser.csv_val is not None: print('Evaluating dataset') mAP = csv_eval.evaluate(dataset_val, retinanet) f_map.write('mAP:{}, epoch:{}'.format(mAP[0][0], epoch_num)) f_map.write('\n') scheduler.step(np.mean(epoch_loss)) torch.save(retinanet.module, './ckpt/' + parser.model_name + '_{}.pt'.format(epoch_num)) retinanet.eval() writer.export_scalars_to_json( "./summary/' + parser.pretrained + 'all_scalars.json") f_map.close() writer.close()