博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用TensorFlow的递归神经网络(LSTM)进行序列预测
阅读量:6371 次
发布时间:2019-06-23

本文共 8011 字,大约阅读时间需要 26 分钟。

本篇文章介绍使用TensorFlow的递归神经网络(LSTM)进行序列预测。作者在网上找到的使用LSTM模型的案例都是解决自然语言处理的问题,而没有一个是来预测连续值的。

\\

所以呢,这里是基于历史观察数据进行实数序列的预测。传统的神经网络模型并不能解决这种问题,进而开发出递归神经网络模型,递归神经网络模型可以存储历史数据来预测未来的事情。

\\

在这个例子里将预测几个函数:

\\
  • 正弦函数:sin\

3df4e1752e9b14c8c3ad65b50f973627.png

\\
  • 同时存在正弦函数和余弦函数:sin和cos\

fb7f1a0538d9637c0d119274fb1285ac.png

\\
  • x*sin(x)\

15117ac90c23755ac54f86d2ae723fc0.png

\\

首先,建立LSTM模型,lstm_model,这个模型有一系列的不同时间步的lstm单元(cell),紧跟其后的是稠密层。

\\
\def lstm_model(time_steps, rnn_layers, dense_layers=None):\     def lstm_cells(layers):\         if isinstance(layers[0], dict):\             return [tf.nn.rnn_cell.DropoutWrapper(tf.nn.rnn_cell.BasicLSTMCell(layer['steps']), layer['keep_prob'])\                     if layer.get('keep_prob') else tf.nn.rnn_cell.BasicLSTMCell(layer['steps'])\                     for layer in layers]\         return [tf.nn.rnn_cell.BasicLSTMCell(steps) for steps in layers]\     def dnn_layers(input_layers, layers):\         if layers and isinstance(layers, dict):\             return skflow.ops.dnn(input_layers,\                                   layers['layers'],\                                   activation=layers.get('activation'),\                                   dropout=layers.get('dropout'))\         elif layers:\             return skflow.ops.dnn(input_layers, layers)\         else:\             return input_layers\     def _lstm_model(X, y):\         stacked_lstm = tf.nn.rnn_cell.MultiRNNCell(lstm_cells(rnn_layers))\         x_ = skflow.ops.split_squeeze(1, time_steps, X)\         output, layers = tf.nn.rnn(stacked_lstm, x_, dtype=dtypes.float32)\         output = dnn_layers(output[-1], dense_layers)\         return skflow.models.linear_regression(output, y)\     return _lstm_model\
\\

所建立的模型期望输入数据的维度与(batch size,第一个lstm cell的时间步长time_step,特征数量num_features)相关。\

接下来我们按模型所能接受的数据方式来准备数据。

\\
\def rnn_data(data, time_steps, labels=False):\    \"\"\"\    creates new data frame based on previous observation\      * example:\        l = [1, 2, 3, 4, 5]\        time_steps = 2\        -\u0026gt; labels == False [[1, 2], [2, 3], [3, 4]]\        -\u0026gt; labels == True [2, 3, 4, 5]\    \"\"\"\    rnn_df = []\    for i in range(len(data) - time_steps):\        if labels:\            try:\                rnn_df.append(data.iloc[i + time_steps].as_matrix())\            except AttributeError:\                rnn_df.append(data.iloc[i + time_steps])\        else:\            data_ = data.iloc[i: i + time_steps].as_matrix()\            rnn_df.append(data_ if len(data_.shape) \u0026gt; 1 else [[i] for i in data_])\    return np.array(rnn_df)\def split_data(data, val_size=0.1, test_size=0.1):\    \"\"\"\    splits data to training, validation and testing parts\    \"\"\"\    ntest = int(round(len(data) * (1 - test_size)))\    nval = int(round(len(data.iloc[:ntest]) * (1 - val_size)))\    df_train, df_val, df_test = data.iloc[:nval], data.iloc[nval:ntest], data.iloc[ntest:]\    return df_train, df_val, df_test\def prepare_data(data, time_steps, labels=False, val_size=0.1, test_size=0.1):\    \"\"\"\    Given the number of `time_steps` and some data.\    prepares training, validation and test data for an lstm cell.\    \"\"\"\    df_train, df_val, df_test = split_data(data, val_size, test_size)\    return (rnn_data(df_train, time_steps, labels=labels),\            rnn_data(df_val, time_steps, labels=labels),\            rnn_data(df_test, time_steps, labels=labels))\def generate_data(fct, x, time_steps, seperate=False):\    \"\"\"generate data with based on a function fct\"\"\"\    data = fct(x)\    if not isinstance(data, pd.DataFrame):\        data = pd.DataFrame(data)\    train_x, val_x, test_x = prepare_data(data['a'] if seperate else data, time_steps)\    train_y, val_y, test_y = prepare_data(data['b'] if seperate else data, time_steps, labels=True)\    return dict(train=train_x, val=val_x, test=test_x), dict(train=train_y, val=val_y, test=test\
\\

