def trainIters(encoder, attn_decoder, n_iters, learning_rate, print_every=1000, plot_every=100): # TODO preprocess the input file to get standard vectors configuration = config.get_config() filepath = configuration['datafile_path'] """divides the data into train and dev""" processed_data = DataProcessing.ProcessData(filepath) run_model = DataProcessing.RunModel() """ Model designing part """ # TODO design encoder # max_action_len = 30 start = time.time() plot_losses = [] print_loss_total = 0 # Reset every print_every plot_loss_total = 0 # Reset every plot_every encoder_optimizer = optim.SGD(encoder.parameters(), lr=learning_rate) decoder_optimizer = optim.SGD(attn_decoder.parameters(), lr=learning_rate) count = 0 folds = configuration['folds'] criterion = nn.NLLLoss() """ Training part """ for epi in range(n_iters): # print "training epoch ", epi # train_err_epoch = [] val_err_epoch = [] accuracy_for_epoch = [] # TODO: shuffle the training data and train this epoch ## train_start = time.time() # for fold in range(folds): print "Fold: ", fold train_err = 0.0 num_steps = 0 seq_lang_numpy = [] seq_world_numpy = [] seq_action_numpy = [] for name_map in configuration['maps_train'][fold]: max_steps = len(processed_data.dict_data['train'][name_map]) print 'max_steps=', max_steps for idx_data, data in enumerate( processed_data.dict_data['train'][name_map]): count += 1 # seq_lang_numpy, seq_world_numpy and seq_action_numpy will be set seq_lang_numpy, seq_world_numpy, seq_action_numpy = processed_data.process_one_data( idx_data, name_map, 'train') seq_lang_numpy = Variable( torch.LongTensor(seq_lang_numpy).view(-1, 1)) seq_world_numpy = Variable( torch.FloatTensor(seq_world_numpy)) seq_action_numpy = Variable( torch.LongTensor(seq_action_numpy).view(-1, 1)) """ trainer = Instantiates the model """ loss = train(idx_data, name_map, seq_lang_numpy, seq_world_numpy, seq_action_numpy, encoder, attn_decoder, encoder_optimizer, decoder_optimizer, criterion, processed_data, "train", run_model) train_err += loss print_loss_total += loss plot_loss_total += loss if idx_data % 100 == 99: print "training i-th out of N in map : ", (idx_data, max_steps, name_map) if count % print_every == 0: print_loss_avg = print_loss_total / print_every print_loss_total = 0 print "----------------calculating training loss------------" print "TimeSince=", time_since(start, count / n_iters) print "Itr=", count print " Percentage of code run=", count / n_iters * 100 print "Loss=", print_loss_avg print "--------------------------------------------" print "" print "" # if idx_data == 20: # break num_steps += max_steps # avg_train_err = train_err / num_steps train_err_epoch.append(avg_train_err) print "validating ... " # val_err = 0.0 num_steps = 0 dev_start = time.time() # for name_map in configuration['maps_train'][fold]: max_steps = len(processed_data.dict_data['dev'][name_map]) for idx_data, data in enumerate( processed_data.dict_data['dev'][name_map]): count += 1 # seq_lang_numpy, seq_world_numpy and seq_action_numpy will be set seq_lang_numpy, seq_world_numpy, seq_action_numpy = processed_data.process_one_data( idx_data, name_map, 'dev') seq_lang_numpy = Variable( torch.LongTensor(seq_lang_numpy).view(-1, 1)) seq_world_numpy = Variable( torch.FloatTensor(seq_world_numpy)) seq_action_numpy = Variable( torch.LongTensor(seq_action_numpy).view(-1, 1)) """ trainer = Instantiates the model """ loss = train(idx_data, name_map, seq_lang_numpy, seq_world_numpy, seq_action_numpy, encoder, attn_decoder, encoder_optimizer, decoder_optimizer, criterion, processed_data, "dev", run_model) val_err += loss print_loss_total += loss plot_loss_total += loss if idx_data % 100 == 99: print "training i-th out of N in map : ", (idx_data, max_steps, name_map) if count % print_every == 0: print_loss_avg = print_loss_total / print_every print_loss_total = 0 print "----------------calculating validation loss------------" print "TimeSince=", time_since(start, count / n_iters) print "Itr=", count print " Percentage of code run=", (count / n_iters) * 100 print "Loss=", print_loss_avg print "--------------------------------------------" print "" print "" # if idx_data == 20: # break num_steps += max_steps avg_val_error = val_err / num_steps val_err_epoch.append(avg_val_error) print "Epoch = ", epi, " Train error = ", avg_train_err, " Validation error = ", avg_val_error, " diff = "\ , avg_train_err - avg_val_error # Add testing code here test_map_name = configuration['map_test'][fold] print "maptest = ", test_map_name cnt_success = 0 tag_split = 'train' cnt, total_tuples1, _, _ = evaluate(encoder, attn_decoder, tag_split, test_map_name, processed_data, run_model) cnt_success += cnt tag_split = 'dev' cnt, total_tuples2, _, _ = evaluate(encoder, attn_decoder, tag_split, test_map_name, processed_data, run_model) cnt_success += cnt accuracy_for_fold = (cnt_success / ((total_tuples1 + total_tuples2) * 1.0)) * 100 accuracy_for_epoch.append(accuracy_for_fold) print "Accuracy:for fold:", fold, "= ", accuracy_for_fold, " %" avg_train_err_epi = (sum(train_err_epoch) / 3.0) avg_val_error_epi = (sum(val_err_epoch) / 3.0) avg_accuracy_epi = (sum(accuracy_for_epoch) / 3.0) print "Average train error for epoch ", epi, ": ", avg_train_err_epi print "Average val error for epoch ", epi, ": ", avg_val_error_epi print "Average accuracy for epoch ", epi, ": ", avg_accuracy_epi print "Train error - val error : ", avg_train_err_epi - avg_val_error_epi # Save the model after every epoch tracks = configuration['save_filepath'] id_process = os.getpid() time_current = datetime.datetime.now().isoformat() tag_model = '_PID=' + str(id_process) + '_TIME=' + time_current path_track = tracks + 'track' + "_3FoldEpoch_" + str( epi) + "_" + tag_model + '/' command_mkdir = 'mkdir -p ' + os.path.abspath(path_track) os.system(command_mkdir) # ENCODER_PATH = path_track + 'encoder.pkl' DECODER_PATH = path_track + 'decoder.pkl' torch.save(encoder, ENCODER_PATH) torch.save(attn_decoder, DECODER_PATH)
def SampleTest(encoder, decoder, idx_data, sentence, map_name, max_length=MAX_LENGTH): """ idx_data: this is the index number of test data of 'l' map's dev set""" configuration = config.get_config() filepath = configuration['datafile_path'] name_map = configuration['map_test'][0] processed_data = DataProcessing.ProcessData(filepath) run_model = DataProcessing.RunModel() idx_data, path = get_data_tuple(idx_data, sentence, processed_data, map_name) all_actions = [] all_attentions = [] print "Given instruction: ", sentence seq_lang_numpy, seq_world_numpy, seq_action_numpy = processed_data.process_one_data( idx_data, name_map, 'dev') seq_lang = Variable(torch.LongTensor(seq_lang_numpy).view(-1, 1)) seq_world = Variable(torch.FloatTensor(seq_world_numpy)) seq_action = Variable(torch.LongTensor(seq_action_numpy).view(-1, 1)) input_length = seq_lang.size()[0] pos_start, pos_end = processed_data.get_pos(idx_data, name_map, 'dev') pos_curr = pos_start encoder_hidden = encoder.initHidden() encoder_outputs = Variable(torch.zeros(max_length, encoder.hidden_size)) encoder_outputs = encoder_outputs.cuda() if use_cuda else encoder_outputs for ei in range(input_length): encoder_output, encoder_hidden = encoder(seq_lang[ei], encoder_hidden) # encoder_outputs[ei] is an extra term when compared to that in train function encoder_outputs[ei] = encoder_outputs[ei] + encoder_output[0][0] decoder_input = seq_world[0] decoder_input = decoder_input.cuda() if use_cuda else decoder_input decoder_hidden = encoder_hidden.view(1, 1, encoder.hidden_size) decoded_actions = [] decoder_attentions = torch.zeros(max_length, max_length) for di in range(max_length): decoder_output, decoder_hidden, decoder_attention = decoder( decoder_input, decoder_hidden, encoder_outputs) decoder_attentions[di] = decoder_attention.data topv, topi = decoder_output.data.topk(1) ni = topi[0][0] pos_curr = run_model.take_one_step(pos_curr, ni) # world state of next position decoder_input = run_model.get_feat_current_position(pos_curr, name_map) decoder_input = Variable(torch.FloatTensor([decoder_input])) decoder_input = decoder_input.cuda() if use_cuda else decoder_input if ni == STOP: decoded_actions.append(3) break else: decoded_actions.append(ni) print "decoded action = ", decoded_actions return decoded_actions, decoder_attentions[:di + 1], path
def evaluate(encoder, decoder, tag_split, max_length=MAX_LENGTH): configuration = config.get_config() filepath = configuration['datafile_path'] name_map = configuration['map_test'][0] processed_data = DataProcessing.ProcessData(filepath) run_model = DataProcessing.RunModel() all_actions = [] all_attentions = [] cnt_success = 0 for idx_data, data in enumerate( processed_data.dict_data[tag_split][name_map]): actions = [] for act in data['action']: actions.append(np.argmax(act)) seq_lang_numpy, seq_world_numpy, seq_action_numpy = processed_data.process_one_data( idx_data, name_map, tag_split) seq_lang = Variable(torch.LongTensor(seq_lang_numpy).view(-1, 1)) seq_world = Variable(torch.FloatTensor(seq_world_numpy)) seq_action = Variable(torch.LongTensor(seq_action_numpy).view(-1, 1)) input_length = seq_lang.size()[0] pos_start, pos_end = processed_data.get_pos(idx_data, name_map, tag_split) pos_curr = pos_start encoder_hidden = encoder.initHidden() encoder_outputs = Variable(torch.zeros(max_length, encoder.hidden_size)) encoder_outputs = encoder_outputs.cuda( ) if use_cuda else encoder_outputs for ei in range(input_length): encoder_output, encoder_hidden = encoder(seq_lang[ei], encoder_hidden) # encoder_outputs[ei] is an extra term when compared to that in train function encoder_outputs[ei] = encoder_outputs[ei] + encoder_output[0][0] decoder_input = seq_world[0] decoder_input = decoder_input.cuda() if use_cuda else decoder_input decoder_hidden = encoder_hidden.view(1, 1, encoder.hidden_size) decoded_actions = [] decoder_attentions = torch.zeros(max_length, max_length) for di in range(max_length): decoder_output, decoder_hidden, decoder_attention = decoder( decoder_input, decoder_hidden, encoder_outputs) decoder_attentions[di] = decoder_attention.data topv, topi = decoder_output.data.topk(1) ni = topi[0][0] pos_curr = run_model.take_one_step(pos_curr, ni) # world state of next position decoder_input = run_model.get_feat_current_position( pos_curr, name_map) decoder_input = Variable(torch.FloatTensor([decoder_input])) decoder_input = decoder_input.cuda() if use_cuda else decoder_input if ni == STOP: decoded_actions.append(3) break else: decoded_actions.append(ni) all_actions.append(decoded_actions) all_attentions.append(decoder_attentions[:di + 1]) if check_position_end(pos_curr, data['cleanpath'][-1]): cnt_success += 1 print "decoded action = ", decoded_actions return cnt_success, all_actions, all_attentions
def train(idx_data, map_name, input_variable, target_variable, action_seq, encoder, decoder, encoder_optimizer, decoder_optimizer, criterion, processed_data, flag, max_length=MAX_LENGTH): """ Args: idx_data: index of the data in pkl file map_name: name of the map on which the training is being done input_variable: seq_lang_numpy (torch.Tensor) -> Array target_variable: seq_world_numpy (torch.Tensor) -> Matrix action_seq: seq_action_numpy (torch.Tensor) -> Array encoder: Object of EncoderRNN decoder: Object of AttnDecoder encoder_optimizer: Optimizer applied to Encoder (SGD) decoder_optimizer: Optimizer applied to AttnDecoder (SGD) criterion: Loss function (NLLloss) processed_data: Object of ProcessData class flag: train or validate max_length: Length of longest input instruction """ encoder_hidden = encoder.initHidden() if flag == "train": encoder_optimizer.zero_grad() decoder_optimizer.zero_grad() input_length = input_variable.size()[0] # total no. of words action_length = action_seq.size()[0] # total no. action sequence encoder_outputs = Variable(torch.zeros(max_length, encoder.hidden_size)) encoder_outputs = encoder_outputs.cuda() if use_cuda else encoder_outputs loss = 0 # count = 0 for ei in range(input_length): encoder_output, encoder_hidden = encoder(input_variable[ei], encoder_hidden) # if count == 0: # print ("encoder_output: ", encoder_output) # print("encoder_output.shape() : ", encoder_output.size()) # print("encoder_hidden: ", encoder_hidden) # print("encoder_hidden.shape(): ", encoder_hidden.size()) # count = 1 encoder_outputs[ei] = encoder_output[0][0] decoder_input = target_variable[0] decoder_input = decoder_input.cuda() if use_cuda else decoder_input decoder_hidden = encoder_hidden.view(1, 1, encoder.hidden_size) use_teacher_forcing = True if flag == "train" else False run_model = DataProcessing.RunModel() pos_start, pos_end = processed_data.get_pos(idx_data, map_name, 'train') pos_curr = pos_start if use_teacher_forcing: # Teacher forcing: Feed the target as the next input for di in range(action_length): decoder_output, decoder_hidden, decoder_attention = decoder( decoder_input, decoder_hidden, encoder_outputs) loss += criterion(decoder_output, action_seq[di]) if di == action_length - 1 or action_seq[di].data[0] == 3: break decoder_input = target_variable[di + 1] # Teacher forcing else: # Without teacher forcing: use its own predictions as the next input for di in range(action_length): # decoder_output : (4,) decoder_output, decoder_hidden, decoder_attention = decoder( decoder_input, decoder_hidden, encoder_outputs) # topv = top_value topi = top_index i.e index with highest probability topv, topi = decoder_output.data.topk(1) ni = topi[0][0] # coz, decoder_output is 3D ''' 'ni' is the action_sequence, so, TODO: calculate the next position based on the current position calculate world state of next position decoder_input = world_state(next_position) ''' # calculating next position based on highest probability pos_curr = run_model.take_one_step(pos_curr, ni) # world state of next position decoder_input = run_model.get_feat_current_position( pos_curr, map_name) decoder_input = Variable(torch.FloatTensor([decoder_input])) decoder_input = decoder_input.cuda() if use_cuda else decoder_input loss += criterion(decoder_output, action_seq[di]) # print("ni=",ni) if ni == STOP: break loss.backward() if flag == "train": encoder_optimizer.step() decoder_optimizer.step() return loss.data[0] / action_length