5-RNN-03_双向rnn_英文小短文



import os
import numpy as np
import tensorflow as tf

def load_data(file_path):
    """
    加载原始数据
    :param file_path:
    :return:
    """
    with open(file_path, 'r') as reader:
        data = reader.readlines()
    return data

def create_lookup_table(text):
    """
    构建字典表  {单词:数字} {数字:单词}
    :param text:
    :return:
    """
    words = sorted(list(set(text)))
    # 构建字典
    word2int = {word:idx for idx,word in enumerate(words)}
    int2word = dict(enumerate(words))
    return word2int, int2word

def create_X_and_Y(data, word2int, number_time_steps=3):
    """
    基于原始数据,构建训练数据集的 X和Y
    :param data:
    :param word2int:
    :param number_time_steps:
    :return:
    """
    X, Y = [], []
    for content in data:
        # 得到当前文本对应的单词序列。  strip()去除前后空格
        words = content.strip().split(' ')
        # 获得单词总数量
        words_number = len(words)

        offset = 0
        while offset < words_number - number_time_steps:
            temp_x = words[offset: offset+number_time_steps]
            temp_y = words[offset+number_time_steps]
            X.append([word2int[tx] for tx in temp_x])
            Y.append(word2int[temp_y])
            offset +=1
    # 将列表转为numpy ndarray
    X = np.asarray(X).reshape([-1, number_time_steps])
    Y = np.asarray(Y).reshape(-1)
    return X, Y




def create_model(vocab_size, num_units=32, number_time_steps=3):
    """
    :param vocab_size:   词表大小
    :param num_units:     隐藏层的节点数量(神经元个数)
    :param number_time_steps:  时间步
    :return:
    """
    with tf.variable_scope('Network', initializer=tf.truncated_normal_initializer(stddev=0.1)):
        with tf.variable_scope('input'):
            # 输入数据的形状
            """
            x:
              [[2, 3, 4],
              [7, 8, 9]]
            y:
               [[5],
                [10]],
            """
            _x = tf.placeholder(tf.int32, shape=[None, number_time_steps], name='x')
            _y = tf.placeholder(tf.int32, shape=[None], name='y')
            _x = tf.cast(_x, tf.float32)

            # 需要将原始的输入_x 按照时间步进行分割,变成列表。
            # todo 用的真实的值,但实际项目中 应该 用one-hot或者embedding。
            input_x = tf.split(_x, num_or_size_splits=number_time_steps, axis=1)
            # [[N, 1], [N,1], ......]
        with tf.variable_scope('rnn'):
            # a、定义cell
            cell_fw = tf.nn.rnn_cell.BasicLSTMCell(num_units=num_units)
            cell_bw = tf.nn.rnn_cell.BasicLSTMCell(num_units=num_units)

            # b、调用双向静态rnn 获取隐藏层输出结果
            rnn_outputs, _, _ = tf.nn.static_bidirectional_rnn(
                cell_fw=cell_fw, cell_bw=cell_bw, inputs=input_x, dtype=tf.float32
            )
            # rnn_outputs: [[N, 2*lstm_size], [N, 2*lstm_size], ....]

        with tf.variable_scope('logits'):
            # a、获取隐藏层最后一个时刻的输出
            rnn_output = rnn_outputs[-1]

            # b、构建输出层变量
            softmax_w = tf.get_variable(
                'w', shape=[2*num_units, vocab_size], dtype=tf.float32
            )
            softmax_b = tf.get_variable(
                'b', shape=[vocab_size], dtype=tf.float32, initializer=tf.zeros_initializer()
            )
            logits = tf.nn.xw_plus_b(rnn_output, softmax_w, softmax_b)

        with tf.variable_scope('Predict'):
            predictions = tf.argmax(logits, axis=1)
    return _x, _y, logits, predictions

def create_loss(logits, labels):
    """
    创建损失
    :param logits:
    :param labels:
    :return:
    """
    with tf.name_scope('loss'):
        # a\将标签转换为1维的形式
        labels = tf.reshape(labels, shape=[-1])
        loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(
            logits=logits, labels=labels
        ))
        return loss


def create_optimizer(loss, lr=1e-3):
    """
    构建优化器
    :param loss:
    :param lr:
    :return:
    """
    with tf.name_scope('optimizer'):
        optimizer = tf.train.AdamOptimizer(learning_rate=lr)
        train_opt = optimizer.minimize(loss)
    return train_opt