这将会创建一个数据让模型可以查找过去time_steps步来预测数据。比如,LSTM模型的第一个cell是10 time_steps cell,为了做预测我们需要输入10个历史数据点。y值跟我们想预测的第十个值相关。\

现在创建一个基于LSTM模型的回归量。

\\
\regressor = skflow.TensorFlowEstimator(model_fn=lstm_model(TIMESTEPS, RNN_LAYERS, DENSE_LAYERS),\                                       n_classes=0,\                                       verbose=1,  \                                       steps=TRAINING_STEPS,\                                       optimizer='Adagrad',\                                       learning_rate=0.03,\                                       batch_size=BATCH_SIZE)\
\\

预测sin函数

\\
\X, y = generate_data(np.sin, np.linspace(0, 100, 10000), TIMESTEPS, seperate=False)\# create a lstm instance and validation monitor\validation_monitor = skflow.monitors.ValidationMonitor(X['val'], y['val'], n_classes=0,\                                                       print_steps=PRINT_STEPS,\                                                       early_stopping_rounds=1000,\                                                       logdir=LOG_DIR)\regressor.fit(X['train'], y['train'], validation_monitor, logdir=LOG_DIR)\# \u0026gt; last training steps\# Step #9700, epoch #119, avg. train loss: 0.00082, avg. val loss: 0.00084\# Step #9800, epoch #120, avg. train loss: 0.00083, avg. val loss: 0.00082\# Step #9900, epoch #122, avg. train loss: 0.00082, avg. val loss: 0.00082\# Step #10000, epoch #123, avg. train loss: 0.00081, avg. val loss: 0.00081\
\\

预测测试数据

