def main(options): DTYPE = torch.FloatTensor LONG = torch.LongTensor # parse the input args epochs = options['epochs'] data_path = options['data_path'] model_path = options['model_path'] output_path = options['output_path'] signiture = options['signiture'] patience = options['patience'] emotion = options['emotion'] output_dim = options['output_dim'] # prepare the paths for storing models and outputs model_path = os.path.join(model_path, "model_{}_{}.pt".format(signiture, emotion)) output_path = os.path.join(output_path, "results_{}_{}.csv".format(signiture, emotion)) print("Temp location for models: {}".format(model_path)) print("Grid search results are in: {}".format(output_path)) os.makedirs(os.path.dirname(output_path), exist_ok=True) os.makedirs(os.path.dirname(model_path), exist_ok=True) train_set, valid_set, test_set, input_dims = load_iemocap( data_path, emotion) params = dict() params['audio_hidden'] = [8, 16, 32] params['video_hidden'] = [4, 8, 16] params['text_hidden'] = [64, 128, 256] params['audio_dropout'] = [0, 0.1, 0.15, 0.2, 0.3, 0.5] params['video_dropout'] = [0, 0.1, 0.15, 0.2, 0.3, 0.5] params['text_dropout'] = [0, 0.1, 0.15, 0.2, 0.3, 0.5] params['factor_learning_rate'] = [0.0003, 0.0005, 0.001, 0.003] params['learning_rate'] = [0.0003, 0.0005, 0.001, 0.003] params['rank'] = [1, 4, 8, 16] params['batch_size'] = [8, 16, 32, 64, 128] params['weight_decay'] = [0, 0.001, 0.002, 0.01] total_settings = total(params) print("There are {} different hyper-parameter settings in total.".format( total_settings)) seen_settings = set() if not os.path.isfile(output_path): with open(output_path, 'w+') as out: writer = csv.writer(out) writer.writerow([ "audio_hidden", "video_hidden", 'text_hidden', 'audio_dropout', 'video_dropout', 'text_dropout', 'factor_learning_rate', 'learning_rate', 'rank', 'batch_size', 'weight_decay', 'Best Validation CrossEntropyLoss', 'Test CrossEntropyLoss', 'Test F1-score', 'Test Accuracy Score' ]) for i in range(total_settings): ahid = random.choice(params['audio_hidden']) vhid = random.choice(params['video_hidden']) thid = random.choice(params['text_hidden']) thid_2 = thid // 2 adr = random.choice(params['audio_dropout']) vdr = random.choice(params['video_dropout']) tdr = random.choice(params['text_dropout']) factor_lr = random.choice(params['factor_learning_rate']) lr = random.choice(params['learning_rate']) r = random.choice(params['rank']) batch_sz = random.choice(params['batch_size']) decay = random.choice(params['weight_decay']) # reject the setting if it has been tried current_setting = (ahid, vhid, thid, adr, vdr, tdr, factor_lr, lr, r, batch_sz, decay) if current_setting in seen_settings: continue else: seen_settings.add(current_setting) model = LMF(input_dims, (ahid, vhid, thid), thid_2, (adr, vdr, tdr, 0.5), output_dim, r) if options['cuda']: model = model.cuda() DTYPE = torch.cuda.FloatTensor LONG = torch.cuda.LongTensor print("Model initialized") criterion = nn.CrossEntropyLoss(size_average=False) factors = list(model.parameters())[:3] other = list(model.parameters())[3:] optimizer = optim.Adam([{ "params": factors, "lr": factor_lr }, { "params": other, "lr": lr }], weight_decay=decay) # setup training complete = True min_valid_loss = float('Inf') train_iterator = DataLoader(train_set, batch_size=batch_sz, num_workers=4, shuffle=True) valid_iterator = DataLoader(valid_set, batch_size=len(valid_set), num_workers=4, shuffle=True) test_iterator = DataLoader(test_set, batch_size=len(test_set), num_workers=4, shuffle=True) curr_patience = patience for e in range(epochs): model.train() model.zero_grad() avg_train_loss = 0.0 for batch in train_iterator: model.zero_grad() x = batch[:-1] x_a = Variable(x[0].float().type(DTYPE), requires_grad=False) x_v = Variable(x[1].float().type(DTYPE), requires_grad=False) x_t = Variable(x[2].float().type(DTYPE), requires_grad=False) y = Variable(batch[-1].view(-1, output_dim).float().type(LONG), requires_grad=False) try: output = model(x_a, x_v, x_t) except ValueError as e: print(x_a.data.shape) print(x_v.data.shape) print(x_t.data.shape) raise e loss = criterion(output, torch.max(y, 1)[1]) loss.backward() avg_loss = loss.data[0] avg_train_loss += avg_loss / len(train_set) optimizer.step() print("Epoch {} complete! Average Training loss: {}".format( e, avg_train_loss)) # Terminate the training process if run into NaN if np.isnan(avg_train_loss): print("Training got into NaN values...\n\n") complete = False break model.eval() for batch in valid_iterator: x = batch[:-1] x_a = Variable(x[0].float().type(DTYPE), requires_grad=False) x_v = Variable(x[1].float().type(DTYPE), requires_grad=False) x_t = Variable(x[2].float().type(DTYPE), requires_grad=False) y = Variable(batch[-1].view(-1, output_dim).float().type(LONG), requires_grad=False) output = model(x_a, x_v, x_t) valid_loss = criterion(output, torch.max(y, 1)[1]) avg_valid_loss = valid_loss.data[0] y = y.cpu().data.numpy().reshape(-1, output_dim) if np.isnan(avg_valid_loss): print("Training got into NaN values...\n\n") complete = False break avg_valid_loss = avg_valid_loss / len(valid_set) print("Validation loss is: {}".format(avg_valid_loss)) if (avg_valid_loss < min_valid_loss): curr_patience = patience min_valid_loss = avg_valid_loss torch.save(model, model_path) print("Found new best model, saving to disk...") else: curr_patience -= 1 if curr_patience <= 0: break print("\n\n") if complete: best_model = torch.load(model_path) best_model.eval() for batch in test_iterator: x = batch[:-1] x_a = Variable(x[0].float().type(DTYPE), requires_grad=False) x_v = Variable(x[1].float().type(DTYPE), requires_grad=False) x_t = Variable(x[2].float().type(DTYPE), requires_grad=False) y = Variable(batch[-1].view(-1, output_dim).float().type(LONG), requires_grad=False) output_test = model(x_a, x_v, x_t) loss_test = criterion(output_test, torch.max(y, 1)[1]) test_loss = loss_test.data[0] output_test = output_test.cpu().data.numpy().reshape( -1, output_dim) y = y.cpu().data.numpy().reshape(-1, output_dim) test_loss = test_loss / len(test_set) # these are the needed metrics all_true_label = np.argmax(y, axis=1) all_predicted_label = np.argmax(output_test, axis=1) f1 = f1_score(all_true_label, all_predicted_label, average='weighted') acc_score = accuracy_score(all_true_label, all_predicted_label) display(f1, acc_score) with open(output_path, 'a+') as out: writer = csv.writer(out) writer.writerow([ ahid, vhid, thid, adr, vdr, tdr, factor_lr, lr, r, batch_sz, decay, min_valid_loss.cpu().data.numpy(), test_loss.cpu().data.numpy(), f1, acc_score ])
def main(options): DTYPE = torch.FloatTensor # parse the input args run_id = options['run_id'] epochs = options['epochs'] data_path = options['data_path'] model_path = options['model_path'] output_path = options['output_path'] signiture = options['signiture'] patience = options['patience'] output_dim = options['output_dim'] print("Training initializing... Setup ID is: {}".format(run_id)) # prepare the paths for storing models and outputs model_path = os.path.join(model_path, "model_{}_{}.pt".format(signiture, run_id)) output_path = os.path.join(output_path, "results_{}_{}.csv".format(signiture, run_id)) print("Temp location for models: {}".format(model_path)) print("Grid search results are in: {}".format(output_path)) train_set, valid_set, test_set, input_dims = load_pom(data_path) params = dict() params['audio_hidden'] = [4, 8, 16] params['video_hidden'] = [4, 8, 16] params['text_hidden'] = [64, 128, 256] params['audio_dropout'] = [0, 0.1, 0.15, 0.2, 0.3, 0.5] params['video_dropout'] = [0, 0.1, 0.15, 0.2, 0.3, 0.5] params['text_dropout'] = [0, 0.1, 0.15, 0.2, 0.3, 0.5] params['factor_learning_rate'] = [0.0003, 0.0005, 0.001, 0.003] params['learning_rate'] = [0.0003, 0.0005, 0.001, 0.003] params['rank'] = [1, 4, 8, 16] params['batch_size'] = [4, 8, 16, 32, 64, 128] params['weight_decay'] = [0, 0.001, 0.002, 0.01] total_settings = total(params) print("There are {} different hyper-parameter settings in total.".format( total_settings)) seen_settings = set() with open(output_path, 'w+') as out: writer = csv.writer(out) writer.writerow([ "audio_hidden", "video_hidden", 'text_hidden', 'audio_dropout', 'video_dropout', 'text_dropout', 'factor_learning_rate', 'learning_rate', 'rank', 'batch_size', 'weight_decay', 'Best Validation MAE', 'Confidence accuracy', 'Passionate accuracy', 'Pleasant accuracy', 'Dominant accuracy', 'Credible accuracy', 'Vivid accuracy', 'Expertise accuracy', 'Entertaining accuracy', 'Reserved accuracy', 'Trusting accuracy', 'Relaxed accuracy', 'Outgoing accuracy', 'Thorough accuracy', 'Nervous accuracy', 'Persuasive accuracy', 'Humorous accuracy', 'Confidence MAE', 'Passionate MAE', 'Pleasant MAE', 'Dominant MAE', 'Credible MAE', 'Vivid MAE', 'Expertise MAE', 'Entertaining MAE', 'Reserved MAE', 'Trusting MAE', 'Relaxed MAE', 'Outgoing MAE', 'Thorough MAE', 'Nervous MAE', 'Persuasive MAE', 'Humorous MAE', 'Confidence corr', 'Passionate corr', 'Pleasant corr', 'Dominant corr', 'Credible corr', 'Vivid corr', 'Expertise corr', 'Entertaining corr', 'Reserved corr', 'Trusting corr', 'Relaxed corr', 'Outgoing corr', 'Thorough corr', 'Nervous corr', 'Persuasive corr', 'Humorous corr' ]) for i in range(total_settings): ahid = random.choice(params['audio_hidden']) vhid = random.choice(params['video_hidden']) thid = random.choice(params['text_hidden']) thid_2 = thid / 2 adr = random.choice(params['audio_dropout']) vdr = random.choice(params['video_dropout']) tdr = random.choice(params['text_dropout']) factor_lr = random.choice(params['factor_learning_rate']) lr = random.choice(params['learning_rate']) r = random.choice(params['rank']) batch_sz = random.choice(params['batch_size']) decay = random.choice(params['weight_decay']) # reject the setting if it has been tried current_setting = (ahid, vhid, thid, adr, vdr, tdr, factor_lr, lr, r, batch_sz, decay) if current_setting in seen_settings: continue else: seen_settings.add(current_setting) model = LMF(input_dims, (ahid, vhid, thid), thid_2, (adr, vdr, tdr, 0.5), output_dim, r) if options['cuda']: model = model.cuda() DTYPE = torch.cuda.FloatTensor print("Model initialized") criterion = nn.L1Loss(size_average=False) factors = list(model.parameters())[:3] other = list(model.parameters())[5:] optimizer = optim.Adam( [{ "params": factors, "lr": factor_lr }, { "params": other, "lr": lr }], weight_decay=decay ) # don't optimize the first 2 params, they should be fixed (output_range and shift) # setup training complete = True min_valid_loss = float('Inf') train_iterator = DataLoader(train_set, batch_size=batch_sz, num_workers=4, shuffle=True) valid_iterator = DataLoader(valid_set, batch_size=len(valid_set), num_workers=4, shuffle=True) test_iterator = DataLoader(test_set, batch_size=len(test_set), num_workers=4, shuffle=True) curr_patience = patience for e in range(epochs): model.train() model.zero_grad() avg_train_loss = 0.0 for batch in train_iterator: model.zero_grad() x = batch[:-1] x_a = Variable(x[0].float().type(DTYPE), requires_grad=False) x_v = Variable(x[1].float().type(DTYPE), requires_grad=False) x_t = Variable(x[2].float().type(DTYPE), requires_grad=False) y = Variable(batch[-1].view(-1, output_dim).float().type(DTYPE), requires_grad=False) output = model(x_a, x_v, x_t) loss = criterion(output, y) loss.backward() avg_loss = loss.data[0] / float(output_dim) avg_train_loss += avg_loss / len(train_set) optimizer.step() print("Epoch {} complete! Average Training loss: {}".format( e, avg_train_loss)) # Terminate the training process if run into NaN if np.isnan(avg_train_loss): print("Training got into NaN values...\n\n") complete = False break model.eval() for batch in valid_iterator: x = batch[:-1] x_a = Variable(x[0].float().type(DTYPE), requires_grad=False) x_v = Variable(x[1].float().type(DTYPE), requires_grad=False) x_t = Variable(x[2].float().type(DTYPE), requires_grad=False) y = Variable(batch[-1].view(-1, output_dim).float().type(DTYPE), requires_grad=False) output = model(x_a, x_v, x_t) valid_loss = criterion(output, y) avg_valid_loss = valid_loss.data[0] / float(output_dim) y = y.cpu().data.numpy().reshape(-1, output_dim) if np.isnan(avg_valid_loss): print("Training got into NaN values...\n\n") complete = False break avg_valid_loss = avg_valid_loss / len(valid_set) print("Validation loss is: {}".format(avg_valid_loss)) if (avg_valid_loss < min_valid_loss): curr_patience = patience min_valid_loss = avg_valid_loss torch.save(model, model_path) print("Found new best model, saving to disk...") else: curr_patience -= 1 if curr_patience <= 0: break print("\n\n") if complete: best_model = torch.load(model_path) best_model.eval() for batch in test_iterator: x = batch[:-1] x_a = Variable(x[0].float().type(DTYPE), requires_grad=False) x_v = Variable(x[1].float().type(DTYPE), requires_grad=False) x_t = Variable(x[2].float().type(DTYPE), requires_grad=False) y = Variable(batch[-1].view(-1, output_dim).float().type(DTYPE), requires_grad=False) output_test = best_model(x_a, x_v, x_t) loss_test = criterion(output_test, y) test_loss = loss_test.data[0] avg_test_loss = test_loss / float(output_dim) output_test = output_test.cpu().data.numpy().reshape( -1, output_dim) y = y.cpu().data.numpy().reshape(-1, output_dim) # these are the needed metrics mae = np.mean(np.absolute(output_test - y), axis=0) mae = [round(a, 3) for a in mae] corr = [ round(np.corrcoef(output_test[:, i], y[:, i])[0][1], 3) for i in xrange(y.shape[1]) ] mult_acc = [ round( sum(np.round(output_test[:, i]) == np.round(y[:, i])) / float(len(y)), 3) for i in xrange(y.shape[1]) ] display(mae, corr, mult_acc) results = [ ahid, vhid, thid, adr, vdr, tdr, factor_lr, lr, r, batch_sz, decay, min_valid_loss.cpu().data.numpy() ] results.extend(mult_acc) results.extend(mae) results.extend(corr) with open(output_path, 'a+') as out: writer = csv.writer(out) writer.writerow(results)
def main(options): DTYPE = torch.FloatTensor # parse the input args run_id = options['run_id'] epochs = options['epochs'] data_path = options['data_path'] model_path = options['model_path'] output_path = options['output_path'] signiture = options['signiture'] patience = options['patience'] output_dim = options['output_dim'] print("Training initializing... Setup ID is: {}".format(run_id)) # prepare the paths for storing models and outputs model_path = os.path.join(model_path, "model_{}_{}.pt".format(signiture, run_id)) output_path = os.path.join(output_path, "results_{}_{}.csv".format(signiture, run_id)) print("Temp location for models: {}".format(model_path)) print("Grid search results are in: {}".format(output_path)) os.makedirs(os.path.dirname(output_path), exist_ok=True) os.makedirs(os.path.dirname(model_path), exist_ok=True) train_set, valid_set, test_set, input_dims = load_mosi(data_path) params = dict() params['audio_hidden'] = [4, 8, 16] params['video_hidden'] = [4, 8, 16] params['text_hidden'] = [64, 128, 256] params['audio_dropout'] = [0, 0.1, 0.15, 0.2, 0.3, 0.5] params['video_dropout'] = [0, 0.1, 0.15, 0.2, 0.3, 0.5] params['text_dropout'] = [0, 0.1, 0.15, 0.2, 0.3, 0.5] params['factor_learning_rate'] = [0.0003, 0.0005, 0.001, 0.003] params['learning_rate'] = [0.0003, 0.0005, 0.001, 0.003] params['rank'] = [1, 4, 8, 16] params['batch_size'] = [4, 8, 16, 32, 64, 128] params['weight_decay'] = [0, 0.001, 0.002, 0.01] total_settings = total(params) ## wyw 8957952 print("There are {} different hyper-parameter settings in total.".format( total_settings)) seen_settings = set() with open(output_path, 'w+') as out: writer = csv.writer(out) writer.writerow([ "audio_hidden", "video_hidden", 'text_hidden', 'audio_dropout', 'video_dropout', 'text_dropout', 'factor_learning_rate', 'learning_rate', 'rank', 'batch_size', 'weight_decay', 'Best Validation MAE', 'Test MAE', 'Test Corr', 'Test multiclass accuracy', 'Test binary accuracy', 'Test f1_score' ]) ## wyw 用Excel记录grid search的过程,这种方式很666 for i in range(total_settings): ahid = random.choice(params['audio_hidden']) vhid = random.choice(params['video_hidden']) thid = random.choice(params['text_hidden']) thid_2 = thid // 2 adr = random.choice(params['audio_dropout']) vdr = random.choice(params['video_dropout']) tdr = random.choice(params['text_dropout']) factor_lr = random.choice(params['factor_learning_rate']) lr = random.choice(params['learning_rate']) r = random.choice(params['rank']) batch_sz = random.choice(params['batch_size']) decay = random.choice(params['weight_decay']) # reject the setting if it has been tried current_setting = (ahid, vhid, thid, adr, vdr, tdr, factor_lr, lr, r, batch_sz, decay) if current_setting in seen_settings: continue else: seen_settings.add(current_setting) ## wyw 这种grid search的方式真牛逼!!不服不行,学习了学习了 model = LMF(input_dims, (ahid, vhid, thid), thid_2, (adr, vdr, tdr, 0.5), output_dim, r) if options['cuda']: model = model.cuda() DTYPE = torch.cuda.FloatTensor print("Model initialized") criterion = nn.L1Loss(size_average=False) factors = list(model.parameters())[:3] other = list( model.parameters())[3:] ## wyw 这里将参数分为factor 和other的原因?未看懂 optimizer = optim.Adam([{ "params": factors, "lr": factor_lr }, { "params": other, "lr": lr }], weight_decay=decay) # setup training complete = True min_valid_loss = float('Inf') train_iterator = DataLoader(train_set, batch_size=batch_sz, num_workers=4, shuffle=True) valid_iterator = DataLoader(valid_set, batch_size=len(valid_set), num_workers=4, shuffle=True) test_iterator = DataLoader(test_set, batch_size=len(test_set), num_workers=4, shuffle=True) curr_patience = patience ## 容忍 ##wyw 这里以下才是训练过程,以上为grid search 及模型框架搭建 for e in range(epochs): model.train() model.zero_grad() avg_train_loss = 0.0 for batch in train_iterator: model.zero_grad() x = batch[:-1] x_a = Variable(x[0].float().type(DTYPE), requires_grad=False).squeeze() x_v = Variable(x[1].float().type(DTYPE), requires_grad=False).squeeze() x_t = Variable(x[2].float().type(DTYPE), requires_grad=False) y = Variable(batch[-1].view(-1, output_dim).float().type(DTYPE), requires_grad=False) output = model(x_a, x_v, x_t) loss = criterion(output, y) loss.backward() print("#########each batch loss###############") print(loss.data) print("########################################") avg_loss = loss.data.item() ## wyw origin:loss.data[0] avg_train_loss += avg_loss / len(train_set) optimizer.step() print("Epoch {} complete! Average Training loss: {}".format( e, avg_train_loss)) # Terminate the training process if run into NaN if np.isnan(avg_train_loss): print("Training got into NaN values...\n\n") complete = False break model.eval() for batch in valid_iterator: x = batch[:-1] x_a = Variable(x[0].float().type(DTYPE), requires_grad=False).squeeze() x_v = Variable(x[1].float().type(DTYPE), requires_grad=False).squeeze() x_t = Variable(x[2].float().type(DTYPE), requires_grad=False) y = Variable(batch[-1].view(-1, output_dim).float().type(DTYPE), requires_grad=False) output = model(x_a, x_v, x_t) valid_loss = criterion(output, y) avg_valid_loss = valid_loss.data[0] y = y.cpu().data.numpy().reshape(-1, output_dim) if np.isnan(avg_valid_loss): print("Training got into NaN values...\n\n") complete = False break avg_valid_loss = avg_valid_loss / len(valid_set) print("Validation loss is: {}".format(avg_valid_loss)) if (avg_valid_loss < min_valid_loss): curr_patience = patience min_valid_loss = avg_valid_loss torch.save(model, model_path) print("Found new best model, saving to disk...") else: curr_patience -= 1 if curr_patience <= 0: break print("\n\n") model.eval() for batch in test_iterator: x = batch[:-1] x_a = Variable(x[0].float().type(DTYPE), requires_grad=False).squeeze() x_v = Variable(x[1].float().type(DTYPE), requires_grad=False).squeeze() x_t = Variable(x[2].float().type(DTYPE), requires_grad=False) y = Variable(batch[-1].view(-1, output_dim).float().type(DTYPE), requires_grad=False) output_test = model(x_a, x_v, x_t) loss_test = criterion(output_test, y) avg_test_loss = loss_test.data[0] / len(test_set) output_test = output_test.cpu().data.numpy().reshape( -1, output_dim) y = y.cpu().data.numpy().reshape(-1, output_dim) # these are the needed metrics output_test = output_test.reshape((len(output_test), )) y = y.reshape((len(y), )) mae = np.mean(np.absolute(output_test - y)) if complete: best_model = torch.load(model_path) best_model.eval() for batch in test_iterator: x = batch[:-1] x_a = Variable(x[0].float().type(DTYPE), requires_grad=False).squeeze() x_v = Variable(x[1].float().type(DTYPE), requires_grad=False).squeeze() x_t = Variable(x[2].float().type(DTYPE), requires_grad=False) y = Variable(batch[-1].view(-1, output_dim).float().type(DTYPE), requires_grad=False) output_test = best_model(x_a, x_v, x_t) loss_test = criterion(output_test, y) output_test = output_test.cpu().data.numpy().reshape( -1, output_dim) y = y.cpu().data.numpy().reshape(-1, output_dim) # these are the needed metrics output_test = output_test.reshape((len(output_test), )) y = y.reshape((len(y), )) mae = np.mean(np.absolute(output_test - y)) corr = round(np.corrcoef(output_test, y)[0][1], 5) ##wyw 两个输出向量的output居然也可以作为一种评测方式!! multi_acc = round( sum(np.round(output_test) == np.round(y)) / float(len(y)), 5) true_label = (y >= 0) predicted_label = (output_test >= 0) bi_acc = accuracy_score(true_label, predicted_label) f1 = f1_score(true_label, predicted_label, average='weighted') display(mae, corr, multi_acc, bi_acc, f1) with open(output_path, 'a+') as out: writer = csv.writer(out) writer.writerow([ ahid, vhid, thid, adr, vdr, tdr, factor_lr, lr, r, batch_sz, decay, min_valid_loss.cpu().data.numpy(), mae, corr, multi_acc, bi_acc, f1 ])