#compute loss loss = criterion(outputs, labels) #backward loss.backward() optimizer.step() total_loss += loss.item() #print log if (i + 1) & 100 == 0: print("epoch {}/{} - step: {}/{} - loss: {:.4f}".format( epoch, num_epochs, i, num_steps, total_loss / (i + 1))) #----Validation---- #set model to evaluating model.eval() val_losses = 0 with torch.no_grad(): correct = 0 total = 0 for _, (images, labels) in enumerate(val_loader): images, labels = images.to(device), labels.to(device) outputs = model(images) _, predicted = torch.max(outputs, 1) loss = criterion(outputs, labels)
def train(args): device = torch.device("cuda" if torch.cuda.is_available() else "cpu") print(device) renew_path(args.save) train_set = IkeaSet(TRAIN_MAT_PATH) train_loader = DataLoader(train_set, num_workers=4, pin_memory=True) test_set = IkeaSet(TEST_MAT_PATH) test_loader = DataLoader(test_set, num_workers=4, pin_memory=True) model = SimpleModel(n_class=len(train_set.classes)).to(device) model = load_model(model, 'model', args.save) optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # learing rate scheduler lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=20, gamma=0.5) loss_fn = F.cross_entropy # training log training_log = {} training_log['args'] = [] training_log['train_loss'] = [] training_log['val_loss'] = [] training_log['train_acc'] = [] training_log['val_acc'] = [] training_log['max_acc'] = 0.0 for epoch in range(1, args.epoch + 1): time_a = datetime.datetime.now() model.train() average_loss = 0 average_accuracy = 0 for i, batch in enumerate(train_loader, 1): batch[0].to(device), batch[1].to(device) label = batch[1] label = label.type(torch.cuda.LongTensor if torch.cuda.is_available() else torch.LongTensor) pred = model(batch[0]) loss = loss_fn(pred, label) print(pred) print(torch.argmax(pred, dim=1), label) acc = get_accuracy(label, pred) if i % 20 == 0: print('epoch{}, {}/{}, lost={:.4f} acc={:.4f}'.format(epoch, i, len(train_loader), loss.item(), acc)) average_loss = update_avg(i + 1, average_loss, loss.item()) average_accuracy = update_avg(i + 1, average_accuracy, acc) #optimizer.zero_grad() loss.backward() optimizer.step() lr_scheduler.step() embedding = None loss = None distanece = None model.eval() average_loss_val = 0 average_accuracy_val = 0 # evaluate after epoch. with torch.no_grad(): for i, batch in enumerate(test_loader, 1): batch[0].to(device), batch[1].to(device) label = batch[1] #label = query_y.type(torch.cuda.LongTensor if torch.cuda.is_available() else torch.LongTensor) label = label.type(torch.cuda.LongTensor if torch.cuda.is_available() else torch.LongTensor) pred = model(batch[0]) loss = loss_fn(pred, label) acc = get_accuracy(label, pred) average_loss_val = update_avg(i + 1, average_loss_val, loss.item()) average_accuracy_val = update_avg(i + 1, average_accuracy_val, acc) embedding = None loss = None distanece = None print("epoch {} validation: loss={:4f} acc={:4f}".format(epoch, average_loss, average_accuracy)) if average_accuracy > training_log['max_acc']: training_log['max_acc'] = acc save_model(model, 'max-acc', args.save) training_log['train_loss'].append(average_loss) training_log['train_acc'].append(average_accuracy) training_log['val_loss'].append(average_loss_val) training_log['val_acc'].append(average_accuracy_val) torch.save(training_log, os.path.join(args.save, 'training_log')) save_model(model, 'model', args.save) if epoch % 1 == 0: save_model(model, 'model', args.save) time_b = datetime.datetime.now() print('ETA:{}s/{}s'.format((time_b - time_a).seconds, (time_b - time_a).seconds * (args.epoch - epoch)))
def train(args): """ Terminology: k-way n-shot, k classes, n shots per class """ device = torch.device("cuda" if torch.cuda.is_available() else "cpu") print(device) renew_path(args.save) shots = args.shot + args.query train_set = IkeaSet(TRAIN_MAT_PATH) train_sampler = Sampler(train_set.label, args.batch_num_train, args.train_way, shots, limit_class=args.limit_class) train_loader = DataLoader(train_set, batch_sampler=train_sampler, num_workers=4, pin_memory=True) test_set = IkeaSet(TEST_MAT_PATH) test_sampler = Sampler(test_set.label, args.batch_num_test, args.test_way, shots, limit_class=args.limit_class) test_loader = DataLoader(test_set, batch_sampler=test_sampler, num_workers=4, pin_memory=True) model = SimpleModel().to(device) model = load_model(model, 'model', args.save) optimizer = torch.optim.Adam(model.parameters(), lr=0.001) # learing rate scheduler lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=20, gamma=0.5) loss_fn = F.cross_entropy # training log training_log = {} training_log['args'] = [] training_log['train_loss'] = [] training_log['val_loss'] = [] training_log['train_acc'] = [] training_log['val_acc'] = [] training_log['max_acc'] = 0.0 for epoch in range(1, args.epoch + 1): time_a = datetime.datetime.now() model.train() average_loss = 0 average_accuracy = 0 print("Start epoch: ", epoch) for i, batch in enumerate(train_loader, 1): num = args.shot * args.train_way support_x, query_x = batch[0][:num].to(device), batch[0][num:].to( device) #support_y, query_y = batch[1][:num], batch[1][num:] #print(support_x.shape) embedding = model(support_x.float()) # Get the mean of all the embeddings to get the prototype for a class embedding = embedding.reshape(args.shot, args.train_way, -1).mean(dim=0) #print(batch[0].shape) # Tough it seems strange here to just use labels in range but instead of real lables # , but that is beacause of the way the data was sampled (see sampled.py for structure # of a batch). The real label of the data does not correspond to the index of the closest # cluster center since the samples in the batch are shuffled, so instead we transform the data # label into the relative index in the range of classes, in this way the closest cluster # center index matches the relative index. label = torch.arange(args.train_way).repeat(args.query) #label = query_y.type(torch.cuda.LongTensor if torch.cuda.is_available() else torch.LongTensor) label = label.type(torch.cuda.LongTensor if torch.cuda. is_available() else torch.LongTensor) distance = euclidean(model(query_x), embedding) prob = F.softmax(distance, dim=1) loss = loss_fn(prob, label) acc = get_accuracy(label, prob) if i % 30 == 0: print(label.shape, distance.shape) print('epoch{}, {}/{}, lost={:.4f} acc={:.4f}'.format( epoch, i, len(train_loader), loss.item(), acc)) average_loss = update_avg(i + 1, average_loss, loss.item()) average_accuracy = update_avg(i + 1, average_accuracy, acc) #optimizer.zero_grad() loss.backward() optimizer.step() lr_scheduler.step() embedding = None loss = None distanece = None model.eval() average_loss_val = 0 average_accuracy_val = 0 # evaluate after epoch. with torch.no_grad(): for i, batch in enumerate(test_loader, 1): num = args.shot * args.test_way support_x, query_x = batch[0][:num].to( device), batch[0][num:].to(device) #support_y, query_y = batch[1][:num], batch[1][num:] embedding = model(support_x) embedding = embedding.reshape(args.shot, args.test_way, -1).mean(dim=0) label = torch.arange(args.train_way).repeat(args.query) #label = query_y.type(torch.cuda.LongTensor if torch.cuda.is_available() else torch.LongTensor) label = label.type(torch.cuda.LongTensor if torch.cuda. is_available() else torch.LongTensor) distance = euclidean(model(query_x), embedding) prob = F.softmax(distance, dim=1) loss = loss_fn(prob, label) acc = get_accuracy(label, prob) average_loss_val = update_avg(i + 1, average_loss_val, loss.item()) average_accuracy_val = update_avg(i + 1, average_accuracy_val, acc) embedding = None loss = None distanece = None print("epoch {} validation: loss={:4f} acc={:4f}".format( epoch, average_loss, average_accuracy)) if average_accuracy > training_log['max_acc']: training_log['max_acc'] = acc save_model(model, 'max-acc', args.save) training_log['train_loss'].append(average_loss) training_log['train_acc'].append(average_accuracy) training_log['val_loss'].append(average_loss_val) training_log['val_acc'].append(average_accuracy_val) torch.save(training_log, os.path.join(args.save, 'training_log')) save_model(model, 'model', args.save) if epoch % 1 == 0: save_model(model, 'model', args.save) time_b = datetime.datetime.now() print('ETA:{}s/{}s'.format( (time_b - time_a).seconds, (time_b - time_a).seconds * (args.epoch - epoch)))
train_loss_total = 0 for data, target in train_loader: data, target = data.to(device), target.float().to(device) optimizer.zero_grad() output = model_pytorch(data) train_loss = criterion(output, target) train_loss.backward() optimizer.step() train_loss_total += train_loss.item() * data.size(0) print('Epoch {} completed. Train loss is {:.3f}'.format(epoch + 1, train_loss_total / train_size)) print('Time taken to completed {} epochs: {:.2f} minutes'.format(num_epochs, (time.time() - time_start) / 60)) # Evaluate model model_pytorch.eval() test_loss_total = 0 total_num_corrects = 0 threshold = 0.5 time_start = time.time() for data, target in test_loader: data, target = data.to(device), target.float().to(device) optimizer.zero_grad() output = model_pytorch(data) train_loss = criterion(output, target) train_loss.backward() optimizer.step() train_loss_total += train_loss.item() * data.size(0)