简体   繁体   English

在 keras 中使用 LSTM 进行预测

[英]prediction with LSTM in keras

I'm stuck with a problem with my LSTM.我的 LSTM 有问题。 What I want to do is the following:我想要做的是以下内容:

I have a dataset in the form:我有一个以下形式的数据集:

0.04,-9.77,0.71,1,0,0,0
...
...

The first three parameters are data collected by an accelerometer: X acceleration, Y acceleration, Z acceleration前三个参数是加速度计采集的数据:X加速度、Y加速度、Z加速度

The last four columns are the labels:最后四列是标签:

[1,0,0,0] [0,1,0,0] [0,0,1,0] [0,0,0,1] [0,0,0,0]

where each one represents a different class.其中每个代表一个不同的类。

My network is declared as follows:我的网络声明如下:

 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)

Now, the problem is that this is not working as i would.现在,问题是这不像我那样工作。 When i try to predict, let's say using an array:当我尝试预测时,假设使用数组:

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)])

Composed by 20 triplette of 3d vectors (accelerations) what i obtain is由 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]]

which is a vector that represents a prediction for each triplette in the arr vector.这是一个向量,表示对 arr 向量中每个三元组的预测。 What i want, is to have ONLY ONE prediction, after the 20 triplette.我想要的是在 20 个三元组之后只有一个预测。 This is because my data represent a time series and what i am interested in, is to know if the network is able to classify data after a certain amount of acceleration vectors (20 in this case).这是因为我的数据代表一个时间序列,而我感兴趣的是知道网络是否能够在一定数量的加速度向量(在这种情况下为 20)后对数据进行分类。

Can help me please?可以帮我吗?

EDIT编辑

full code:完整代码:

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)

There are two possible issues.有两个可能的问题。 One is if you set一种是如果你设置

tf.keras.layers.LSTM(units=.., return_sequences=True, return_state=False)

You would get as follows if you print model. summary()如果您打印model. summary()您将得到如下结果model. summary() model. summary() in the final layer of your model. model. summary()在模型的最后一层。 And that probably not what you want in your final layer.这可能不是您在最后一层中想要的。

dense_5 (Dense)              (None, 20, 4)             404       
=================================================================

So, you should use return_sequence = False to get the final layer output shape as follows:因此,您应该使用return_sequence = False来获得最终的图层输出形状,如下所示:

dense_7 (Dense)              (None, 4)                 404       
=================================================================

Second, you set in your loss function that其次,您在损失函数中设置

 ....CategoricalCrossentropy(from_logits=True)

but you set activation='softma' in the final layer to get the probabilities instead of logits.但是你在最后一层设置了activation='softma'来获得概率而不是 logits。

....Dense(units=config.num_classes, activation='softmax')

So, based on this set the parameter as follows:因此,基于此设置参数如下:

....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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM