-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathbasic_rnn_lstm_gru.py
138 lines (104 loc) · 4.06 KB
/
basic_rnn_lstm_gru.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
127
128
129
130
131
132
133
134
135
136
137
138
"""General RNN core functions for time-series prediction.
Author: Jinsung Yoon
Contact: [email protected]
"""
# Necessary packages
import os
import tensorflow as tf
import numpy as np
from datetime import datetime
from tensorflow.keras import layers
from keras.callbacks import ModelCheckpoint
from utils import binary_cross_entropy_loss, mse_loss, rnn_sequential
class GeneralRNN():
"""RNN predictive model to time-series.
Attributes:
- model_parameters:
- task: classification or regression
- model_type: 'rnn', 'lstm', or 'gru'
- h_dim: hidden dimensions
- n_layer: the number of layers
- batch_size: the number of samples in each batch
- epoch: the number of iteration epochs
- learning_rate: the learning rate of model training
"""
def __init__(self, model_parameters):
self.task = model_parameters['task']
self.model_type = model_parameters['model_type']
self.h_dim = model_parameters['h_dim']
self.n_layer = model_parameters['n_layer']
self.batch_size = model_parameters['batch_size']
self.epoch = model_parameters['epoch']
self.learning_rate = model_parameters['learning_rate']
assert self.model_type in ['rnn', 'lstm', 'gru']
# Predictor model define
self.predictor_model = None
# Set path for model saving
model_path = 'tmp'
if not os.path.exists(model_path):
os.makedirs(model_path)
self.save_file_name = '{}'.format(model_path) + \
datetime.now().strftime('%H%M%S') + '.hdf5'
def _build_model(self, x, y):
"""Construct the model using feature and label statistics.
Args:
- x: features
- y: labels
Returns:
- model: predictor model
"""
# Parameters
h_dim = self.h_dim
n_layer = self.n_layer
dim = len(x[0, 0, :])
max_seq_len = len(x[0, :, 0])
model = tf.keras.Sequential()
model.add(layers.Masking(mask_value=0., input_shape=(max_seq_len, dim)))
for _ in range(n_layer - 1):
model = rnn_sequential(model, self.model_type, h_dim, return_seq=True)
model = rnn_sequential(model, self.model_type, h_dim,
return_seq=False)
adam = tf.keras.optimizers.Adam(learning_rate=self.learning_rate,
beta_1=0.9, beta_2=0.999, amsgrad=False)
if self.task == 'classification':
model.add(layers.Dense(y.shape[-1], activation='sigmoid'))
model.compile(loss=binary_cross_entropy_loss, optimizer=adam)
elif self.task == 'regression':
model.add(layers.Dense(y.shape[-1], activation='linear'))
model.compile(loss=mse_loss, optimizer=adam, metrics=['mse'])
return model
def fit(self, x, y):
"""Fit the predictor model.
Args:
- x: training features
- y: training labels
Returns:
- self.predictor_model: trained predictor model
"""
idx = np.random.permutation(len(x))
train_idx = idx[:int(len(idx)*0.8)]
valid_idx = idx[int(len(idx)*0.8):]
train_x, train_y = x[train_idx], y[train_idx]
valid_x, valid_y = x[valid_idx], y[valid_idx]
self.predictor_model = self._build_model(train_x, train_y)
# Callback for the best model saving
save_best = ModelCheckpoint(self.save_file_name, monitor='val_loss',
mode='min', verbose=False,
save_best_only=True)
# Train the model
self.predictor_model.fit(train_x, train_y,
batch_size=self.batch_size, epochs=self.epoch,
validation_data=(valid_x, valid_y),
callbacks=[save_best], verbose=True)
self.predictor_model.load_weights(self.save_file_name)
os.remove(self.save_file_name)
return self.predictor_model
def predict(self, test_x):
"""Return the temporal and feature importance.
Args:
- test_x: testing features
Returns:
- test_y_hat: predictions on testing set
"""
test_y_hat = self.predictor_model.predict(test_x)
return test_y_hat