Switch to unified view

a b/Models/main-RNN-with-Attention.py
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
4
# Import useful packages
5
from __future__ import absolute_import
6
from __future__ import print_function
7
from __future__ import division
8
9
# Hide the Configuration and Warnings
10
import os
11
os.environ["TF_CPP_MIN_LOG_LEVEL"] = '3'
12
13
import random
14
import numpy as np
15
import tensorflow as tf
16
from Models.DatasetAPI.DataLoader import DatasetLoader
17
from Models.Network.RNN_with_Attention import RNN_with_Attention
18
from Models.Loss_Function.Loss import loss
19
from Models.Evaluation_Metrics.Metrics import evaluation
20
21
# Model Name
22
Model = 'Attention_based_Recurrent_Neural_Network'
23
24
# Clear all the stack and use GPU resources as much as possible
25
tf.reset_default_graph()
26
config = tf.ConfigProto()
27
config.gpu_options.allow_growth = True
28
sess = tf.Session(config=config)
29
30
# Your Dataset Location, for example EEG-Motor-Movement-Imagery-Dataset
31
# The CSV file should be named as training_set.csv, training_label.csv, test_set.csv, and test_label.csv
32
DIR = 'DatasetAPI/EEG-Motor-Movement-Imagery-Dataset/'
33
SAVE = 'Saved_Files/' + Model + '/'
34
if not os.path.exists(SAVE):  # If the SAVE folder doesn't exist, create one
35
    os.mkdir(SAVE)
36
37
# Load the dataset, here it uses one-hot representation for labels
38
train_data, train_labels, test_data, test_labels = DatasetLoader(DIR=DIR)
39
train_labels = tf.one_hot(indices=train_labels, depth=4)
40
train_labels = tf.squeeze(train_labels).eval(session=sess)
41
test_labels = tf.one_hot(indices=test_labels, depth=4)
42
test_labels = tf.squeeze(test_labels).eval(session=sess)
43
44
# Model Hyper-parameters
45
n_input  = 64       # The input size of signals at each time
46
max_time = 64       # The unfolded time slices of the RNN Model
47
rnn_size = 256      # The number of RNNs inside the RNN Model
48
attention_size = 8  # The number of neurons of fully-connected layer inside the Attention Mechanism
49
50
n_class   = 4     # The number of classification classes
51
n_hidden  = 64    # The number of hidden units in the first fully-connected layer
52
num_epoch = 300   # The number of Epochs that the Model run
53
keep_rate = 0.75  # Keep rate of the Dropout
54
55
lr = tf.constant(1e-4, dtype=tf.float32)  # Learning rate
56
lr_decay_epoch = 50    # Every (50) epochs, the learning rate decays
57
lr_decay       = 0.50  # Learning rate Decay by (50%)
58
59
batch_size = 1024
60
n_batch = train_data.shape[0] // batch_size
61
62
# Initialize Model Parameters (Network Weights and Biases)
63
# This Model only uses Two fully-connected layers, and u sure can add extra layers DIY
64
weights_1 = tf.Variable(tf.truncated_normal([rnn_size, n_hidden], stddev=0.01))
65
biases_1  = tf.Variable(tf.constant(0.01, shape=[n_hidden]))
66
weights_2 = tf.Variable(tf.truncated_normal([n_hidden, n_class], stddev=0.01))
67
biases_2  = tf.Variable(tf.constant(0.01, shape=[n_class]))
68
69
# Define Placeholders
70
x = tf.placeholder(tf.float32, [None, 64 * 64])
71
y = tf.placeholder(tf.float32, [None, 4])
72
keep_prob = tf.placeholder(tf.float32)
73
74
# Load Model Network
75
prediction, features, attention_weights = RNN_with_Attention(Input=x,
76
                                                             max_time=max_time,
77
                                                             rnn_size=rnn_size,
78
                                                             n_input=n_input,
79
                                                             attention_size=attention_size,
80
                                                             keep_prob=keep_prob,
81
                                                             weights_1=weights_1,
82
                                                             biases_1=biases_1,
83
                                                             weights_2=weights_2,
84
                                                             biases_2=biases_2)
