import tensorflow as tf
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from tensorflow.keras import layers, losses
from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Model
import warnings
warnings.filterwarnings('ignore')
df = pd.read_csv('http://storage.googleapis.com/download.tensorflow.org/data/ecg.csv', header=None)
df.head()
Note: The dataset has 140 columns which represents the ECG readings and a labels column which has been encoded to 0 or 1 showing whether the ECG is abnormal or normal.
#separate the data and labels so that it will be easy for understanding
data = df.iloc[:,:-1].values
labels = df.iloc[:,-1].values
labels
array([1., 1., 1., ..., 0., 0., 0.])
train_data, test_data, train_labels, test_labels = train_test_split(data, labels, test_size = 0.2, random_state = 21)
Normalizing the data to the range [0-1]
#Now lets Normalize the data
#First we will calculate the maximum and minimum value from the training set
min = tf.reduce_min(train_data)
max = tf.reduce_max(train_data)
#Now we will use the formula (data - min)/(max - min)
train_data = (train_data - min)/(max - min)
test_data = (test_data - min)/(max - min)
#I have converted the data into float
train_data = tf.cast(train_data, dtype=tf.float32)
test_data = tf.cast(test_data, dtype=tf.float32)
#The labels are either 0 or 1, so I will convert them into boolean(true or false)
train_labels = train_labels.astype(bool)
test_labels = test_labels.astype(bool)
#Now let's separate the data for normal ECG from that of abnormal ones
#Normal ECG data
n_train_data = train_data[train_labels]
n_test_data = test_data[test_labels]
#Abnormal ECG data
an_train_data = train_data[~train_labels]
an_test_data = test_data[~test_labels]
print(n_train_data)
tf.Tensor(
[[0.57030463 0.46561658 0.29058117 ... 0.48504233 0.4233502 0.47598344]
[0.48320588 0.28246963 0.16471253 ... 0.567567 0.4677294 0.2692329 ]
[0.48144642 0.35151404 0.25972766 ... 0.5479421 0.5077544 0.54298663]
...
[0.41039047 0.24164985 0.13120876 ... 0.5277313 0.5654091 0.5023885 ]
[0.5397748 0.4140786 0.28101394 ... 0.51266515 0.43706053 0.4426865 ]
[0.29639772 0.15988176 0.18883787 ... 0.53766966 0.545786 0.40826708]], shape=(2359, 140), dtype=float32)
#Lets plot a normal ECG
plt.plot(np.arange(140), n_train_data[0])
plt.grid()
plt.title('Normal ECG')
plt.show()
#Lets plot one from abnormal ECG
plt.plot(np.arange(140), an_train_data[0])
plt.grid()
plt.title('Abnormal ECG')
plt.show()
Autoencoders
#Now let's define the model!
#Here I have used the Model Subclassing API (but we can also use the Sequential API)
#The model has 2 parts : 1. Encoder and 2. Decoder
class detector(Model):
def __init__(self):
super(detector, self).__init__()
self.encoder = tf.keras.Sequential([
layers.Dense(32, activation='relu'),
layers.Dense(16, activation='relu'),
layers.Dense(8, activation='relu')
])
self.decoder = tf.keras.Sequential([
layers.Dense(16, activation='relu'),
layers.Dense(32, activation='relu'),
layers.Dense(140, activation='sigmoid')
])
def call(self, x):
encoded = self.encoder(x)
decoded = self.decoder(encoded)
return decoded
#Let's compile and train the model!!
autoencoder = detector()
autoencoder.compile(optimizer='adam', loss='mae')
autoencoder.fit(n_train_data, n_train_data, epochs = 20, batch_size=512, validation_data=(n_test_data, n_test_data))
#Now let's define a function in order to plot the original ECG and reconstructed ones and also show the error
def plot(data, n):
enc_img = autoencoder.encoder(data)
dec_img = autoencoder.decoder(enc_img)
plt.plot(data[n], 'b')
plt.plot(dec_img[n], 'r')
plt.fill_between(np.arange(140), data[n], dec_img[n], color = 'lightcoral')
plt.legend(labels=['Input', 'Reconstruction', 'Error'])
plt.show()
plot(n_test_data, 0)
plot(an_test_data, 0)
reconstructed = autoencoder(n_train_data)
train_loss = losses.mae(reconstructed, n_train_data)
t = np.mean(train_loss) + np.std(train_loss)
def prediction(model, data, threshold):
rec = model(data)
loss = losses.mae(rec, data)
return tf.math.less(loss, threshold)
print(t)
0.030792654
pred = prediction(autoencoder, n_test_data, t)
#Lets see some more result visually !!
plot(n_test_data, 0)
plot(n_test_data, 1)
plot(n_test_data, 3)
Accuracy
threshold = np.mean(train_loss) + 2*np.std(train_loss)
preds = tf.math.less(train_loss, threshold)
tf.math.count_nonzero(preds)
<tf.Tensor: shape=(), dtype=int64, numpy=2232>
preds.shape
TensorShape([2359])
acc = 2240/2359*100
print("Accuracy = ", acc, "%")
Accuracy = 94.95548961424333 %
知乎学术咨询:https://www.zhihu.com/consult/people/792359672131756032?isMe=1
担任《Mechanical System and Signal Processing》等审稿专家,擅长领域:信号滤波/降噪,机器学习/深度学习,时间序列预分析/预测,设备故障诊断/缺陷检测/异常检测。
分割线
EMG信号降噪方法(MATLAB)
包括概率自适应模板减法PATS,经验模态分解方法EMD,二阶扩展卡尔曼平滑方法EKS2,平稳小波变换方法SWT,自适应模板减法+高通滤波方法,高通滤波方法,自适应模板减法,模板减法
完整代码可通过知乎学术咨询获得:
https://www.zhihu.com/consult/people/792359672131756032?isMe=1