init project
commit
8ff41bacfb
|
@ -0,0 +1,11 @@
|
|||
Tensorflow Workspace for K210
|
||||
======
|
||||
|
||||
## Classifier for ImageNet
|
||||
1. 下载ImageNet数据集,按照说明解压缩训练数据集到文件夹ILSVRC2012\_img\_train,内含1000个子文件夹,每个子文件夹的命名为其分类代号(类似n02484975),每个子文件夹内为该分类的训练数据
|
||||
2. mobilenet v1定义文件:mobilenetv1/models/mobilenet\_v1.py,需要注意由于K210不支持tensorflow的SAME padding,所以在stride=2时先固定padding一圈0,然后再进行stride=2的卷积(padding=VALID)
|
||||
3. 训练脚本 mobilenetv1/run\_mobilenet\_v1.sh,根据需要修改其中的参数,然后运行
|
||||
4. freeze\_graph.py将训练ckpt转成pb文件,命令格式如下:
|
||||
python mobilenetv1/freeze\_graph.py model.mobilenet\_v1 ckpt\_fold pb\_file
|
||||
5. 测试在ImageNet验证集上的性能,下载验证集,将文件按类别解压好(与训练集类似),运行 python mobilenetv1/validation\_imagenet.py pb\_file(or ckpt folder) val\_set\_fold
|
||||
6. 预测单张图片,python mobilenetv1/predict\_one\_pic.py pb\_file(or ckpt folder) pic
|
|
@ -0,0 +1,387 @@
|
|||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
from subprocess import Popen, PIPE
|
||||
import tensorflow as tf
|
||||
import numpy as np
|
||||
from scipy import misc
|
||||
from scipy import interpolate
|
||||
from tensorflow.python.training import training
|
||||
import random
|
||||
import re
|
||||
from tensorflow.python.platform import gfile
|
||||
import math
|
||||
import time
|
||||
from six import iteritems
|
||||
|
||||
|
||||
|
||||
def get_image_paths_and_labels(dataset):
|
||||
image_paths_flat = []
|
||||
labels_flat = []
|
||||
for i in range(len(dataset)):
|
||||
image_paths_flat += dataset[i].image_paths
|
||||
labels_flat += [i] * len(dataset[i].image_paths)
|
||||
return image_paths_flat, labels_flat
|
||||
|
||||
def shuffle_examples(image_paths, labels):
|
||||
shuffle_list = list(zip(image_paths, labels))
|
||||
random.shuffle(shuffle_list)
|
||||
image_paths_shuff, labels_shuff = zip(*shuffle_list)
|
||||
return image_paths_shuff, labels_shuff
|
||||
|
||||
def random_rotate_image(image):
|
||||
angle = np.random.uniform(low=-10.0, high=10.0)
|
||||
return misc.imrotate(image, angle, 'bicubic')
|
||||
|
||||
# 1: Random rotate 2: Random crop 4: Random flip 8: Fixed image standardization 16: Flip
|
||||
RANDOM_ROTATE = 1
|
||||
RANDOM_CROP = 2
|
||||
RANDOM_FLIP = 4
|
||||
FIXED_STANDARDIZATION = 8
|
||||
FLIP = 16
|
||||
def create_input_pipeline(input_queue, image_size, nrof_preprocess_threads, batch_size_placeholder):
|
||||
t=time.time()
|
||||
images_and_labels_list = []
|
||||
for _ in range(nrof_preprocess_threads):
|
||||
filenames, label, control = input_queue.dequeue()
|
||||
images = []
|
||||
for filename in tf.unstack(filenames):
|
||||
file_contents = tf.read_file(filename)
|
||||
image = tf.image.decode_image(file_contents, 3)
|
||||
# image = tf.image.resize_images(image, [image_size[0], image_size[1]],method=tf.image.ResizeMethod.BILINEAR)
|
||||
image = tf.cond(get_control_flag(control[0], RANDOM_ROTATE),
|
||||
lambda:tf.py_func(random_rotate_image, [image], tf.uint8),
|
||||
lambda:tf.identity(image))
|
||||
image = tf.cond(get_control_flag(control[0], RANDOM_CROP),
|
||||
lambda:tf.random_crop(image, image_size + (3,)),
|
||||
lambda:tf.image.resize_image_with_crop_or_pad(image, image_size[0], image_size[1]))
|
||||
image = tf.cond(get_control_flag(control[0], RANDOM_FLIP),
|
||||
lambda:tf.image.random_flip_left_right(image),
|
||||
lambda:tf.identity(image))
|
||||
image = tf.cond(get_control_flag(control[0], FIXED_STANDARDIZATION),
|
||||
lambda:(tf.cast(image, tf.float32))/255.0,
|
||||
lambda:tf.image.per_image_standardization(image))
|
||||
image = tf.cond(get_control_flag(control[0], FLIP),
|
||||
lambda:tf.image.flip_left_right(image),
|
||||
lambda:tf.identity(image))
|
||||
#pylint: disable=no-member
|
||||
image.set_shape(image_size + (3,))
|
||||
images.append(image)
|
||||
images_and_labels_list.append([images, label])
|
||||
|
||||
image_batch, label_batch = tf.train.batch_join(
|
||||
images_and_labels_list, batch_size=batch_size_placeholder,
|
||||
shapes=[image_size + (3,), ()], enqueue_many=True,
|
||||
capacity=4 * nrof_preprocess_threads * 100,
|
||||
allow_smaller_final_batch=True)
|
||||
tt = time.time()-t
|
||||
print('pre_process time %f' % tt)
|
||||
print('LLLLLLLLLLLLLLLLL')
|
||||
|
||||
|
||||
return image_batch, label_batch
|
||||
|
||||
def get_control_flag(control, field):
|
||||
return tf.equal(tf.mod(tf.floor_div(control, field), 2), 1)
|
||||
|
||||
def _add_loss_summaries(total_loss):
|
||||
"""Add summaries for losses.
|
||||
|
||||
Generates moving average for all losses and associated summaries for
|
||||
visualizing the performance of the network.
|
||||
|
||||
Args:
|
||||
total_loss: Total loss from loss().
|
||||
Returns:
|
||||
loss_averages_op: op for generating moving averages of losses.
|
||||
"""
|
||||
# Compute the moving average of all individual losses and the total loss.
|
||||
loss_averages = tf.train.ExponentialMovingAverage(0.9, name='avg')
|
||||
losses = tf.get_collection('losses')
|
||||
loss_averages_op = loss_averages.apply(losses + [total_loss])
|
||||
|
||||
# Attach a scalar summmary to all individual losses and the total loss; do the
|
||||
# same for the averaged version of the losses.
|
||||
for l in losses + [total_loss]:
|
||||
# Name each loss as '(raw)' and name the moving average version of the loss
|
||||
# as the original loss name.
|
||||
tf.summary.scalar(l.op.name +' (raw)', l)
|
||||
tf.summary.scalar(l.op.name, loss_averages.average(l))
|
||||
|
||||
return loss_averages_op
|
||||
|
||||
def train(total_loss, global_step, optimizer, learning_rate, moving_average_decay, update_gradient_vars, log_histograms=True):
|
||||
# Generate moving averages of all losses and associated summaries.
|
||||
loss_averages_op = _add_loss_summaries(total_loss)
|
||||
|
||||
# Compute gradients.
|
||||
with tf.control_dependencies([loss_averages_op]):
|
||||
if optimizer=='ADAGRAD':
|
||||
opt = tf.train.AdagradOptimizer(learning_rate)
|
||||
elif optimizer=='ADADELTA':
|
||||
opt = tf.train.AdadeltaOptimizer(learning_rate, rho=0.9, epsilon=1e-6)
|
||||
elif optimizer=='ADAM':
|
||||
opt = tf.train.AdamOptimizer(learning_rate, beta1=0.9, beta2=0.999, epsilon=0.1)
|
||||
elif optimizer=='RMSPROP':
|
||||
opt = tf.train.RMSPropOptimizer(learning_rate, decay=0.9, momentum=0.9, epsilon=1.0)
|
||||
elif optimizer=='MOM':
|
||||
opt = tf.train.MomentumOptimizer(learning_rate, 0.9, use_nesterov=True)
|
||||
else:
|
||||
raise ValueError('Invalid optimization algorithm')
|
||||
|
||||
grads = opt.compute_gradients(total_loss, update_gradient_vars)
|
||||
|
||||
# Apply gradients.
|
||||
apply_gradient_op = opt.apply_gradients(grads, global_step=global_step)
|
||||
|
||||
# Add histograms for trainable variables.
|
||||
if log_histograms:
|
||||
for var in tf.trainable_variables():
|
||||
tf.summary.histogram(var.op.name, var)
|
||||
|
||||
# Add histograms for gradients.
|
||||
if log_histograms:
|
||||
for grad, var in grads:
|
||||
if grad is not None:
|
||||
tf.summary.histogram(var.op.name + '/gradients', grad)
|
||||
|
||||
# Track the moving averages of all trainable variables.
|
||||
variable_averages = tf.train.ExponentialMovingAverage(
|
||||
moving_average_decay, global_step)
|
||||
variables_averages_op = variable_averages.apply(tf.trainable_variables())
|
||||
|
||||
with tf.control_dependencies([apply_gradient_op, variables_averages_op]):
|
||||
train_op = tf.no_op(name='train')
|
||||
|
||||
return train_op
|
||||
|
||||
def prewhiten(x):
|
||||
mean = np.mean(x)
|
||||
std = np.std(x)
|
||||
std_adj = np.maximum(std, 1.0/np.sqrt(x.size))
|
||||
y = np.multiply(np.subtract(x, mean), 1/std_adj)
|
||||
return y
|
||||
|
||||
def prewhiten_fix(x):
|
||||
y = x/255.
|
||||
return y
|
||||
|
||||
def crop(image, random_crop, image_size):
|
||||
image_crop = np.zeros((image_size, image_size, 3))
|
||||
m_min = image.shape[0] if image.shape[0]<image.shape[1] else image.shape[1]
|
||||
m_max = image.shape[0] if image.shape[0]>image.shape[1] else image.shape[1]
|
||||
|
||||
if m_max < image_size:
|
||||
v_0 = (image_size-m_max)//2
|
||||
image_crop[v_0:v_0+image_size,v_0:v_0+image_size,:] = image
|
||||
elif m_min < image_size:
|
||||
if image.shape[0]<image.shape[1]:
|
||||
h_0 = (image_size - m_min)//2
|
||||
v_0 = (image.shape[1] - image_size)//2
|
||||
image_crop[h_0:h_0+image.shape[0],0:image_size,:] = image[0:image.shape[0],v_0:v_0+image_size,:]
|
||||
else:
|
||||
h_0 = (image.shape[0] - image_size)//2
|
||||
v_0 = (image_size - m_min)//2
|
||||
image_crop[0:image_size,v_0:v_0+image.shape[1]:] = image[h_0:h_0+image_size,0:image.shape[1],:]
|
||||
else:
|
||||
sz1 = int(image.shape[1]//2)
|
||||
sz2 = int(image_size//2)
|
||||
if random_crop:
|
||||
diff = sz1-sz2
|
||||
(h, v) = (np.random.randint(-diff, diff+1), np.random.randint(-diff, diff+1))
|
||||
else:
|
||||
(h, v) = (0,0)
|
||||
image = image[(sz1-sz2+v):(sz1+sz2+v),(sz1-sz2+h):(sz1+sz2+h),:]
|
||||
return image
|
||||
|
||||
def flip(image, random_flip):
|
||||
if random_flip and np.random.choice([True, False]):
|
||||
image = np.fliplr(image)
|
||||
return image
|
||||
|
||||
def to_rgb(img):
|
||||
w, h = img.shape
|
||||
ret = np.empty((w, h, 3), dtype=np.uint8)
|
||||
ret[:, :, 0] = ret[:, :, 1] = ret[:, :, 2] = img
|
||||
return ret
|
||||
|
||||
def load_data(image_paths, do_random_crop, do_random_flip, image_size, do_prewhiten=True):
|
||||
print("enter load_data")
|
||||
nrof_samples = len(image_paths)
|
||||
images = np.zeros((nrof_samples, image_size, image_size, 3))
|
||||
for i in range(nrof_samples):
|
||||
img = misc.imread(image_paths[i])
|
||||
if img.ndim == 2:
|
||||
img = to_rgb(img)
|
||||
if 1:
|
||||
print("enter whiten")
|
||||
# img = prewhiten(img)
|
||||
img = img/255.0
|
||||
img = crop(img, do_random_crop, image_size)
|
||||
img = misc.imresize(img, (image_size, image_size), interp='bilinear')
|
||||
img = flip(img, do_random_flip)
|
||||
images[i,:,:,:] = img
|
||||
return images
|
||||
|
||||
def get_label_batch(label_data, batch_size, batch_index):
|
||||
nrof_examples = np.size(label_data, 0)
|
||||
j = batch_index*batch_size % nrof_examples
|
||||
if j+batch_size<=nrof_examples:
|
||||
batch = label_data[j:j+batch_size]
|
||||
else:
|
||||
x1 = label_data[j:nrof_examples]
|
||||
x2 = label_data[0:nrof_examples-j]
|
||||
batch = np.vstack([x1,x2])
|
||||
batch_int = batch.astype(np.int64)
|
||||
return batch_int
|
||||
|
||||
def get_batch(image_data, batch_size, batch_index):
|
||||
nrof_examples = np.size(image_data, 0)
|
||||
j = batch_index*batch_size % nrof_examples
|
||||
if j+batch_size<=nrof_examples:
|
||||
batch = image_data[j:j+batch_size,:,:,:]
|
||||
else:
|
||||
x1 = image_data[j:nrof_examples,:,:,:]
|
||||
x2 = image_data[0:nrof_examples-j,:,:,:]
|
||||
batch = np.vstack([x1,x2])
|
||||
batch_float = batch.astype(np.float32)
|
||||
return batch_float
|
||||
|
||||
|
||||
def get_learning_rate_from_file(filename, epoch):
|
||||
with open(filename, 'r') as f:
|
||||
for line in f.readlines():
|
||||
line = line.split('#', 1)[0]
|
||||
if line:
|
||||
par = line.strip().split(':')
|
||||
e = int(par[0])
|
||||
if par[1]=='-':
|
||||
lr = -1
|
||||
else:
|
||||
lr = float(par[1])
|
||||
if e <= epoch:
|
||||
learning_rate = lr
|
||||
else:
|
||||
return learning_rate
|
||||
|
||||
class ImageClass():
|
||||
"Stores the paths to images for a given class"
|
||||
def __init__(self, name, image_paths):
|
||||
self.name = name
|
||||
self.image_paths = image_paths
|
||||
|
||||
def __str__(self):
|
||||
return self.name + ', ' + str(len(self.image_paths)) + ' images'
|
||||
|
||||
def __len__(self):
|
||||
return len(self.image_paths)
|
||||
|
||||
def get_dataset(path, has_class_directories=True):
|
||||
dataset = []
|
||||
path_exp = os.path.expanduser(path)
|
||||
classes = [path for path in os.listdir(path_exp) \
|
||||
if os.path.isdir(os.path.join(path_exp, path))]
|
||||
classes.sort()
|
||||
|
||||
nrof_classes = len(classes)
|
||||
# with open("label.txt","w") as f:
|
||||
# for ii in range(nrof_classes):
|
||||
# f.writelines(classes[ii]+"\n")
|
||||
|
||||
for i in range(nrof_classes):
|
||||
class_name = classes[i]
|
||||
facedir = os.path.join(path_exp, class_name)
|
||||
image_paths = get_image_paths(facedir)
|
||||
dataset.append(ImageClass(class_name, image_paths))
|
||||
|
||||
return dataset
|
||||
|
||||
def get_image_paths(facedir):
|
||||
image_paths = []
|
||||
if os.path.isdir(facedir):
|
||||
images = os.listdir(facedir)
|
||||
image_paths = [os.path.join(facedir,img) for img in images]
|
||||
return image_paths
|
||||
|
||||
def split_dataset(dataset, split_ratio, min_nrof_images_per_class, mode):
|
||||
if mode=='SPLIT_CLASSES':
|
||||
nrof_classes = len(dataset)
|
||||
class_indices = np.arange(nrof_classes)
|
||||
np.random.shuffle(class_indices)
|
||||
split = int(round(nrof_classes*(1-split_ratio)))
|
||||
train_set = [dataset[i] for i in class_indices[0:split]]
|
||||
test_set = [dataset[i] for i in class_indices[split:-1]]
|
||||
elif mode=='SPLIT_IMAGES':
|
||||
train_set = []
|
||||
test_set = []
|
||||
for cls in dataset:
|
||||
paths = cls.image_paths
|
||||
np.random.shuffle(paths)
|
||||
nrof_images_in_class = len(paths)
|
||||
split = int(math.floor(nrof_images_in_class*(1-split_ratio)))
|
||||
if split==nrof_images_in_class:
|
||||
split = nrof_images_in_class-1
|
||||
if split>=min_nrof_images_per_class and nrof_images_in_class-split>=1:
|
||||
train_set.append(ImageClass(cls.name, paths[:split]))
|
||||
test_set.append(ImageClass(cls.name, paths[split:]))
|
||||
else:
|
||||
raise ValueError('Invalid train/test split mode "%s"' % mode)
|
||||
return train_set, test_set
|
||||
|
||||
def load_model(model, input_map=None):
|
||||
# Check if the model is a model directory (containing a metagraph and a checkpoint file)
|
||||
# or if it is a protobuf file with a frozen graph
|
||||
model_exp = os.path.expanduser(model)
|
||||
if (os.path.isfile(model_exp)):
|
||||
print('Model filename: %s' % model_exp)
|
||||
with gfile.FastGFile(model_exp,'rb') as f:
|
||||
graph_def = tf.GraphDef()
|
||||
graph_def.ParseFromString(f.read())
|
||||
tf.import_graph_def(graph_def, input_map=input_map, name='')
|
||||
else:
|
||||
print('Model directory: %s' % model_exp)
|
||||
meta_file, ckpt_file = get_model_filenames(model_exp)
|
||||
|
||||
print('Metagraph file: %s' % meta_file)
|
||||
print('Checkpoint file: %s' % ckpt_file)
|
||||
|
||||
saver = tf.train.import_meta_graph(os.path.join(model_exp, meta_file), input_map=input_map)
|
||||
saver.restore(tf.get_default_session(), os.path.join(model_exp, ckpt_file))
|
||||
|
||||
def get_model_filenames(model_dir):
|
||||
files = os.listdir(model_dir)
|
||||
meta_files = [s for s in files if s.endswith('.meta')]
|
||||
if len(meta_files)==0:
|
||||
raise ValueError('No meta file found in the model directory (%s)' % model_dir)
|
||||
elif len(meta_files)>1:
|
||||
raise ValueError('There should not be more than one meta file in the model directory (%s)' % model_dir)
|
||||
meta_file = meta_files[0]
|
||||
ckpt = tf.train.get_checkpoint_state(model_dir)
|
||||
if ckpt and ckpt.model_checkpoint_path:
|
||||
ckpt_file = os.path.basename(ckpt.model_checkpoint_path)
|
||||
return meta_file, ckpt_file
|
||||
|
||||
meta_files = [s for s in files if '.ckpt' in s]
|
||||
max_step = -1
|
||||
for f in files:
|
||||
step_str = re.match(r'(^model-[\w\- ]+.ckpt-(\d+))', f)
|
||||
if step_str is not None and len(step_str.groups())>=2:
|
||||
step = int(step_str.groups()[1])
|
||||
if step > max_step:
|
||||
max_step = step
|
||||
ckpt_file = step_str.groups()[0]
|
||||
return meta_file, ckpt_file
|
||||
|
||||
def list_variables(filename):
|
||||
reader = training.NewCheckpointReader(filename)
|
||||
variable_map = reader.get_variable_to_shape_map()
|
||||
names = sorted(variable_map.keys())
|
||||
return names
|
||||
|
||||
def write_arguments_to_file(args, filename):
|
||||
with open(filename, 'w') as f:
|
||||
for key, value in iteritems(vars(args)):
|
||||
f.write('%s: %s\n' % (key, str(value)))
|
Binary file not shown.
After Width: | Height: | Size: 139 KiB |
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,5 @@
|
|||
# Learning rate schedule
|
||||
# Maps an epoch number to a learning rate
|
||||
0: 0.01
|
||||
11: 0.001
|
||||
50: 0.0001
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,87 @@
|
|||
import tensorflow as tf
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import argparse
|
||||
import base_func
|
||||
import importlib
|
||||
import models
|
||||
from tensorflow.python.framework import graph_util
|
||||
|
||||
def freeze_graph(model_def,input_dir, output_graph):
|
||||
sess = tf.InteractiveSession()
|
||||
meta_file, ckpt_file = base_func.get_model_filenames(input_dir)
|
||||
|
||||
network = importlib.import_module(model_def)
|
||||
|
||||
images_placeholder = tf.placeholder(tf.float32,shape=(None,224,224,3),name='input')
|
||||
|
||||
logits, _ = network.inference(images_placeholder, keep_probability=0,
|
||||
phase_train=False, class_num=1000)
|
||||
|
||||
|
||||
ckpt_dir_exp = os.path.expanduser(input_dir)
|
||||
|
||||
|
||||
meta_file = os.path.join(ckpt_dir_exp, meta_file)
|
||||
ckpt_file = os.path.join(ckpt_dir_exp, ckpt_file)
|
||||
|
||||
print("meta-file is %s" % meta_file)
|
||||
|
||||
|
||||
saver = tf.train.Saver(tf.global_variables())
|
||||
|
||||
|
||||
graph = tf.get_default_graph() # 获得默认的图
|
||||
input_graph_def = graph.as_graph_def() # 返回一个序列化的图代表当前的图
|
||||
|
||||
|
||||
output_node_names = "MobileNetV1/Bottleneck2/BatchNorm/Reshape_1"
|
||||
|
||||
|
||||
with tf.Session() as sess:
|
||||
|
||||
saver.restore(sess, ckpt_file) #恢复图并得到数据
|
||||
# sess.run(embeddings,feed_dict=feed_dict)
|
||||
|
||||
|
||||
# fix batch norm nodes
|
||||
for node in input_graph_def.node:
|
||||
if node.op == 'RefSwitch':
|
||||
node.op = 'Switch'
|
||||
for index in range(len(node.input)):
|
||||
if 'moving_' in node.input[index]:
|
||||
node.input[index] = node.input[index] + '/read'
|
||||
elif node.op == 'AssignSub':
|
||||
node.op = 'Sub'
|
||||
if 'use_locking' in node.attr: del node.attr['use_locking']
|
||||
elif node.op == 'AssignAdd':
|
||||
node.op = 'Add'
|
||||
if 'use_locking' in node.attr: del node.attr['use_locking']
|
||||
|
||||
|
||||
output_graph_def = graph_util.convert_variables_to_constants(
|
||||
sess=sess,
|
||||
input_graph_def=input_graph_def,
|
||||
output_node_names=output_node_names.split(","))# 如果有多个输出节点,以逗号隔开
|
||||
with tf.gfile.GFile(output_graph, "wb") as f: #保存模型
|
||||
f.write(output_graph_def.SerializeToString()) #序列化输出
|
||||
print("%d ops in the final graph." % len(output_graph_def.node)) #得到当前图有几个操作节点 # for op in graph.get_operations(): # print(op.name, op.values())
|
||||
|
||||
|
||||
def main(args):
|
||||
freeze_graph(args.model_def,args.ckpt_dir,args.output_file)
|
||||
|
||||
def parse_arguments(argv):
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--model_def', type=str,
|
||||
help='Model definition. Points to a module containing the definition of the inference graph.', default='models.mobilenet_v1')
|
||||
parser.add_argument('ckpt_dir', type=str,
|
||||
help='Directory containing the metagraph (.meta) file and the checkpoint (ckpt) file containing model parameters')
|
||||
parser.add_argument('output_file', type=str,
|
||||
help='Filename for the exported graphdef protobuf (.pb)')
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(parse_arguments(sys.argv[1:]))
|
|
@ -0,0 +1,2 @@
|
|||
# flake8: noqa
|
||||
|
|
@ -0,0 +1,159 @@
|
|||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
import tensorflow as tf
|
||||
import tensorflow.contrib.slim as slim
|
||||
|
||||
def inference(images, keep_probability, phase_train=True,
|
||||
class_num=1000, weight_decay=0.0, reuse=None):
|
||||
batch_norm_params = {
|
||||
'decay': 0.995,
|
||||
'epsilon': 0.001,
|
||||
'updates_collections': None,
|
||||
'variables_collections': [ tf.GraphKeys.TRAINABLE_VARIABLES ],
|
||||
}
|
||||
with slim.arg_scope([slim.conv2d, slim.separable_conv2d,slim.fully_connected],
|
||||
weights_initializer=slim.initializers.xavier_initializer(),
|
||||
weights_regularizer=slim.l2_regularizer(weight_decay),
|
||||
normalizer_fn=slim.batch_norm,
|
||||
normalizer_params=batch_norm_params):
|
||||
return mobilenet_v1(images, is_training=phase_train,
|
||||
dropout_keep_prob=keep_probability, class_num=class_num, reuse=reuse)
|
||||
|
||||
|
||||
|
||||
def block_14x14(net, outputs, scope=None, reuse=None):
|
||||
with tf.variable_scope(scope, "block-14x14", reuse=reuse):
|
||||
net = slim.separable_conv2d(net, None, [3, 3],
|
||||
depth_multiplier=1,
|
||||
stride=1,
|
||||
padding='SAME',
|
||||
normalizer_fn=slim.batch_norm,
|
||||
scope='dw_Conv2d')
|
||||
net = slim.conv2d(net, outputs, 1, stride=1, padding='SAME',normalizer_fn=slim.batch_norm,scope='conv')
|
||||
return net
|
||||
|
||||
def mobilenet_v1(inputs, is_training=True,
|
||||
dropout_keep_prob=0.5,
|
||||
class_num=1000,
|
||||
reuse=None,
|
||||
scope='MobileNetV1'):
|
||||
end_points = {}
|
||||
net = None
|
||||
_l = 0
|
||||
with tf.variable_scope(scope, 'MobileNetV1', [inputs], reuse=reuse):
|
||||
with slim.arg_scope([slim.batch_norm, slim.dropout],
|
||||
is_training=is_training):
|
||||
with slim.arg_scope([slim.conv2d,slim.separable_conv2d],
|
||||
stride=1, padding='SAME',normalizer_fn=slim.batch_norm):
|
||||
inputs = tf.space_to_batch(inputs,[[1,1],[1,1]],block_size=1,name=None)
|
||||
# ------------------------x224------------------------- #
|
||||
net = slim.conv2d(inputs, 32, 3, stride=2,padding='VALID',normalizer_fn=slim.batch_norm,
|
||||
scope='Conv2d_%i_3x3'%(_l))
|
||||
_l += 1
|
||||
# ------------------------x112------------------------- #
|
||||
net = slim.separable_conv2d(net, None, [3, 3],
|
||||
depth_multiplier=1,
|
||||
stride=1,
|
||||
normalizer_fn=slim.batch_norm,
|
||||
scope='dw_Conv2d_%i_3x3'%(_l))
|
||||
_l += 1
|
||||
net = slim.conv2d(net, 64, 1, stride=1, padding='SAME',normalizer_fn=slim.batch_norm,
|
||||
scope='Conv2d_%i_1x1'%(_l))
|
||||
_l += 1
|
||||
net = tf.space_to_batch(net,[[1,1],[1,1]],block_size=1,name=None)
|
||||
net = slim.separable_conv2d(net, None, [3, 3],
|
||||
depth_multiplier=1,
|
||||
stride=2,
|
||||
padding='VALID',
|
||||
normalizer_fn=slim.batch_norm,
|
||||
scope='dw_Conv2d_%i_3x3'%(_l))
|
||||
_l += 1
|
||||
# ------------------------x56-------------------------- #
|
||||
net = slim.conv2d(net, 128, 1, stride=1, padding='SAME',normalizer_fn=slim.batch_norm,
|
||||
scope='Conv2d_%i_1x1'%(_l))
|
||||
_l += 1
|
||||
net = slim.separable_conv2d(net, None, [3, 3],
|
||||
depth_multiplier=1,
|
||||
stride=1,
|
||||
normalizer_fn=slim.batch_norm,
|
||||
scope='dw_Conv2d_%i_3x3'%(_l))
|
||||
_l += 1
|
||||
net = slim.conv2d(net, 128, 1, stride=1, padding='SAME',normalizer_fn=slim.batch_norm,
|
||||
scope='Conv2d_%i_1x1'%(_l))
|
||||
_l += 1
|
||||
net = tf.space_to_batch(net,[[1,1],[1,1]],block_size=1,name=None)
|
||||
net = slim.separable_conv2d(net, None, [3, 3],
|
||||
depth_multiplier=1,
|
||||
stride=2,
|
||||
padding='VALID',
|
||||
normalizer_fn=slim.batch_norm,
|
||||
scope='dw_Conv2d_%i_3x3'%(_l))
|
||||
_l += 1
|
||||
# ------------------------x28-------------------------- #
|
||||
net = slim.conv2d(net, 256, 1, stride=1, padding='SAME',normalizer_fn=slim.batch_norm,
|
||||
scope='Conv2d_%i_1x1'%(_l))
|
||||
_l += 1
|
||||
net = slim.separable_conv2d(net, None, [3, 3],
|
||||
depth_multiplier=1,
|
||||
stride=1,
|
||||
normalizer_fn=slim.batch_norm,
|
||||
scope='dw_Conv2d_%i_3x3'%(_l))
|
||||
_l += 1
|
||||
net = slim.conv2d(net, 256, 1, stride=1, padding='SAME',normalizer_fn=slim.batch_norm,
|
||||
scope='Conv2d_%i_1x1'%(_l))
|
||||
_l += 1
|
||||
net = tf.space_to_batch(net,[[1,1],[1,1]],block_size=1,name=None)
|
||||
net = slim.separable_conv2d(net, None, [3, 3],
|
||||
depth_multiplier=1,
|
||||
stride=2,
|
||||
padding='VALID',
|
||||
normalizer_fn=slim.batch_norm,
|
||||
scope='dw_Conv2d_%i_3x3'%(_l))
|
||||
_l += 1
|
||||
# ------------------------x14-------------------------- #
|
||||
net = slim.conv2d(net, 512, 1, stride=1, padding='SAME',normalizer_fn=slim.batch_norm,
|
||||
scope='Conv2d_%i_1x1'%(_l))
|
||||
_l += 1
|
||||
|
||||
with tf.variable_scope(scope,'block_repeat_%i'%(_l)):
|
||||
for _k in range(5):
|
||||
net = block_14x14(net,512)
|
||||
_l += 1
|
||||
|
||||
net = tf.space_to_batch(net,[[1,1],[1,1]],block_size=1,name=None)
|
||||
net = slim.separable_conv2d(net, None, [3, 3],
|
||||
depth_multiplier=1,
|
||||
stride=2,
|
||||
padding='VALID',
|
||||
normalizer_fn=slim.batch_norm,
|
||||
scope='dw_Conv2d_%i_3x3'%(_l))
|
||||
_l += 1
|
||||
# -------------------------x7-------------------------- #
|
||||
net = slim.conv2d(net, 1024, 1, stride=1, padding='SAME',normalizer_fn=slim.batch_norm,
|
||||
scope='Conv2d_%i_1x1'%(_l))
|
||||
_l += 1
|
||||
net = slim.separable_conv2d(net, None, [3, 3],
|
||||
depth_multiplier=1,
|
||||
stride=1,
|
||||
padding='SAME',
|
||||
normalizer_fn=slim.batch_norm,
|
||||
scope='dw_Conv2d_%i_3x3'%(_l))
|
||||
_l += 1
|
||||
net = slim.conv2d(net, 1024, 1, stride=1, padding='SAME',normalizer_fn=slim.batch_norm,
|
||||
scope='Conv2d_%i_1x1'%(_l))
|
||||
_l += 1
|
||||
# ---------------------softmax out---------------------- #
|
||||
net = slim.avg_pool2d(net, net.get_shape()[1:3], padding='VALID',
|
||||
scope='AvgPool_%i'%(_l))
|
||||
_l += 1
|
||||
|
||||
net = slim.flatten(net)
|
||||
net = slim.dropout(net, dropout_keep_prob, is_training=is_training,
|
||||
scope='Dropout_1')
|
||||
|
||||
net = slim.fully_connected(net, class_num, activation_fn=None,
|
||||
scope='Bottleneck2', reuse=False)
|
||||
|
||||
return net, None
|
|
@ -0,0 +1,91 @@
|
|||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from datetime import datetime
|
||||
import os.path
|
||||
from os import environ
|
||||
import time
|
||||
import sys
|
||||
import random
|
||||
import tensorflow as tf
|
||||
import numpy as np
|
||||
import importlib
|
||||
import argparse
|
||||
import base_func
|
||||
import h5py
|
||||
import math
|
||||
import tensorflow.contrib.slim as slim
|
||||
from tensorflow.python.ops import data_flow_ops
|
||||
from tensorflow.python.framework import ops
|
||||
from tensorflow.python.ops import array_ops
|
||||
import pickle
|
||||
from scipy import misc
|
||||
|
||||
def _softmax(x, axis=-1, t=-100.):
|
||||
x = x - np.max(x)
|
||||
if np.min(x) < t:
|
||||
x = x / np.min(x) * t
|
||||
e_x = np.exp(x)
|
||||
return e_x / e_x.sum(axis, keepdims=True)
|
||||
|
||||
def main(args):
|
||||
|
||||
image_size = (args.image_size, args.image_size)
|
||||
|
||||
top1 = 0.0
|
||||
top5 = 0.0
|
||||
|
||||
with tf.Graph().as_default() as graph:
|
||||
with tf.Session() as sess:
|
||||
base_func.load_model(args.model)
|
||||
|
||||
input_image = sess.graph.get_tensor_by_name('input:0')
|
||||
output = sess.graph.get_tensor_by_name('MobileNetV1/Bottleneck2/BatchNorm/Reshape_1:0')
|
||||
|
||||
if (os.path.isdir(args.model)):
|
||||
phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0")
|
||||
|
||||
img = np.array(misc.imread(args.image, mode='RGB'))
|
||||
# img = base_func.crop(img, False, args.image_size)
|
||||
img = misc.imresize(img, image_size, interp='bilinear')
|
||||
img = img / 255.
|
||||
images = [img]
|
||||
|
||||
feed_dict={input_image:images}
|
||||
if (os.path.isdir(args.model)):
|
||||
feed_dict={input_image:images,phase_train_placeholder:False}
|
||||
|
||||
logits = sess.run(output,feed_dict=feed_dict)
|
||||
pred = _softmax(logits[0,:])
|
||||
|
||||
des_idx = np.argsort(pred)
|
||||
|
||||
with open("data/names.list","r") as f:
|
||||
lines = f.readlines()
|
||||
# with open("data/names2.list","w") as f1:
|
||||
# for k in range(1000):
|
||||
# f1.writelines(lines[k].split(":")[1])
|
||||
|
||||
for j in range(5):
|
||||
print("%.2f%%--%s" % (pred[des_idx[999-j]]*100,lines[des_idx[999-j]].strip()))
|
||||
|
||||
|
||||
|
||||
def parse_arguments(argv):
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument('model', type=str,
|
||||
help='Model definition. Points to a module containing the definition of the inference graph.', default='models.inception_resnet_v1')
|
||||
parser.add_argument('image', type=str,
|
||||
help='Path to the data directory containing aligned face patches.',
|
||||
default='data/eagle.jpg')
|
||||
parser.add_argument('--image_size', type=int,
|
||||
help='image size.', default=224)
|
||||
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = parse_arguments(sys.argv[1:])
|
||||
main(args)
|
|
@ -0,0 +1,20 @@
|
|||
#!/bin/bash
|
||||
|
||||
python3 train_softmax.py \
|
||||
--model_def models.mobilenet_v1 \
|
||||
--data_dir /data/datasets/ImageNet2012/ILSVRC2012_img_train/ \
|
||||
--pretrained_model "../pretrained/mobilenetv1_1.0.pb"\
|
||||
--gpu_memory_fraction 0.85 \
|
||||
--gpus 1 \
|
||||
--image_size 224 \
|
||||
--logs_base_dir backup_classifier \
|
||||
--models_base_dir backup_classifier \
|
||||
--batch_size 100 \
|
||||
--epoch_size 5000 \
|
||||
--learning_rate -1 \
|
||||
--max_nrof_epochs 50 \
|
||||
--class_num 1000 \
|
||||
--use_fixed_image_standardization \
|
||||
--optimizer MOM \
|
||||
--learning_rate_schedule_file data/learning_rate.txt \
|
||||
--keep_probability 1.0
|
|
@ -0,0 +1,322 @@
|
|||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from datetime import datetime
|
||||
import os.path
|
||||
from os import environ
|
||||
import time
|
||||
import sys
|
||||
import random
|
||||
import tensorflow as tf
|
||||
import numpy as np
|
||||
import importlib
|
||||
import argparse
|
||||
import base_func
|
||||
import h5py
|
||||
import math
|
||||
import tensorflow.contrib.slim as slim
|
||||
from tensorflow.python.ops import data_flow_ops
|
||||
from tensorflow.python.framework import ops
|
||||
from tensorflow.python.ops import array_ops
|
||||
import pickle
|
||||
from scipy import misc
|
||||
|
||||
def main(args):
|
||||
environ['CUDA_VISIBLE_DEVICES'] = args.gpus
|
||||
network = importlib.import_module(args.model_def)
|
||||
image_size = (args.image_size, args.image_size)
|
||||
|
||||
subdir = datetime.strftime(datetime.now(), '%Y%m%d-%H%M%S')
|
||||
log_dir = os.path.join(os.path.expanduser(args.logs_base_dir), subdir)
|
||||
if not os.path.isdir(log_dir): # Create the log directory if it doesn't exist
|
||||
os.makedirs(log_dir)
|
||||
model_dir = os.path.join(os.path.expanduser(args.models_base_dir), subdir)
|
||||
if not os.path.isdir(model_dir): # Create the model directory if it doesn't exist
|
||||
os.makedirs(model_dir)
|
||||
|
||||
# Write arguments to a text file
|
||||
base_func.write_arguments_to_file(args, os.path.join(log_dir, 'arguments.txt'))
|
||||
|
||||
np.random.seed(seed=args.seed)
|
||||
random.seed(args.seed)
|
||||
dataset = base_func.get_dataset(args.data_dir)
|
||||
|
||||
train_set, val_set = dataset, []
|
||||
|
||||
nrof_classes = len(train_set)
|
||||
|
||||
print('Model directory: %s' % model_dir)
|
||||
print('Log directory: %s' % log_dir)
|
||||
pretrained_model = None
|
||||
if args.pretrained_model:
|
||||
pretrained_model = os.path.expanduser(args.pretrained_model)
|
||||
print('Pre-trained model: %s' % pretrained_model)
|
||||
|
||||
|
||||
with tf.Graph().as_default():
|
||||
tf.set_random_seed(args.seed)
|
||||
global_step = tf.Variable(0, trainable=False)
|
||||
|
||||
# Get a list of image paths and their labels
|
||||
image_list, label_list = base_func.get_image_paths_and_labels(train_set)
|
||||
|
||||
assert len(image_list)>0, 'The training set should not be empty'
|
||||
|
||||
val_image_list, val_label_list = base_func.get_image_paths_and_labels(val_set)
|
||||
|
||||
# Create a queue that produces indices into the image_list and label_list
|
||||
labels = ops.convert_to_tensor(label_list, dtype=tf.int32)
|
||||
range_size = array_ops.shape(labels)[0]
|
||||
index_queue = tf.train.range_input_producer(range_size, num_epochs=None,
|
||||
shuffle=True, seed=None, capacity=32)
|
||||
|
||||
index_dequeue_op = index_queue.dequeue_many(args.batch_size*args.epoch_size, 'index_dequeue')
|
||||
|
||||
learning_rate_placeholder = tf.placeholder(tf.float32, name='learning_rate')
|
||||
batch_size_placeholder = tf.placeholder(tf.int32, name='batch_size')
|
||||
phase_train_placeholder = tf.placeholder(tf.bool, name='phase_train')
|
||||
image_paths_placeholder = tf.placeholder(tf.string, shape=(None,1), name='image_paths')
|
||||
labels_placeholder = tf.placeholder(tf.int32, shape=(None,1), name='labels')
|
||||
control_placeholder = tf.placeholder(tf.int32, shape=(None,1), name='control')
|
||||
|
||||
nrof_preprocess_threads = 4
|
||||
input_queue = data_flow_ops.FIFOQueue(capacity=2000000,
|
||||
dtypes=[tf.string, tf.int32, tf.int32],
|
||||
shapes=[(1,), (1,), (1,)],
|
||||
shared_name=None, name=None)
|
||||
enqueue_op = input_queue.enqueue_many([image_paths_placeholder, labels_placeholder, control_placeholder], name='enqueue_op')
|
||||
image_batch, label_batch = base_func.create_input_pipeline(input_queue, image_size, nrof_preprocess_threads, batch_size_placeholder)
|
||||
|
||||
image_batch = tf.identity(image_batch, 'image_batch')
|
||||
image_batch = tf.identity(image_batch, 'input')
|
||||
label_batch = tf.identity(label_batch, 'label_batch')
|
||||
|
||||
print('Number of classes in training set: %d' % nrof_classes)
|
||||
print('Number of examples in training set: %d' % len(image_list))
|
||||
|
||||
print('Number of classes in validation set: %d' % len(val_set))
|
||||
print('Number of examples in validation set: %d' % len(val_image_list))
|
||||
|
||||
print('Building training graph')
|
||||
|
||||
# Build the inference graph
|
||||
logits, _ = network.inference(image_batch, args.keep_probability,
|
||||
phase_train=phase_train_placeholder, class_num=args.class_num,
|
||||
weight_decay=args.weight_decay)
|
||||
|
||||
prelogits = logits
|
||||
|
||||
print('class_num=%d' % len(train_set))
|
||||
|
||||
learning_rate = tf.train.exponential_decay(learning_rate_placeholder, global_step,
|
||||
args.learning_rate_decay_epochs*args.epoch_size, args.learning_rate_decay_factor, staircase=True)
|
||||
tf.summary.scalar('learning_rate', learning_rate)
|
||||
|
||||
# Calculate the average cross entropy loss across the batch
|
||||
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(
|
||||
labels=label_batch, logits=logits, name='cross_entropy_per_example')
|
||||
cross_entropy_mean = tf.reduce_mean(cross_entropy, name='cross_entropy')
|
||||
tf.add_to_collection('losses', cross_entropy_mean)
|
||||
|
||||
correct_prediction = tf.cast(tf.equal(tf.argmax(logits, 1), tf.cast(label_batch, tf.int64)), tf.float32)
|
||||
accuracy = tf.reduce_mean(correct_prediction)
|
||||
|
||||
total_loss = tf.add_n([cross_entropy_mean],name='total_loss')
|
||||
|
||||
# Build a Graph that trains the model with one batch of examples and updates the model parameters
|
||||
train_op = base_func.train(total_loss, global_step, args.optimizer,
|
||||
learning_rate, args.moving_average_decay, tf.global_variables(), args.log_histograms)
|
||||
|
||||
# Create a saver
|
||||
var_list = tf.trainable_variables()
|
||||
g_list = tf.global_variables()
|
||||
bn_moving_vars = [g for g in g_list if 'moving_mean' in g.name]
|
||||
bn_moving_vars += [g for g in g_list if 'moving_variance' in g.name]
|
||||
# var_list += bn_moving_vars
|
||||
var_list = list(set(var_list+bn_moving_vars))
|
||||
|
||||
saver = tf.train.Saver(var_list=var_list, max_to_keep=10)
|
||||
|
||||
if pretrained_model:
|
||||
saver_restore = tf.train.Saver(var_list=var_list)
|
||||
|
||||
# Start running operations on the Graph.
|
||||
gpu_options = tf.GPUOptions(per_process_gpu_memory_fraction=args.gpu_memory_fraction)
|
||||
sess = tf.Session(config=tf.ConfigProto(gpu_options=gpu_options, log_device_placement=False))
|
||||
sess.run(tf.global_variables_initializer())
|
||||
sess.run(tf.local_variables_initializer())
|
||||
summary_writer = tf.summary.FileWriter(log_dir, sess.graph)
|
||||
coord = tf.train.Coordinator()
|
||||
tf.train.start_queue_runners(coord=coord, sess=sess)
|
||||
|
||||
with sess.as_default():
|
||||
|
||||
if pretrained_model:
|
||||
print('Restoring pretrained model: %s' % pretrained_model)
|
||||
saver_restore.restore(sess, tf.train.latest_checkpoint(pretrained_model))
|
||||
|
||||
# Training and validation loop
|
||||
print('Running training')
|
||||
nrof_steps = args.max_nrof_epochs*args.epoch_size
|
||||
|
||||
for epoch in range(1,args.max_nrof_epochs+1):
|
||||
step = sess.run(global_step, feed_dict=None)
|
||||
# Train for one epoch
|
||||
t = time.time()
|
||||
cont = train(args, sess, epoch, image_list, label_list, index_dequeue_op, enqueue_op, image_paths_placeholder, labels_placeholder,
|
||||
learning_rate_placeholder, phase_train_placeholder, batch_size_placeholder, control_placeholder, global_step,
|
||||
total_loss, train_op, args.learning_rate_schedule_file,
|
||||
cross_entropy_mean, accuracy, learning_rate,
|
||||
prelogits, args.random_rotate, args.random_crop, args.random_flip, args.use_fixed_image_standardization)
|
||||
# stat['time_train'][epoch-1] = time.time() - t
|
||||
|
||||
if not cont:
|
||||
break
|
||||
|
||||
# Save variables and the metagraph if it doesn't exist already
|
||||
save_variables_and_metagraph(sess, saver, summary_writer, model_dir, subdir, epoch)
|
||||
|
||||
return model_dir
|
||||
|
||||
|
||||
def train(args, sess, epoch, image_list, label_list, index_dequeue_op, enqueue_op, image_paths_placeholder, labels_placeholder,
|
||||
learning_rate_placeholder, phase_train_placeholder, batch_size_placeholder, control_placeholder, step,
|
||||
loss, train_op, learning_rate_schedule_file,
|
||||
cross_entropy_mean, accuracy,
|
||||
learning_rate, prelogits, random_rotate, random_crop, random_flip, use_fixed_image_standardization):
|
||||
batch_number = 0
|
||||
|
||||
if args.learning_rate>0.0:
|
||||
lr = args.learning_rate
|
||||
else:
|
||||
lr = base_func.get_learning_rate_from_file(learning_rate_schedule_file, epoch)
|
||||
|
||||
if lr<=0:
|
||||
return False
|
||||
|
||||
index_epoch = sess.run(index_dequeue_op)
|
||||
label_epoch = np.array(label_list)[index_epoch]
|
||||
image_epoch = np.array(image_list)[index_epoch]
|
||||
|
||||
# Enqueue one epoch of image paths and labels
|
||||
labels_array = np.expand_dims(np.array(label_epoch),1)
|
||||
image_paths_array = np.expand_dims(np.array(image_epoch),1)
|
||||
control_value = base_func.RANDOM_ROTATE * random_rotate + base_func.RANDOM_CROP * random_crop + base_func.RANDOM_FLIP * random_flip + base_func.FIXED_STANDARDIZATION * use_fixed_image_standardization
|
||||
print('use_fixed_image_standardization=%d' % use_fixed_image_standardization)
|
||||
control_array = np.ones_like(labels_array) * control_value
|
||||
sess.run(enqueue_op, {image_paths_placeholder: image_paths_array, labels_placeholder: labels_array, control_placeholder: control_array})
|
||||
|
||||
# Training loop
|
||||
train_time = 0
|
||||
while batch_number < args.epoch_size:
|
||||
start_time = time.time()
|
||||
feed_dict = {learning_rate_placeholder: lr, phase_train_placeholder:True, batch_size_placeholder:args.batch_size}
|
||||
tensor_list = [loss, train_op, step, prelogits, cross_entropy_mean, learning_rate, accuracy]
|
||||
|
||||
loss_, _, step_, prelogits_, cross_entropy_mean_, lr_, accuracy_ = sess.run(tensor_list, feed_dict=feed_dict)
|
||||
|
||||
duration = time.time() - start_time
|
||||
print('Epoch: [%d][%d/%d]\tTime %.3f\tLoss %2.3f\tXent %2.3f\tAccuracy %2.3f\tLr %2.5f' %
|
||||
(epoch, batch_number+1, args.epoch_size, duration, loss_, cross_entropy_mean_, accuracy_, lr_ ))
|
||||
batch_number += 1
|
||||
train_time += duration
|
||||
|
||||
return True
|
||||
|
||||
def save_variables_and_metagraph(sess, saver, summary_writer, model_dir, model_name, step):
|
||||
# Save the model checkpoint
|
||||
print('Saving variables')
|
||||
start_time = time.time()
|
||||
checkpoint_path = os.path.join(model_dir, 'model-%s.ckpt' % model_name)
|
||||
saver.save(sess, checkpoint_path, global_step=step, write_meta_graph=False)
|
||||
save_time_variables = time.time() - start_time
|
||||
print('Variables saved in %.2f seconds' % save_time_variables)
|
||||
metagraph_filename = os.path.join(model_dir, 'model-%s.meta' % model_name)
|
||||
save_time_metagraph = 0
|
||||
if not os.path.exists(metagraph_filename):
|
||||
print('Saving metagraph')
|
||||
start_time = time.time()
|
||||
saver.export_meta_graph(metagraph_filename)
|
||||
save_time_metagraph = time.time() - start_time
|
||||
print('Metagraph saved in %.2f seconds' % save_time_metagraph)
|
||||
summary = tf.Summary()
|
||||
#pylint: disable=maybe-no-member
|
||||
summary.value.add(tag='time/save_variables', simple_value=save_time_variables)
|
||||
summary.value.add(tag='time/save_metagraph', simple_value=save_time_metagraph)
|
||||
summary_writer.add_summary(summary, step)
|
||||
|
||||
|
||||
def parse_arguments(argv):
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument('--logs_base_dir', type=str,
|
||||
help='Directory where to write event logs.', default='~/logs/base_func')
|
||||
parser.add_argument('--models_base_dir', type=str,
|
||||
help='Directory where to write trained models and checkpoints.', default='~/models/base_func')
|
||||
parser.add_argument('--gpu_memory_fraction', type=float,
|
||||
help='Upper bound on the amount of GPU memory that will be used by the process.', default=1.0)
|
||||
parser.add_argument('--gpus', type=str,
|
||||
help='Indicate the GPUs to be used.', default='2')
|
||||
|
||||
parser.add_argument('--pretrained_model', type=str,
|
||||
help='Load a pretrained model before training starts.')
|
||||
|
||||
parser.add_argument('--class_num_changed', type=bool, default=False,
|
||||
help='indicate if the class_num is different from pretrained.')
|
||||
parser.add_argument('--data_dir', type=str,
|
||||
help='Path to the data directory containing aligned face patches.',
|
||||
default='~/datasets/casia/casia_maxpy_mtcnnalign_182_160')
|
||||
parser.add_argument('--model_def', type=str,
|
||||
help='Model definition. Points to a module containing the definition of the inference graph.', default='models.inception_resnet_v1')
|
||||
parser.add_argument('--max_nrof_epochs', type=int,
|
||||
help='Number of epochs to run.', default=20)
|
||||
parser.add_argument('--batch_size', type=int,
|
||||
help='Number of images to process in a batch.', default=100)
|
||||
parser.add_argument('--image_size', type=int,
|
||||
help='Image size (height, width) in pixels.', default=224)
|
||||
parser.add_argument('--epoch_size', type=int,
|
||||
help='Number of batches per epoch.', default=5000)
|
||||
parser.add_argument('--class_num', type=int,
|
||||
help='Dimensionality of the embedding.', default=1000)
|
||||
parser.add_argument('--random_crop',
|
||||
help='Performs random cropping of training images. If false, the center image_size pixels from the training images are used. ' +
|
||||
'If the size of the images in the data directory is equal to image_size no cropping is performed', action='store_true')
|
||||
parser.add_argument('--random_flip',
|
||||
help='Performs random horizontal flipping of training images.', action='store_true')
|
||||
parser.add_argument('--random_rotate',
|
||||
help='Performs random rotations of training images.', action='store_true')
|
||||
parser.add_argument('--use_fixed_image_standardization',
|
||||
help='Performs fixed standardization of images.', action='store_true')
|
||||
parser.add_argument('--keep_probability', type=float,
|
||||
help='Keep probability of dropout for the fully connected layer(s).', default=1.0)
|
||||
parser.add_argument('--weight_decay', type=float,
|
||||
help='L2 weight regularization.', default=0.0)
|
||||
parser.add_argument('--optimizer', type=str, choices=['ADAGRAD', 'ADADELTA', 'ADAM', 'RMSPROP', 'MOM'],
|
||||
help='The optimization algorithm to use', default='ADAGRAD')
|
||||
parser.add_argument('--learning_rate', type=float,
|
||||
help='Initial learning rate. If set to a negative value a learning rate ' +
|
||||
'schedule can be specified in the file "learning_rate_schedule.txt"', default=0.1)
|
||||
parser.add_argument('--learning_rate_decay_epochs', type=int,
|
||||
help='Number of epochs between learning rate decay.', default=100)
|
||||
parser.add_argument('--learning_rate_decay_factor', type=float,
|
||||
help='Learning rate decay factor.', default=1.0)
|
||||
parser.add_argument('--moving_average_decay', type=float,
|
||||
help='Exponential decay for tracking of training parameters.', default=0.9999)
|
||||
parser.add_argument('--seed', type=int,
|
||||
help='Random seed.', default=666)
|
||||
parser.add_argument('--nrof_preprocess_threads', type=int,
|
||||
help='Number of preprocessing (data loading and augmentation) threads.', default=4)
|
||||
parser.add_argument('--log_histograms',
|
||||
help='Enables logging of weight/bias histograms in tensorboard.', action='store_true')
|
||||
parser.add_argument('--learning_rate_schedule_file', type=str,
|
||||
help='File containing the learning rate schedule that is used when learning_rate is set to to -1.', default='data/learning_rate_schedule.txt')
|
||||
|
||||
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = parse_arguments(sys.argv[1:])
|
||||
print('gpu device ID: %s'%args.gpus)
|
||||
main(args)
|
|
@ -0,0 +1,110 @@
|
|||
from __future__ import absolute_import
|
||||
from __future__ import division
|
||||
from __future__ import print_function
|
||||
|
||||
from datetime import datetime
|
||||
import os.path
|
||||
from os import environ
|
||||
import time
|
||||
import sys
|
||||
import random
|
||||
import tensorflow as tf
|
||||
import numpy as np
|
||||
import importlib
|
||||
import argparse
|
||||
import base_func
|
||||
import h5py
|
||||
import math
|
||||
import tensorflow.contrib.slim as slim
|
||||
from tensorflow.python.ops import data_flow_ops
|
||||
from tensorflow.python.framework import ops
|
||||
from tensorflow.python.ops import array_ops
|
||||
import pickle
|
||||
from scipy import misc
|
||||
|
||||
def _softmax(x, axis=-1, t=-100.):
|
||||
x = x - np.max(x)
|
||||
if np.min(x) < t:
|
||||
x = x / np.min(x) * t
|
||||
e_x = np.exp(x)
|
||||
return e_x / e_x.sum(axis, keepdims=True)
|
||||
|
||||
def main(args):
|
||||
environ['CUDA_VISIBLE_DEVICES'] = args.gpus
|
||||
|
||||
image_size = (args.image_size, args.image_size)
|
||||
|
||||
dataset = base_func.get_dataset(args.data_dir)
|
||||
|
||||
val_set = dataset
|
||||
image_list, label_list = base_func.get_image_paths_and_labels(val_set)
|
||||
|
||||
nrof_classes = len(val_set)
|
||||
val_image_num = len(image_list)
|
||||
|
||||
top1 = 0.0
|
||||
top5 = 0.0
|
||||
|
||||
with tf.Graph().as_default() as graph:
|
||||
with tf.Session() as sess:
|
||||
base_func.load_model(args.model)
|
||||
|
||||
input_image = sess.graph.get_tensor_by_name('input:0')
|
||||
output = sess.graph.get_tensor_by_name('MobileNetV1/Bottleneck2/BatchNorm/Reshape_1:0')
|
||||
|
||||
if (os.path.isdir(args.model)):
|
||||
phase_train_placeholder = tf.get_default_graph().get_tensor_by_name("phase_train:0")
|
||||
|
||||
|
||||
for i in range(val_image_num):
|
||||
print(image_list[i])
|
||||
# images = base_func.load_data([image_list[i]], False, False, args.image_size)
|
||||
img = np.array(misc.imread(image_list[i], mode='RGB'))
|
||||
# img = base_func.crop(img, False, args.image_size)
|
||||
img = misc.imresize(img, image_size, interp='bilinear')
|
||||
img = img / 255.
|
||||
images = [img]
|
||||
|
||||
feed_dict={input_image:images}
|
||||
if (os.path.isdir(args.model)):
|
||||
feed_dict={input_image:images,phase_train_placeholder:False}
|
||||
|
||||
logits = sess.run(output,feed_dict=feed_dict)
|
||||
pred = _softmax(logits[0,:])
|
||||
# print(logits)
|
||||
des_idx = np.argsort(pred)
|
||||
# des_data = np.sort(logits)
|
||||
# print(des_data[0,995:])
|
||||
|
||||
if (des_idx[nrof_classes-1]) == label_list[i]:
|
||||
top1 += 1
|
||||
for j in range(5):
|
||||
if (des_idx[nrof_classes-1-j]) == label_list[i]:
|
||||
top5 += 1
|
||||
break
|
||||
print("%05d th pic have been validated, top1 = %.2f%% top5 = %.2f%% " % (i+1,top1/(i+1)*100.,top5/(i+1)*100.))
|
||||
|
||||
|
||||
def parse_arguments(argv):
|
||||
parser = argparse.ArgumentParser()
|
||||
|
||||
parser.add_argument('model', type=str,
|
||||
help='Model definition. ckpt folder or pb file', default='mobilenet_v1.pb')
|
||||
parser.add_argument('data_dir', type=str,
|
||||
help='Path to the data directory containing aligned face patches.',
|
||||
default='~/datasets/iamgenet_val')
|
||||
parser.add_argument('--image_size', type=int,
|
||||
help='image size.', default=224)
|
||||
parser.add_argument('--gpu_memory_fraction', type=float,
|
||||
help='Upper bound on the amount of GPU memory that will be used by the process.', default=1.0)
|
||||
parser.add_argument('--gpus', type=str,
|
||||
help='Indicate the GPUs to be used.', default='3')
|
||||
|
||||
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = parse_arguments(sys.argv[1:])
|
||||
print('gpu device ID: %s'%args.gpus)
|
||||
main(args)
|
Binary file not shown.
Loading…
Reference in New Issue