init project

master
latyas 2019-01-21 19:18:34 +08:00
commit 8ff41bacfb
16 changed files with 3194 additions and 0 deletions

0
.gitignore vendored Normal file
View File

11
README.md Normal file
View File

@ -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\_fileor ckpt folder val\_set\_fold
6. 预测单张图片python mobilenetv1/predict\_one\_pic.py pb\_fileor ckpt folder pic

0
mobilenetv1/__init__.py Normal file
View File

387
mobilenetv1/base_func.py Normal file
View File

@ -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)))

BIN
mobilenetv1/data/eagle.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 KiB

1000
mobilenetv1/data/label.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
# Learning rate schedule
# Maps an epoch number to a learning rate
0: 0.01
11: 0.001
50: 0.0001

1000
mobilenetv1/data/names.list Normal file

File diff suppressed because it is too large Load Diff

View File

@ -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:]))

View File

@ -0,0 +1,2 @@
# flake8: noqa

View File

@ -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

View File

@ -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)

20
mobilenetv1/run_mobilenet_v1.sh Executable file
View File

@ -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

View File

@ -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)

View File

@ -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.