使用具有 2 个同时信号的 LSTM 模型对其中一个信号进行降噪

问题描述 投票:0回答:1

在医学成像领域,通常有两个信号,其中一个信号中的伪影会渗入另一个信号中。我正在探索是否可以将深度学习模型与这些信号一起使用来消除伪影(这是为了学生项目和我自己的好奇心)。

这是一个过于简单化的例子:我们有两个信号,signal_X 和 signal_Y。 Signal_X 是一条平坦的线,偶尔带有方波脉冲。 Signal_Y 是纯正弦波。当 signal_X 产生脉冲时,它会泄漏到 signal_Y 中,从而导致 signal_Y 的幅度增加。我们认为这是神器。

我们的目标是使用 LSTM 模型来学习 signal_X 和 signal_Y 之间的关系,以便我们可以回归出 signal_X 脉冲时注入到 signal_Y 中的“噪声”。

下面我在 signal_X 和 signal_Y 的 (x,y) 对上训练模型。然后我将该模型拟合到 signal_X 本身以获得预测值。然后我将修正后的 signal_Y 定义为

corrected_signal_Y =  Y_train - pred_Y

结果不是很好,但我觉得我可能离基地很远。 我实际上只是训练我的模型来预测 signal_Y (包括工件)吗?如果是这样,那么我的“ Corrected_Y”计算在概念上一定是错误的。

最小工作示例

您可以看到使用下面的代码,或者只是在这个colab笔记本

中运行它

您可以跳过这个:第一个代码块只是为了生成信号

import numpy as np
import matplotlib.pyplot as plt

def simulate_signals(N, sine_amplitude, sine_frequency, square_amplitude, square_duration, pulse_prob):
  """simulate a square wave (signal X) and a sine wave (signal Y)


  Parameters
  ----------
  N : int
    the length of the signals, in samples.
  sin_amplitude: int | float
    The amplitude of the sine wave
  sine_frequency: int
    Frequency of the sine wave
  square_amplitude : int
    Amplitude of the artifact square wave in signal Y
  square_duration: int
    Duration of the artifact square wave in signal Y
  pulse_prob: float
    Probability of a square wave pulse occurring in signal X at each time step

  Returns
  -------
  Signal_X, signal_Y
  """
  # Generate time axis
  t = np.arange(N)

  # Simulate signal X with occasional square wave pulses
  signal_X = np.zeros(N)
  for i in range(N):
      if np.random.rand() < pulse_prob:
          signal_X[i:i+square_duration] = 1

  # Simulate signal Y as a pure sine wave with added artifact square wave component
  signal_Y_sine = sine_amplitude * np.sin(2 * np.pi * sine_frequency * t)
  signal_Y_square = square_amplitude * signal_X
  signal_Y = signal_Y_sine + signal_Y_square

  return signal_X, signal_Y

# Parameters for the simulation
N = 1000
sine_amplitude = 1.0
sine_frequency = 0.05
square_amplitude = 0.5
square_duration = 20
pulse_prob = 0.02

# Simulate signals X and Y
signal_X, signal_Y = simulate_signals(N, sine_amplitude, sine_frequency,
                                      square_amplitude, square_duration,
                                      pulse_prob)

# Plot the signals
plt.figure(figsize=(12, 6))
plt.subplot(2, 1, 1)
plt.plot(signal_X, label='Signal X')
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.legend()
plt.xlim(0, 1000)


plt.subplot(2, 1, 2)
plt.plot(signal_Y, label='Signal Y')
plt.xlabel('Time')
plt.ylabel('Amplitude')
plt.legend()
plt.xlim(0, 1000)

plt.tight_layout()
plt.show()

Image of signal_X and signal_Y

这是带有模型的代码块

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dropout, LSTM

from sklearn.preprocessing import StandardScaler


scaler = StandardScaler()
# normalize, add empty dimension, downsample by factor of 10
X = scaler.fit_transform(signal_X.reshape(-1, 1))
Y = scaler.fit_transform(signal_Y.reshape(-1, 1))
print(f"X, Y shape: {X.shape}, {Y.shape}")

nb_time = 100
n_blocks = 50
step = 10
model = Sequential()


# Split dataset
n = int(X.shape[0] / nb_time) # i.e 1000 / 100
X_train = X[:nb_time * n, :].reshape((-1, nb_time, X.shape[-1]), order='C')
Y_train = Y[:nb_time * n, :].reshape((-1, nb_time, Y.shape[-1]), order='C')


# LSTM layer accepts a 3D array as input which has a shape of (n_sample, n_timesteps, n_features)
model.add(LSTM(n_blocks, input_shape=(nb_time,  X_train.shape[-1]),
               return_sequences=True))
model.add(Dropout(0.5))
model.add(LSTM(Y.shape[1],
               return_sequences=True))
model.add(Dropout(0.5))


# try this optimizer instead of 'adam'
adagrad = tf.keras.optimizers.Adagrad(learning_rate=1)
model.compile(loss='mean_squared_error', optimizer=adagrad)
print(model.summary())


model.fit(X_train, Y_train, epochs=50,
          validation_split=0.2, batch_size=1, verbose=2)


# Visualize loss
fig, ax = plt.subplots()
ax.plot(model.history.history["loss"], label="Training Loss") # blue
ax.plot(model.history.history["val_loss"], label="Validation Loss") # orange
plt.legend()

Visualization of the Loss

# Make predictions
predicted_Y = model.predict(X_train)

# Deno[enter image description here](https://i.stack.imgur.com/ECfJP.png)rmalize predictions
predicted_Y_denormalized = scaler.inverse_transform(predicted_Y.reshape(-1, 1))

# Correct the signal: I'm unsure whether this is conceptually correct
corrected_signal_Y = Y_train.reshape((-1,1)) - predicted_Y_denormalized

# Plot original signal_Y and predicted signal_Y
fig, ax = plt.subplots(figsize=(12, 6))
ax.plot(Y_train.reshape((-1,1)), label='Original Signal Y')
ax.plot(predicted_Y_denormalized, label='Predicted Signal Y')
ax.plot(corrected_signal_Y, label="Corrected Signal_Y")
ax.set_xlabel('Time')
ax.set_ylabel('Amplitude')
ax.legend()
plt.show()

Plot of signal_Y, pred_Y, and corrected_Y

tensorflow machine-learning deep-learning lstm signal-processing
1个回答
0
投票

我认为您需要提供方波

signal_X
和噪声信号
signal_Y
作为输入特征(或者仅提供其中之一,如果您愿意)。使用干净的信号
signal_Y_sine
作为目标。模型应该学会从输入特征再现干净的信号。

signal_X, signal_Y, signal_Y_target = simulate_signals(...)

# Plot the signals
f, ax = plt.subplots(figsize=(10, 2.5))
ax.plot(signal_X, 'r-', lw=1.3, label='signal_X')
ax.plot(signal_Y, 'tab:green', lw=1.3, label='signal_Y')
ax.plot(signal_Y_target, lw=2, color='tab:brown', label='Target: signal_Y_sine')
ax.set_ylabel('Amplitude')
ax.set_xlabel('n')
f.legend(loc='upper center', ncol=3)
© www.soinside.com 2019 - 2024. All rights reserved.