|
a |
|
b/Conv1D_ECG.py |
|
|
1 |
# source:https://github.com/ismorphism/DeepECG |
|
|
2 |
# 2019/11/25 YANG Jie 小修改 |
|
|
3 |
from sklearn.metrics import confusion_matrix, accuracy_score |
|
|
4 |
from keras.callbacks import ModelCheckpoint |
|
|
5 |
from sklearn.preprocessing import MinMaxScaler, RobustScaler |
|
|
6 |
import pandas as pd |
|
|
7 |
import scipy.io as sio |
|
|
8 |
from os import listdir |
|
|
9 |
from os.path import isfile, join |
|
|
10 |
import numpy as np |
|
|
11 |
import keras |
|
|
12 |
from keras.models import Sequential |
|
|
13 |
from keras.layers import Dense, Activation, Dropout, Conv1D, GlobalAveragePooling1D, MaxPooling1D |
|
|
14 |
from keras import regularizers |
|
|
15 |
from keras.utils import np_utils |
|
|
16 |
|
|
|
17 |
number_of_classes = 4 # Total number of classes |
|
|
18 |
|
|
|
19 |
|
|
|
20 |
def to_one_hot(y): |
|
|
21 |
return np_utils.to_categorical(y) |
|
|
22 |
|
|
|
23 |
|
|
|
24 |
def change(x): # From boolean arrays to decimal arrays |
|
|
25 |
answer = np.zeros((np.shape(x)[0])) |
|
|
26 |
for i in range(np.shape(x)[0]): |
|
|
27 |
max_value = max(x[i, :]) |
|
|
28 |
max_index = list(x[i, :]).index(max_value) |
|
|
29 |
answer[i] = max_index |
|
|
30 |
return answer.astype(np.int) |
|
|
31 |
|
|
|
32 |
|
|
|
33 |
mypath = 'training2017/' # Training directory |
|
|
34 |
onlyfiles = [f for f in listdir(mypath) if (isfile(join(mypath, f)) and f[0] == 'A')] |
|
|
35 |
bats = [f for f in onlyfiles if f[7] == 'm'] |
|
|
36 |
check = 100 |
|
|
37 |
mats = [f for f in bats if (np.shape(sio.loadmat(mypath + f)['val'])[1] >= check)] |
|
|
38 |
size = len(mats) |
|
|
39 |
print('Total training size is ', size) |
|
|
40 |
big = 10100 |
|
|
41 |
X = np.zeros((size, big)) |
|
|
42 |
|
|
|
43 |
for i in range(size): |
|
|
44 |
dummy = sio.loadmat(mypath + mats[i])['val'][0, :] |
|
|
45 |
if (big - len(dummy)) <= 0: |
|
|
46 |
X[i, :] = dummy[0:big] |
|
|
47 |
else: |
|
|
48 |
b = dummy[0:(big - len(dummy))] |
|
|
49 |
goal = np.hstack((dummy, b)) |
|
|
50 |
while len(goal) != big: |
|
|
51 |
b = dummy[0:(big - len(goal))] |
|
|
52 |
goal = np.hstack((goal, b)) |
|
|
53 |
X[i, :] = goal |
|
|
54 |
|
|
|
55 |
target_train = np.zeros((size, 1)) |
|
|
56 |
Train_data = pd.read_csv(mypath + 'REFERENCE.csv', sep=',', header=None, names=None) |
|
|
57 |
for i in range(size): |
|
|
58 |
if Train_data.loc[Train_data[0] == mats[i][:6], 1].values == 'N': |
|
|
59 |
target_train[i] = 0 |
|
|
60 |
elif Train_data.loc[Train_data[0] == mats[i][:6], 1].values == 'A': |
|
|
61 |
target_train[i] = 1 |
|
|
62 |
elif Train_data.loc[Train_data[0] == mats[i][:6], 1].values == 'O': |
|
|
63 |
target_train[i] = 2 |
|
|
64 |
else: |
|
|
65 |
target_train[i] = 3 |
|
|
66 |
|
|
|
67 |
Label_set = to_one_hot(target_train) |
|
|
68 |
|
|
|
69 |
X = (X - X.mean()) / (X.std()) # Some normalization here |
|
|
70 |
X = np.expand_dims(X, axis=2) # For Keras's data input size |
|
|
71 |
|
|
|
72 |
values = [i for i in range(size)] |
|
|
73 |
permutations = np.random.permutation(values) |
|
|
74 |
X = X[permutations, :] |
|
|
75 |
Label_set = Label_set[permutations, :] |
|
|
76 |
|
|
|
77 |
train = 0.9 # Size of training set in percentage |
|
|
78 |
X_train = X[:int(train * size), :] |
|
|
79 |
Y_train = Label_set[:int(train * size), :] |
|
|
80 |
X_val = X[int(train * size):, :] |
|
|
81 |
Y_val = Label_set[int(train * size):, :] |
|
|
82 |
|
|
|
83 |
# def create_model(): |
|
|
84 |
model = Sequential() |
|
|
85 |
model.add(Conv1D(128, 55, activation='relu', input_shape=(big, 1))) |
|
|
86 |
model.add(MaxPooling1D(10)) |
|
|
87 |
model.add(Dropout(0.5)) |
|
|
88 |
model.add(Conv1D(128, 25, activation='relu')) |
|
|
89 |
model.add(MaxPooling1D(5)) |
|
|
90 |
model.add(Dropout(0.5)) |
|
|
91 |
model.add(Conv1D(128, 10, activation='relu')) |
|
|
92 |
model.add(MaxPooling1D(5)) |
|
|
93 |
model.add(Dropout(0.5)) |
|
|
94 |
model.add(Conv1D(128, 5, activation='relu')) |
|
|
95 |
model.add(GlobalAveragePooling1D()) |
|
|
96 |
# model.add(Flatten()) |
|
|
97 |
model.add(Dense(256, kernel_initializer='normal', activation='relu')) |
|
|
98 |
model.add(Dropout(0.5)) |
|
|
99 |
model.add(Dense(128, kernel_initializer='normal', activation='relu')) |
|
|
100 |
model.add(Dropout(0.5)) |
|
|
101 |
model.add(Dense(64, kernel_initializer='normal', activation='relu')) |
|
|
102 |
model.add(Dropout(0.5)) |
|
|
103 |
model.add(Dense(number_of_classes, kernel_initializer='normal', activation='softmax')) |
|
|
104 |
|
|
|
105 |
model.summary() |
|
|
106 |
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) |
|
|
107 |
hist = model.fit(X_train, Y_train, validation_data=(X_val, Y_val), batch_size=256, epochs=50, verbose=2, shuffle=True) |
|
|
108 |
pd.DataFrame(hist.history).to_csv(path_or_buf='Conv_models/History.csv') |
|
|
109 |
predictions = model.predict(X_val) |
|
|
110 |
score = accuracy_score(change(Y_val), change(predictions)) |
|
|
111 |
print('Last epoch\'s validation score is ', score) |
|
|
112 |
df = pd.DataFrame(change(predictions)) |
|
|
113 |
df.to_csv(path_or_buf='Conv_models/Preds_' + str(format(score, '.4f')) + '.csv', index=None, header=None) |
|
|
114 |
pd.DataFrame(confusion_matrix(change(Y_val), change(predictions))).to_csv( |
|
|
115 |
path_or_buf='Conv_models/Result_Conf' + str(format(score, '.4f')) + '.csv', index=None, header=None) |