dre*_*mer 36 python pandas lstm keras
我知道Keras的LSTM需要一个带有形状(nb_samples, timesteps, input_dim)作为输入的3D张量.但是,我不完全确定在我的情况下输入应该是什么样子,因为我只有一个T观察样本用于每个输入,而不是多个样本,即(nb_samples=1, timesteps=T, input_dim=N).将每个输入分成长度样本是否更好T/M?T对我来说是几百万的观察,那么在这种情况下每个样本应该多长时间,即我将如何选择M?
另外,我是正确的,因为这个张量应该看起来像:
[[[a_11, a_12, ..., a_1M], [a_21, a_22, ..., a_2M], ..., [a_N1, a_N2, ..., a_NM]],
[[b_11, b_12, ..., b_1M], [b_21, b_22, ..., b_2M], ..., [b_N1, b_N2, ..., b_NM]],
...,
[[x_11, x_12, ..., a_1M], [x_21, x_22, ..., x_2M], ..., [x_N1, x_N2, ..., x_NM]]]
Run Code Online (Sandbox Code Playgroud)
其中M和N如前所述定义,x对应于我将从上面讨论的分裂中获得的最后一个样本?
最后,给定一个pandas数据帧,T每列中都有观察值,N列,每个输入一个,如何创建这样的输入以馈送给Keras?
And*_*rew 43
下面是一个设置时间序列数据以训练LSTM的示例.模型输出是无稽之谈,因为我只是设置它来演示如何构建模型.
import pandas as pd
import numpy as np
# Get some time series data
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/timeseries.csv")
df.head()
Run Code Online (Sandbox Code Playgroud)
时间序列数据帧:
Date A B C D E F G
0 2008-03-18 24.68 164.93 114.73 26.27 19.21 28.87 63.44
1 2008-03-19 24.18 164.89 114.75 26.22 19.07 27.76 59.98
2 2008-03-20 23.99 164.63 115.04 25.78 19.01 27.04 59.61
3 2008-03-25 24.14 163.92 114.85 27.41 19.61 27.84 59.41
4 2008-03-26 24.44 163.45 114.84 26.86 19.53 28.02 60.09
Run Code Online (Sandbox Code Playgroud)
您可以将put输入构建到向量中,然后使用pandas .cumsum()函数构建时间序列的序列:
# Put your inputs into a single list
df['single_input_vector'] = df[input_cols].apply(tuple, axis=1).apply(list)
# Double-encapsulate list so that you can sum it in the next step and keep time steps as separate elements
df['single_input_vector'] = df.single_input_vector.apply(lambda x: [list(x)])
# Use .cumsum() to include previous row vectors in the current row list of vectors
df['cumulative_input_vectors'] = df.single_input_vector.cumsum()
Run Code Online (Sandbox Code Playgroud)
输出可以以类似的方式设置,但它将是单个向量而不是序列:
# If your output is multi-dimensional, you need to capture those dimensions in one object
# If your output is a single dimension, this step may be unnecessary
df['output_vector'] = df[output_cols].apply(tuple, axis=1).apply(list)
Run Code Online (Sandbox Code Playgroud)
输入序列必须具有相同的长度才能在模型中运行它们,因此您需要将它们填充为累积向量的最大长度:
# Pad your sequences so they are the same length
from keras.preprocessing.sequence import pad_sequences
max_sequence_length = df.cumulative_input_vectors.apply(len).max()
# Save it as a list
padded_sequences = pad_sequences(df.cumulative_input_vectors.tolist(), max_sequence_length).tolist()
df['padded_input_vectors'] = pd.Series(padded_sequences).apply(np.asarray)
Run Code Online (Sandbox Code Playgroud)
可以从数据框中提取训练数据并将其放入numpy数组中. 请注意,从数据帧中输出的输入数据不会生成3D数组.它创建了一个数组数组,这不是一回事.
您可以使用hstack和reshape来构建3D输入数组.
# Extract your training data
X_train_init = np.asarray(df.padded_input_vectors)
# Use hstack to and reshape to make the inputs a 3d vector
X_train = np.hstack(X_train_init).reshape(len(df),max_sequence_length,len(input_cols))
y_train = np.hstack(np.asarray(df.output_vector)).reshape(len(df),len(output_cols))
Run Code Online (Sandbox Code Playgroud)
为了证明这一点:
>>> print(X_train_init.shape)
(11,)
>>> print(X_train.shape)
(11, 11, 6)
>>> print(X_train == X_train_init)
False
Run Code Online (Sandbox Code Playgroud)
获得训练数据后,您可以定义输入图层和输出图层的尺寸.
# Get your input dimensions
# Input length is the length for one input sequence (i.e. the number of rows for your sample)
# Input dim is the number of dimensions in one input vector (i.e. number of input columns)
input_length = X_train.shape[1]
input_dim = X_train.shape[2]
# Output dimensions is the shape of a single output vector
# In this case it's just 1, but it could be more
output_dim = len(y_train[0])
Run Code Online (Sandbox Code Playgroud)
建立模型:
from keras.models import Model, Sequential
from keras.layers import LSTM, Dense
# Build the model
model = Sequential()
# I arbitrarily picked the output dimensions as 4
model.add(LSTM(4, input_dim = input_dim, input_length = input_length))
# The max output value is > 1 so relu is used as final activation.
model.add(Dense(output_dim, activation='relu'))
model.compile(loss='mean_squared_error',
optimizer='sgd',
metrics=['accuracy'])
Run Code Online (Sandbox Code Playgroud)
最后,您可以训练模型并将训练日志保存为历史记录:
# Set batch_size to 7 to show that it doesn't have to be a factor or multiple of your sample size
history = model.fit(X_train, y_train,
batch_size=7, nb_epoch=3,
verbose = 1)
Run Code Online (Sandbox Code Playgroud)
输出:
Epoch 1/3
11/11 [==============================] - 0s - loss: 3498.5756 - acc: 0.0000e+00
Epoch 2/3
11/11 [==============================] - 0s - loss: 3498.5755 - acc: 0.0000e+00
Epoch 3/3
11/11 [==============================] - 0s - loss: 3498.5757 - acc: 0.0000e+00
Run Code Online (Sandbox Code Playgroud)
而已.使用model.predict(X)地方X是相同的格式(比样本的数量等),如X_train为了使从模型预测.
张量形状
你说得对,Keras期待一个LSTM神经网络三维张量,但我认为你缺少的一块是Keras预计每个观察可以有多个层面.
例如,在Keras中,我使用单词向量来表示自然语言处理的文档.文档中的每个单词都由一个n维数字向量表示(如果n = 2单词'cat'将用类似的东西表示[0.31, 0.65]).为了表示单个文档,单词向量按顺序排列(例如'The cat sat.'= [[0.12, 0.99], [0.31, 0.65], [0.94, 0.04]]).文档将是Keras LSTM中的单个样本.
这类似于您的时间序列观察.文档就像一个时间序列,一个单词就像你的时间序列中的单个观察,但在你的情况下,你的观察的表示只是n = 1维度.
正因为如此,我认为你应该张是有点像[[[a1], [a2], ... , [aT]], [[b1], [b2], ..., [bT]], ..., [[x1], [x2], ..., [xT]]],其中x对应nb_samples,timesteps = T以及input_dim = 1,因为每个你所观察的是只有一个号码.
批量大小
根据此Cross Validated帖子,应将批量大小设置为最大化吞吐量,而不会超出计算机上的内存容量.据我所知,您的输入不需要是批量大小的倍数,无论是在训练模型还是从中进行预测时.
例子
如果您正在寻找示例代码,那么在Keras Github上有许多使用LSTM和其他具有排序输入的网络类型的示例.
| 归档时间: |
|
| 查看次数: |
17715 次 |
| 最近记录: |