LSTM проблема сдвига во времени между обучающим сигналом ЛЧМ и тестовым сигналом гармоник c в тенорном потоке керас - PullRequest
0 голосов
/ 19 февраля 2020

Я использую последовательную модель keras с бэкэндом тензорного потока и сетевую архитектуру LSTM.

Я хочу обучить модель с обучающим входным сигналом линейного ЛЧМ (диапазон частот от 1 до 6 Гц) и выход - линейный чирп с задержкой по времени. Затем я хочу предсказать гармонические c синусоидальные входные сигналы (с частотой в диапазоне частот линейного ЛЧМ) и предсказать выходной сигнал. Вход и выход имеют совершенно разные физические значения, но они каким-то образом коррелируют друг с другом, что должно быть зафиксировано нейронной сетью.

Таким образом, форма (выборки, временные шаги, особенности) моих сигналов выглядит следующим образом:

X_train_signal.shape = (1, 2001, 1)
y_train_signal.shape = (1, 2001, 1)
X_test_signal.shape = (1, 400, 1)
y_test_signal.shape = (1, 400, 1)

Если я установлю сдвиги времени на 0, модель будет работать хорошо, что можно увидеть здесь: train0 и test0

проблема в том, что он полностью терпит неудачу, когда есть сдвиг во времени между сигналами, как можно увидеть здесь train0.3 и test0.3

для примера из

time_shift_train = 0.3
time_shift_test = 0.3

Если time_shift_train и time_shift_test не равны 0 и не отличаются друг от друга, это еще хуже.

Может кто-то объяснить, почему это так?

Это мой код:

import matplotlib.pyplot as plt
import tensorflow as tf
from keras import models, layers, optimizers
from scipy.signal import chirp



t = np.linspace(0, 10, 2001)
A_X = 1  # Amplitude for X_train
A_y = 5  # Amplitude for X_train
f = 4  # frequency for harmonic test signal

# time shifting settings
time_shift_train = 0.3
time_shift_test = 0.3

# creating linear chirp training signal
X_train_signal = A_X * chirp(t, f0=1, f1=6, t1=10, method='linear')
y_train_signal = A_y * chirp(t+time_shift_train, f0=1, f1=6, t1=10, method='linear')

# creating harmonic test signal with 400 sample points
X_test_signal = A_X * np.sin(2.0 * np.pi * f * t[:400])
y_test_signal = A_y * np.sin(2.0 * np.pi * f * (t[:400]+time_shift_test))

# convert data into LSTM compatible format
X_train_signal = X_train_signal.reshape(1, -1, 1)
X_test_signal = X_test_signal.reshape(1, -1, 1)

y_train_signal = y_train_signal.reshape(1, -1, 1)
y_test_signal = y_test_signal.reshape(1, -1, 1)


# build model
model = models.Sequential()
model.add(layers.LSTM(32, input_shape=(None, X_train_signal.shape[2],), recurrent_activation='sigmoid',
                      activation='tanh', return_sequences=True))
model.add(layers.Dense(1))
model.compile(optimizer=optimizers.Adam(lr=0.01), loss='logcosh',
              metrics=['mae'])

# fit model
history = model.fit(X_train_signal, y_train_signal, validation_data=(X_test_signal, y_test_signal), epochs=40, batch_size=1,
                    shuffle=False)

# plot loss history
plt.figure()
plt.plot(history.history['loss'], label="loss")
plt.plot(history.history['val_loss'], label='val_loss')
plt.legend(loc="upper right")
plt.yscale('log')
plt.show()

# prediction
y_pred_test = model.predict(X_test_signal)
y_pred_train = model.predict(X_train_signal)

# plot predictions and inputs
#train
plt.figure()
plt.plot(y_train_signal.reshape(-1), 'r', label='ground truth train',
         linestyle='solid', linewidth=0.8)
plt.plot(y_pred_train.reshape(-1), 'g',
         label='y pred train', linestyle='dashed',
         linewidth=1.0)
plt.title('train')
plt.xlabel('time steps')
plt.ylabel('y')
plt.legend(prop={'size': 8})
plt.show()

#test
plt.figure()
plt.plot(y_test_signal.reshape(-1), 'tab:orange', label='ground truth test',
         linestyle='solid', linewidth=0.8)
plt.plot(y_pred_test.reshape(-1), 'b',
         label='y pred test', linestyle='dashed',
         linewidth=1.0)
plt.title('test')
plt.xlabel('time steps')
plt.ylabel('y')
plt.legend(prop={'size': 8})
plt.show()
...