【问题标题】:How to convert 1D flattened MNIST Keras to LSTM model without unflattening?如何在不展平的情况下将 1D 展平的 MNIST Keras 转换为 LSTM 模型?
【发布时间】:2019-08-16 04:15:26
【问题描述】:

我想在 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 展平,它会起作用。但是,我希望这只是“另一种模型选择”,它以相同的预处理输入为食。我认为传递 shape[1:] 会像真正扁平的 input_shape 一样起作用。我敢肯定,我很容易错过关于维度的东西,但是经过一个小时的摆弄和调试后我无法得到它,尽管确实发现没有将 28x28 展平为 784 作品,但我不明白为什么作品。非常感谢!

对于奖励积分,最好举个例子说明如何在 1D (784,) 或 2D (28, 28) 中执行 DNN 或 LSTM。

【问题讨论】:

    标签: python machine-learning keras lstm mnist


    【解决方案1】:

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

    现在,如果您坚持将扁平图像(即形状为(784,))提供给 LSTM 模型,您至少有两个选择:或者您可以将其视为长度为 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...
    

    【讨论】:

    • 这是有道理的。谢谢!
    猜你喜欢
    • 2015-05-28
    • 2019-04-07
    • 1970-01-01
    • 2020-01-20
    • 1970-01-01
    • 1970-01-01
    • 2017-10-08
    • 2019-02-21
    • 2011-12-29
    相关资源
    最近更新 更多