tensorflow使用lstm实现sin函数


sin函数可以看做是一个序列的图线,并且sin函数是一个连续的曲线,循环神经网络的预测是离散的时刻取值,为了模拟出sin函数这种连续的图线,所以需要将连续的sin函数曲线离散化,也就是在某一个区间内找到有限个点来大致描绘出sin函数曲线的样子。

构造数据

为了模拟出sin函数,那么首先需要对sin函数的数据进行采样,TRAINING_EXAMPLES为训练数据的个数,设置为10000个点,每隔SAMPLE_GAP取一个点,该值设置为0.01,TESTING_EXAMPLES为测试样本的个数。那么对于我们选取的[0,test_end]这段序列中,我们选取[0,test_start)这段抽取数据作为训练数据,而测试集的数据在[test_start,test_end]。

test_start = (TRAINING_EXAMPLES + TIMESTEPS) * SAMPLE_GAP
test_end = test_start + (TESTING_EXAMPLES + TIMESTEPS) * SAMPLE_GAP

接下来就也要根据上面生成的时间信息去生成数据,通俗的就是知道x,需要找到sin(x)的值。
对于np.linspace这个函数,是构成了一个等差序列的数组,起始点为第一个参数,终止点是第二个参数,第三个参数是等差数列中的d。经过sin函数一求就可以得到(0,test_start)这个区间的sin函数的采样点了,同理得到(test_start,test_end)区间的sin函数的采样点。

train_X, train_y = generate_data(np.sin(np.linspace(
    0, test_start, TRAINING_EXAMPLES + TIMESTEPS, dtype=np.float32)))
test_X, test_y = generate_data(np.sin(np.linspace(
    test_start, test_end, TESTING_EXAMPLES + TIMESTEPS, dtype=np.float32)))

我们得到这两段sin函数的取样点怎么构造输入数据呢,根据generate_data函数就可以得到输入数据。其实也很简单,就是根据前面一小段数据预测下一个点,就这样不停从训练数据构造n个小段。这样就明确了数据了。这儿采取的根据前TIMESTEPS-1个采样点来预测第TIMESTEPS点的值

def generate_data(seq):
    """
    构造输入数据
    :param seq:
    :return:
    """
    X = []
    y = []

    for i in range(len(seq) - TIMESTEPS):
        X.append([seq[i: i + TIMESTEPS]])
        y.append([seq[i + TIMESTEPS]])
    return np.array(X, dtype=np.float32), np.array(y, dtype=np.float32)

创建模型

接下来就是常规的构造模型了

def lstm_model(X, y, is_training):
    # 使用多层的LSTM结构。
    cell = tf.nn.rnn_cell.MultiRNNCell([
        tf.nn.rnn_cell.BasicLSTMCell(HIDDEN_SIZE)
        for _ in range(NUM_LAYERS)])

    # 使用TensorFlow接口将多层的LSTM结构连接成RNN网络并计算其前向传播结果。
    outputs, _ = tf.nn.dynamic_rnn(cell, X, dtype=tf.float32)
    output = outputs[:, -1, :]

    # 对LSTM网络的输出再做加一层全链接层并计算损失。注意这里默认的损失为平均
    # 平方差损失函数。
    predictions = tf.contrib.layers.fully_connected(
        output, 1, activation_fn=None)

    # 只在训练时计算损失函数和优化步骤。测试时直接返回预测结果。
    if not is_training:
        return predictions, None, None

    # 计算损失函数。
    loss = tf.losses.mean_squared_error(labels=y, predictions=predictions)

    # 创建模型优化器并得到优化步骤。
    train_op = tf.contrib.layers.optimize_loss(
        loss, tf.train.get_global_step(),
        optimizer="Adagrad", learning_rate=0.1)
    return predictions, loss, train_op

验证模型

得到模型之后,需要将模型应用到测试数据,并且画图观测预测的图线是否符合一个sin函数

def run_eval(sess, test_X, test_y):
    # 将测试数据以数据集的方式提供给计算图。
    ds = tf.data.Dataset.from_tensor_slices((test_X, test_y))
    ds = ds.batch(1)
    X, y = ds.make_one_shot_iterator().get_next()

    # 调用模型得到计算结果。这里不需要输入真实的y值。
    with tf.variable_scope("model", reuse=True):
        prediction, _, _ = lstm_model(X, [0.0], False)

    # 将预测结果存入一个数组。
    predictions = []
    labels = []
    for i in range(TESTING_EXAMPLES):
        p, l = sess.run([prediction, y])
        predictions.append(p)
        labels.append(l)

    # 计算rmse作为评价指标。
    predictions = np.array(predictions).squeeze()
    labels = np.array(labels).squeeze()
    rmse = np.sqrt(((predictions - labels) ** 2).mean(axis=0))
    print("Root Mean Square Error is: %f" % rmse)

    # 对预测的sin函数曲线进行绘图。
    plt.figure()
    plt.plot(predictions, label='predictions')
    plt.plot(labels, label='real_sin')
    plt.legend()
    plt.show()
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值