-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathmodel.py
126 lines (97 loc) · 3.18 KB
/
model.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import pandas as pd
import numpy as np
DATADIR = '/content/drive/My Drive/UCI HAR Dataset'
SIGNALS = [
"body_acc_x",
"body_acc_y",
"body_acc_z",
"body_gyro_x",
"body_gyro_y",
"body_gyro_z",
"total_acc_x",
"total_acc_y",
"total_acc_z"
]
def _read_csv(filename):
return pd.read_csv(filename, delim_whitespace=True, header=None)
def load_signals(subset):
signals_data = []
for signal in SIGNALS:
filename = f'{DATADIR}/{subset}/Inertial Signals/{signal}_{subset}.txt'
signals_data.append(
_read_csv(filename).values
)
# Transpose is used to change the dimensionality of the output,
# aggregating the signals by combination of sample/timestep.
# Resultant shape is (7352 train/2947 test samples, 128 timesteps, 9 signals)
return np.transpose(signals_data, (1, 2, 0))
def load_y(subset):
"""
The objective that we are trying to predict is a integer, from 1 to 6,
that represents a human activity. We return a binary representation of
every sample objective as a 6 bits vector using One Hot Encoding
(https://pandas.pydata.org/pandas-docs/stable/generated/pandas.get_dummies.html)
"""
filename = f'{DATADIR}/{subset}/y_{subset}.txt'
y = _read_csv(filename)[0]
return pd.get_dummies(y).values
def load_data():
"""
Obtain the dataset from multiple files.
Returns: X_train, X_test, y_train, y_test
"""
X_train, X_test = load_signals('train'), load_signals('test')
y_train, y_test = load_y('train'), load_y('test')
return X_train, X_test, y_train, y_test
load_data()
import pandas as pd
import numpy as np
ACTIVITIES = {
0: 'WALKING',
1: 'WALKING_UPSTAIRS',
2: 'WALKING_DOWNSTAIRS',
3: 'SITTING',
4: 'STANDING',
5: 'LAYING',
}
def confusion_matrix(Y_true, Y_pred):
Y_true = pd.Series([ACTIVITIES[y] for y in np.argmax(Y_true, axis=1)])
Y_pred = pd.Series([ACTIVITIES[y] for y in np.argmax(Y_pred, axis=1)])
return pd.crosstab(Y_true, Y_pred, rownames=['True'], colnames=['Pred'])
import numpy as np
np.random.seed(42)
import tensorflow as tf
tf.random.set_seed(42)
# for reproducibility
# https://github.com/fchollet/keras/issues/2280
#session_conf = tf.compat.v1.ConfigProto(
# intra_op_parallelism_threads=1,
# inter_op_parallelism_threads=1
#)
from keras import backend as K
from keras.models import Sequential
from keras.layers import LSTM
from keras.layers.core import Dense, Dropout
epochs = 30
batch_size = 16
n_hidden = 32
def _count_classes(y):
return len(set([tuple(category) for category in y]))
X_train, X_test, Y_train, Y_test = load_data()
timesteps = len(X_train[0])
input_dim = len(X_train[0][0])
n_classes = _count_classes(Y_train)
model = Sequential()
model.add(LSTM(n_hidden, input_shape=(timesteps, input_dim)))
model.add(Dropout(0.5))
model.add(Dense(n_classes, activation='sigmoid'))
model.compile(loss='categorical_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
model.fit(X_train,
Y_train,
batch_size=batch_size,
validation_data=(X_test, Y_test),
epochs=epochs)
# Evaluate
print(confusion_matrix(Y_test, model.predict(X_test)))