\\
\mse = mean_squared_error(regressor.predict(X['test']), y['test'])\print (\"Error: {}\".format(mse))\# 0.000776\
\\

真实sin函数

\\

3df4e1752e9b14c8c3ad65b50f973627.png

\\

预测sin函数

\\

ce275cc36d33ce478323c4921bac53c5.png

\\

预测sin和cos混合函数

\\
\def sin_cos(x):\    return pd.DataFrame(dict(a=np.sin(x), b=np.cos(x)), index=x)\X, y = generate_data(sin_cos, np.linspace(0, 100, 10000), TIMESTEPS, seperate=False)\# create a lstm instance and validation monitor\validation_monitor = skflow.monitors.ValidationMonitor(X['val'], y['val'], n_classes=0,\                                                       print_steps=PRINT_STEPS,\                                                       early_stopping_rounds=1000,\                                                       logdir=LOG_DIR)\regressor.fit(X['train'], y['train'], validation_monitor, logdir=LOG_DIR)\# \u0026gt; last training steps\# Step #9500, epoch #117, avg. train loss: 0.00120, avg. val loss: 0.00118\# Step #9600, epoch #118, avg. train loss: 0.00121, avg. val loss: 0.00118\# Step #9700, epoch #119, avg. train loss: 0.00118, avg. val loss: 0.00118\# Step #9800, epoch #120, avg. train loss: 0.00118, avg. val loss: 0.00116\# Step #9900, epoch #122, avg. train loss: 0.00118, avg. val loss: 0.00115\# Step #10000, epoch #123, avg. train loss: 0.00117, avg. val loss: 0.00115\
\\

预测测试数据

\\
\mse = mean_squared_error(regressor.predict(X['test']), y['test'])\print (\"Error: {}\".format(mse))\# 0.001144\
\\

真实的sin_cos函数

\\

fb7f1a0538d9637c0d119274fb1285ac.png

\\

预测的sin_cos函数

\\

bd4a9dea64226614d1c2171bfd754f99.png

\\
预测x*sin函数
\\
\def x_sin(x):\     return x * np.sin(x)\ X, y = generate_data(x_sin, np.linspace(0, 100, 10000), TIMESTEPS, seperate=False)\ # create a lstm instance and validation monitor\ validation_monitor = skflow.monitors.ValidationMonitor(X['val'], y['val'], n_classes=0,\                                                        print_steps=PRINT_STEPS,\                                                        early_stopping_rounds=1000,\                                                        logdir=LOG_DIR)\ regressor.fit(X['train'], y['train'], validation_monitor, logdir=LOG_DIR)\ # \u0026gt; last training steps\ # Step #32500, epoch #401, avg. train loss: 0.48248, avg. val loss: 15.98678\ # Step #33800, epoch #417, avg. train loss: 0.47391, avg. val loss: 15.92590\ # Step #35100, epoch #433, avg. train loss: 0.45570, avg. val loss: 15.77346\ # Step #36400, epoch #449, avg. train loss: 0.45853, avg. val loss: 15.61680\ # Step #37700, epoch #465, avg. train loss: 0.44212, avg. val loss: 15.48604\ # Step #39000, epoch #481, avg. train loss: 0.43224, avg. val loss: 15.43947\
\\

预测测试数据

\\
\mse = mean_squared_error(regressor.predict(X['test']), y['test'])\print (\"Error: {}\".format(mse))\# 61.024454351\
\\

真实的x*sin函数

\\

15117ac90c23755ac54f86d2ae723fc0.png

\\

预测的x*sin函数

\\

a213b516943f882848665cdf35aea858.png

\\

译者信息:侠天,专注于大数据、机器学习和数学相关的内容,并有个人公众号:bigdata_ny分享相关技术文章。

\\

英文原文:

转载地址:http://rvyqa.baihongyu.com/

你可能感兴趣的文章
CentOS 7 中使用NTP进行时间同步
查看>>
在MongoDB数据库中查询数据(上)
查看>>
Python import其他文件夹的文件
查看>>
Jvm(22),回收策略-----标记清除算法
查看>>
MySQL多表关联查询效率高点还是多次单表查询效率高,为什么?
查看>>
UNIX 高手的 10 个习惯
查看>>
传值与传引用
查看>>
HDU 1538 A Puzzle for Pirates(海盗分金问题)
查看>>
C# Web Forms - Using jQuery FullCalendar
查看>>
Sublime-Text-2-pydocstring --- 自动生成python docstring的插件
查看>>
UNIX进程环境
查看>>
学习面试题Day03
查看>>
我最喜欢的jQuery插件模板
查看>>
【云计算】Docker 多进程管理方案
查看>>
[LeetCode] Best Meeting Point 最佳开会地点
查看>>
基于InstallShield2013LimitedEdition的安装包制作
查看>>
【转】从Shell脚本内部将所有标准输出及标准错误显示在屏幕并同时写入文件的方法...
查看>>
Python中的图形库
查看>>
Linux操作系统分析 ------------------中国科技大学
查看>>
Apache多站点实现原理和配置
查看>>