def _eval(args): label_dict = None if args.nontyped: label_dict = {'O': 0, 'Keyphrase': 1} else: label_dict = {'O': 0, 'Material': 1, 'Process': 2, 'Task': 3} label_list = [None for _ in range(len(label_dict))] for key, val in label_dict.items(): label_list[val] = key num_lbls = len(label_dict) (sequences, labels) = tt.preprocess(args.word2vec_path, args.labels_path) # Prepare zipped sequences of vectored words and labels. scalar_labels = tt.numeric_labels(labels, label_dict) num_seqs = len(sequences) num_feats = np.shape(sequences[0])[1] seq_lens = [len(sequence) for sequence in sequences] # Pad sentences and labels. pad_seqs, pad_lbls = tt.pad_data(sequences, scalar_labels, label_dict) num_words = np.shape(pad_seqs)[1] with tf.name_scope('inputs'): x = tf.placeholder(tf.float32, shape=(num_seqs, num_words, num_feats), name='sentences') x_lens = tf.placeholder(tf.int32, shape=(None), name='sentence_lens') gold_lbls = tf.placeholder(tf.int32, shape=(num_seqs, None), name='gold_lbls') with tf.variable_scope('crf'): weights = tt.weight_variable([num_feats, num_lbls], 'weights') x_matrix = tf.reshape(x, [-1, num_feats]) unary_scores_matrix = tf.matmul(x_matrix, weights) unary_scores = tf.reshape(unary_scores_matrix, [num_seqs, num_words, num_lbls]) log_likelihood, trans_params = tf.contrib.crf.crf_log_likelihood(unary_scores, gold_lbls, x_lens) loss = tf.reduce_mean(-log_likelihood) objective = tf.train.GradientDescentOptimizer(args.alpha).minimize(loss) saver = tf.train.Saver() init = tf.global_variables_initializer() path = os.path.join(args.load_path, '') filename = os.path.splitext(os.path.basename(__file__))[0] checkpoint = "{path}{filename}.ckpt".format(path=path, filename=filename) with tf.Session() as sess: sess.run(init) print("Loading {checkpoint}...".format(checkpoint=checkpoint)) saver.restore(sess, checkpoint) # Load trained weights and biases. print("Loaded {checkpoint}.".format(checkpoint=checkpoint)) feed_dict = {x: pad_seqs, x_lens: seq_lens, gold_lbls: pad_lbls} sess_unary_scores, sess_trans_params, sess_loss, _ = sess.run([unary_scores, trans_params, loss, objective], feed_dict=feed_dict) path = os.path.join(args.conll_path, '') filename = os.path.splitext(os.path.basename(__file__))[0] conll_file = "{path}{filename}.log".format(path=path, filename=filename) # Write expected and predicted values to file in CoNLL format. with open(conll_file, mode='a+') as conll: for (sess_score, sess_lbl, sess_seq_len) in zip(sess_unary_scores, pad_lbls, seq_lens): sess_score = sess_score[:sess_seq_len] sess_lbl = sess_lbl[:sess_seq_len] viterbi_seq, _ = tf.contrib.crf.viterbi_decode(sess_score, sess_trans_params) for expect, predict in zip(sess_lbl, viterbi_seq): line = "{e}\t{p}\n".format(e=label_list[expect], p=label_list[predict]) conll.write(line)
def _learn(args): label_dict = None if args.nontyped: label_dict = {'O': 0, 'Keyphrase': 1} else: label_dict = {'O': 0, 'Material': 1, 'Process': 2, 'Task': 3} num_lbls = len(label_dict) (sequences, labels) = tt.preprocess(args.word2vec_path, args.labels_path) # Prepare zipped sequences of vectored words and labels. scalar_labels = tt.numeric_labels(labels, label_dict) num_seqs = len(sequences) num_feats = np.shape(sequences[0])[1] seq_lens = [len(sequence) for sequence in sequences] seq_lens = np.array(seq_lens) # Pad sentences and labels. pad_seqs, pad_lbls = tt.pad_data(sequences, scalar_labels, label_dict) num_words = np.shape(pad_seqs)[1] with tf.name_scope('inputs'): x = tf.placeholder(tf.float32, shape=(None, num_words, num_feats), name='sentences') x_lens = tf.placeholder(tf.int32, shape=(None), name='sentence_lens') gold_lbls = tf.placeholder(tf.int32, shape=(None, num_words), name='gold_lbls') with tf.variable_scope('crf'): weights = tt.weight_variable([num_feats, num_lbls], 'weights') x_matrix = tf.reshape(x, [-1, num_feats]) unary_scores_matrix = tf.matmul(x_matrix, weights) unary_scores = tf.reshape(unary_scores_matrix, [-1, num_words, num_lbls]) log_likelihood, trans_params = tf.contrib.crf.crf_log_likelihood(unary_scores, gold_lbls, x_lens) loss = tf.reduce_mean(-log_likelihood) optimizer = None if args.optimizer == 'adam': optimizer = tf.train.AdamOptimizer(args.alpha) elif args.optimizer == 'rms': optimizer = tf.train.RMSPropOptimizer(args.alpha) elif args.optimzier == 'sgd': optimizer = tf.train.GradientDescentOptimizer(args.alpha) objective = optimizer.minimize(loss) init = tf.global_variables_initializer() with tf.Session() as sess: sess.run(init) learning = True epoch = 0 plateau_cnt = 0 num_batches = num_seqs // args.target_batch_size epoch_accuracy = [] epoch_loss = [] while learning: correct_lbls = 0 totals_lbls = 0 if (epoch + 1) % 10 == 0: epoch_accuracy.append([]) epoch_loss.append([]) for batch_idx in np.arange(num_batches): seq_batch = None lbl_batch = None batch_lens = None if batch_idx < num_batches: seq_batch = pad_seqs[(batch_idx * args.target_batch_size): ((batch_idx + 1) * args.target_batch_size)] lbl_batch = pad_lbls[(batch_idx * args.target_batch_size): ((batch_idx + 1) * args.target_batch_size)] batch_lens = seq_lens[(batch_idx * args.target_batch_size): ((batch_idx + 1) * args.target_batch_size)] else: seq_batch = pad_seqs[(batch_idx * args.target_batch_size):] lbl_batch = pad_lbls[(batch_idx * args.target_batch_size):] batch_lens = seq_lens[(batch_idx * args.target_batch_size):] feed_dict = {x: seq_batch, x_lens: batch_lens, gold_lbls: lbl_batch} sess_unary_scores, sess_trans_params, sess_loss, _ = sess.run([unary_scores, trans_params, loss, objective], feed_dict=feed_dict) if (epoch + 1) % 10 == 0: for (sess_score, sess_lbl, sess_seq_len) in zip(sess_unary_scores, lbl_batch, seq_lens): sess_score = sess_score[:sess_seq_len] sess_lbl = sess_lbl[:sess_seq_len] viterbi_seq, _ = tf.contrib.crf.viterbi_decode(sess_score, sess_trans_params) correct_lbls += np.sum(np.equal(viterbi_seq, sess_lbl)) totals_lbls += sess_seq_len accuracy = 100 * correct_lbls / float(totals_lbls) epoch_accuracy[-1].append(accuracy) epoch_loss[-1].append(sess_loss) if len(epoch_loss) > 2: previous_loss = np.mean(epoch_loss[-2]) current_loss = np.mean(epoch_loss[-1]) loss_diff = previous_loss - current_loss print("Epoch [{}] Accuracy {:.2f} | Loss: {:.5f} | Loss Diff: {:.5f}".format(epoch, np.mean(epoch_accuracy[-1]), current_loss, loss_diff)) if abs(loss_diff) < args.epsilon: plateau_cnt += 1 if plateau_cnt >= 3: learning = False if epoch >= args.kill_zone: learning = False epoch += 1 path = os.path.join(args.save_path, '') filename = os.path.splitext(os.path.basename(__file__))[0] checkpoint = "{path}{filename}.ckpt".format(path=path, filename=filename) print("Saving model variables to: {checkpoint}".format(checkpoint=checkpoint)) saver = tf.train.Saver() saver.save(sess, checkpoint)
def _eval(args): label_dict = None if args.nontyped: label_dict = {'O': 0, 'Keyphrase': 1} else: label_dict = {'O': 0, 'Material': 1, 'Process': 2, 'Task': 3} label_list = ['' for n in np.arange(len(label_dict))] for k, v in label_dict.items(): label_list[v] = k num_labels = len(label_dict) (sequences, labels) = tt.preprocess( args.word2vec_path, args.labels_path ) # Prepare zipped sequences of vectored words and labels. num_inputs = len(sequences) # Determine number of training examples. feature_size = len(sequences[0][0]) # Determine word vector size. one_hot_labels = tt.one_hot(labels, label_dict) # Calculate batches. batch_size, steps = tt.batch_calc(num_inputs, args.target_batch_size) _, iter_wait = tt.batch_calc(batch_size, args.target_batch_size // 4) print("Evaluating {steps} batches of size {batch_size}.".format( steps=steps, batch_size=batch_size)) with tf.variable_scope('lstm_model'): input_keep_prob = args.input_keep_prob if input_keep_prob == 0.0: input_keep_prob = None if args.bi: model = rnn.MultiRNNLSTM(args.rnn_size, args.depth, num_labels, batch_size, feature_size, args.optimizer, args.alpha, bi=True, input_keep_prob=input_keep_prob) else: model = rnn.MultiRNNLSTM(args.rnn_size, args.depth, num_labels, batch_size, feature_size, args.optimizer, args.alpha, bi=False, input_keep_prob=input_keep_prob) saver = tf.train.Saver() init = tf.global_variables_initializer() path = os.path.join(args.load_path, '') filename = os.path.splitext(os.path.basename(__file__))[0] checkpoint = "{path}{filename}.ckpt".format(path=path, filename=filename) with tf.Session() as sess: sess.run(init) saver.restore(sess, checkpoint) # Load trained weights and biases. losses = np.zeros(steps) accuracies = np.zeros(steps) conll_list = [] # Evaluate model. for step in np.arange(steps): state = np.zeros( (args.depth, 2, batch_size, args.rnn_size)) # Set empty initial state for each batch. chosen_seqs = np.arange(batch_size * step, batch_size * (step + 1)) (seq_len, seq_lbl_zip) = tt.package_batch(chosen_seqs, sequences, one_hot_labels, label_dict) batch_x, batch_y = zip(*seq_lbl_zip) feed_dict = { model.x: batch_x, model.y: batch_y, model.seq_len: seq_len, model.init_state: state } expectation, prediction, eval_cross_entropy, eval_accuracy, state = sess.run( [ model.expect, model.predict, model.cross_entropy, model.accuracy, model.dynamic_state ], feed_dict=feed_dict) losses[step] = eval_cross_entropy accuracies[step] = eval_accuracy if (step + 1) % iter_wait == 0: print( "[Step {step:0>4d}] Loss: {loss:.5f} | Accuracy: {accuracy:.5f}" .format(step=step, loss=eval_cross_entropy, accuracy=eval_accuracy)) zip_list = [] for e, p in zip(expectation, prediction): zip_list.append((label_list[e], label_list[p])) conll_list.extend(zip_list) print("(Average) Loss: {}".format(np.mean(losses, axis=0))) print("(Average) Accuracy: {}".format(np.mean(accuracies, axis=0))) path = os.path.join(args.conll_path, '') filename = os.path.splitext(os.path.basename(__file__))[0] conll_file = "{path}{filename}.log".format(path=path, filename=filename) # Write expected and predicted values to file in CoNLL format. with open(conll_file, mode='w+') as conll: for pairing in conll_list: line = "{e}\t{p}\n".format(e=pairing[0], p=pairing[1]) conll.write(line)
def _learn(args): label_dict = None if args.nontyped: label_dict = {'O': 0, 'Keyphrase': 1} else: label_dict = {'O': 0, 'Material': 1, 'Process': 2, 'Task': 3} num_labels = len(label_dict) (sequences, labels) = tt.preprocess( args.word2vec_path, args.labels_path ) # Prepare zipped sequences of vectored words and labels. num_inputs = len(sequences) # Determine number of training examples. feature_size = len(sequences[0][0]) # Determine word vector size. one_hot_labels = tt.one_hot(labels, label_dict) batch_size = args.target_batch_size with tf.variable_scope('lstm_model'): input_keep_prob = args.input_keep_prob if input_keep_prob == 0.0: input_keep_prob = None if args.bi: model = rnn.MultiRNNLSTM(args.rnn_size, args.depth, num_labels, batch_size, feature_size, args.optimizer, args.alpha, bi=True, input_keep_prob=input_keep_prob) else: model = rnn.MultiRNNLSTM(args.rnn_size, args.depth, num_labels, batch_size, feature_size, args.optimizer, args.alpha, bi=False, input_keep_prob=input_keep_prob) sum_merge = tf.summary.merge_all() init = tf.global_variables_initializer() with tf.Session() as sess: logpath = os.path.join(args.board_path, '') tt.clear_logs(logpath) writer = tf.summary.FileWriter(logpath, graph=sess.graph) sess.run(init) losses = [] accuracies = [] scores = [] epoch_cnt = 0 step_cnt = 0 plateau_cnt = 0 learning = True # Train model. while learning: # Add placeholder lists. losses.append([]) accuracies.append([]) scores.append([]) rounds, choices = tt.random_choices( num_inputs, batch_size) # Calculate batches. steps = np.arange(rounds) # Each step is a batch of sequences. for step in steps: state = np.zeros( (args.depth, 2, batch_size, args.rnn_size)) # Set empty initial state for each batch. chosen_seqs = choices[step] (seq_len, seq_lbl_zip) = tt.package_batch(chosen_seqs, sequences, one_hot_labels, label_dict) batch_x, batch_y = zip(*seq_lbl_zip) feed_dict = { model.x: batch_x, model.y: batch_y, model.seq_len: seq_len, model.init_state: state } _, logits, train_cross_entropy, train_accuracy, state, summary = sess.run( [ model.optimize, model.logits, model.cross_entropy, model.accuracy, model.dynamic_state, sum_merge ], feed_dict=feed_dict) # Check if learning has plateaued. if plateau_cnt == 3: print('Learning plateaued.') learning = False break elif step_cnt * batch_size >= args.kill_zone: print('Learning timeout.') learning = False break else: if len(losses[epoch_cnt]) > 0 and abs( losses[epoch_cnt][-1] - train_cross_entropy) < args.epsilon: plateau_cnt += 1 else: plateau_cnt = 0 # Update performance logs. losses[epoch_cnt].append(train_cross_entropy) accuracies[epoch_cnt].append(train_accuracy) scores[epoch_cnt].append(logits) if learning and (step_cnt * batch_size) % (10 * batch_size) == 0: print( "[Step {steps:0>3d}] Loss: {loss:.5f} | Accuracy: {accuracy:.5f}" .format(steps=(step_cnt * batch_size), loss=train_cross_entropy, accuracy=train_accuracy)) writer.add_summary(summary, step) step_cnt += 1 # Increase step counter. epoch_cnt += 1 # Increase epoch counter. path = os.path.join(args.save_path, '') filename = os.path.splitext(os.path.basename(__file__))[0] checkpoint = "{path}{filename}.ckpt".format(path=path, filename=filename) print("Saving model variables to: {checkpoint}".format( checkpoint=checkpoint)) saver = tf.train.Saver() saver.save(sess, checkpoint) zip_loss_accuracy = zip(tt.epoch_mean(losses), tt.epoch_mean(accuracies)) for zip_loss, zip_accuracy in zip_loss_accuracy: if zip_loss is not None and zip_accuracy is not None: print("(Average) Loss: {loss:.5f} | Accuracy {accuracy:.5f}". format(loss=zip_loss, accuracy=zip_accuracy)) if args.peek: logits_path = os.path.join(args.peek, '') logits_filename = os.path.splitext(os.path.basename(__file__))[0] logits_file = "{path}{filename}.csv".format( path=logits_path, filename=logits_filename) if os.path.exists(logits_file): os.remove(logits_file) print("Saving scores to {logits_file}".format( logits_file=logits_file)) tt.csv_log(logits_file, label_dict, scores)
def _eval(args): label_dict = None if args.nontyped: label_dict = {'O': 0, 'Keyphrase': 1} else: label_dict = {'O': 0, 'Material': 1, 'Process': 2, 'Task': 3} label_list = [None for _ in range(len(label_dict))] for key, val in label_dict.items(): label_list[val] = key num_labels = len(label_dict) (sequences, labels) = tt.preprocess( args.word2vec_path, args.labels_path ) # Prepare zipped sequences of vectored words and labels. scalar_labels = tt.numeric_labels(labels, label_dict) num_inputs = len(sequences) # Determine number of training examples. num_feats = len(sequences[0][0]) # Determine word vector size. seq_lens = [len(sequence) for sequence in sequences] seq_lens = np.array(seq_lens) # Pad sentences and labels. pad_seqs, pad_lbls = tt.pad_data(sequences, scalar_labels, label_dict) num_words = np.shape(pad_seqs)[1] num_batches = num_inputs // args.target_batch_size with tf.variable_scope('lstm_model'): input_keep_prob = args.input_keep_prob if input_keep_prob == 0.0: input_keep_prob = None if args.bi: model = rnn_crf.RCRF(args.rnn_size, args.depth, num_labels, num_words, num_feats, args.optimizer, args.alpha, bi=True, input_keep_prob=input_keep_prob) else: model = rnn_crf.RCRF(args.rnn_size, args.depth, num_labels, num_words, num_feats, args.optimizer, args.alpha, bi=False, input_keep_prob=input_keep_prob) saver = tf.train.Saver() init = tf.global_variables_initializer() path = os.path.join(args.load_path, '') filename = os.path.splitext(os.path.basename(__file__))[0] checkpoint = "{path}{filename}.ckpt".format(path=path, filename=filename) with tf.Session() as sess: sess.run(init) saver.restore(sess, checkpoint) # Load trained weights and biases. for batch_idx in np.arange(num_batches): if batch_idx < num_batches: batch_x = pad_seqs[(batch_idx * args.target_batch_size):( (batch_idx + 1) * args.target_batch_size)] batch_y = pad_lbls[(batch_idx * args.target_batch_size):( (batch_idx + 1) * args.target_batch_size)] batch_seq_lens = seq_lens[( batch_idx * args.target_batch_size):((batch_idx + 1) * args.target_batch_size)] else: batch_x = pad_seqs[(batch_idx * args.target_batch_size):] batch_y = pad_lbls[(batch_idx * args.target_batch_size):] batch_seq_lens = seq_lens[(batch_idx * args.target_batch_size):] current_batch_size = np.shape(batch_seq_lens)[0] state = np.zeros( (args.depth, 2, current_batch_size, args.rnn_size)) # Set empty initial state for each batch. feed_dict = { model.x: batch_x, model.y: batch_y, model.seq_lens: batch_seq_lens, model.init_state: state } eval_logits, eval_trans_params, state = sess.run( [model.logits, model.trans_params, model.dynamic_state], feed_dict=feed_dict) for (logit, lbl, seq_len) in zip(eval_logits, batch_y, batch_seq_lens): logit = logit[:seq_len] lbl = lbl[:seq_len] viterbi_seq, viterbi_score = tf.contrib.crf.viterbi_decode( logit, eval_trans_params) path = os.path.join(args.conll_path, '') filename = os.path.splitext(os.path.basename(__file__))[0] conll_file = "{path}{filename}.log".format(path=path, filename=filename) # Write expected and predicted values to file in CoNLL format. with open(conll_file, mode='a+') as conll: for expect, predict in zip(lbl, viterbi_seq): line = "{e}\t{p}\n".format(e=label_list[expect], p=label_list[predict]) conll.write(line)
def _learn(args): label_dict = None if args.nontyped: label_dict = {'O': 0, 'Keyphrase': 1} else: label_dict = {'O': 0, 'Material': 1, 'Process': 2, 'Task': 3} num_labels = len(label_dict) (sequences, labels) = tt.preprocess( args.word2vec_path, args.labels_path ) # Prepare zipped sequences of vectored words and labels. scalar_labels = tt.numeric_labels(labels, label_dict) num_inputs = len(sequences) # Determine number of training examples. num_feats = len(sequences[0][0]) # Determine word vector size. seq_lens = [len(sequence) for sequence in sequences] seq_lens = np.array(seq_lens) # Pad sentences and labels. pad_seqs, pad_lbls = tt.pad_data(sequences, scalar_labels, label_dict) num_words = np.shape(pad_seqs)[1] num_batches = num_inputs // args.target_batch_size with tf.variable_scope('lstm_model'): input_keep_prob = args.input_keep_prob if input_keep_prob == 0.0: input_keep_prob = None if args.bi: model = rnn_crf.RCRF(args.rnn_size, args.depth, num_labels, num_words, num_feats, args.optimizer, args.alpha, bi=True, input_keep_prob=input_keep_prob) else: model = rnn_crf.RCRF(args.rnn_size, args.depth, num_labels, num_words, num_feats, args.optimizer, args.alpha, bi=False, input_keep_prob=input_keep_prob) init = tf.global_variables_initializer() with tf.Session() as sess: sess.run(init) losses = [] accuracies = [] scores = [] epoch = 0 plateau_cnt = 0 learning = True # Train model. while learning: # Add placeholder lists. losses.append([]) accuracies.append([]) scores.append([]) for batch_idx in np.arange(num_batches): total_lbls = 0 correct_lbls = 0 train_accuracy = None batch_x = None batch_y = None batch_seq_lens = None if batch_idx < num_batches: batch_x = pad_seqs[(batch_idx * args.target_batch_size):( (batch_idx + 1) * args.target_batch_size)] batch_y = pad_lbls[(batch_idx * args.target_batch_size):( (batch_idx + 1) * args.target_batch_size)] batch_seq_lens = seq_lens[( batch_idx * args.target_batch_size):((batch_idx + 1) * args.target_batch_size)] else: batch_x = pad_seqs[(batch_idx * args.target_batch_size):] batch_y = pad_lbls[(batch_idx * args.target_batch_size):] batch_seq_lens = seq_lens[(batch_idx * args.target_batch_size):] current_batch_size = np.shape(batch_seq_lens)[0] state = np.zeros( (args.depth, 2, current_batch_size, args.rnn_size)) # Set empty initial state for each batch. feed_dict = { model.x: batch_x, model.y: batch_y, model.seq_lens: batch_seq_lens, model.init_state: state } train_logits, train_trans_params, train_loss, state, _, = sess.run( [ model.logits, model.trans_params, model.loss, model.dynamic_state, model.optimize ], feed_dict=feed_dict) for (logit, lbl, seq_len) in zip(train_logits, batch_y, batch_seq_lens): logit = logit[:seq_len] lbl = lbl[:seq_len] viterbi_seq, viterbi_score = tf.contrib.crf.viterbi_decode( logit, train_trans_params) correct_lbls += np.sum(np.equal(viterbi_seq, lbl)) total_lbls += seq_len train_accuracy = 100 * correct_lbls / float(total_lbls) accuracies[-1].append(train_accuracy) losses[-1].append(train_loss) # Check loss diff if len(losses) > 1: loss_diff = np.mean(losses[-2], axis=0) - np.mean(losses[-1], axis=0) if abs(loss_diff) < args.epsilon: plateau_cnt += 1 else: plateau_cnt = 0 # Check if learning has plateaued. if plateau_cnt >= 3: print('Learning plateaued.') learning = False break elif epoch >= args.kill_zone: print('Learning timeout.') learning = False break if learning and (epoch + 1) % 100: print( "[Epoch {epoch}] Loss: {loss:.5f} | Accuracy: {accuracy:.5f}" .format(epoch=epoch, loss=np.mean(losses[-1], axis=0), accuracy=np.mean(accuracies[-1], axis=0))) epoch += 1 # Increase epoch counter. path = os.path.join(args.save_path, '') filename = os.path.splitext(os.path.basename(__file__))[0] checkpoint = "{path}{filename}.ckpt".format(path=path, filename=filename) print("Saving model variables to: {checkpoint}".format( checkpoint=checkpoint)) saver = tf.train.Saver() saver.save(sess, checkpoint)