def train(checkpoint_dir, max_steps=10000, batch_size=64, num_units=32, number_time_steps=10):
    graph = tf.Graph()
    with graph.as_default():
        # 加载数据
        data = load_data(file_path='../datas/belling_the_cat.txt')

        text = []
        for line in data:
            line = line.strip()
            for word in line.split(' '):
                text.append(word)

        word2int, int2word = create_lookup_table(text)
        x, y = create_X_and_Y(data, word2int, number_time_steps=number_time_steps)
        # print(word2int, '\n', int2word)

        # 1、构建网络
        _x, _y, logits, predictions = create_model(
            len(word2int), num_units=num_units, number_time_steps=number_time_steps)

        # 2、模型损失
        loss = create_loss(logits, _y)
        # 3、优化器
        train_opt = create_optimizer(loss)

        saver = tf.train.Saver()

    with tf.Session(graph=graph) as sess:
        sess.run(tf.global_variables_initializer())

        # 构建迭代数据
        total_samples = x.shape[0]
        n_batches = total_samples // batch_size
        time = 0
        # 返回一个随机打乱下标的  array, 功能就是shuffle
        random_index = np.random.permutation(total_samples)

        for step in range(1, max_steps):
            # 获取当前批量的训练数据
            start_idx = time * batch_size
            end_idx = start_idx + batch_size
            idx = random_index[start_idx: end_idx]
            train_x = x[idx]
            train_y = y[idx]

            # 构建输入数据对象
            feed = {_x: train_x, _y: train_y}

            sess.run(train_opt, feed)
            if step % 200==0:
                train_loss = sess.run(loss, feed)
                print('step:{} - Train loss:{}'.format(step, train_loss))
                # 做一个预测的
                index = np.random.randint(low=0, high=total_samples)
                sample_in = np.reshape(x[index], newshape=[-1, number_time_steps])
                sample_out = sess.run(predictions, feed_dict={_x: sample_in})
                print('输入:{} - 预测:{} VS 真实值:{}'.format(
                    x[index], int2word[sample_out[0]], int2word[y[index]]))
            if step % 1000 == 0:
                # 模型持久化
                files = 'model.ckpt'
                save_files = os.path.join(checkpoint_dir, files)
                saver.save(sess, save_path=save_files, global_step=step)
                print('model saved!!')

            # 更新样本顺序的
            time += 1
            if time == n_batches:
                time =0
                random_index = np.random.permutation(total_samples)


if __name__ == '__main__':
    checkpoint_dir = './models'
    if not os.path.exists(checkpoint_dir):
        os.makedirs(checkpoint_dir)
    train(
        checkpoint_dir, max_steps=10000, batch_size=64, num_units=32, number_time_steps=10
    )



