-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathtrain.py
More file actions
executable file
·188 lines (153 loc) · 9.54 KB
/
Copy pathtrain.py
File metadata and controls
executable file
·188 lines (153 loc) · 9.54 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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
import os
import sys
import argparse
import time
import tensorflow as tf
from tensorflow.contrib import layers
from utils import load_image, parse_function, average_gradients, assign_to_device
from inceptionV1 import inception_v1
def parse_arguments(argv):
parser = argparse.ArgumentParser()
parser.add_argument("--data_dir", type=str, default="/home/skj/huyz/data/mini-imagenet/train", help="Path to the data directory")
parser.add_argument("--num_epochs", type=int, default=500, help="The number of epochs to run")
parser.add_argument("--batch_size", type=int, default=128, help="Number of images to process in a batch")
parser.add_argument("--save_freq", type=int, default=15000, help="The frequence of saving checkpoint model")
parser.add_argument("--lr_steps", type=list, default=[20000, 40000, 60000], help="Learning rate deacy steps")
parser.add_argument("--image_height", type=int, default=224, help="The height of image in pixels")
parser.add_argument("--image_width", type=int, default=224, help="The width of iamge in pixels")
parser.add_argument("--weight_decay", type=float, default=5e-4, help="L2 weight regularization")
parser.add_argument("--num_gpu", type=list, default=2, help="The GPU device to use")
parser.add_argument("--log_dir", type=str, default="./logs", help="Directory name to save training logs")
parser.add_argument("--checkpoint_dir", type=str, default="./checkpoint", help="Directory name to save checkpoint model")
parser.add_argument("--learning_rate", type=float, default=0.0001, help="Initial learning rate")
parser.add_argument("--summary_freq", type=int, default=300, help="The frequency of saving summary")
parser.add_argument("--momentum", type=float, default=0.9, help="")
parser.add_argument("--dropout", type=float, default=0.4, help="Dropout rate")
parser.add_argument("--gpu_device", default=[0, 1], help="GPU device to use")
parser.add_argument("--max_steps", type=int, default=30000, help="The number of iterations")
args = parser.parse_args()
return args
all_classes, all_images, all_labels = load_image("/home/skj/huyz/data/mini-imagenet/train")
filenames = tf.constant(all_images)
labels = tf.constant(all_labels)
dataset = tf.data.Dataset.from_tensor_slices((filenames, labels))
dataset = dataset.map(parse_function)
dataset = dataset.shuffle(len(all_images)).apply(tf.contrib.data.batch_and_drop_remainder(256)).repeat(500)
iterator = dataset.make_one_shot_iterator()
one_element = iterator.get_next()
def main(args):
with tf.device("/cpu:0"):
global_step = tf.Variable(0, trainable=False)
images = tf.placeholder(tf.float32, shape=[None, args.image_height, args.image_width, 3], name="img_inputs")
labels = tf.placeholder(tf.int64, shape=[None], name="img_labels")
dropout_rate = tf.placeholder(tf.float32, name="dropout")
# define learning rate schedule
p = int(512.0/args.batch_size)
# lr_steps = [p*val for val in args.lr_steps]
lr_steps = [5000, 10000]
lr = tf.train.piecewise_constant(global_step, boundaries=lr_steps, values=[0.0001, 0.00005, 0.00003], name='lr_schedule')
# define optimize method
optimizer = tf.train.AdamOptimizer(learning_rate=lr)
tower_grads = []
loss_dict = {}
loss_keys = []
reuse_vars = False
# Loop over all GPUs and construct their own computation graph
for i in range(len(args.gpu_device)):
with tf.device("/gpu:%d"%args.gpu_device[i]):
# split data between GPUs
_x = images[i * args.batch_size: (i+1) * args.batch_size]
_y = labels[i * args.batch_size: (i+1) * args.batch_size]
# print(_x.shape)
# print(_y.shape)
# Because Dropout have different behavior at training and prediction time, we
# need to create 2 distinct computation graphs that share the same weights.
# Create a graph for training
ax1_out_train, ax2_out_train, main_out_train = inception_v1(_x, args.dropout, is_training=True, reuse=reuse_vars)
# Create another graph for testing that reuse the same weights
ax1_out_test, ax2_out_test, main_out_test = inception_v1(_x, args.dropout, is_training=False, reuse=True)
# tf.nn.sparse_softmax_cross_entropy_with_logits()传入的logits为神经网络的输出,
# shape为[batch_size, num_classes]
# 传入的labels为一维向量,长度是batch_size,每一个值的取值为[0, num_classes),
# 每一个值代表对应样本的类别
ax1_loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=ax1_out_train, labels=_y))
ax2_loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=ax2_out_train, labels=_y))
main_loss = tf.reduce_mean(tf.nn.sparse_softmax_cross_entropy_with_logits(logits=main_out_train, labels=_y))
loss = main_loss + 0.3 * ax1_loss + 0.3 * ax2_loss
loss_dict[('ax1_loss_%s_%d' % ('gpu', i))] = ax1_loss
loss_keys.append(('ax1_loss_%s_%d' % ('gpu', i)))
loss_dict[('ax2_loss_%s_%d' % ('gpu', i))] = ax2_loss
loss_keys.append(('ax2_loss_%s_%d' % ('gpu', i)))
loss_dict[('main_loss_%s_%d' % ('gpu', i))] = main_loss
loss_keys.append(('main_loss_%s_%d' % ('gpu', i)))
grads = optimizer.compute_gradients(loss)
tower_grads.append(grads)
# Only first GPU compute accuracy
if i == 0:
pred = tf.nn.softmax(main_out_test)
# Evaluate model (with test logits, for dropout to be disabled)
correct_prediction = tf.equal(tf.argmax(pred, -1), _y)
accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
reuse_vars = True
tower_grads = average_gradients(tower_grads)
# Apply the gradients to adjust the shared variables.
train_op = optimizer.apply_gradients(grads, global_step=global_step)
# Start traininig
config = tf.ConfigProto(allow_soft_placement=True, log_device_placement=False)
config.gpu_options.allow_growth = True
with tf.Session(config=config) as sess:
# summary writer
summary = tf.summary.FileWriter(args.log_dir, sess.graph)
summaries = []
# add grad histogram op
for grad, var in grads:
if grad is not None:
summaries.append(tf.summary.histogram(var.op.name + '/gradients', grad))
# add trainabel variable gradients
for var in tf.trainable_variables():
summaries.append(tf.summary.histogram(var.op.name, var))
# add loss summary
for keys, val in loss_dict.items():
summaries.append(tf.summary.scalar(keys, val))
# add learning rate
summaries.append(tf.summary.scalar('leraning_rate', lr))
# add train accuracy
summaries.append(tf.summary.scalar("train_acc", accuracy))
summary_op = tf.summary.merge(summaries)
init = tf.global_variables_initializer()
sess.run(init)
saver = tf.train.Saver()
# restore checkpoint if it exists
could_load = load_ckpt(sess, saver, args.checkpoint_dir)
# begin iteration
for step in range(1, args.max_steps+1):
image_batch, label_batch = sess.run(one_element)
feed_dict={images: image_batch, labels: label_batch}
start = time.time()
_, summary_op_val, train_loss, train_acc = sess.run([train_op, summary_op, loss, accuracy], feed_dict=feed_dict)
end = time.time()
print("Current step: %d/%d Time: %.4f Train_loss: %.6f Train_acc: %.4f"%(step, args.max_steps, end - start, train_loss, train_acc))
if step % args.summary_freq == 0:
summary.add_summary(summary_op_val, step)
# save the checkpoint per save_freq
if step % args.save_freq == 0:
save_ckpt(sess, saver, args.checkpoint_dir, global_step)
# Reference: https://github.com/taki0112/Self-Attention-GAN-Tensorflow/blob/master/SAGAN.py
def load_ckpt(sess, saver, checkpoint_dir):
import re
print("[*] Reading checkpoints...")
ckpt = tf.train.get_checkpoint_state(checkpoint_dir)
if ckpt and ckpt.model_checkpoint_path:
ckpt_name = os.path.basename(ckpt.model_checkpoint_path)
saver.restore(sess, os.path.join(checkpoint_dir, ckpt_name))
print("[*] Success to read {}".format(ckpt_name))
return True
else:
print("[*] Failed to find a checkpoint")
return False
def save_ckpt(sess, saver, checkpoint_dir, step):
if not os.path.exists(checkpoint_dir):
os.makedirs(checkpoint_dir)
saver.save(sess, os.path.join(checkpoint_dir, "inception.model"), global_step=step)
if __name__ == "__main__":
main(parse_arguments(sys.argv[1:]))