diff --git a/ECG_read_weiyuqing_without_wfdb.py b/ECG_read_weiyuqing_without_wfdb.py index 34f2bc3..5475b5a 100644 --- a/ECG_read_weiyuqing_without_wfdb.py +++ b/ECG_read_weiyuqing_without_wfdb.py @@ -3,13 +3,13 @@ import matplotlib.pyplot as plt from numpy import reshape # arr = -PATH = "mit-bih-arrhythmia-database-1.0.0/" +ECGDATAPATH = "mit-bih-arrhythmia-database-1.0.0/" HEADERFILE = "100.hea" ATRFILE = '100.atr' DATAFILE = "100.dat" # Obtain the information of each part from the hea file and fill in -f = open(PATH + HEADERFILE, "r") +f = open(ECGDATAPATH + HEADERFILE, "r") z = f.readline().split() nosig, sfreq = int(z[1]), int(z[2]) # single number,samp number SAMPLES2READ = 10 * sfreq # number of data points @@ -26,7 +26,7 @@ for i in range(nosig): f.close() # Obtain the information of each part from the dat file and fill in -f=open(PATH+DATAFILE, "rb") +f=open(ECGDATAPATH + DATAFILE, "rb") b = f.read() f.close() @@ -70,7 +70,7 @@ else: print("Sorting algorithm for more than 2 signals not programmed yet") # atr deal -f = open(PATH + ATRFILE, "rb") +f = open(ECGDATAPATH + ATRFILE, "rb") b = f.read() f.close() A_init = np.frombuffer(b, dtype=np.uint8) diff --git a/_mian_pytorch.py b/_mian_pytorch.py index 22c4b63..0a8e320 100644 --- a/_mian_pytorch.py +++ b/_mian_pytorch.py @@ -3,7 +3,7 @@ import pywt import wfdb import torch -from ECG_read_weiyuqing_without_wfdb import PATH +from ECG_read_weiyuqing_without_wfdb import ECGDATAPATH def denoise(date): @@ -28,13 +28,13 @@ def denoise(date): def getDataSet(number, X_data, Y_data): ecgClassSet = ['N', 'A', 'V', 'l', 'R'] print('get' + number + ' ECG data') - record = wfdb.rdrecord(PATH + number, channel_names=['MLII']) + record = wfdb.rdrecord(ECGDATAPATH + number, channel_names=['MLII']) data = record.p_signal.flatten() # use def denoise rdata = denoise(date=data) # get type of ECG data - annotation = wfdb.rdann(PATH + number, 'atr') + annotation = wfdb.rdann(ECGDATAPATH + number, 'atr') Rlocation = annotation.sample # annotation.sample:get R Rclass = annotation.symbol diff --git a/_mian_tensorflow.py b/_mian_tensorflow.py index 37eb11d..2609590 100644 --- a/_mian_tensorflow.py +++ b/_mian_tensorflow.py @@ -1,97 +1,105 @@ +import datetime +import os + import numpy as np import pywt import wfdb import tensorflow as tf from tensorflow import keras +from utils import loadData, plot_history_tf, plot_heat_map -from ECG_read_weiyuqing_without_wfdb import PATH +from ECG_read_weiyuqing_without_wfdb import ECGDATAPATH + +Project_PATH = './' +log_dir = Project_PATH + "logs/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S") +model_Path_one = Project_PATH + "Number-Of-CNN-Layers/" + "ecg_model_one_layer.h5" +#model_Path_one = Project_PATH + "ecg_model_one_layer.h5" + +RATIO = 0.3 +RANDOM_SEED = 42 +BATCH_SIZE = 128 +NUM_EPOCHS = 30 -def denoise(date): - # Wavelet db5 level9 - coeffs = pywt.wavedec(data=date, wavelet='db5', level=9) - cA9, cD9, cD8, cD7, cD6, cD5, cD4, cD3, cD2, cD1 = coeffs - # noice del - threshold = (np.median(np.abs(cD1)) / 0.6745) * (np.sqrt(2 * np.log(len(cD1)))) - # take cD 1,2 turn 0 to denoise - cD1.fill(0) - cD2.fill(0) - for i in range(1, len(coeffs) - 2): - coeffs[i] = pywt.threshold(coeffs[i], threshold) - # get signal that before wavelet - rdata = pywt.waverec(coeffs=coeffs, wavelet='db5') - return rdata +def CNN_model_level_one(): + leavlOneModel = tf.keras.models.Sequential([ + tf.keras.layers.InputLayer(input_shape=(300,)), + # reshape the tensor with shape (batch_size, 300) to (batch_size, 300, 1) + tf.keras.layers.Reshape(target_shape=(300, 1)), + # the first convolution layer, 4 21x1 convolution kernels, output shape (batch_size, 300, 4) + tf.keras.layers.Conv1D(filters=4, kernel_size=21, strides=1, padding='SAME', activation='relu'), + # the first pooling layer, max pooling, pooling size=3 , stride=2, output shape (batch_size, 150, 4) + tf.keras.layers.MaxPool1D(pool_size=3, strides=2, padding='SAME'), + # the second convolution layer, 16 23x1 convolution kernels, output shape (batch_size, 150, 16) + tf.keras.layers.Conv1D(filters=16, kernel_size=23, strides=1, padding='SAME', activation='relu'), + # the second pooling layer, max pooling, pooling size=3, stride=2, output shape (batch_size, 75, 16) + tf.keras.layers.MaxPool1D(pool_size=3, strides=2, padding='SAME'), + # the third convolution layer, 32 25x1 convolution kernels, output shape (batch_size, 75, 32) + tf.keras.layers.Conv1D(filters=32, kernel_size=25, strides=1, padding='SAME', activation='relu'), + # the third pooling layer, average pooling, pooling size=3, stride=2, output shape (batch_size, 38, 32) + tf.keras.layers.AvgPool1D(pool_size=3, strides=2, padding='SAME'), + # the fourth convolution layer, 64 27x1 convolution kernels, output shape (batch_size, 38, 64) + tf.keras.layers.Conv1D(filters=64, kernel_size=27, strides=1, padding='SAME', activation='relu'), + # flatten layer, for the next fully connected layer, output shape (batch_size, 38*64) + tf.keras.layers.Flatten(), + # fully connected layer, 128 nodes, output shape (batch_size, 128) + tf.keras.layers.Dense(128, activation='relu'), + # Dropout layer, dropout rate = 0.2 + tf.keras.layers.Dropout(rate=0.2), + # fully connected layer, 5 nodes (number of classes), output shape (batch_size, 5) + tf.keras.layers.Dense(5, activation='softmax') + # tf.keras.layers.InputLayer(input_shape=(300, 1)), + # + # # ECG data cant add 0 in edge, will broken data ,take false answer. So we need padding same data in edge. + # + # # take four 21*1 conv excitation function used RElu + # tf.keras.layers.Conv1D(filters=4, kernel_size=21, strides=1, padding='same', activation='relu'), + # # take four 3*1 pool,take strids 2. + # + # tf.keras.layers.MaxPool1D(pool_size=3, strides=2, padding='same'), + # + # # tf.keras.layers.Conv1D(filters=4, kernel_size=21, strides=1, padding='same', activation='relu'), + # # tf.keras.layers.MaxPool1D(pool_size=3, strides=2, padding='same'), + # + # tf.keras.layers.Flatten(), + # tf.keras.layers.Dense(128, activation='relu'), + # tf.keras.layers.Dropout(rate=0.2), + # tf.keras.layers.Dense(5, activation='softmax') + ]) + return leavlOneModel -# get ECG data,date type and denoise -# this function without return -# use append take return data to pass data -def getDataSet(number, X_data, Y_data): - ecgClassSet = ['N', 'A', 'V', 'l', 'R'] - print('get' + number + ' ECG data') - record = wfdb.rdrecord(PATH + number, channel_names=['MLII']) - data = record.p_signal.flatten() - # use def denoise - rdata = denoise(date=data) +def main(): + # get traxin test + X_train, X_test, y_train, y_test = loadData(RATIO, RANDOM_SEED) - # get type of ECG data - annotation = wfdb.rdann(PATH + number, 'atr') - Rlocation = annotation.sample # annotation.sample:get R - Rclass = annotation.symbol + # get model or create model + if os.path.exists(model_Path_one): + print(' get model in h5 file') + model = tf.keras.models.load_model(filepath=model_Path_one) + else: + # create new model(if model unexists) + model = CNN_model_level_one() + model.compile(optimizer='adam', + loss='sparse_categorical_crossentropy', + metrics=['accuracy']) + model.summary() + # TB make + tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=log_dir, + histogram_freq=1, + ) + # Training and validation + history = model.fit(X_train, y_train, epochs=NUM_EPOCHS, + batch_size=BATCH_SIZE, + validation_data=(X_test, y_test), + callbacks=[tensorboard_callback]) + # validation_split=RATIO, + model.save(filepath=model_Path_one) + plot_history_tf(history) - # delete stable date near R - start = 10 - end = 5 - i = start - j = len(annotation.symbol) - end - - # get NAVLR type data - while i < j: - try: - lable = ecgClassSet.index(Rclass[i]) - x_train = rdata[Rlocation[i] - 99:Rlocation[i] + 201] - X_data.append(x_train) - Y_data.append(lable) - i += 1 - except ValueError: - i += 1 - return + y_pred = np.argmax(model.predict(X_test), axis=-1) + plot_heat_map(y_test, y_pred) -# RATIO=The ratio of the training set to the test set,usually is 0.3 -def loadData(RATIO): - numberSet = [ - '100', '101', '103', '105', '106', '107', '108', '109', '111', '112', '113', '114', '115', '116', '117', '119', - '121', '122', '123', '124', '200', '201', '202', '203', '205', '208', '210', '212', '213', '214', '215', '217', - '219', '220', '221', '222', '223', '228', '230', '231', '232', '233', '234' - ] - dataSet = [] - labelSet = [] - for n in numberSet: - getDataSet(n, dataSet, labelSet) - - dataSet = np.array(dataSet).reshape(-1, 300) - labelSet = np.array(labelSet).reshape(-1, 1) - train_ds = np.hstack((dataSet, labelSet)) - np.random.shuffle(train_ds) - - X = train_ds[:, :300].reshape(-1, 300, 1) - Y = train_ds[:, 300] - # cut test and train data from ECG data - shuffle_index = np.random.permutation(len(X)) - test_length = int(RATIO * len(shuffle_index)) - test_index = shuffle_index[:test_length] - train_index = shuffle_index[test_index:] - X_test, Y_test = X[test_index:], Y[test_index] - X_train, Y_train = X[train_index], Y[train_index] - return X_train, Y_test, X_test, Y_train - - -class CNN_model_level_one(): - def __init__(self): - newModel = tf.keras.models.Sequential([ - tf.keras.InputLayer(input_shape=(300, 1)), - tf.keras.layers.Conv1D(filters=4, kernel_size=21, strides=1, padding='same', activation='relu'), - tf.keras.layers.MaxPool1D(pool_size=3, strides=2, padding='same'), - tf.keras.layers.Conv1D(filters=16,) - ]) +if __name__ == '__main__': + main() diff --git a/_mian_tensorflow_keras_.py b/_mian_tensorflow_keras_.py index 0e06d9e..832b64e 100644 --- a/_mian_tensorflow_keras_.py +++ b/_mian_tensorflow_keras_.py @@ -3,7 +3,7 @@ import pywt import wfdb import tensorflow as tf -from ECG_read_weiyuqing_without_wfdb import PATH +from ECG_read_weiyuqing_without_wfdb import ECGDATAPATH def denoise(date): @@ -28,13 +28,13 @@ def denoise(date): def getDataSet(number, X_data, Y_data): ecgClassSet = ['N', 'A', 'V', 'l', 'R'] print('get' + number + ' ECG data') - record = wfdb.rdrecord(PATH + number, channel_names=['MLII']) + record = wfdb.rdrecord(ECGDATAPATH + number, channel_names=['MLII']) data = record.p_signal.flatten() # use def denoise rdata = denoise(date=data) # get type of ECG data - annotation = wfdb.rdann(PATH + number, 'atr') + annotation = wfdb.rdann(ECGDATAPATH + number, 'atr') Rlocation = annotation.sample # annotation.sample:get R Rclass = annotation.symbol diff --git a/logs/20230316-201043/train/events.out.tfevents.1678968646.WEIYUQING.70736.0.v2 b/logs/20230316-201043/train/events.out.tfevents.1678968646.WEIYUQING.70736.0.v2 new file mode 100644 index 0000000..1f4b420 Binary files /dev/null and b/logs/20230316-201043/train/events.out.tfevents.1678968646.WEIYUQING.70736.0.v2 differ diff --git a/logs/20230316-201316/train/events.out.tfevents.1678968799.WEIYUQING.69432.0.v2 b/logs/20230316-201316/train/events.out.tfevents.1678968799.WEIYUQING.69432.0.v2 new file mode 100644 index 0000000..37927c0 Binary files /dev/null and b/logs/20230316-201316/train/events.out.tfevents.1678968799.WEIYUQING.69432.0.v2 differ diff --git a/logs/20230316-201450/train/events.out.tfevents.1678968893.WEIYUQING.65212.0.v2 b/logs/20230316-201450/train/events.out.tfevents.1678968893.WEIYUQING.65212.0.v2 new file mode 100644 index 0000000..df5fdad Binary files /dev/null and b/logs/20230316-201450/train/events.out.tfevents.1678968893.WEIYUQING.65212.0.v2 differ diff --git a/logs/20230316-203620/train/events.out.tfevents.1678970182.WEIYUQING.35808.0.v2 b/logs/20230316-203620/train/events.out.tfevents.1678970182.WEIYUQING.35808.0.v2 new file mode 100644 index 0000000..0901d9b Binary files /dev/null and b/logs/20230316-203620/train/events.out.tfevents.1678970182.WEIYUQING.35808.0.v2 differ diff --git a/logs/20230316-203806/train/events.out.tfevents.1678970289.WEIYUQING.72584.0.v2 b/logs/20230316-203806/train/events.out.tfevents.1678970289.WEIYUQING.72584.0.v2 new file mode 100644 index 0000000..e119e8d Binary files /dev/null and b/logs/20230316-203806/train/events.out.tfevents.1678970289.WEIYUQING.72584.0.v2 differ diff --git a/logs/20230316-203916/train/events.out.tfevents.1678970359.WEIYUQING.71944.0.v2 b/logs/20230316-203916/train/events.out.tfevents.1678970359.WEIYUQING.71944.0.v2 new file mode 100644 index 0000000..13e9e73 Binary files /dev/null and b/logs/20230316-203916/train/events.out.tfevents.1678970359.WEIYUQING.71944.0.v2 differ diff --git a/logs/20230316-203916/validation/events.out.tfevents.1678970360.WEIYUQING.71944.1.v2 b/logs/20230316-203916/validation/events.out.tfevents.1678970360.WEIYUQING.71944.1.v2 new file mode 100644 index 0000000..c4db941 Binary files /dev/null and b/logs/20230316-203916/validation/events.out.tfevents.1678970360.WEIYUQING.71944.1.v2 differ diff --git a/logs/20230316-204324/train/events.out.tfevents.1678970606.WEIYUQING.72540.0.v2 b/logs/20230316-204324/train/events.out.tfevents.1678970606.WEIYUQING.72540.0.v2 new file mode 100644 index 0000000..6580d74 Binary files /dev/null and b/logs/20230316-204324/train/events.out.tfevents.1678970606.WEIYUQING.72540.0.v2 differ diff --git a/logs/20230316-204324/validation/events.out.tfevents.1678970607.WEIYUQING.72540.1.v2 b/logs/20230316-204324/validation/events.out.tfevents.1678970607.WEIYUQING.72540.1.v2 new file mode 100644 index 0000000..1d97ddf Binary files /dev/null and b/logs/20230316-204324/validation/events.out.tfevents.1678970607.WEIYUQING.72540.1.v2 differ diff --git a/logs/20230316-204654/train/events.out.tfevents.1678970817.WEIYUQING.59208.0.v2 b/logs/20230316-204654/train/events.out.tfevents.1678970817.WEIYUQING.59208.0.v2 new file mode 100644 index 0000000..606c9b2 Binary files /dev/null and b/logs/20230316-204654/train/events.out.tfevents.1678970817.WEIYUQING.59208.0.v2 differ diff --git a/logs/20230316-204654/validation/events.out.tfevents.1678970818.WEIYUQING.59208.1.v2 b/logs/20230316-204654/validation/events.out.tfevents.1678970818.WEIYUQING.59208.1.v2 new file mode 100644 index 0000000..5b7a538 Binary files /dev/null and b/logs/20230316-204654/validation/events.out.tfevents.1678970818.WEIYUQING.59208.1.v2 differ diff --git a/logs/20230316-204755/train/events.out.tfevents.1678970878.WEIYUQING.70276.0.v2 b/logs/20230316-204755/train/events.out.tfevents.1678970878.WEIYUQING.70276.0.v2 new file mode 100644 index 0000000..b1d95fa Binary files /dev/null and b/logs/20230316-204755/train/events.out.tfevents.1678970878.WEIYUQING.70276.0.v2 differ diff --git a/logs/20230316-204755/validation/events.out.tfevents.1678970879.WEIYUQING.70276.1.v2 b/logs/20230316-204755/validation/events.out.tfevents.1678970879.WEIYUQING.70276.1.v2 new file mode 100644 index 0000000..10fb6ad Binary files /dev/null and b/logs/20230316-204755/validation/events.out.tfevents.1678970879.WEIYUQING.70276.1.v2 differ diff --git a/logs/20230316-205441/train/events.out.tfevents.1678971284.WEIYUQING.74296.0.v2 b/logs/20230316-205441/train/events.out.tfevents.1678971284.WEIYUQING.74296.0.v2 new file mode 100644 index 0000000..f1129ae Binary files /dev/null and b/logs/20230316-205441/train/events.out.tfevents.1678971284.WEIYUQING.74296.0.v2 differ diff --git a/logs/20230316-205441/validation/events.out.tfevents.1678971285.WEIYUQING.74296.1.v2 b/logs/20230316-205441/validation/events.out.tfevents.1678971285.WEIYUQING.74296.1.v2 new file mode 100644 index 0000000..1614383 Binary files /dev/null and b/logs/20230316-205441/validation/events.out.tfevents.1678971285.WEIYUQING.74296.1.v2 differ diff --git a/logs/20230317-131055/train/events.out.tfevents.1679029869.WEIYUQING.58064.0.v2 b/logs/20230317-131055/train/events.out.tfevents.1679029869.WEIYUQING.58064.0.v2 new file mode 100644 index 0000000..b0c6778 Binary files /dev/null and b/logs/20230317-131055/train/events.out.tfevents.1679029869.WEIYUQING.58064.0.v2 differ diff --git a/logs/20230317-131055/validation/events.out.tfevents.1679029877.WEIYUQING.58064.1.v2 b/logs/20230317-131055/validation/events.out.tfevents.1679029877.WEIYUQING.58064.1.v2 new file mode 100644 index 0000000..b8583eb Binary files /dev/null and b/logs/20230317-131055/validation/events.out.tfevents.1679029877.WEIYUQING.58064.1.v2 differ diff --git a/mit-bih-arrhythmia-database-1.0.0/102-0.atr b/mit-bih-arrhythmia-database-1.0.0/102-0.atr deleted file mode 100644 index e79579d..0000000 Binary files a/mit-bih-arrhythmia-database-1.0.0/102-0.atr and /dev/null differ diff --git a/noise_take_ecg.py b/noise_take_ecg.py index 4b7eff5..bd4f428 100644 --- a/noise_take_ecg.py +++ b/noise_take_ecg.py @@ -6,11 +6,11 @@ from matplotlib import pyplot as plt #file error #use db5 ,level9 do deviose -from ECG_read_weiyuqing_without_wfdb import PATH +from ECG_read_weiyuqing_without_wfdb import ECGDATAPATH #from ECG_read_weiyuqing_without_wfdb import PATH -record=wfdb.rdrecord(PATH+100,channel_names=['MLII']) +record=wfdb.rdrecord(ECGDATAPATH + 100, channel_names=['MLII']) data=record.p_signal.flatten() coeffs=pywt.wavedec(data=data,wavelet='db5',level=9) diff --git a/pytorch_gpu_test.py b/pytorch_gpu_test.py new file mode 100644 index 0000000..3d43daa --- /dev/null +++ b/pytorch_gpu_test.py @@ -0,0 +1,2 @@ +import torch +torch.cuda.is_available() \ No newline at end of file diff --git a/tf_run_in_gpu.py b/tf_run_in_gpu.py new file mode 100644 index 0000000..ba34a47 --- /dev/null +++ b/tf_run_in_gpu.py @@ -0,0 +1,52 @@ +import tensorflow as tf + +tf.test.is_gpu_available() + +# # Tensorflow 2.10是最后一个在本地windows上支持GPU的版本。从2.11版本开始,需要在windows WLS2(适用于 Linux 的 Windows 子系统)上安装才能使用GPU。所以要在native-windows上使用GPU,就只能安装2.10.0版本及以下的版本,或者安装老版的tensorflow-gpu. +# # 指定在cpu上运行 +# with tf.device('/cpu:0'): +# cpu_a = tf.random.normal([10000, 1000]) +# cpu_b = tf.random.normal([1000, 2000]) +# cpu_c = tf.matmul(cpu_a, cpu_b) +# print("cpu_a:", cpu_a.device) +# print("cpu_b:", cpu_b.device) +# print("cpu_c:", cpu_c.device) +# # 查看gpu是否可用 +# print(tf.config.list_physical_devices('GPU')) +# # 指定在gpu上运行 +# with tf.device('/gpu:0'): +# gpu_a = tf.random.normal([10000, 1000]) +# gpu_b = tf.random.normal([1000, 2000]) +# gpu_c = tf.matmul(gpu_a, gpu_b) +# print("gpu_a:", gpu_a.device) +# print("gpu_b:", gpu_b.device) +# print("gpu_c:", gpu_c.device) +# +# import tensorflow as tf +# import timeit +# +# +# def cpu_run(): +# with tf.device('/cpu:0'): +# cpu_a = tf.random.normal([10000, 1000]) +# cpu_b = tf.random.normal([1000, 2000]) +# c = tf.matmul(cpu_a, cpu_b) +# return c +# +# +# def gpu_run(): +# with tf.device('/gpu:0'): +# gpu_a = tf.random.normal([10000, 1000]) +# gpu_b = tf.random.normal([1000, 2000]) +# c = tf.matmul(gpu_a, gpu_b) +# return c +# +# +# cpu_time = timeit.timeit(cpu_run, number=10) +# gpu_time = timeit.timeit(gpu_run, number=10) +# print("cpu:", cpu_time, " gpu:", gpu_time) +# # 检测 tensorflow 能使用的设备情况 +# from tensorflow.python.client import device_lib +# +# # os.environ["CUDA_VISIBLE_DEVICES"] = "1" # 这个可以指定使用哪个设备 +# print(device_lib.list_local_devices()) diff --git a/utils.py b/utils.py new file mode 100644 index 0000000..48a84a1 --- /dev/null +++ b/utils.py @@ -0,0 +1,158 @@ +import wfdb +import pywt +import seaborn +import numpy as np +import matplotlib.pyplot as plt +from sklearn.metrics import confusion_matrix +from sklearn.model_selection import train_test_split +from ECG_read_weiyuqing_without_wfdb import ECGDATAPATH + + +# wavelet denoise preprocess using mallat algorithm + +def denoise(date): + # Wavelet db5 level9 + coeffs = pywt.wavedec(data=date, wavelet='db5', level=9) + cA9, cD9, cD8, cD7, cD6, cD5, cD4, cD3, cD2, cD1 = coeffs + # noice del + threshold = (np.median(np.abs(cD1)) / 0.6745) * (np.sqrt(2 * np.log(len(cD1)))) + # take cD 1,2 turn 0 to denoise + cD1.fill(0) + cD2.fill(0) + for i in range(1, len(coeffs) - 2): + coeffs[i] = pywt.threshold(coeffs[i], threshold) + # get signal that before wavelet + rdata = pywt.waverec(coeffs=coeffs, wavelet='db5') + return rdata + + +# get ECG data,date type and denoise +# this function without return +# use append take return data to pass data +def getDataSet(number, X_data, Y_data): + ecgClassSet = ['N', 'A', 'V', 'l', 'R'] + print('get' + number + ' ECG data') + record = wfdb.rdrecord(ECGDATAPATH + number, channel_names=['MLII']) + data = record.p_signal.flatten() + # use def denoise + rdata = denoise(date=data) + + # get type of ECG data + annotation = wfdb.rdann(ECGDATAPATH + number, 'atr') + Rlocation = annotation.sample # annotation.sample:get R + Rclass = annotation.symbol + + # delete stable date near R + start = 10 + end = 5 + i = start + j = len(annotation.symbol) - end + + # get NAVLR type data + while i < j: + try: + lable = ecgClassSet.index(Rclass[i]) + x_train = rdata[Rlocation[i] - 99:Rlocation[i] + 201] + X_data.append(x_train) + Y_data.append(lable) + i += 1 + except ValueError: + i += 1 + return + + +# RATIO=The ratio of the training set to the test set,usually is 0.3 +def loadData(ratio, random_seed): + numberSet = ['100', '101', '103', '105', '106', '107', '108', '109', '111', '112', '113', '114', '115', + '116', '117', '119', '121', '122', '123', '124', '200', '201', '202', '203', '205', '208', + '210', '212', '213', '214', '215', '217', '219', '220', '221', '222', '223', '228', '230', + '231', '232', '233', '234'] + dataSet = [] + labelSet = [] + for n in numberSet: + getDataSet(n, dataSet, labelSet) + + # dataSet = np.array(dataSet).reshape(-1, 300) + # labelSet = np.array(labelSet).reshape(-1, 1) + + # reshape the data and split the dataset + dataSet = np.array(dataSet).reshape(-1, 300) + lableSet = np.array(labelSet).reshape(-1) + X_train, X_test, y_train, y_test = train_test_split(dataSet, lableSet, test_size=ratio, random_state=random_seed) + return X_train, X_test, y_train, y_test + + # train_ds = np.hstack((dataSet, labelSet)) + # np.random.shuffle(train_ds) + # + # X = train_ds[:, :300].reshape(-1, 300, 1) + # Y = train_ds[:, 300] + # # cut test and train data from ECG data + # shuffle_index = np.random.permutation(len(X)) + # test_length = int(RATIO * len(shuffle_index)) + # test_index = shuffle_index[:test_length] + # train_index = shuffle_index[test_index:] + # X_test, Y_test = X[test_index:], Y[test_index] + # X_train, Y_train = X[train_index], Y[train_index] + # return X_train, Y_test, X_test, Y_train + + +# confusion matrix +def plot_heat_map(y_test, y_pred): + con_mat = confusion_matrix(y_test, y_pred) + # normalize + # con_mat_norm = con_mat.astype('float') / con_mat.sum(axis=1)[:, np.newaxis] + # con_mat_norm = np.around(con_mat_norm, decimals=2) + + # plot + plt.figure(figsize=(8, 8)) + seaborn.heatmap(con_mat, annot=True, fmt='.20g', cmap='Blues') + plt.ylim(0, 5) + plt.xlabel('Predicted labels') + plt.ylabel('True labels') + plt.title('Confusion Matrix') + plt.savefig('confusion_matrix.png') + plt.show() + + +def plot_history_tf(history): + plt.figure(figsize=(8, 8)) + plt.plot(history.history['accuracy']) + plt.plot(history.history['val_accuracy']) + plt.title('Model Accuracy') + plt.ylabel('Accuracy') + plt.xlabel('Epoch') + plt.legend(['Train', 'Test'], loc='upper left') + plt.savefig('accuracy.png') + plt.show() + + plt.figure(figsize=(8, 8)) + plt.plot(history.history['loss']) + plt.plot(history.history['val_loss']) + plt.title('Model Loss') + plt.ylabel('Loss') + plt.xlabel('Epoch') + plt.legend(['Train', 'Test'], loc='upper left') + plt.savefig('loss.png') + plt.show() + + +def plot_history_torch(history): + plt.figure(figsize=(8, 8)) + plt.plot(history['train_acc']) + plt.plot(history['test_acc']) + plt.title('Model Accuracy') + plt.ylabel('Accuracy') + plt.xlabel('Epoch') + plt.legend(['Train', 'Test'], loc='upper left') + plt.savefig('accuracy.png') + plt.show() + + plt.figure(figsize=(8, 8)) + plt.plot(history['train_loss']) + plt.plot(history['test_loss']) + plt.title('Model Loss') + plt.ylabel('Loss') + plt.xlabel('Epoch') + plt.legend(['Train', 'Test'], loc='upper left') + plt.savefig('loss.png') + plt.show()