在医学成像领域,通常有两个信号,其中一个信号中的伪影会渗入另一个信号中。我正在探索是否可以将深度学习模型与这些信号一起使用来消除伪影(这是为了学生项目和我自己的好奇心)。
这是一个过于简单化的例子:我们有两个信号,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()
这是带有模型的代码块
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()
# 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()
我认为您需要提供方波
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)