LSTM 解决回归问题时,出现了 model.predict() 输出的值几乎是常数值的问题,后来发现是因为数据没有标准化(归一化),导致 loss 不下降,也就是不收敛。后来加入了数据的标准化之后,就可以拟合了。

from keras.datasets import mnist
from keras.layers import Dense, LSTM
from keras.utils import to_categorical
from keras.models import Sequential
import keras
from keras.layers.core import Dense, Activation, Dropout
import matplotlib.pyplot as plt
import numpy as np
from sklearn import preprocessing


#parameters for LSTM
nb_lstm_outputs = 32  #神经元个数
nb_time_steps = 1  #时间序列长度
nb_input_vector = 16  #输入序列

def generate_data(start, num_sample):
    x_train = np.zeros((1, 16))
    for i in range(start, num_sample + start):
        temp_data = np.array([i * 10] * 16)
        x_train = np.vstack((x_train, temp_data))
    x_train = x_train[1:]

    y_train = np.array([i for i in range(start, num_sample + start)])
    return x_train, y_train

x_train, y_train = generate_data(start = 1, num_sample = 2804)
x_test, y_test = generate_data(start = 3000, num_sample = 100)

mean_ = np.mean(x_train, axis=0)
std_ = np.std(x_train, axis=0)

x_train = (x_train - mean_) / std_
y_train = (y_train - mean_[0]) / std_[0]
x_test = (x_test - mean_) / std_
y_test = (y_test - mean_[0]) / std_[0]
print("x_train, y_train after normalization \n", x_train, y_train)


print(x_train.shape)
print(y_train.shape)
print(x_test.shape)
print(y_test.shape)
#
def build_model():
    model = Sequential()
    layers = [1, 50, 100, 1]

    model.add(LSTM(layers[1], input_shape=(None, layers[0]), return_sequences=True))
    model.add(Dropout(0.2))
    model.add(LSTM(layers[2], return_sequences=False))
    model.add(Dropout(0.2))
    model.add(Dense(layers[3]))
    model.add(Activation("linear"))  # 由于在进行线性回归操作,所以激活函数填 linear

    model.compile(loss="mse", optimizer=keras.optimizers.Adam(lr=0.0005), metrics=['mae', 'mape'])
    return model

model = build_model()

x_train = x_train.reshape(-1, 16, 1)
x_test = x_test.reshape(-1, 16, 1)
#train: epcoch, batch_size
print(x_train.shape, y_train.shape)

model.fit(x_train, y_train, epochs=30, batch_size=128, verbose=1)

# model.summary()
score = model.evaluate(x_test, y_test,batch_size=128, verbose=1)
print(score)

pred_y = model.predict(x_train, batch_size=128)
print("pred_y", pred_y)

# x_train = (x_train ) * std_ + mean_
# y_train = (y_train ) * std_[0] + mean_[0]
# x_test = (x_test ) * std_+ mean_
# y_test = (y_test ) * std_[0] + mean_[0]
# pred_y = (pred_y ) * std_[0] + mean_[0]

plt.figure(figsize=(16, 8))
plt.plot(y_train, "red")
plt.scatter([x for x in range(pred_y.shape[0])],pred_y)
plt.legend(["True_label", "pred_label"], fontsize=14)
plt.tight_layout()
plt.savefig("./figures/regression.png")
plt.show()