Keras 中 LSTM 的 2D 输入

数据挖掘 神经网络 喀拉斯 时间序列 lstm rnn
2022-01-22 12:32:08

我有以下问题:我想喂 LSTM

train_datagen.flow_from_directory

输入基本上是从时间序列转换为 PNG 格式的时频域的频谱图图像,其维度为:时间步长 x 频谱。1 个样本 = 1 个uint8中的 PNG 图像。在我的示例中:3601 个时间步长,217 个频谱(=特征)/时间步长。

频谱图本身只是一维的,但我认为“从目录流”功能被硬编码为只准备 3D 图像矩阵,因此输入形状变成了,这完全是遗憾,因为有些人只使用纯灰度uint8 图像,以及一些使用多光谱和高光谱图像的人。

我的代码如下:

import keras
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Activation, Dropout, Flatten, Dense
from keras.layers import LSTM
from keras import optimizers
from keras import backend as K
import tensorflow as tf

img_width, img_height = 3601,217
train_data_dir = 'sensor1/training'
validation_data_dir = 'sensor1/validation'

num_classes = 10
nb_train_samples = num_classes*70
nb_validation_samples = num_classes*20
epochs = 20
batch_size = 10
input_shape = (img_width, img_height)

model.add(LSTM(units=256, input_shape= input_shape, return_sequences=True))
model.add(LSTM(units=128, return_sequences=True))
model.add(LSTM(units=64))
model.add(Dense(128))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])

train_datagen = ImageDataGenerator(rescale = 1. / 255)
test_datagen = ImageDataGenerator(rescale = 1. / 255)

train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size)

validation_generator = test_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size)

model.fit_generator(
    train_generator,
    steps_per_epoch=nb_train_samples // batch_size,
    epochs=epochs,
    callbacks=[plot_losses],
    validation_data=validation_generator,
    validation_steps=nb_validation_samples // batch_size)

然后,一旦我运行该程序,它当然会给出一条错误消息:

**ValueError: Error when checking input: expected lstm_50_input to have 3 dimensions, but got array with shape (10, 3601, 217, 3)**

消息:

预期 lstm_50_input 有 3 个维度,但得到了形状为 (10, 3601, 217, 3) 的数组

清楚地表明它不同意我对输入形状的定义: (3601, 217)

有什么想法可以轻松解决问题吗?提前致谢。

1个回答

为什么将最后一个维度定义为input_shapeas3? 只需相应地输入您想要的输入尺寸,就可以了:

input_shape = (img_width, img_height)

使用完整代码更新:

最好的方法是使用TimeseriesGenerator而不是,ImageDataGenerator但似乎没有flow_from_directory满足您需求的方法。所以,我认为最好的解决方案是压缩生成器输出的最后一个维度。此外,您还有一个color_mode选项,允许为灰度图像生成仅 1 通道的张量。相关部分的完整代码:

model = Sequential()
model.add(Lambda(lambda x: x[:,:,:,0], input_shape=(*input_shape, 1)))
model.add(LSTM(units=256, return_sequences=True))
model.add(LSTM(units=128, return_sequences=True))
model.add(LSTM(units=64))
model.add(Dense(128))
model.add(Dense(num_classes, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop', metrics=['accuracy'])


train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    color_mode='grayscale')

validation_generator = test_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_width, img_height),
    batch_size=batch_size,
    color_mode='grayscale')