D:\Anaconda\python.exe D:/AI20/HJZ/04-深度学习/4-RNN/20191228___AI20_RNN/03_双向rnn_英文小短文.py
2020-02-18 10:42:51.076290: I tensorflow/core/platform/cpu_feature_guard.cc:141] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX AVX2
step:200 - Train loss:3.9305477142333984
输入:[ 8  7  1 76 39  1 85 66 24 30] - 预测:, VS 真实值:consists
step:400 - Train loss:3.4807467460632324
输入:[ 77 100  44  86  60   2  91  69  56 109] - 预测:, VS 真实值:general
step:600 - Train loss:2.976116418838501
输入:[ 86  59  63  86  23   2  21  91  53 101] - 预测:the VS 真实值:should
step:800 - Train loss:2.6706745624542236
输入:[65 12 11 61 83  2 88 86 64 58] - 预测:the VS 真实值:said
step:1000 - Train loss:2.3042399883270264
输入:[ 39  92 110  55  86  22   2 111 108   8] - 预测:agree VS 真实值:agree
model saved!!
step:1200 - Train loss:1.834552526473999
输入:[64 58 37 96 11 76  0 85 45  8] - 预测:very VS 真实值:very
step:1400 - Train loss:1.6621453762054443
输入:[ 40  14   1 101  28  31  34  35  40   2] - 预测:i VS 真实值:i
step:1600 - Train loss:1.3067286014556885
输入:[ 29  93  26 103  54  90  28  84  93  67] - 预测:their VS 真实值:their
step:1800 - Train loss:1.2478928565979004
输入:[  1  86  57  38   4  36  29  93  26 103] - 预测:measures VS 真实值:measures
step:2000 - Train loss:0.9508646726608276
输入:[ 92 110  55  86  22   2 111 108   8   7] - 预测:, VS 真实值:,
model saved!!
step:2200 - Train loss:0.8384971618652344
输入:[61 83  2 88 86 64 58 76 46 45] - 预测:easy VS 真实值:easy
step:2400 - Train loss:0.5928971171379089
输入:[64 58 37 96 11 76  0 85 45  8] - 预测:very VS 真实值:very
step:2600 - Train loss:0.5592891573905945
输入:[31 34 35 40  2 41 98  1 89  1] - 预测:to VS 真实值:to
step:2800 - Train loss:0.4942898452281952
输入:[ 14   1 101  28  31  34  35  40   2  41] - 预测:venture VS 真实值:venture
step:3000 - Train loss:0.35549503564834595
输入:[ 77 100  44  86  60   2  91  69  56 109] - 预测:general VS 真实值:general
model saved!!
step:3200 - Train loss:0.3749193549156189
输入:[93 19 86 23  3 86 57 50 16 65] - 预测:another VS 真实值:another
step:3400 - Train loss:0.29113298654556274
输入:[86 23  2 82 76 91  1 11 82 76] - 预测:that VS 真实值:that
step:3600 - Train loss:0.25510722398757935
输入:[93 70 85  4 81 19 18 68  1 11] - 预测:attached VS 真实值:attached
step:3800 - Train loss:0.2347201555967331
输入:[ 26 103  54  90  28  84  93  67  87  25] - 预测:enemy VS 真实值:enemy
step:4000 - Train loss:0.18923482298851013
输入:[ 1 95 10 64 58 37 96 11 76  0] - 预测:that VS 真实值:that
model saved!!
step:4200 - Train loss:0.16195067763328552
输入:[23  3 86 57 50 16 65 12 11 61] - 预测:spoke VS 真实值:spoke
step:4400 - Train loss:0.13978148996829987
输入:[ 86  59  63  86  23   2  21  91  53 101] - 预测:should VS 真实值:should
step:4600 - Train loss:0.1490730196237564
输入:[103  54  90  28  84  93  67  87  25  33] - 预测:, VS 真实值:,
step:4800 - Train loss:0.10961226373910904
输入:[  1  11  82  76  85  20  16  48   4 112] - 预测:mouse VS 真实值:mouse
step:5000 - Train loss:0.11105622351169586
输入:[ 86  22   2 111 108   8   7   1  76  39] - 预测:, VS 真实值:,
model saved!!
step:5200 - Train loss:0.0975622832775116
输入:[ 78   9  47 104  77 100   5   1  11  28] - 预测:easily VS 真实值:easily
step:5400 - Train loss:0.0716937854886055
输入:[18 68  1 11 17 21  4 74 75 86] - 预测:neck VS 真实值:neck
step:5600 - Train loss:0.07302534580230713
输入:[ 91  53 101  78   9  47 104  77 100   5] - 预测:, VS 真实值:,
step:5800 - Train loss:0.05743904039263725
输入:[66 24 30 27 44 86 80 11 94 52] - 预测:in VS 真实值:in
step:6000 - Train loss:0.05397602543234825
输入:[ 1 85 66 24 30 27 44 86 80 11] - 预测:treacherous VS 真实值:treacherous
model saved!!
step:6200 - Train loss:0.054213933646678925
输入:[87 25 33  1 86 23  2 82 76 91] - 预测:, VS 真实值:,
step:6400 - Train loss:0.0373719185590744
输入:[23  2 82 76 91  1 11 82 76 85] - 预测:but VS 真实值:but
step:6600 - Train loss:0.046218693256378174
输入:[ 42 101  28  71  82  79  63  40  14   1] - 预测:we VS 真实值:we
step:6800 - Train loss:0.03185339272022247
输入:[ 20  16  48   4 112  58  37  96  11  76] - 预测:he VS 真实值:he
step:7000 - Train loss:0.026730481535196304
输入:[ 1 11 17 21  4 74 75 86 59 63] - 预测:the VS 真实值:the
model saved!!
step:7200 - Train loss:0.02903711423277855
输入:[111 108   8   7   1  76  39   1  85  66] - 预测:chief VS 真实值:chief
step:7400 - Train loss:0.026526065543293953
输入:[ 57  38   4  36  29  93  26 103  54  90] - 预测:could VS 真实值:could
step:7600 - Train loss:0.02054942026734352
输入:[107  45  93  19  86  23   3  86  57  50] - 预测:at VS 真实值:at
step:7800 - Train loss:0.01777688041329384
输入:[ 85  20  16  48   4 112  58  37  96  11] - 预测:said VS 真实值:said
step:8000 - Train loss:0.014596270397305489
输入:[112  58  37  96  11  76  39  38   4  69] - 预测:to VS 真实值:to
model saved!!
step:8200 - Train loss:0.015546170994639397
输入:[107  45  93  19  86  23   3  86  57  50] - 预测:at VS 真实值:at
step:8400 - Train loss:0.01338121946901083
输入:[16 65 12 11 61 83  2 88 86 64] - 预测:mouse VS 真实值:mouse
step:8600 - Train loss:0.014673653990030289
输入:[ 1 85 66 24 30 27 44 86 80 11] - 预测:treacherous VS 真实值:treacherous
step:8800 - Train loss:0.010602903552353382
输入:[75 86 59 63 86 23  2 21 91 53] - 预测:we VS 真实值:we
step:9000 - Train loss:0.01917443238198757
输入:[  1  20 107  45  93  19  86  23   3  86] - 预测:mice VS 真实值:mice
model saved!!
step:9200 - Train loss:0.012528151273727417
输入:[ 1 89  1 93 70 85  4 81 19 18] - 预测:procured VS 真实值:procured
step:9400 - Train loss:0.009897150099277496
输入:[ 26 103  54  90  28  84  93  67  87  25] - 预测:enemy VS 真实值:enemy
step:9600 - Train loss:0.007559692487120628
输入:[ 20  16  48   4 112  58  37  96  11  76] - 预测:he VS 真实值:he
step:9800 - Train loss:0.008503235876560211
输入:[33  1 86 23  2 82 76 91  1 11] - 预测:some VS 真实值:some

Process finished with exit code 0

发布了88 篇原创文章 · 获赞 2 · 访问量 1328

猜你喜欢

转载自blog.csdn.net/HJZ11/article/details/104371057
RNN