Keras LSTM未添加

时间:2019-01-17 07:19:27

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

这是我要创建的模型:

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

2 个答案:

答案 0 :(得分:1)

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

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)

答案 1 :(得分:1)

您的数据的格式为(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顺序模型中,第一层应提及期望的数据形状。因此,您必须在input_shape中设置LSTM参数。可以这样

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)