1. Inception-ResNet-v1简介
2.实验代码
import inception_resnet_v1
import tensorflow.contrib.slim as slim
import numpy as np
import cv2
import face_image_input
import tensorflow as tf
from datetime import datetime
import math
import time
import os
import matplotlib.pyplot as plt
# 配置神经网络的参数
BATCH_SIZE = 128
batch_size = 128
LEARNING_RATE_BASE = 0.01 #0.8 #
LEARNING_RATE_DECAY = 0.0005 # 0.99
REGULARAZTION_RATE = 0.0001
TRAIN_STEPS = 10000 #3000
MOVING_AVERAGE_DECAY = 0.99
MODEL_SAVE_PATH = "./model/"
MODEL_NAME = "model3.ckpt"
slim = tf.contrib.slim
DATA_DIR = './datasets/data/flowers'
# 输出类别
NUM_CLASSES = 5
# 获取图片大小
IMAGE_SIZE = 160
def face_fine_tuning():
'''
1.设置参数,并加载数据
'''
# 用于保存微调后的检查点文件和日志文件路径
train_log_dir = './finetune_face'
train_log_file = 'face_fine_tune.ckpt'
# 官方下载的检查点文件路径
checkpoint_file = './20180402-114759/model-20180402-114759.ckpt-275' # -275.index
# './20180402-114759/model-20180402-114759.ckpt-275'
learning_rate = 1e-4
# 设置batch_size
batch_size =32 # 32 #128 #256
# 训练集数据长度
n_train = 120 #3320
# 测试集数据长度
# n_test = 350
# 迭代轮数
training_epochs = 500 #100
display_epoch = 1
if not tf.gfile.Exists(train_log_dir):
tf.gfile.MakeDirs(train_log_dir)
# 加载数据
train_images, train_labels = face_image_input.distorted_inputs("",batch_size)
test_images, test_labels = face_image_input.inputs(eval_data=False, data_dir="", batch_size=batch_size)
# 获取模型参数的命名空间
#arg_scope = inception_resnet_v1.vgg_arg_scope()
#arg_scope = inception_resnet_v2_arg_scope()
# 创建网络
#with slim.arg_scope(""):
if 1==1:
'''
2.定义占位符和网络结构
'''
# 输入图片
input_images = tf.placeholder(dtype=tf.float32, shape=[None, IMAGE_SIZE, IMAGE_SIZE, 3])
# 图片标签
input_labels = tf.placeholder(dtype=tf.float32, shape=[None, 5])
#input_labels = tf.placeholder(dtype=tf.int32, shape=[batch_size])
label_holder = tf.placeholder(tf.int32, [batch_size], name='y-input')
# 训练还是测试?测试的时候弃权参数会设置为1.0
is_training = tf.placeholder(dtype=tf.bool)
# 创建vgg16网络 如果想冻结所有层,可以指定slim.conv2d中的 trainable=False
logits, end_points = inception_resnet_v1.inception_resnet_v1(input_images, is_training=is_training)
# print(end_points) 每个元素都是以vgg_16/xx命名
# Restore only the convolutional layers: 从检查点载入当前图除了fc8层之外所有变量的参数
params = slim.get_variables_to_restore(exclude=['Logits','InceptionResnetV1/Bottleneck'])
variables_to_restore = slim.get_variables_to_restore(exclude=['Logits','InceptionResnetV1/Bottleneck'])
#InceptionResnetV1/Bottleneck
print("输出变量000:")
print(variables_to_restore)
# 用于恢复模型 如果使用这个保存或者恢复的话,只会保存或者恢复指定的变量
restorer = tf.train.Saver(params)
init_assign_op, init_feed_dict = slim.assign_from_checkpoint(checkpoint_file, variables_to_restore,ignore_missing_vars=True)
# 预测标签
pred = tf.argmax(logits, axis=1)
'''
定义代价函数和优化器
'''
# 代价函数
cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=input_labels, logits=logits))
# 设置优化器
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(cost) #全部参数重新训练
# 预测结果评估
correct = tf.equal(pred, tf.argmax(input_labels, 1)) # 返回一个数组 表示统计预测正确或者错误
accuracy = tf.reduce_mean(tf.cast(correct, tf.float32)) # 求准确率
num_batch = int(np.ceil(n_train / batch_size))
# 用于保存检查点文件
save = tf.train.Saver(max_to_keep=1)
# 恢复模型
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
variables_to_restore1 = sess.run(variables_to_restore)
#print("输出变量:")
#print(variables_to_restore1)
# 检查最近的检查点文件
ckpt = tf.train.latest_checkpoint(train_log_dir)
if ckpt != None:
save.restore(sess, ckpt)
print('从上次训练保存后的模型继续训练!')
else:
#restorer.restore(sess, checkpoint_file)
sess.run(init_assign_op, init_feed_dict) # 添加
print('从官方模型加载训练!')
# 创建一个协调器,管理线程
coord = tf.train.Coordinator()
# 启动QueueRunner, 此时文件名才开始进队。
threads = tf.train.start_queue_runners(sess=sess, coord=coord)
'''
查看预处理之后的图片
imgs, labs = sess.run([train_images, train_labels])
print('原始训练图片信息:', imgs.shape, labs.shape)
print("lable:",labs)
labs = tf.one_hot(labs, depth=5, axis=-1)
print('原始测试图片信息:', imgs.shape, labs.shape)
print("lable:", labs)
show_img = np.array(imgs[0], dtype=np.uint8)
plt.imshow(show_img)
plt.title('Original train image')
plt.show()
imgs, labs = sess.run([test_images, test_labels])
print('原始测试图片信息:', imgs.shape, labs.shape)
labs = tf.one_hot(labs, depth=5, axis=-1)
print('原始测试图片信息:', imgs.shape, labs.shape)
show_img = np.array(imgs[0], dtype=np.uint8)
plt.imshow(show_img)
plt.title('Original test image')
plt.show()
'''
print('开始训练!')
for epoch in range(training_epochs):
total_cost = 0.0
print("训练111111!!!")
for i in range(num_batch):
print("批次:"+str(i))
print("训练222222!!!")
imgs, labs = sess.run([train_images, train_labels])
labs = tf.one_hot(labs, depth=5, axis=-1)
print('原始训练图片信息,程序运行中:', imgs.shape, labs.shape)
labs = sess.run(labs)
#print(labs)
#print(type(labs))
_, loss = sess.run([optimizer, cost],
feed_dict={input_images: imgs, input_labels: labs, is_training: True})
total_cost += loss
print("训练ing!!!")
# 打印信息
if epoch % display_epoch == 0:
print('Epoch {}/{} average cost {:.9f}'.format(epoch + 1, training_epochs, total_cost / num_batch))
# 进行预测处理
imgs, labs = sess.run([test_images, test_labels])
labs = tf.one_hot(labs, depth=5, axis=-1)
labs = sess.run(labs)
print('原始测试图片信息,程序运行中:', imgs.shape, labs.shape)
#print(labs)
#labs = labs.eval()
#print(type(labs))
cost_values, accuracy_value = sess.run([cost, accuracy],
feed_dict={input_images: imgs, input_labels: labs,
is_training: False})
print('Epoch {}/{} Test cost {:.9f}'.format(epoch + 1, training_epochs, cost_values))
print('准确率:', accuracy_value)
# 保存模型
save.save(sess, os.path.join(train_log_dir, train_log_file), global_step=epoch)
print('Epoch {}/{} 模型保存成功'.format(epoch + 1, training_epochs))
print('训练完成')
# 终止线程
coord.request_stop()
coord.join(threads)
def face_test():
'''
使用微调好的网络进行测试
'''
'''
1.设置参数,并加载数据
'''
# 微调后的检查点文件和日志文件路径
save_dir = './finetune_face'
# 设置batch_size
batch_size = 64 #128
# 加载数据
train_images, train_labels = face_image_input.distorted_inputs("", batch_size)
test_images, test_labels = face_image_input.inputs(eval_data=False, data_dir="", batch_size=batch_size)
# 获取模型参数的命名空间
#arg_scope = inception_resnet_v1.vgg_arg_scope()
# 创建网络
#with slim.arg_scope(arg_scope):
if 1==1:
'''
2.定义占位符和网络结构
'''
# 输入图片
input_images = tf.placeholder(dtype=tf.float32, shape=[None, IMAGE_SIZE, IMAGE_SIZE, 3])
# 训练还是测试?测试的时候弃权参数会设置为1.0
is_training = tf.placeholder(dtype=tf.bool)
# 创建vgg16网络
logits, end_points = inception_resnet_v1.inception_resnet_v1(input_images, is_training=False)
# 预测标签
pred = tf.argmax(logits, axis=1)
restorer = tf.train.Saver()
# 恢复模型
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
ckpt = tf.train.latest_checkpoint(save_dir)
if ckpt != None:
# 恢复模型
restorer.restore(sess, ckpt)
print("Model restored.")
# 创建一个协调器,管理线程
coord = tf.train.Coordinator()
# 启动QueueRunner, 此时文件名才开始进队。
threads = tf.train.start_queue_runners(sess=sess, coord=coord)
'''
查看预处理之后的图片
'''
imgs, labs = sess.run([test_images, test_labels])
print('原始测试图片信息:', imgs.shape, labs.shape)
show_img = np.array(imgs[0], dtype=np.uint8)
plt.imshow(show_img)
plt.title('Original test image')
plt.show()
pred_value = sess.run(pred, feed_dict={input_images: imgs, is_training: False})
print('预测结果为:', pred_value)
print('实际结果为:', labs)
correct = np.equal(pred_value, labs)
print('准确率为:', np.mean(correct))
# 终止线程
coord.request_stop()
coord.join(threads)
if __name__ == '__main__':
tf.reset_default_graph()
face_fine_tuning()
tf.reset_default_graph()
face_test()
3.实验结果
3.1
batch_size =16
# 训练集数据长度
n_train = 163
# 迭代轮数
training_epochs =10
(1)准确率为: 0.40625
3.2
batch_size =32
# 训练集数据长度
n_train = 163 #3320
# 迭代轮数
training_epochs = 50
(2)训练: Epoch 50/50 Test cost 3.713762522
准确率: 0.4375
Epoch 50/50 模型保存成功
准确率为: 0.390625
3.3 Epoch 100/100 Test cost 4.668624878
准确率: 0.46875
Epoch 100/100 模型保存成功
训练完成
原始测试图片信息: (64, 160, 160, 3) (64,)
预测结果为: [1 3 1 2 2 0 2 1 1 0 2 2 4 4 2 3 1 2 2 2 2 4 4 2 2 4 4 1 1 4 3 4 1 1 2 2 4
2 0 2 0 1 3 2 4 2 2 2 1 2 2 2 4 2 4 1 4 4 4 1 3 2 1 1]
实际结果为: [0 0 0 0 0 2 2 1 1 2 2 1 1 1 2 2 2 2 2 2 2 3 4 3 4 4 4 4 0 4 0 4 1 0 0 2 1
0 2 1 2 1 2 2 1 2 2 2 2 2 2 3 3 4 4 4 4 4 4 0 0 0 0 1]
准确率为: 0.4375
3.4 Epoch 500/500 average cost 0.000000050
原始测试图片信息,程序运行中: (32, 160, 160, 3) (32, 5)
Epoch 500/500 Test cost 6.768644810
准确率: 0.4375
Epoch 500/500 模型保存成功
训练完成
['./bin/face_train_160_tf']
开始读取lable:
Tensor("data_augmentation/Cast:0", shape=(?,), dtype=int32)
读取数据完成!
<class 'face_image_input.read_cifar10.<locals>.CIFAR10Record'>
Filling queue with 203 CIFAR images before starting to train. This will take a few minutes.
shuffle1111
开始读取lable:
Tensor("input/Cast:0", shape=(?,), dtype=int32)
shuffle0000
Model restored.
原始测试图片信息: (64, 160, 160, 3) (64,)
预测结果为: [1 2 1 1 2 3 4 2 1 1 2 0 3 2 0 4 4 2 2 1 4 2 2 2 1 4 4 2 2 1 1 2 4 1 2 1 1
2 3 4 2 1 0 2 2 3 0 4 2 2 1 1 4 4 1 2 4 2 4 4 4 2 2 2]
实际结果为: [0 0 1 0 0 0 1 2 1 1 2 2 2 1 2 2 3 3 2 2 4 2 2 2 4 4 4 0 1 1 1 2 4 4 4 0 0
0 0 1 2 1 2 2 2 2 2 2 3 2 4 2 4 3 4 4 4 1 4 4 1 2 2 0]
准确率为: 0.421875
3.5
Epoch 1000/1000 Test cost 20.401565552
准确率: 0.375
Epoch 1000/1000 模型保存成功
训练完成
['./bin/face_train_160_tf']
开始读取lable:
Tensor("data_augmentation/Cast:0", shape=(?,), dtype=int32)
读取数据完成!
<class 'face_image_input.read_cifar10.<locals>.CIFAR10Record'>
Filling queue with 203 CIFAR images before starting to train. This will take a few minutes.
shuffle1111
开始读取lable:
Tensor("input/Cast:0", shape=(?,), dtype=int32)
shuffle0000
Model restored.
原始测试图片信息: (64, 160, 160, 3) (64,)
预测结果为: [1 2 4 1 1 4 0 0 4 1 2 4 0 2 4 1 2 2 1 2 2 2 3 2 4 4 2 2 4 4 1 4 1 2 1 4 0
0 4 1 2 0 2 4 1 4 2 1 2 2 3 2 2 4 2 4 2 4 2 2 1 4 1 4]
实际结果为: [0 0 0 0 1 0 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3 2 4 4 4 4 4 4 4 0 0 0 0 1 0 1
1 1 1 2 2 2 2 2 2 2 2 2 2 2 3 3 4 4 4 4 4 0 4 0 4 0 0]
准确率为: 0.34375
参考资料
Inception-ResNet-v1
[1] 深度学习--Inception-ResNet-v1网络结构
[2] ResNet-V1-50卷积神经网络迁移学习进行不同品种的花的分类识别
[3] 【Tensorflow系列】使用Inception_resnet_v2训练自己的数据集并用Tensorboard监控
[4] 使用TensorFlow打造自己的图像识别模型
[5] tensorflow实现迁移学习 此例程出自《TensorFlow实战Google深度学习框架》6.5.2小节 卷积神经网络迁移学习
官方代码
[1] davidsandberg/facenet
[2] Classifier training of inception resnet v1
[3] facenet/src/models/inception_resnet_v1.py
网友评论