如何将1D扁平MNIST Keras转换为LSTM模型而不会松弛?

问题描述 投票:0回答:1

我想在LSTM上稍微改变我的模型架构,因此它接受完全连接方法所做的相同的精确平坦输入。

从Keras示例中使用Dnn模型

import keras

from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras.utils import to_categorical

# import the data
from keras.datasets import mnist

# read the data
(x_train, y_train), (x_test, y_test) = mnist.load_data()

num_pixels = x_train.shape[1] * x_train.shape[2] # find size of one-dimensional vector

x_train = x_train.reshape(x_train.shape[0], num_pixels).astype('float32') # flatten training images
x_test = x_test.reshape(x_test.shape[0], num_pixels).astype('float32') # flatten test images

# normalize inputs from 0-255 to 0-1
x_train = x_train / 255
x_test = x_test / 255

# one hot encode outputs
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)

num_classes = y_test.shape[1]
print(num_classes)



# define classification model
def classification_model():
    # create model
    model = Sequential()
    model.add(Dense(num_pixels, activation='relu', input_shape=(num_pixels,)))
    model.add(Dense(100, activation='relu'))
    model.add(Dense(num_classes, activation='softmax'))


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


# build the model
model = classification_model()

# fit the model
model.fit(x_train, y_train, validation_data=(x_test, y_test), epochs=10, verbose=2)

# evaluate the model
scores = model.evaluate(x_test, y_test, verbose=0)

同样的问题,但尝试LSTM(语法错误仍然)

def kaggle_LSTM_model():
    model = Sequential()
    model.add(LSTM(128, input_shape=(x_train.shape[1:]), activation='relu', return_sequences=True))
    # What does return_sequences=True do?
    model.add(Dropout(0.2))

    model.add(Dense(32, activation='relu'))
    model.add(Dropout(0.2))

    model.add(Dense(10, activation='softmax'))

    opt = tf.keras.optimizers.Adam(lr=1e-3, decay=1e-5)
    model.compile(loss='sparse_categorical_crossentropy', optimizer=opt,
             metrics=['accuracy'])

    return model

model_kaggle_LSTM = kaggle_LSTM_model()

# fit the model
model_kaggle_LSTM.fit(x_train, y_train, validation_data=(x_test, y_test), epochs=10, verbose=2)

# evaluate the model
scores = model_kaggle_LSTM.evaluate(x_test, y_test, verbose=0)

问题在这里:

model.add(LSTM(128, input_shape=(x_train.shape[1:]), activation='relu', return_sequences=True))

ValueError:输入0与层lstm_17不兼容:预期ndim = 3,发现ndim = 2

如果我回去并且不压平x_train和y_train,它就可以了。但是,我希望这是“另一种模式选择”,它可以提供相同的预处理输入。我认为传递形状[1:]会像真正扁平化的input_shape一样工作。我确信这是一件容易的事情,我对于维度感觉很缺乏,但经过一个小时的调整和调试后我无法得到它,虽然确实没有弄清楚28x28到784的作品,但我不明白为什么它作品。非常感谢!

对于奖励积分,如何在1D(784,)或2D(28,28)中进行DNN或LSTM的示例将是最佳的。

python machine-learning keras lstm mnist
1个回答
1
投票

诸如LSTM的RNN层用于序列处理(即,它们的出现顺序重要的一系列向量)。您可以从上到下查看图像,并将每行像素视为矢量。因此,图像将是一系列矢量并且可以被馈送到RNN层。因此,根据此描述,您应该期望RNN层采用形状(sequence_length, number_of_features)的输入。这就是为什么当您将图像以其原始形状(即(28,28))提供给LSTM网络时,它可以正常工作。

现在如果你坚持给LSTM模型喂食扁平的图像,即形状为(784,),你至少有两种选择:要么你可以认为这是一个长度为1的序列,即(1, 748),它没有多大意义;或者您可以将Reshape图层添加到模型中,以将输入重新整形为适合LSTM图层输入形状的原始形状,如下所示:

from keras.layers import Reshape

def kaggle_LSTM_model():
    model = Sequential()
    model.add(Reshape((28,28), input_shape=x_train.shape[1:]))
    # the rest is the same...
© www.soinside.com 2019 - 2024. All rights reserved.