【问题标题】:Keras LSTM is not getting added没有添加 Keras LSTM
【发布时间】:2019-01-17 07:19:27
【问题描述】:

这是我正在尝试创建的模型:

def build_model(inputs_size):
    # create model
    model = Sequential()
    model.add(LSTM(100,activation="relu"))
    model.add(Dense(100, input_dim=inputs_size, init='normal', activation='relu'))
    model.add(Dense(200, input_dim=inputs_size, init='normal', activation='relu'))
    model.add(Dense(100, input_dim=inputs_size, init='normal', activation='relu'))
    model.add(Dense(3, init='normal', activation='relu'))
    model.compile(loss=losses.mean_squared_logarithmic_error, optimizer='adam', metrics=['accuracy'])

    return model

def save_model(model):
    # saving model
    json_model = model.to_json()
    open('model_architecture.json', 'w').write(json_model)
    # saving weights
    model.save_weights('model_weights.h5', overwrite=True)

def load_model():
    # loading model
    model = model_from_json(open('model_architecture.json').read())
    model.load_weights('model_weights.h5')
    model.compile(loss=losses.mean_squared_logarithmic_error, optimizer='adam',metrics=["accuracy"])
    return model
dataframe = pandas.read_csv("training.csv", header=0,index_col=0)
print(dataframe.columns)
dataset = dataframe.values
X = dataset[:,:-1].astype(float)
Y = dataset[:,-1]
X = preprocessing.scale(X)
encoder = LabelEncoder()
encoder.fit(Y)
encoded_Y = encoder.transform(Y)
y = np_utils.to_categorical(encoded_Y)
X_train, X_test, Y_train, Y_test = train_test_split(X, y, test_size=0.1)
model = build_model(X.shape[1])
model.fit(X_train, Y_train, epochs=100, batch_size=10, verbose=True)
save_model(model)

错误是:

ValueError: Input 0 is incompatible with layer lstm_1: expected ndim=3, found ndim=2

让我知道我错过了什么。我猜是输入形状的问题,但不知道该怎么做。

已编辑:示例数据集:training.csv

【问题讨论】:

  • 向我们展示 X_train 的样本
  • 当然...我将添加带有我忘记的问题的示例数据集。
  • Sequential 模型中的第一层是LSTM。在 keras 中,第一层应该包含输入的形状,这在您的代码中不存在
  • @SreeramTP 我尝试将 th input_dim 与 LSTM 一起使用,但出现此错误:ValueError: Error when checking input: expected lstm_2_input to have 3 dimensions, but got array with shape (1799, 6)
  • 您将二维序列输入网络,而 LSTM 需要 3D 序列。将输入更改为 one_hot 编码,然后将其传递给 LSTM 或使用嵌入层。

标签: python python-3.x tensorflow keras lstm


【解决方案1】:

问题是您将二维序列提供给网络,而 LSTM 需要 3 维序列。将您的输入更改为 one_hot 编码,然后将其传递给 LSTM 或使用嵌入层。您的网络应该是这样的:

import numpy as np
from tensorflow.python.keras.layers import Dense, LSTM
from tensorflow.python.keras.models import Sequential

model = Sequential()
model.add(LSTM(100, activation="relu"))
model.add(Dense(100, input_dim=100, activation='relu'))
model.add(Dense(200, input_dim=100, activation='relu'))
model.add(Dense(100, input_dim=100, activation='relu'))
model.add(Dense(3, activation='softmax'))
model.compile(loss='mse', optimizer='adam', metrics=['accuracy'])

x = np.zeros(shape=(10000, 32, 50))
y = np.zeros(shape=(10000, 3))

model.fit(x, y, batch_size=128)

注意xy的大小。

替代方法

model = Sequential()
model.add(Embedding(10000, 50))
model.add(LSTM(100, activation="relu"))
model.add(Dense(100, input_dim=100, activation='relu'))
model.add(Dense(200, input_dim=100, activation='relu'))
model.add(Dense(100, input_dim=100, activation='relu'))
model.add(Dense(3, activation='softmax'))
model.compile(loss='mse', optimizer='adam', metrics=['accuracy'])

x = np.zeros(shape=(10000, 32))
y = np.zeros(shape=(10000, 3))

model.fit(x, y, batch_size=128)

