def create_submission(path_to_files): df = pd.read_csv(path_to_files + '/meta/meta.txt', header=None, sep='\t', names=['id', 'c1', 'c2', 'c3', 'label'], usecols=['id', 'label']) test_path = path_to_files + '/test/' files = glob(test_path + '*.wav') test_dataset = FullClipDataset(files, df=df, skip_unknonw=False, transforms=DataToMelSpectrogram()) checkpoint = torch.load('checkpoints/ckpt.pth') device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = vgg16_bn(pretrained=False, in_channels=1, num_classes=len(Meta.classes)).to(device) model.load_state_dict(checkpoint['state_dict']) model.float() model.eval() with open('result.txt', "w+") as csv_file: writer = csv.writer(csv_file, delimiter='\t') for sample in test_dataset: splits = sample['input'].to(device) outputs = model(splits) outputs = torch.mean(outputs, dim=0) outputs = F.softmax(outputs) score = outputs.data.max() prediction = outputs.data.argmax() writer.writerow([ sample['name'], '%.3f' % round(score.item(), 3), Meta.classes[prediction] ])
def train(path_to_files): batch_size = 128 learning_rate = 1e-4 weight_decay = 1e-2 criterion = torch.nn.CrossEntropyLoss() device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = vgg16_bn(pretrained=False, in_channels=1, num_classes=len(Meta.classes)).to(device) optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate, momentum=0.9, weight_decay=weight_decay) start_epoch = 0 lr_scheduler_patience = 10 lr_scheduler_gamma = 0.1 lr_scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau( optimizer, patience=lr_scheduler_patience, factor=lr_scheduler_gamma) def get_lr(): return optimizer.param_groups[0]['lr'] writer = SummaryWriter() df = pd.read_csv(path_to_files + '/meta/meta.txt', header=None, sep='\t', names=['id', 'c1', 'c2', 'c3', 'label'], usecols=['id', 'label']) train_dataset = AudioSamplesDataset(glob(path_to_files + '/audio/*.wav'), df=df, transforms=ToMelSpectrogram()) weights = train_dataset.make_weights_for_balanced_classes() sampler = WeightedRandomSampler(weights, len(weights)) train_dataloader = DataLoader(train_dataset, batch_size=batch_size, sampler=sampler, num_workers=2) test_path = path_to_files + '/test/' files = [ test_path + f for f in os.listdir(test_path) if not re.search(r'unknown.*\.wav$', f) ] test_dataset = AudioSamplesDataset(files, df=df, transforms=ToMelSpectrogram()) test_dataloader = DataLoader(test_dataset, batch_size=batch_size, num_workers=2) def run_train_epoch(epoch): global global_step print("epoch %3d with lr=%.02e" % (epoch, get_lr())) phase = 'train' writer.add_scalar('%s/learning_rate' % phase, get_lr(), epoch) model.train() # Set model to training mode running_loss = 0.0 it = 0 correct = 0 total = 0 pbar = tqdm(train_dataloader, unit="audios", unit_scale=train_dataloader.batch_size) for batch in pbar: inputs = batch['input'].to(device) targets = batch['target'].to(device) outputs = model(inputs) loss = criterion(outputs, targets) optimizer.zero_grad() loss.backward() optimizer.step() # statistics it += 1 global_step += 1 running_loss += loss.data[0] pred = outputs.data.max(1, keepdim=True)[1] correct += pred.eq(targets.data.view_as(pred)).sum() total += targets.size(0) writer.add_scalar('%s/loss' % phase, loss.data[0], global_step) # update the progress bar pbar.set_postfix({ 'loss': "%.05f" % (running_loss / it), 'acc': "%.02f%%" % (100 * correct / total) }) accuracy = correct / total epoch_loss = running_loss / it writer.add_scalar('%s/accuracy' % phase, 100 * accuracy, epoch) writer.add_scalar('%s/epoch_loss' % phase, epoch_loss, epoch) def validate_on_test_set(epoch): global best_loss, global_step phase = 'valid' model.eval() running_loss = 0.0 it = 0 correct = 0 total = 0 pbar = tqdm(test_dataloader, unit="audios", unit_scale=test_dataloader.batch_size) for batch in pbar: inputs = batch['input'].to(device) targets = batch['target'].to(device) outputs = model(inputs) loss = criterion(outputs, targets) # statistics it += 1 global_step += 1 running_loss += loss.data[0] pred = outputs.data.max(1, keepdim=True)[1] correct += pred.eq(targets.data.view_as(pred)).sum() total += targets.size(0) writer.add_scalar('%s/loss' % phase, loss.data[0], global_step) # update the progress bar pbar.set_postfix({ 'loss': "%.05f" % (running_loss / it), 'acc': "%.02f%%" % (100 * correct / total) }) accuracy = correct / total epoch_loss = running_loss / it writer.add_scalar('%s/accuracy' % phase, 100 * accuracy, epoch) writer.add_scalar('%s/epoch_loss' % phase, epoch_loss, epoch) checkpoint = { 'epoch': epoch, 'step': global_step, 'state_dict': model.state_dict(), 'loss': epoch_loss, 'accuracy': accuracy, 'optimizer': optimizer.state_dict(), } if epoch_loss < best_loss: best_loss = epoch_loss torch.save(checkpoint, 'checkpoints/ckpt.pth') del checkpoint return epoch_loss for epoch in range(start_epoch, 70): run_train_epoch(epoch) epoch_loss = validate_on_test_set(epoch) lr_scheduler.step(metrics=epoch_loss)
def main(): # LOAD DATASET stat_file = args.stat_file with open(stat_file, 'r') as f: data = pickle.load(f) mean, std = data['mean'], data['std'] mean = [float(m) for m in mean] std = [float(s) for s in std] normalize = transforms.Normalize(mean=mean, std=std) img_transform = transforms.Compose( [transforms.Resize((224, 224)), transforms.ToTensor(), normalize]) if args.shape_dataset: classes = ['shape'] dataset = ShapeDataset( root_dir='/export/home/kschwarz/Documents/Data/Geometric_Shapes', split=args.info_file, classes=classes, transform=img_transform) elif args.stl_dataset: dataset = STL(transform=img_transform, test='test' in args.info_file.split('/')[-1]) else: dataset = Wikiart(path_to_info_file=args.info_file, path_to_images=args.im_path, classes=['image_id'], transform=img_transform) # PARAMETERS use_cuda = args.use_gpu and torch.cuda.is_available() device_nb = args.device if use_cuda: torch.cuda.set_device(device_nb) # INITIALIZE NETWORK if args.model.lower() not in ['mobilenet_v2', 'vgg16_bn']: raise NotImplementedError( 'Unknown Model {}\n\t+ Choose from: [mobilenet_v2, vgg16_bn].'. format(args.model)) elif args.model.lower() == 'mobilenet_v2': featurenet = mobilenet_v2(pretrained=True) elif args.model.lower() == 'vgg16_bn': featurenet = vgg16_bn(pretrained=True) if args.not_narrow: net = featurenet else: net = narrownet(featurenet, dim_feature_out=args.feature_dim) if use_cuda: net = net.cuda() if args.weight_file is not None: remove_fc(net, inplace=True) else: make_featurenet(net, inplace=True) print('Extract features using {}.'.format(str(net))) if args.weight_file: pretrained_dict = load_weights(args.weight_file, net.state_dict(), prefix_file='bodynet.') net.load_state_dict(pretrained_dict) if use_cuda: net = net.cuda() kwargs = {'num_workers': 8} if use_cuda else {} loader = torch.utils.data.DataLoader(dataset, batch_size=args.batch_size, shuffle=False, **kwargs) net.eval() features = [] for i, data in enumerate(loader): if isinstance(data, tuple) or isinstance( data, list): # loader returns data, label data = data[0] if (i + 1) % 10 == 0: print('{}/{}'.format(i + 1, len(loader))) input = Variable(data, requires_grad=False) if not use_cuda else Variable( data.cuda(), requires_grad=False) output = net(input) features.append(output.data.cpu()) features = torch.cat(features) features = features.numpy() image_names = dataset.df['image_id'].values.astype(str) if not os.path.isdir(args.output_dir): os.makedirs(args.output_dir) expname = '' if args.exp_name is None else '_' + args.exp_name if args.shape_dataset: outfile = os.path.join( args.output_dir, 'ShapeDataset_' + str(net).split('(')[0] + '_' + args.info_file.split('/')[-1].split('.')[0] + expname + '.hdf5') elif args.office_dataset: outfile = os.path.join( args.output_dir, 'OfficeDataset_' + str(net).split('(')[0] + '_' + args.info_file.split('/')[-1].split('.')[0] + expname + '.hdf5') elif args.bam_dataset: outfile = os.path.join( args.output_dir, 'BAMDataset_' + str(net).split('(')[0] + '_' + args.info_file.split('/')[-1].split('.')[0] + expname + '.hdf5') elif args.stl_dataset: outfile = os.path.join( args.output_dir, 'STLDataset_' + str(net).split('(')[0] + '_' + args.info_file.split('/')[-1].split('.')[0] + expname + '.hdf5') else: outfile = os.path.join( args.output_dir, str(net).split('(')[0] + '_' + args.info_file.split('/')[-1].split('.')[0] + expname + '.hdf5') with h5py.File(outfile, 'w') as f: f.create_dataset('features', features.shape, dtype=features.dtype, data=features) f.create_dataset('image_names', image_names.shape, dtype=image_names.dtype, data=image_names) print('Saved features to {}'.format(outfile))
def main(): args.task_selection = args.task_selection.split(',') torch.manual_seed(args.seed) # LOAD DATASET stat_file = args.stat_file with open(stat_file, 'r') as f: data = pickle.load(f) mean, std = data['mean'], data['std'] mean = [float(m) for m in mean] std = [float(s) for s in std] normalize = transforms.Normalize(mean=mean, std=std) train_transform = transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.RandomRotation(90), transforms.ToTensor(), normalize, ]) val_transform = transforms.Compose([ transforms.Resize((224, 224)), transforms.ToTensor(), normalize, ]) if not args.shape_dataset: if args.task_selection is not None: classes = args.task_selection elif args.office_dataset: classes = ['style', 'genre'] elif args.bam_dataset: classes = ['content', 'emotion', 'media'] else: classes = ['artist_name', 'genre', 'style', 'technique', 'century'] valset = Wikiart(path_to_info_file=args.val_file, path_to_images=args.im_path, classes=classes, transform=val_transform) trainset = Wikiart(path_to_info_file=args.train_file, path_to_images=args.im_path, classes=classes, transform=train_transform) else: if args.task_selection is not None: classes = args.task_selection else: classes = ['shape', 'n_shapes', 'color_shape', 'color_background'] valset = ShapeDataset(root_dir='/export/home/kschwarz/Documents/Data/Geometric_Shapes', split='val', classes=classes, transform=val_transform) trainset = ShapeDataset(root_dir='/export/home/kschwarz/Documents/Data/Geometric_Shapes', split='train', classes=classes, transform=train_transform) if not trainset.labels_to_ints == valset.labels_to_ints: print('validation set and training set int labels do not match. Use int conversion of trainset') print(trainset.labels_to_ints, valset.labels_to_ints) valset.labels_to_ints = trainset.labels_to_ints.copy() num_labels = [len(trainset.labels_to_ints[c]) for c in classes] # PARAMETERS use_cuda = args.use_gpu and torch.cuda.is_available() device_nb = args.device if use_cuda: torch.cuda.set_device(device_nb) torch.cuda.manual_seed_all(args.seed) # INITIALIZE NETWORK if args.model.lower() not in ['mobilenet_v2', 'vgg16_bn']: raise NotImplementedError('Unknown Model {}\n\t+ Choose from: [mobilenet_v2, vgg16_bn].' .format(args.model)) elif args.model.lower() == 'mobilenet_v2': featurenet = mobilenet_v2(pretrained=True) elif args.model.lower() == 'vgg16_bn': featurenet = vgg16_bn(pretrained=True) if args.not_narrow: bodynet = featurenet else: bodynet = narrownet(featurenet, dim_feature_out=args.feature_dim) net = OctopusNet(bodynet, n_labels=num_labels) n_parameters = sum([p.data.nelement() for p in net.parameters() if p.requires_grad]) if use_cuda: net = net.cuda() print('Using {}\n\t+ Number of params: {}'.format(str(bodynet).split('(')[0], n_parameters)) # LOG/SAVE OPTIONS log_interval = args.log_interval log_dir = args.log_dir if not os.path.isdir(log_dir): os.makedirs(log_dir) # tensorboard summary writerR timestamp = time.strftime('%m-%d-%H-%M') if args.shape_dataset: expname = timestamp + '_ShapeDataset_' + str(bodynet).split('(')[0] else: expname = timestamp + '_' + str(bodynet).split('(')[0] if args.exp_name is not None: expname = expname + '_' + args.exp_name log = TBPlotter(os.path.join(log_dir, 'tensorboard', expname)) log.print_logdir() # allow auto-tuner to find best algorithm for the hardware cudnn.benchmark = True write_config(args, os.path.join(log_dir, expname)) # ININTIALIZE TRAINING optimizer = optim.SGD(net.parameters(), lr=args.lr, momentum=args.momentum) scheduler = optim.lr_scheduler.ReduceLROnPlateau(optimizer, 'min', patience=10, threshold=1e-1, verbose=True) criterion = nn.CrossEntropyLoss() if use_cuda: criterion = criterion.cuda() kwargs = {'num_workers': 8, 'pin_memory': True} if use_cuda else {} trainloader = DataLoader(trainset, batch_size=args.batch_size, shuffle=True, **kwargs) valloader = DataLoader(valset, batch_size=args.batch_size, shuffle=True, **kwargs) # optionally resume from a checkpoint start_epoch = 1 if args.chkpt is not None: if os.path.isfile(args.chkpt): print("=> loading checkpoint '{}'".format(args.chkpt)) checkpoint = torch.load(args.chkpt, map_location=lambda storage, loc: storage) start_epoch = checkpoint['epoch'] best_acc_score = checkpoint['best_acc_score'] best_acc = checkpoint['acc'] net.load_state_dict(checkpoint['state_dict']) optimizer.load_state_dict(checkpoint['optimizer']) scheduler.load_state_dict(checkpoint['scheduler']) print("=> loaded checkpoint '{}' (epoch {})" .format(args.chkpt, checkpoint['epoch'])) else: print("=> no checkpoint found at '{}'".format(args.chkpt)) def train(epoch): losses = AverageMeter() accs = AverageMeter() class_acc = [AverageMeter() for i in range(len(classes))] # switch to train mode net.train() for batch_idx, (data, target) in enumerate(trainloader): if use_cuda: data, target = Variable(data.cuda()), [Variable(t.cuda()) for t in target] else: data, target = Variable(data), [Variable(t) for t in target] # compute output outputs = net(data) preds = [torch.max(outputs[i], 1)[1] for i in range(len(classes))] loss = Variable(torch.Tensor([0])).type_as(data[0]) for i, o, t, p in zip(range(len(classes)), outputs, target, preds): # in case of None labels mask = t != -1 if mask.sum() == 0: continue o, t, p = o[mask], t[mask], p[mask] loss += criterion(o, t) # measure class accuracy and record loss class_acc[i].update((torch.sum(p == t).type(torch.FloatTensor) / t.size(0)).data) accs.update(torch.mean(torch.stack([class_acc[i].val for i in range(len(classes))])), target[0].size(0)) losses.update(loss.data, target[0].size(0)) # compute gradient and do optimizer step optimizer.zero_grad() loss.backward() optimizer.step() if batch_idx % log_interval == 0: print('Train Epoch: {} [{}/{}]\t' 'Loss: {:.4f} ({:.4f})\t' 'Acc: {:.2f}% ({:.2f}%)'.format( epoch, batch_idx * len(target), len(trainloader.dataset), float(losses.val), float(losses.avg), float(accs.val) * 100., float(accs.avg) * 100.)) print('\t' + '\n\t'.join(['{}: {:.2f}%'.format(classes[i], float(class_acc[i].val) * 100.) for i in range(len(classes))])) # log avg values to somewhere log.write('loss', float(losses.avg), epoch, test=False) log.write('acc', float(accs.avg), epoch, test=False) for i in range(len(classes)): log.write('class_acc', float(class_acc[i].avg), epoch, test=False) def test(epoch): losses = AverageMeter() accs = AverageMeter() class_acc = [AverageMeter() for i in range(len(classes))] # switch to evaluation mode net.eval() for batch_idx, (data, target) in enumerate(valloader): if use_cuda: data, target = Variable(data.cuda()), [Variable(t.cuda()) for t in target] else: data, target = Variable(data), [Variable(t) for t in target] # compute output outputs = net(data) preds = [torch.max(outputs[i], 1)[1] for i in range(len(classes))] loss = Variable(torch.Tensor([0])).type_as(data[0]) for i, o, t, p in zip(range(len(classes)), outputs, target, preds): # in case of None labels mask = t != -1 if mask.sum() == 0: continue o, t, p = o[mask], t[mask], p[mask] loss += criterion(o, t) # measure class accuracy and record loss class_acc[i].update((torch.sum(p == t).type(torch.FloatTensor) / t.size(0)).data) accs.update(torch.mean(torch.stack([class_acc[i].val for i in range(len(classes))])), target[0].size(0)) losses.update(loss.data, target[0].size(0)) score = accs.avg - torch.std(torch.stack([class_acc[i].avg for i in range( len(classes))])) / accs.avg # compute mean - std/mean as measure for accuracy print('\nVal set: Average loss: {:.4f} Average acc {:.2f}% Acc score {:.2f} LR: {:.6f}' .format(float(losses.avg), float(accs.avg) * 100., float(score), optimizer.param_groups[-1]['lr'])) print('\t' + '\n\t'.join(['{}: {:.2f}%'.format(classes[i], float(class_acc[i].avg) * 100.) for i in range(len(classes))])) log.write('loss', float(losses.avg), epoch, test=True) log.write('acc', float(accs.avg), epoch, test=True) for i in range(len(classes)): log.write('class_acc', float(class_acc[i].avg), epoch, test=True) return losses.avg.cpu().numpy(), float(score), float(accs.avg), [float(class_acc[i].avg) for i in range(len(classes))] if start_epoch == 1: # compute baseline: _, best_acc_score, best_acc, _ = test(epoch=0) else: # checkpoint was loaded best_acc_score = best_acc_score best_acc = best_acc for epoch in range(start_epoch, args.epochs + 1): # train for one epoch train(epoch) # evaluate on validation set val_loss, val_acc_score, val_acc, val_class_accs = test(epoch) scheduler.step(val_loss) # remember best acc and save checkpoint is_best = val_acc_score > best_acc_score best_acc_score = max(val_acc_score, best_acc_score) save_checkpoint({ 'epoch': epoch, 'state_dict': net.state_dict(), 'optimizer': optimizer.state_dict(), 'scheduler': scheduler.state_dict(), 'best_acc_score': best_acc_score, 'acc': val_acc, 'class_acc': {c: a for c, a in zip(classes, val_class_accs)} }, is_best, expname, directory=log_dir) if val_acc > best_acc: shutil.copyfile(os.path.join(log_dir, expname + '_checkpoint.pth.tar'), os.path.join(log_dir, expname + '_model_best_mean_acc.pth.tar')) best_acc = max(val_acc, best_acc) if optimizer.param_groups[-1]['lr'] < 1e-5: print('Learning rate reached minimum threshold. End training.') break # report best values try: best = torch.load(os.path.join(log_dir, expname + '_model_best.pth.tar'), map_location=lambda storage, loc: storage) except IOError: # could be only one task best = torch.load(os.path.join(log_dir, expname + '_model_best_mean_acc.pth.tar'), map_location=lambda storage, loc: storage) print('Finished training after epoch {}:\n\tbest acc score: {}\n\tacc: {}\n\t class acc: {}' .format(best['epoch'], best['best_acc_score'], best['acc'], best['class_acc'])) print('Best model mean accuracy: {}'.format(best_acc)) try: shutil.copyfile(os.path.join(log_dir, expname + '_model_best.pth.tar'), os.path.join('models', expname + '_model_best.pth.tar')) except IOError: # could be only one task shutil.copyfile(os.path.join(log_dir, expname + '_model_best_mean_acc.pth.tar'), os.path.join('models', expname + '_model_best.pth.tar'))
epochs = 500 batch_size = 2 train_data_path = '../../../data/face_data' train_dataset = FER(train_data_path, image_size=64, mode='train') train_dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True) valid_data_path = '../../../data/face_data' valid_dataset = FER(valid_data_path, image_size=64, mode='val') valid_dataloader = DataLoader(valid_dataset, batch_size=batch_size, shuffle=False) model = md.vgg16_bn(num_classes=3).to(device) # model_name = 'vgg16' # feature_extract = True # num_classes = 3 # model = md.init_pretrained_models(model_name, num_classes, feature_extract, use_pretrained=True) model.to(device) criterion = torch.nn.CrossEntropyLoss().to(device) optimizer = torch.optim.Adam(params=model.parameters(), lr=lr) ... for epoch in range(epochs): running_loss = 0 running_acc = 0 train_loss = 0