Tensorflow:实战Google深度学习框架(输入数据处理框架)

参考:TensorFlow:实战Google深度学习框架

# *_*coding:utf-8 *_*

import tensorflow as tf
import numpy as np

def distort_color(image, color_ordering=0):
    if color_ordering == 0:
        image = tf.image.random_brightness(image, max_delta=32. / 255.)
        image = tf.image.random_saturation(image, lower=0.5, upper=1.5)
        image = tf.image.random_hue(image, max_delta=0.2)
        image = tf.image.random_contrast(image, lower=0.5, upper=1.5)

    elif color_ordering == 1:
        image = tf.image.random_saturation(image, lower=0.5, upper=1.5)
        image = tf.image.random_hue(image, max_delta=0.2)
        image = tf.image.random_contrast(image, lower=0.5, upper=1.5)
        image = tf.image.random_brightness(image, max_delta=32. / 255.)

    elif color_ordering == 2:
        image = tf.image.random_hue(image, max_delta=0.2)
        image = tf.image.random_contrast(image, lower=0.5, upper=1.5)
        image = tf.image.random_brightness(image, max_delta=32. / 255.)
        image = tf.image.random_saturation(image, lower=0.5, upper=1.5)

    elif color_ordering == 3:
        image = tf.image.random_contrast(image, lower=0.5, upper=1.5)
        image = tf.image.random_brightness(image, max_delta=32. / 255.)
        image = tf.image.random_saturation(image, lower=0.5, upper=1.5)
        image = tf.image.random_hue(image, max_delta=0.2)

    """Clips tensor values to a specified min and max.
    基于定义的min与max对tensor数据进行截断操作,目的是为了应对梯度爆发或者梯度消失的情况
    """
    return tf.clip_by_value(image, 0.0, 1.0)

"""
给定一张解码后的图像,目标图像的尺寸以图像上的标注框,此函数可以对给出的额图像进行预处理
这个函数的输入图像是图像识别问题中的原始的训练数据,而输出则是神经网络模型的输入层。
注意这里只处理模型的训练数据,对于预测数据,一般不需要使用随机变换的步骤
"""
def preprocess_for_train(image, height, width, bbox):
    #如果没有提供标注框,则认为整个图像就是需要关注的部分
    if bbox is None:
        bbox = tf.constant([0.0, 0.0, 1.0, 1.0], dtype=tf.float32, shape=[1, 1, 4])

    #转换图像张量的类型
    if image.dtype != tf.float32:
        image = tf.image.convert_image_dtype(image, dtype=tf.float32)

    #随机截取图像,减小需要关注的物体大小对图像识别算法的影响
    '''注意sample_distorted_bounding_box函数,已经改变了,详细见函数定义'''
    bbox_begin, bbox_size, _ = tf.image.sample_distorted_bounding_box(tf.shape(image),
                                                                      bounding_boxes=bbox, min_object_covered=0.1)
    distort_image = tf.slice(image, bbox_begin, bbox_size)

    #将随机截取的图像调整为神经网络的输入层大小,大小的调整算法是随机选择的
    distort_image = tf.image.resize_images(distort_image, [height, width], method = np.random.randint(4))
    #随机左右翻转图像
    distort_image = tf.image.random_flip_left_right(distort_image)
    #使用一种随机的顺序调整图像色彩
    distort_image = distort_color(distort_image, np.random.randint(3))

    return distort_image
#神经网络的前向传播算法,此处只是为了做一个示意
def inference(image_batch):
    pass
#损失函数的计算,此处只是为了做一个示例函数,具体问题时,在定义函数体的变量和返回值
def calc_loss(logit, label_batch):
    pass

'''
创建文件列表,并通过文件列表创建输入文件队列。在调用输入数据处理流程前,需要统一原始数据格式并将它们存储到TFRecord文件中。
下面给出的文件列表应该包含所有提供训练数据的TFRecord文件
'''
#使用tf.train.match_filenames_once函数获取文件列表
files = tf.train.match_filenames_once('path/too/file_pattern-*')
filename_queue = tf.train.string_input_producer(files, shuffle=False)

'''
使用类似7.1接种介绍的方法解析TFRecord文件中的数据。这里假设image中存储的是图像的原始数据,label为该样例所对应的标签。height、
width和channels给出了图片的维度
'''
#如7.1节所示读取并解析一个样本
#创建一个reader来读取TFRecord文件中的样例
reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)  #返回文件名和文件
features = tf.parse_single_example(
    serialized_example,
    features={
        'image':tf.FixedLenFeature([], tf.string),
        'label':tf.FixedLenFeature([], tf.int64),
        'height':tf.FixedLenFeature([], tf.int64),
        'width':tf.FixedLenFeature([], tf.int64),
        'channels':tf.FixedLenFeature([], tf.int64)
    })

image, label = features['image'], features['label']
height, width = features['height'], features['width']
channels = features['channels']

#从原始图像数据中解析出像素矩阵,并根据图像尺寸还原图像
#使用tf.decode_raw可以将字符串解析成图像对应的像素数组
decoded_image =  tf.decode_raw(image, tf.uint8)
decoded_image.set_shape([height, width, channels])

#定义神经网络输入层图片的大小
'''这里的image_size是神经网络输入层图片的大小,与图片的原始大小无关,这个大小是为了进行图像预处理过程中,对原始图像进行调整的大小
如原始图片为29x29x3,经过preprocess_for_train图像预处理函数过后,输出图片为299x299x3
'''
image_size = 299
#preprocess_for_train为7.1.2节介绍的图像预处理程序
distorted_image = preprocess_for_train(decoded_image, image_size, image_size, None)


#将处理后的图像和标签通过tf.train.shuffle_batch整理成神经网路训练时需要处理的batch
min_after_dequeue = 10000
batch_size = 100
capacity = min_after_dequeue + 3 * batch_size
image_batch, label_batch = tf.train.shuffle_batch(
    [distorted_image, label], batch_size=batch_size, capacity=capacity, min_after_dequeue=min_after_dequeue)

#定义神经网络的结构以及优化过程,image_batch可以作为输入提供给神经网络的输入层
#label_batch则提供输入batch中样例的正确答案
TRAINING_ROUNDS = 30000
logit = inference(image_batch)   #这是前面章节所示的钱箱传播的算法
loss = calc_loss(logit, label_batch)     #这是损失函数的计算
learning_rate = 0.001
train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss)

#声明会话并运行神经网络的优化过程
with tf.Session() as sess:
    #神经网络训练准备工作。这些工作包括变量的初始化、线程启动
    init = tf.global_variables_initializer()
    local_init = tf.local_variables_initializer()
    sess.run([init, local_init])

    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(sess=sess, coord=coord)
    #神经网络的训练过程
    for _ in range(TRAINING_ROUNDS):
        sess.run(train_step)

    coord.request_stop()
    coord.join(threads)



'''
将数据转为 TFRecord 格式的多个文件
用 tf.train.match_filenames_once() 创建文件列表(图中为{A,B,C})
用 tf.train.string_input_producer() 创建输入文件队列,可以将输入文件顺序随机打乱,并加入输入队列(是否打乱为可选项,该函数也会生成并维护一个输入文件队列,不同进程中的文件读取函数可以共享这个输入文件队列)
用 tf.TFRecordReader() 读取文件中的数据
用 tf.parse_single_example() 解析数据
对数据进行解码及预处理
用 tf.train.shuffle_batch() 将数据组合成 batch
将 batch 用于训练

'''

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值