Проблемы понимания проблемы регрессии Keras LSTM: неправильные прогнозы на порядки - PullRequest
0 голосов
/ 10 января 2019

Я пытался немного поэкспериментировать с керасом, и у меня возникли проблемы с явно простой регрессионной задачей. Я хочу предсказать значение сигнала с шумом, используя LSTM. Это мой код Я начинаю создавать шумовой сигнал от синусоиды с частотой 2048 Гц

frequency = 2048
time_interval = 10
x_mock = np.arange(0,time_interval, 1/frequency)
rand_noise = np.array([np.random.randn() for i in range(len(x_mock))])
sine_wit = np.sin(10*x_mock)
target_mock = np.sin(x_mock)+sine_wit*rand_noise 

Затем я определяю сеть LSTM с 3 слоями LSTM, за которыми следуют 4 полностью подключенных.

def keras_LSTM(fs, n_witness, lr=0.000039):
    nRec1 = 64 #originally 32
    nRec2 = 16
    nRec3 = 8
    nFC1 = 128
    nFC2 = 16
    nFC3 = 8
    nFC4 = 1
    model_LSTM = Sequential()
    model_LSTM.add(LSTM(nRec1, activation='tanh', recurrent_activation='hard_sigmoid', use_bias=True, 
                       kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', 
                       bias_initializer='zeros', unit_forget_bias=True, kernel_regularizer=None, 
                       recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, 
                       kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, dropout=0.0,
                       recurrent_dropout=0.0, implementation=1, return_sequences=True, 
                       return_state=False, go_backwards=False, stateful=True, unroll=False, 
                       batch_input_shape=(1,fs,n_witness), input_shape=(None,n_witness)))#,
    model_LSTM.add(LSTM(nRec2, activation='tanh', recurrent_activation='hard_sigmoid', use_bias=True, 
                       kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', 
                       bias_initializer='zeros', unit_forget_bias=True, kernel_regularizer=None, 
                       recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, 
                       kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, dropout=0.0,
                       recurrent_dropout=0.0, implementation=1, return_sequences=True, 
                       return_state=False, go_backwards=False, stateful=True, unroll=False))
    model_LSTM.add(LSTM(nRec3, activation='tanh', recurrent_activation='hard_sigmoid', use_bias=True, 
                       kernel_initializer='glorot_uniform', recurrent_initializer='orthogonal', 
                       bias_initializer='zeros', unit_forget_bias=True, kernel_regularizer=None, 
                       recurrent_regularizer=None, bias_regularizer=None, activity_regularizer=None, 
                       kernel_constraint=None, recurrent_constraint=None, bias_constraint=None, dropout=0.0,
                       recurrent_dropout=0.0, implementation=1, return_sequences=True, 
                       return_state=False, go_backwards=False, stateful=True, unroll=False))
    model_LSTM.add(Dense(nFC1, kernel_initializer='glorot_normal'))
    model_LSTM.add(LeakyReLU(alpha=0.01))
    model_LSTM.add(Dense(nFC2, kernel_initializer='glorot_normal'))
    model_LSTM.add(LeakyReLU(alpha=0.01))
    model_LSTM.add(Dense(nFC3, kernel_initializer='glorot_normal'))
    model_LSTM.add(LeakyReLU(alpha=0.01))
    model_LSTM.add(Dense(nFC4, kernel_initializer='glorot_normal'))      
    model_LSTM.add(LeakyReLU(alpha=0.01))

    model_LSTM.compile(optimizer=keras.optimizers.Adam(lr=0.000039, beta_1=0.9, beta_2=0.999,
                        epsilon=1e-8, decay=0.05, amsgrad=False), 
                       loss='mean_squared_error')
    return model_LSTM

ПРИМЕЧАНИЕ. Я использую оптимизатор ADAM и рэли с утечками в слоях FC и хочу, чтобы последовательности возвращались и передавались на каждом последующем временном шаге. Я выбираю batch_input_shape=(1,fs,n_witness), чтобы передавать в сеть партию из 2048 последовательных выборок за раз (в принципе, насколько я понимаю, я тренирую ее за 1 секунду до вычисления градиентов и обновления весов). Затем я нормализую входные данные и изменяю форму своих данных, чтобы сгенерировать трехмерные входные и целевые массивы. Для каждой выборки по времени входными функциями являются нормализованные значения sine_wit и rand_noise. С этими значениями я хочу предсказать target_mock в то же время.

rand_noise = (rand_noise-min(rand_noise))/(max(rand_noise)-min(rand_noise))
sine_wit = (sine_wit-min(sine_wit))/(max(sine_wit)-min(sine_wit))
X_mock_mat = vstack((sine_wit, rand_noise)).T

X_mock = X_mock_mat.reshape(-1,frequency,2)
Y_mock = target_mock.reshape(-1,frequency,1)

X_train = X_mock[:][:][:]
Y_train = Y_mock[:][:][:]

Наконец, я тренирую модель и предсказываю те же точные данные цели:

model_mock_history = model_mock_LSTM.fit(X_train, Y_train, epochs=30, batch_size=1, verbose=2, shuffle=False) 
trainPredict = model_mock_LSTM.predict(X_train, batch_size=1)

Однако результаты довольно странные как во временной, так и в частотной области, см. Рисунок:

Прогнозирование во временной и частотной области

Что я делаю не так? Я чувствую, что что-то глубоко неправильно понимаю.

...