如何使用 keras 堆叠 LSTM 模型正确塑造多类分类的输入

Posted

技术标签:

【中文标题】如何使用 keras 堆叠 LSTM 模型正确塑造多类分类的输入【英文标题】:how to correctly shape input of a multiclass classification using keras stacked LSTM model 【发布时间】:2020-04-11 22:15:46 【问题描述】:

我正在研究一个多重分类问题,在涉足多种神经网络架构之后,我选择了 stacked LSTM 结构,因为它可以为我的使用提供最佳准确度-案子。不幸的是,即使我使用 GPU 加速,网络也需要很长时间(几乎 48 小时)才能达到良好的精度(~1000 epochs)。得到的准确率和损失函数为:

在这一点上,提供了良好的性能但训练非常缓慢,我怀疑我的代码中存在错误。我使用here 中提到的黄金测试 对其进行了测试,该测试包括运行测试,仅在测试集或训练集中获得 2 分,同时消除了辍学。不幸的是,这些运行的输出导致测试准确度优于训练准确度,据我所知,情况并非如此。我怀疑我以错误的方式塑造我的数据。 感谢任何提示、建议和建议。

我的代码如下:

# -*- coding: utf-8 -*-
import keras
import numpy as np
from time import time
from utils import dmanip, vis
from keras.models import Sequential
from keras.layers import LSTM, Dense
from keras.utils import to_categorical
from keras.callbacks import TensorBoard
from sklearn.preprocessing import LabelEncoder
from tensorflow.python.client import device_lib
from sklearn.model_selection import train_test_split

###############################################################################
####################### Extract the data from .csv file #######################
###############################################################################
# get data
data, column_names = dmanip.get_data(file_path='../data_one_outcome.csv')

# split data
X = data.iloc[:, :-1]
y = data.iloc[:, -1:].astype('category')

###############################################################################
########################## init global config vars ############################
###############################################################################
# check if GPU is used
print(device_lib.list_local_devices())

# init
n_epochs = 1500
n_comps = X.shape[1]

###############################################################################
################################## Keras RNN ##################################
###############################################################################
# encode the classification labels
le = LabelEncoder()
yy = to_categorical(le.fit_transform(y))

# split the dataset
x_train, x_test, y_train, y_test = train_test_split(X, yy, test_size=0.35,
                                                    random_state=True,
                                                    shuffle=True)

# expand dimensions
x_train = np.expand_dims(x_train, axis=2)
x_test = np.expand_dims(x_test, axis=2)

# define model
model = Sequential()
model.add(LSTM(units=n_comps, return_sequences=True,
               input_shape=(x_train.shape[1], 1),
               dropout=0.2, recurrent_dropout=0.2))
model.add(LSTM(64, return_sequences=True, dropout=0.2, recurrent_dropout=0.2))
model.add(LSTM(32, dropout=0.2, recurrent_dropout=0.2))
model.add(Dense(4 ,activation='softmax'))

# print model architecture summary
print(model.summary())

# compile model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

# Create a TensorBoard instance with the path to the logs directory
tensorboard = TensorBoard(log_dir='./logs/rnn/'.format(time()))

# fit the model
history = model.fit(x_train, y_train, epochs=n_epochs, batch_size=100,
                    validation_data=(x_test, y_test), callbacks=[tensorboard])

# plot results
vis.plot_nn_stats(history=history, stat_type="accuracy", fname="RNN-accuracy")
vis.plot_nn_stats(history=history, stat_type="loss", fname="RNN-loss")

我的数据是一个大的二维矩阵(38607, 150),其中 149 是特征数,38607 是样本数,目标向量包括 4 个类。

       feat1   feat2   ...  feat148  feat149  target
1      2.250   0.926   ...  16.0      0.0     class1
2      2.791   1.235   ...  1.0       0.0     class2
         .       .     .     .         .         .
         .       .      .    .         .         .
         .       .       .   .         .         .
38406  2.873   1.262   ...  281.0     0.0     class3
38407  3.222   1.470   ...  467.0     1.0     class4

【问题讨论】:

【参考方案1】:

关于Training的缓慢性:你可以考虑用tf.data代替Data FramesNumpy Arrays,因为Achieving peak performance requires an efficient input pipeline that delivers data for the next step before the current step has finished. The tf.data API helps to build flexible and efficient input pipelines.

更多关于tf.data的信息,请参考这个TensorflowDocumentation 1,Documentation 2。

此Tensorflow Tutorial 指导您将Data Frame 转换为tf.data 格式。

您可以使用的另一个重要功能是tf.profiler。使用Tensorflow Profiler,您不仅可以VisualizeTime and Memory 在数据科学项目的每个阶段使用,还可以为我们提供建议/建议,以减少Time/Memory Consumption,从而优化我们的项目。

有关 Tensorflow Profiler 的更多信息,请参阅 Documentation、Tutorial 和 Tensorflow DevSummit Youtube Video。

关于测试准确性比培训准确性更重要:这不是一个大问题,有时会发生。

可能的原因 1:辍学 ==>您在模型中使用 Dropoutrecurrent_dropout 的原因是什么?模特是Overfitting?如果模型不是Overfitting,没有Dropoutrecurrent_dropout,那么你可以考虑删除它们,因为,如果你设置Dropout (0.2)recurrent_dropout (0.2)这意味着20%特征将是0 20% 的时间步长将为 0,在 training 期间。然而,在testing期间使用了所有的Features和Timesteps,因此模型更加健壮并且具有更好的测试精度

可能的原因 2: 35%Testing Data 比平时多一点。您可以使用20%25%

可能的原因 3:您的 training data 可能有几个难以学习的案例,而您的 Testing data 可能包含更容易预测的案例。为了缓解这种情况,您可以使用不同的随机种子再次拆分数据。

更多信息请参考Research Gate Link和Stack Overflow Link。

希望这会有所帮助。快乐学习!

【讨论】:

以上是关于如何使用 keras 堆叠 LSTM 模型正确塑造多类分类的输入的主要内容,如果未能解决你的问题,请参考以下文章

用于 LSTM 的 Keras 多元形状

如何选择 LSTM Keras 参数?

Keras 在训练分类 LSTM 序列到序列模型时给出 nan

我如何正确使用Keras Add图层?

使用 Keras,如何将 CuDNNLSTM 生成的权重加载到 LSTM 模型中?

如何在 Keras 中组合两个具有不同输入大小的 LSTM 层?