# -- encoding:utf-8 --
"""
使用TensorFlow训练模型
Create by ibf on 2018/5/28
"""
from plate_number.genplate import GenPlate, gen_sample, chars
import tensorflow as tf
import numpy as np
import os
import cv2
def make_example(image, label):
"""
产生Example对象
:param image:
:param label:
:return:
"""
return tf.train.Example(features=tf.train.Features(feature={
'image': tf.train.Feature(bytes_list=tf.train.BytesList(value=[image])),
'label': tf.train.Feature(bytes_list=tf.train.BytesList(value=[label]))
}))
def generate_TFRecord(filename, genplate, height=72, weight=272, num_plat=1000):
"""
随机生成num_plat张车牌照并将数据输出形成TFRecord格式
:param filename: TFRecord格式文件存储的路径
:param genplate: 车牌照生成器
:param height: 车牌照高度
:param weight: 车牌照宽度
:param num_plat: 需要生成车牌照的数量
:return:
"""
writer = tf.python_io.TFRecordWriter(filename)
for i in range(num_plat):
num, img = gen_sample(genplate, weight, height)
# TODO: 因为MxNet中的格式要求导致的问题,必须转换回[height, weight, channels]
img = img.transpose(1, 2, 0)
img = img.reshape(-1).astype(np.float32)
num = np.array(num).reshape(-1).astype(np.int32)
ex = make_example(img.tobytes(), num.tobytes())
writer.write(ex.SerializeToString())
writer.close()
def read_tfrecord(filename, x_name='image', y_name='label', x_shape=[72, 272, 1], y_shape=[7], batch_size=64,
shuffle_data=False, num_threads=1):
"""
读取TFRecord文件
:param filename:
:param x_name: 给定训练用x的名称
:param y_name: 给定训练用y的名称
:param x_shape: x的格式
:param y_shape: y的格式
:param batch_size: 批大小
:param shuffle_data: 是否混淆数据,如果为True,那么进行shuffle操作
:param num_threads: 线程数目
:return:
"""
# 获取队列
filename_queue = tf.train.string_input_producer([filename])
# 构建数据读取器
reader = tf.TFRecordReader()
# 读取队列中的数据
_, serialized_example = reader.read(filename_queue)
# 处理样本
features = tf.parse_single_example(
serialized_example,
features={
x_name: tf.FixedLenFeature([], tf.string),
y_name: tf.FixedLenFeature([], tf.string)
}
)
# 读取特征
image = tf.decode_raw(features[x_name], tf.float32)
label = tf.decode_raw(features[y_name], tf.int32)
# 格式重定
image = tf.reshape(image, x_shape)
label = tf.reshape(label, y_shape)
# 转换为批次的Tensor对象
capacity = batch_size * 6 + 10
if shuffle_data:
image, label = tf.train.shuffle_batch([image, label], batch_size=batch_size, capacity=capacity,
num_threads=num_threads, min_after_dequeue=int(capacity / 2))
else:
image, label = tf.train.batch([image, label], batch_size=batch_size, capacity=capacity, num_threads=num_threads)
return image, label
def model(images, keep_prob):
"""
模型构建
:param images: 图像数据,格式:[batch_size,height,width,channels]
:param keep_prob: 进行dropout时候神经元的保留比例
:return:
"""
with tf.variable_scope('conv1') as scope:
weights = tf.get_variable('weights',
shape=[3, 3, 3, 32],
dtype=tf.float32,
initializer=tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32))
net = tf.nn.conv2d(images, weights, strides=[1, 1, 1, 1], padding='SAME')
biases = tf.get_variable('biases',
shape=[32],
dtype=tf.float32,
initializer=tf.constant_initializer(0.1))
net = tf.nn.relu(tf.nn.bias_add(net, biases))
# conv2
with tf.variable_scope('conv2') as scope:
weights = tf.get_variable('weights',
shape=[3, 3, 32, 32],
dtype=tf.float32,
initializer=tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32))
net = tf.nn.conv2d(net, weights, strides=[1, 1, 1, 1], padding='SAME')
biases = tf.get_variable('biases',
shape=[32],
dtype=tf.float32,
initializer=tf.constant_initializer(0.1))
net = tf.nn.relu(tf.nn.bias_add(net, biases))
with tf.variable_scope('max_pooling1') as scope:
net = tf.nn.max_pool(net, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME')
# conv3
with tf.variable_scope('conv3') as scope:
weights = tf.get_variable('weights',
shape=[3, 3, 32, 64],
dtype=tf.float32,
initializer=tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32))
net = tf.nn.conv2d(net, weights, strides=[1, 1, 1, 1], padding='SAME')
biases = tf.get_variable('biases',
shape=[64],
dtype=tf.float32,
initializer=tf.constant_initializer(0.1))
net = tf.nn.relu(tf.nn.bias_add(net, biases), name=scope.name)
# conv4
with tf.variable_scope('conv4') as scope:
weights = tf.get_variable('weights',
shape=[3, 3, 64, 64],
dtype=tf.float32,
initializer=tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32))
net = tf.nn.conv2d(net, weights, strides=[1, 1, 1, 1], padding='SAME')
biases = tf.get_variable('biases',
shape=[64], dtype=tf.float32,
initializer=tf.constant_initializer(0.1))
net = tf.nn.relu(tf.nn.bias_add(net, biases), name=scope.name)
with tf.variable_scope('max_pooling2') as scope:
net = tf.nn.max_pool(net, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME', name='pooling2')
# conv5
with tf.variable_scope('conv5') as scope:
weights = tf.get_variable('weights',
shape=[3, 3, 64, 128], dtype=tf.float32,
initializer=tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32))
net = tf.nn.conv2d(net, weights, strides=[1, 1, 1, 1], padding='SAME')
biases = tf.get_variable('biases',
shape=[128], dtype=tf.float32,
initializer=tf.constant_initializer(0.1))
net = tf.nn.relu(tf.nn.bias_add(net, biases), name=scope.name)
# conv6
with tf.variable_scope('conv6') as scope:
weights = tf.get_variable('weights',
shape=[3, 3, 128, 128], dtype=tf.float32,
initializer=tf.truncated_normal_initializer(stddev=0.1, dtype=tf.float32))
net = tf.nn.conv2d(net, weights, strides=[1, 1, 1, 1], padding='VALID')
biases = tf.get_variable('biases',
shape=[128], dtype=tf.float32,
initializer=tf.constant_initializer(0.1))
net = tf.nn.relu(tf.nn.bias_add(net, biases), name=scope.name)
# pool3
with tf.variable_scope('max_pool3') as scope:
net = tf.nn.max_pool(net, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='VALID', name='pool3')
# fc1_flatt