【讨论】:

  • 我在嵌入代码的第二部分尝试了你的代码,我得到了错误:InvalidArgumentError: indices[0,0] = -1 is not in [0, 6) [[{{node embedding_2/embedding_lookup}} = GatherV2[Taxis=DT_INT32, Tindices=DT_INT32, Tparams=DT_FLOAT, _class=["loc:@training_3/Adam/Assign_2"], _device="/job:localhost/replica:0/task:0/device:CPU:0"](embedding_2/embeddings/read, embedding_2/Cast, training_3/Adam/gradients/embedding_2/embedding_lookup_grad/concat/axis)]]
  • @JafferWilson 输入数据中的条目之一是 -1,这对于嵌入层是不可接受的。见stackoverflow.com/questions/54176051/…
  • 但数据集中可能存在负值,这是我检测的一部分。那么有没有什么可以做的呢?
  • 将索引更改为从零开始或规范化您的数据。这取决于问题。
  • 是的,它奏效了。我用过`MinMaxScaler。它奏效了。谢谢你的建议,先生。
【解决方案2】:

你的数据是这样的:(1779, 6)

假设它是数字数据,因为我无法查看问题中提供的 training.csv。

如果要将其传递给 LSTM,则数据必须是 3D。因此,您必须根据需要重塑数据。

作为一个玩具示例,考虑下面给出的随机数据。

X = np.random.rand(1779, 6) # some random data
X = X.reshape((1779, 6, 1)) # reshaping the data to 3D
y = np.random.rand(1779, 3) # random target feature

现在,在 Keras Sequential 模型中,第一层应该提到它所期望的数据的形状。所以你必须在LSTM 中设置input_shape 参数。可以这样实现

model.add(LSTM(32, input_shape=(6, 1))) 

无需在模型的任何其他层中提供形状参数,因为 Keras 会自动处理。所以下面的Dense可以是这样的

model.add(Dense(1))

您也在使用init,但现在不推荐使用它,而支持kernel_initializer

综上所述,您的build_model 函数可以这样重写。

from keras.models import Sequential
from keras.layers import LSTM, Dense

def build_model(inputs_size):
    # create model
    model = Sequential()
    model.add(LSTM(100,activation="relu", input_shape=inputs_size))
    model.add(Dense(100, kernel_initializer='normal', activation='relu'))
    model.add(Dense(200, kernel_initializer='normal', activation='relu'))
    model.add(Dense(100, kernel_initializer='normal', activation='relu'))
    model.add(Dense(3, kernel_initializer='normal', activation='relu'))
    model.compile(loss='mse', optimizer='adam', metrics=['accuracy'])

    return model

我已更改为损失函数,但您可以使用应用程序所需的任何损失。

函数可以这样使用。

model = build_model((X.shape[1], 1))
model.fit(X, y)

玩具示例的完整代码

from keras.models import Sequential
from keras.layers import LSTM, Dense
import numpy as np

X = np.random.rand(1779, 6)
y = np.random.rand(1779, 3)

X = X.reshape((X.shape[0],X.shape[1], 1))

def build_model(inputs_size):
    # create model
    model = Sequential()
    model.add(LSTM(100,activation="relu", input_shape=inputs_size))
    model.add(Dense(100, kernel_initializer='normal', activation='relu'))
    model.add(Dense(200, kernel_initializer='normal', activation='relu'))
    model.add(Dense(100, kernel_initializer='normal', activation='relu'))
    model.add(Dense(3, kernel_initializer='normal', activation='relu'))
    model.compile(loss='mse', optimizer='adam', metrics=['accuracy'])

    return model

model = build_model((X.shape[1], 1))

model.fit(X, y)

【讨论】:

  • 它对我没有用,但你的回答很好..可以帮助其他人。
  • 你遇到了什么问题?
  • 我尝试按照您所说的进行整形:X = X.reshape((1779, 6, 1)) 我所做的是这样的,因为我知道我的数据形状是二维的,所以X = X.reshape((X.shape[0],X.shape[1], 1)),它没有用。我猜这个嵌入理念对我有用。重塑给了我错误。你试过了吗?
  • 是的。我已经完成了,我没有遇到任何错误
  • 可能我想我需要再检查一次。我会让你知道错误。给我一点时间。
猜你喜欢
  • 2018-01-08
  • 2019-03-12
  • 1970-01-01
  • 1970-01-01
  • 2017-08-31
  • 2017-09-14
  • 1970-01-01
  • 2018-04-04
  • 2019-04-08
相关资源
最近更新 更多