Я использую последовательную модель 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()