예제 #1
0
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)
예제 #2
0
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)
예제 #3
0
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)
예제 #4
0
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)
예제 #5
0
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)
예제 #6
0
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)