-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathtrain.py
More file actions
173 lines (147 loc) · 6.81 KB
/
Copy pathtrain.py
File metadata and controls
173 lines (147 loc) · 6.81 KB
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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
import time
import pickle
import model
import os
import tensorflow as tf
from tensorflow.contrib.seq2seq.python.ops import beam_search_ops
print('TensorFlow Version: {}'.format(tf.__version__))
def load_pickle(filepath):
"""Load pickled data"""
documents_f = open('data/'+filepath+'.pickle', 'rb')
data = pickle.load(documents_f)
documents_f.close()
return data
#==============================================================================
# # Load data
#==============================================================================
print('Loading and preparing data for training...')
enc_inputs = load_pickle('sorted_inputs')
dec_targets = load_pickle('sorted_targets')
vocab2int = load_pickle('vocab2int')
int2vocab = load_pickle('int2vocab')
word_embedding_matrix = load_pickle('word_embedding_matrix')
assert len(enc_inputs) == len(dec_targets)
assert len(vocab2int) == len(int2vocab)
#==============================================================================
# # Set the Hyperparameters
#==============================================================================
epochs = 100
batch_size = 128
rnn_size = 512
num_layers = 2
learning_rate = 0.005
keep_probability = 0.8
beam_width = 20
print('Building graph')
# Build the graph
train_graph = tf.Graph()
# Set the graph to default to ensure that it is ready for training
with train_graph.as_default():
# Load the model inputs
input_data, targets, lr, keep_prob, target_length, max_target_length, input_length = model.model_inputs()
# Create the training and inference logits
training_logits, inference_logits = model.seq2seq_model(tf.reverse(input_data, [-1]),
targets,
keep_prob,
input_length,
target_length,
max_target_length,
len(vocab2int)+1,
rnn_size,
num_layers,
vocab2int,
word_embedding_matrix,
batch_size,
beam_width)
# Create tensors for the training logits and inference logits
training_logits = tf.identity(training_logits.rnn_output, 'logits')
inference_logits = tf.identity(inference_logits.predicted_ids, name='predictions')
# Create the weights for sequence_loss
masks = tf.sequence_mask(target_length, max_target_length, dtype=tf.float32, name='masks')
with tf.name_scope("optimization"):
# Loss function
cost = tf.contrib.seq2seq.sequence_loss(
training_logits,
targets,
masks)
# Optimizer
optimizer = tf.train.AdamOptimizer(learning_rate)
# Gradient Clipping
gradients = optimizer.compute_gradients(cost)
capped_gradients = [(tf.clip_by_value(grad, -5., 5.), var) for grad, var in gradients if grad is not None]
train_op = optimizer.apply_gradients(capped_gradients)
print("Graph is built.")
#==============================================================================
# Train the model
#==============================================================================
learning_rate_decay = 0.95
min_learning_rate = 0.0005
display_step = 20 # Check training loss after every 20 batches
stop_early = 0
stop = 3 # If the update loss does not decrease in 3 consecutive update checks, stop training
per_epoch = 3 # Make 3 update checks per epoch
update_check = (len(enc_inputs)//batch_size//per_epoch)-1
update_loss = 0
batch_loss = 0
# Record the update losses for saving improvements in the model
question_update_loss = []
checkpoint_dir = 'ckpt'
checkpoint_path = os.path.join(checkpoint_dir, 'model.ckpt')
restore = 0
print('Initializing session and training')
with tf.Session(graph=train_graph) as sess:
sess.run(tf.global_variables_initializer())
saver = tf.train.Saver()
# If we want to continue training a previous session
ckpt = tf.train.get_checkpoint_state(checkpoint_dir)
if ckpt and restore:
print('Restoring old model parameters from %s...' % ckpt.model_checkpoint_path)
saver.restore(sess, ckpt.model_checkpoint_path)
for epoch_i in range(1, epochs+1):
update_loss = 0
batch_loss = 0
for batch_i, (targets_batch, inputs_batch, targets_lengths, inputs_lengths) in enumerate(
model.get_batches(dec_targets, enc_inputs, vocab2int, batch_size)):
start_time = time.time()
_, loss = sess.run(
[train_op, cost],
{input_data: inputs_batch,
targets: targets_batch,
lr: learning_rate,
target_length: targets_lengths,
input_length: inputs_lengths,
keep_prob: keep_probability})
batch_loss += loss
update_loss += loss
end_time = time.time()
batch_time = end_time - start_time
if batch_i % display_step == 0:
print('Epoch {:>3}/{} Batch {:>4}/{} - Loss: {:>6.3f}, Seconds: {:>4.2f}'
.format(epoch_i,
epochs,
batch_i,
len(enc_inputs) // batch_size,
batch_loss / display_step,
batch_time*display_step))
batch_loss = 0
if batch_i % update_check == 0 and batch_i > 0:
print("Average loss for this update:", round(update_loss/update_check, 3))
question_update_loss.append(update_loss)
# If the update loss is at a new minimum, save the model
if update_loss <= min(question_update_loss):
print('New Record! Saving the model.')
stop_early = 0
saver.save(sess, checkpoint_path)
else:
print("No Improvement.")
stop_early += 1
if stop_early == stop:
break
update_loss = 0
# Reduce learning rate, but not below its minimum value
learning_rate *= learning_rate_decay
if learning_rate < min_learning_rate:
learning_rate = min_learning_rate
if stop_early == stop:
print("Stopping Training.")
break