我是Keras的新手,一直在为正确地塑造数据而挣扎。我已经尝试了几周,现在这是我最接近成功的一次。我几乎可以肯定,我只是强行让它工作了,需要调整数据的形状。以下是几个问题:
- 模型、损失函数、优化方法或激活函数是否决定了input_shape或input_dim需要的形状/维度?
如果不是,那我该如何将数据塑造成正确形式呢?
我尝试将数据塑造成(1, 1, 59)的形状,但随后会收到目标数据形状为(1, 1, 19)的抱怨。目前我唯一想到的解决方法是将数据切成一半以使其形状一致,但我希望只使用20%的数据来创建一个新集合。
我的代码:我试图让模型学习从1到100的序列。然后给定一个数字,它应该预测下一个数字是什么。
# 工具设置
import numpy as np
import matplotlib.pyplot as plt
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import LSTM
from keras.layers import Dropout
# 设置我们的数据集和测试集
dataset = [] # 训练集
validset = []
testset = []
dataset = list(range(60))
validset = list(range(60, 80))
testset = list(range(80, 100))
# 数据预处理
X_train = dataset[:-1] # 丢弃最后一个元素
Y_train = dataset[1:] # 第二个元素是预测的目标
# 为Keras LSTM模型重塑训练数据
# 训练数据需要是(batchIndex, timeStepIndex, dimensionIndex)
# 单批次,时间步长,维度
#print(np.array(X_train).shape)
X_train = np.array(X_train).reshape(-1, 59, 1)
Y_train = np.array(Y_train).reshape(-1, 59, 1)
# 归一化数据
#X_train = np.divide(X_train, 200)
#Y_train = np.divide(Y_train, 200)
X_test = validset[:-1] # 丢弃最后一个元素
Y_test = validset[1:] # 第二个元素是预测的目标
#print(np.array(X_test).shape)
X_test = np.array(X_test).reshape(-1, 19, 1)
Y_test = np.array(Y_test).reshape(-1, 19, 1)
# 构建模型
model = Sequential()
#model.add(LSTM(100, input_dim=1, return_sequences=True, activation='softmax'))
model.add(LSTM(100, input_dim=1, return_sequences=True))
model.add(Dense(1))
model.compile(loss='mse', optimizer='rmsprop', metrics=["accuracy"])
#model.add(Dropout(0.80))
# 训练模型
history = model.fit(X_train, Y_train, validation_data=(X_test, Y_test), nb_epoch=10, batch_size=1, verbose=1)
# 在训练过程中检查验证集以监控进度,并可能用于提前停止,
# 但绝不会用于梯度下降。
# validation_data用作保留验证数据。将覆盖validation_split。
# validation_data=(X_test, Y_test)
# validation_split是用作保留验证数据的数据比例。
# validation_split=0.083
from IPython.display import SVG
from keras.utils.visualize_util import model_to_dot
SVG(model_to_dot(model).create(prog='dot', format='svg'))
# 列出历史数据中的所有数据
print(history.history.keys())
# 总结准确率的历史数据
plt.plot(history.history['acc'])
plt.plot(history.history['val_acc'])
plt.title('模型准确率')
plt.ylabel('准确率')
plt.xlabel('轮次')
plt.legend(['训练', '验证'], loc='upper left')
plt.show()
# 总结损失的历史数据
plt.plot(history.history['loss'])
plt.plot(history.history['val_loss'])
plt.title('模型损失')
plt.ylabel('损失')
plt.xlabel('轮次')
plt.legend(['训练', '验证'], loc='upper left')
plt.show()
# 测试模型
#print(np.array(testset).shape)
testset = np.array(testset).reshape(-1, 5, 1)
predict = model.predict(testset)
# 撤销归一化步骤
#predict = np.multiply(data, 200)
predict = predict.reshape(-1)
print(predict[0])
回答:
模型、损失函数、优化方法或激活函数是否决定了input_shape或input_dim需要的形状/维度?
我倾向于答案是肯定的。有些函数需要不同的维度大小。
现在让我们保持简单,只关注问题的本质。
dataset = list(range(100))
validset = dataset[-20:]
testset = dataset[-20:]
看起来Keras希望LSTM的数据被塑造成这样的形状:batchIndex, timestepIndex, dimensionIndex
print(np.array(X_train).shape)
X_train = np.array(X_train).reshape(99, 1, 1)
Y_train = np.array(Y_train).reshape(99, 1, 1)
print(np.array(X_train).shape)
结果:
(99, )
(99, 1, 1)
模型被简化为:
model = Sequential()
model.add(LSTM(100, input_dim=1, return_sequences=True))
model.add(Dense(1))
model.compile(loss='mse', optimizer='rmsprop', metrics=["accuracy"])
从图表和错误的预测来看,还有很多工作要做。至少这可以开始进行。