85
86
# Load Loss Function
87
loss = loss(y=y, prediction=prediction, l2_norm=True)
88
89
# Load Optimizer
90
train_step = tf.train.AdamOptimizer(lr).minimize(loss)
91
92
# Load Evaluation Metrics
93
Global_Average_Accuracy = evaluation(y=y, prediction=prediction)
94
95
# Merge all the summaries
96
merged = tf.summary.merge_all()
97
train_writer = tf.summary.FileWriter(SAVE + '/train_Writer', sess.graph)
98
test_writer = tf.summary.FileWriter(SAVE + '/test_Writer')
99
100
# Initialize all the variables
101
sess.run(tf.global_variables_initializer())
102
for epoch in range(num_epoch + 1):
103
    # U can use learning rate decay or not
104
    # Here, we set a minimum learning rate
105
    # If u don't want this, u definitely can modify the following lines
106
    learning_rate = sess.run(lr)
107
    if epoch % lr_decay_epoch == 0 and epoch != 0:
108
        if learning_rate <= 1e-6:
109
            lr = lr * 1.0
110
            sess.run(lr)
111
        else:
112
            lr = lr * lr_decay
113
            sess.run(lr)
114
115
    # Randomly shuffle the training dataset and train the Model
116
    for batch_index in range(n_batch):
117
        random_batch = random.sample(range(train_data.shape[0]), batch_size)
118
        batch_xs = train_data[random_batch]
119
        batch_ys = train_labels[random_batch]
120
        sess.run(train_step, feed_dict={x: batch_xs, y: batch_ys, keep_prob: keep_rate})
121
122
    # Show Accuracy and Loss on Training and Test Set
123
    # Here, for training set, we only show the result of first 100 samples
124
    # If u want to show the result on the entire training set, please modify it.
125
    train_accuracy, train_loss = sess.run([Global_Average_Accuracy, loss], feed_dict={x: train_data[0:100], y: train_labels[0:100], keep_prob: 1.0})
126
    Test_summary, test_accuracy, test_loss = sess.run([merged, Global_Average_Accuracy, loss], feed_dict={x: test_data, y: test_labels, keep_prob: 1.0})
127
    test_writer.add_summary(Test_summary, epoch)
128
129
    # Show the Model Capability
130
    print("Iter " + str(epoch) + ", Testing Accuracy: " + str(test_accuracy) + ", Training Accuracy: " + str(train_accuracy))
131
    print("Iter " + str(epoch) + ", Testing Loss: " + str(test_loss) + ", Training Loss: " + str(train_loss))
132
    print("Learning rate is ", learning_rate)
133
    print('\n')
134
135
    # Save the prediction and labels for testing set
136
    # The "labels_for_test.csv" is the same as the "test_label.csv"
137
    # We will use the files to draw ROC CCurve and AUC
138
    if epoch == num_epoch:
139
        output_prediction = sess.run(prediction, feed_dict={x: test_data, y: test_labels, keep_prob: 1.0})
140
        np.savetxt(SAVE + "prediction_for_test.csv", output_prediction, delimiter=",")
141
        np.savetxt(SAVE + "labels_for_test.csv", test_labels, delimiter=",")
142
143
    # if you want to extract and save the features from fully-connected layer, use all the dataset and uncomment this.
144
    # All data is the total data = training data + testing data
145
    # We use the features from the overall dataset
146
    # ML models might be used to classify the features further
147
    # if epoch == num_epoch:
148
    #     Features = sess.run(Features, feed_dict={x: all_data, y: all_labels, keep_prob: 1.0})
149
    #     np.savetxt(SAVE + "Features.csv", Features, delimiter=",")
150
151
    # # U can output the Attention Weights at the final output of the Model, and visualize it.
152
    # Uncomment it, and save the Attention Weights
153
    # if epoch == num_epoch:
154
    #     attention_weights = sess.run(attention_weights, feed_dict={x: all_data, y: all_labels, keep_prob: 1.0})
155
    #     np.savetxt(SAVE + "attention_weights.csv", attention_weights, delimiter=",")
156
157
train_writer.close()
158
test_writer.close()
159
sess.close()