python - 如何将一维扁平化 MNIST Keras 转换为 LSTM 模型而不需要取消扁平化?

标签 python machine-learning keras lstm mnist

我想在 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: Input 0 is incompatible with layer lstm_17: expected ndim=3, found ndim=2

如果我返回并且不展平 x_train 和 y_train,它就会起作用。然而,我希望这成为“另一种模型选择”,它提供相同的预处理输入。我认为传递 shape[1:] 会起作用,因为它是真正的扁平 input_shape。我确信这很简单,我错过了维度,但经过一个小时的摆弄和调试后我无法得到它,尽管我确实弄清楚了没有将 28x28 压平为 784 的作品,但我不明白为什么会这样作品。非常感谢!

对于奖励积分,最好提供一个如何在 1D (784,) 或 2D (28, 28) 中执行 DNN 或 LSTM 的示例。

最佳答案

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

现在,如果您坚持向 LSTM 模型提供扁平图像,即形状为 (784,),您至少有两个选择:您可以将其视为长度为 1 的序列,即 (1, 748),这没有多大意义;或者,您可以向模型添加一个 Reshape 层,将输入 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...

关于python - 如何将一维扁平化 MNIST Keras 转换为 LSTM 模型而不需要取消扁平化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55345984/

相关文章:

python - 如何在Python中复制zlib压缩器对象的内部状态

python - 'self' 从哪里来?将成员函数作为 threading.Thread 的目标

python - 为什么Python中的属性查找是这样设计的(优先链)?

python - 这些模型是否等效?

python - Keras/ tensorflow : Loss function with subtraction -

python - Keras CNN 从卷积步骤中获取输出

python - 检索作为 POST 响应提供的重定向 URL 中的 OAuth 代码

tensorflow - 带有 CART 树的 TensorFlow 随机森林使用什么杂质指数(基尼系数、熵?)?

apache-spark - 在 Java 中为 Apache Spark MLlib 构建 LabeledPoint of Features 的最佳方法

machine-learning - FastAI关于使用TextList加载数据的问题