在 keras 中使用 LSTM 进行预测
Posted
技术标签:
【中文标题】在 keras 中使用 LSTM 进行预测【英文标题】:prediction with LSTM in keras 【发布时间】:2021-09-15 13:12:16 【问题描述】:我的 LSTM 遇到了问题。我想做的是:
我有一个表格中的数据集:
0.04,-9.77,0.71,1,0,0,0
...
...
前三个参数是加速度计采集的数据:X加速度、Y加速度、Z加速度
最后四列是标签:
[1,0,0,0] [0,1,0,0] [0,0,1,0] [0,0,0,1] [0,0,0,0]
每个代表一个不同的类。
我的网络声明如下:
class Config:
def __init__(self):
"""network parameters"""
self.batch_size = 16
self.input_size = 3
self.seq_max_len = 20
self.rnn_size = 50
self.keep_prob = 1
self.mlp_hidden_size = 100
self.mlp_projection_activation = tf.nn.tanh
self.num_classes = 4
self.learning_rate = 0.001
self.epochs = 10
model = tf.keras.Sequential([
tf.keras.layers.InputLayer(input_shape=(config.seq_max_len, config.input_size)),
tf.keras.layers.LSTM(units=config.rnn_size, return_sequences=True, return_state=False),
tf.keras.layers.Dense(units=config.mlp_hidden_size, activation=config.mlp_projection_activation),
tf.keras.layers.Dense(units=config.num_classes, activation='softmax'),
])
loss_fn = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
model.compile(optimizer='adam', loss=loss_fn, metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=config.batch_size, epochs=config.epochs)
现在,问题是这不像我想的那样工作。当我尝试预测时,假设使用数组:
arr = np.array([(-0.12,-9.85,0.82),(-1.33,-10,1.61),(-1.57,-10.04,0.9),(0.08,-9.14,0.51),(3.77,-8.36,-0.55),(6.71,-8.43,-1.69),
(9.22,-8.28,-2.63),(10.75,-7.65,-2.98),(9.26,-7.61,-2.35),(6.16,-7.85,-1.77),(2.35,-8.51,-0.78),(-1.10,-8.87,0.71),(-3.61,-9.14,2.31),
(-5.49,-9.65,3.69),
(-5.33,-9.49,3.14),
(-4.24,-9.26,3.30),
(-2.43,-9.06,2.24),
(-0.39,-8.87,1.29),
(3.61,-8.55,-1.22),
(7.10,-8.28,-1.57)])
由 20 个三元组的 3d 向量(加速度)组成,我得到的是
predictions = model.predict_classes(arr)
[[0 2 2 0 0 0 0 0 0 0 0 2 2 2 2 2 2 2 0 0]]
这是一个向量,表示对 arr 向量中每个三元组的预测。我想要的是只有一个预测,在 20 个三元组之后。这是因为我的数据代表一个时间序列,我感兴趣的是知道网络是否能够在一定数量的加速向量(本例中为 20 个)之后对数据进行分类。
可以帮帮我吗?
编辑
完整代码:
import tensorflow as tf
import numpy as np
import pandas as pd
import random
import sys
np.set_printoptions(threshold=sys.maxsize)
def get_dataset(filename, config):
df = pd.read_csv(filename, header=None, skiprows=1)
x = df[[0, 1, 2]].values
y = df[[3, 4, 5, 6]].values
dataset_x, dataset_y = [],[]
for i in range(x.shape[0]//config.seq_max_len):
sequence_x, sequence_y = [],[]
for j in range(config.seq_max_len):
sequence_x.append(x[i*config.seq_max_len + j])
sequence_y.append(y[i*config.seq_max_len + j])
dataset_x.append(sequence_x)
dataset_y.append(sequence_y)
return np.array(dataset_x), np.array(dataset_y)
class Config:
def __init__(self):
"""definizione dei parametri della rete"""
self.batch_size = 16
self.input_size = 3
self.seq_max_len = 20
self.rnn_size = 50
self.keep_prob = 1
self.mlp_hidden_size = 100
self.mlp_projection_activation = tf.nn.tanh
self.num_classes = 4
self.learning_rate = 0.001
self.epochs = 10
config = Config()
x_train, y_train = get_dataset('data_new.csv', config)
arr = np.array([(-0.12,-9.85,0.82),(-1.33,-10,1.61),(-1.57,-10.04,0.9),(0.08,-9.14,0.51),(3.77,-8.36,-0.55),(6.71,-8.43,-1.69),
(9.22,-8.28,-2.63),(10.75,-7.65,-2.98),(9.26,-7.61,-2.35),(6.16,-7.85,-1.77),(2.35,-8.51,-0.78),(-1.10,-8.87,0.71),(-3.61,-9.14,2.31),
(-5.49,-9.65,3.69),
(-5.33,-9.49,3.14),
(-4.24,-9.26,3.30),
(-2.43,-9.06,2.24),
(-0.39,-8.87,1.29),
(3.61,-8.55,-1.22),
(7.10,-8.28,-1.57)])
arr2 = np.reshape(arr,(1,20,3))
print(arr2.shape)
model = tf.keras.Sequential([
tf.keras.layers.InputLayer(input_shape=(config.seq_max_len, config.input_size)),
tf.keras.layers.LSTM(units=config.rnn_size, return_sequences=True, return_state=False),
tf.keras.layers.Dense(units=config.mlp_hidden_size, activation=config.mlp_projection_activation),
tf.keras.layers.Dense(units=config.num_classes, activation='softmax'),
])
loss_fn = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
model.compile(optimizer='adam', loss=loss_fn, metrics=['accuracy'])
model.fit(x_train, y_train, batch_size=config.batch_size, epochs=config.epochs)
predictions = model.predict(arr2)
predictions = np.argmax(predictions, axis=-1)
print("PREDIZIONI---------")
print(predictions.shape)
print(predictions)
【问题讨论】:
【参考方案1】:有两个可能的问题。一个是如果你设置
tf.keras.layers.LSTM(units=.., return_sequences=True, return_state=False)
如果您在模型的最后一层打印model. summary()
,您将得到如下结果。这可能不是你想要的最后一层。
dense_5 (Dense) (None, 20, 4) 404
=================================================================
所以,你应该使用return_sequence = False
来得到最终的层输出形状如下:
dense_7 (Dense) (None, 4) 404
=================================================================
其次,您在损失函数中设置
....CategoricalCrossentropy(from_logits=True)
但您在最后一层设置activation='softma'
以获取概率而不是logits。
....Dense(units=config.num_classes, activation='softmax')
所以,基于此设置参数如下:
....LSTM(units=.., return_sequences=False, return_state=False)
...
....CategoricalCrossentropy(from_logits=False) # compute probabilities
...
y_pred = model.predict(arr)
y_pred = np.argmax(y_pred, axis=-1)
【讨论】:
如果我尝试您的建议,我会得到:ValueError: Shapes (None, 20, 4) and (None, 4) are incompatible 模型的最后一层输出形状是什么?你的标签是什么形状的?两者都必须是形状大小,例如模型输出(None, 4)
和标签形状(None, 4)
。
你能用虚拟数据(在 colab 中)分享可重现的代码吗?
drive.google.com/file/d/1S_G_lgElL3kOeK_k7vfVVlhfmE8sO1aC/… 这里是数据集
我已经在主要问题中添加了完整的代码以上是关于在 keras 中使用 LSTM 进行预测的主要内容,如果未能解决你的问题,请参考以下文章
如何让 Keras LSTM 在多变量设置中对多个时间序列进行预测?