with tf.Session() as sess:
sess.run(result) #得到关心的运算的结果

训练神经网络的步骤:

  1. 定义神经网络结构和前向传播的输出结果
  2. 定义损失函数以及选择反向传播优化的算法
  3. 生成会话并且在训练数据上反复运行反向传播优化算法

判断输出向量和期望向量有多接近?
交叉熵 cross entropy

t.eval() = tf.get_default_session().run(t)


学习率设置方法:指数衰减法

tf.train.exponential_decay(原始学习率,global_step,衰减速度,衰减率,staircase = True)

正则化

tf.contrib.layers.l2_regularizer(lambda)(w)
tf.contrib.layers.l1_regularizer

eg: tf.add_to_collection('losses', tf.contrib.layers.l2_regularizer(lambda)(var))

滑动平均模型

global_step = tf.Variable(0, trainable = False)
variable_averages = tf.train.ExponentialMovingAverage(MOVING_AVERAGE_DECAY, global_step)
variable_averages_op = variable_averages.apply(tf.trainable_variables)


两种写法等价:都是在确保了参数顺序执行之后,再执行train_op。

①train_op = tf.group(train_step, variables_averages_op)
②with tf.control_dependecies([train_step, variables_averages_op]):
train_op = tf.no_op(name='train')\


变量管理

当神经网络的结构更加复杂、参数更多时,需要一个更好的方式来传递和管理神经网络中的参数。
Tensorflow提供了通过变量名称来创建或者获取变量的机制。通过这个机制,在不同的函数中可以直接通过变量的名字来使用变量,而不需要将变量通过参数的形式到处传递。

1.创建变量

v = tf.get_variable("v", shape=[1], initializer=tf.constant_initializer(1.0))
v = tf.Variable(tf.constant(1.0, shape=[1]), name="v")
这两个定义是等价的。
tf.Variable和tf.get_variable最大的区别是:对于tf.Variable函数,变量名称是个可选参数;但是对于tf.get_variable函数,变量名称是个必填参数。tf.get_variable会根据这个名字去创建或者获取变量。

如果需要通过tf.get_variable获取一个已经创建的变量,需要通过tf.variable_scope函数来生成一个上下文管理器,并明确指定在这个上下文管理器中,tf.get_variable将直接获取已经生成的变量。
变量初始化函数
通过名称获取变量

tf.get_variable
tf.varaible_scope

定义变量和前向传播的时候使用
def inference(input_tensor, regularizer):
    with tf.variable_scope('layer1'):
        weights = get_weight_variable([INPUT_NODE, LAYER1_NODE], regularizer)
        biases = tf.get_variable("biases", [LAYER1_NODE], initializer=tf.constant_initializer(0.0))
        layer1 = tf.nn.relu(tf.matmul(input_tensor, weights) + biases)

    with tf.variable_scope('layer2'):
        weights = get_weight_variable([LAYER1_NODE, OUTPUT_NODE], regularizer)
        biases = tf.get_variable("biases", [OUTPUT_NODE], initializer=tf.constant_initializer(0.0))
        layer2 = tf.matmul(layer1, weights) + biases

    return layer2
tf.train.Saver
保存:
saver = tf.train.Saver()
saver.save(sess, "/path/to/model/model.ckpt")

在这个文件目录下会出现三个文件。

  1. model.ckpt.meta:保存了计算图的结构
  2. model.ckpt:保存程序中每个变量的取值
  3. checkpoint文件:保存了一个目录下所有模型文件列表
加载:
  1. 将变量的值通过已经保存的模型加载进来
saver = tf.train.Saver()
saver.restore(sess, "/path/to/model/model.ckpt") 
  1. 直接加载已经持久化的图,无需重复定义图上的运算
saver = tf.train.import_meta_graph("/path/to/model/model.ckpt/model.ckpt.meta")
saver.restore(sess, "/path/to/model/model.ckpt/model.ckpt")
print sess.run(tf.get_default_graph().get_tensor_by_name("add:0"))

为了保存或加载部分变量,在声明tf.train.Saver时可以提供一个列表来指定需要保存或加载的变量
saver = tf.train.Saver([v1])

为了方便加载时重命名滑动平均变量,tf.train.ExponentialMovingAverage类提供了variables_to_restore函数来生成tf.train.Saver类所需要的变量重命名字典。

eg:saver = tf.train.Saver(ema.variables_to_restore())


最佳实践

inference:定义前向传播过程以及参数
  1. 定义神经网络结构相关参数:
    INPUT_NODE
    OUTPUT_NODE
    LAYER1_NODE
def get_weight_variable(shape, regularizer)
    return weights

通过tf.get_variable函数来获取变量

def inference(input_tensor, regularizer)
    return layer_n

声明各层神经网络变量和前向传播过程

train:训练过程
  1. 配置神经网络参数
BATCH_SIZE = 100  #batch大小
LEARNING_RATE_BASE = 0.8 #基础学习率
LEARNING_RATE_DECAY = 0.99 #学习率衰减系数
REGULARIZATION_RATE = 0.0001 #正则化系数
TRAINING_STEPS = 30000 #总训练次数
MOVING_AVERAGE_DECAY = 0.99 #滑动平均衰减率
MODEL_SAVE_PATH="MNIST_model/" #模型存储路径
MODEL_NAME="mnist_model" #模型名称
def train():

(1)定义输入输出placeholder
(2)定义regularizer
(3)前向传播
(4)global_step
(5)定义滑动平均操作
variable_averages
variable_averages_op
(6)定义损失函数
(7)定义学习率
(8)定义优化算法
train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step=global_step)
(9)限定运行顺序
with tf.control_dependencies([train_step, variables_averages_op]):
train_op = tf.no_op(name='train')
(10)存储模型
(11)创建会话
初始化变量
获取xs, ys
循环训练: , loss_value, step = sess.run([train_op, loss, global_step], feed_dict={x: xs, y: ys}) 并存储模型


CNN

卷积层

卷积层过滤器只在长、宽维度移动
conv = tf.nn.conv2d(input, filter_weight, strides=[1, 1, 1, 1], padding='SAME')
input:四维矩阵,第一维对应输入batch,后三维对应节点矩阵
filter_weight:卷积层权重
strides:不同维度的步长,第一维和最后一维都是1,中间的分别为长和宽
padding:SAME是全0填充,VALID表示不添加

bias = tf.nn.bias_add(conv, biases)
矩阵上不同位置的节点都要加上同样的偏置项,不能直接使用加法

actived_conv = tf.nn.relu(bias)

池化层

作用:缩小矩阵尺寸,减少全连接层中的参数;加快计算速度并且防止过拟合
max pooling
average pooling
池化层过滤器在三个维度移动
pool = tf.nn.max_pool(actived_conv, ksize=[1,3,3,1], strides=[1,2,2,1], padding='SAME')

LeNet-5
Inception-v3

使用TensorFlow-Slim实现卷积层

with slim.arg_scope([slim.conv2d, slim.max_pool2d, slim.avg_pool2d], stride=1, padding='SAME'):
调用第一个参数的函数列表时,函数会自动使用默认的参数取值。

卷积神经网络迁移学习

迁移学习:将一个问题上训练好的模型通过简单的调整使其适用于一个新的问题。


TensorFlow图像处理

1. 图像编码处理

将图片还原成三维矩阵,需要进行解码。

解码

读取图像并解码

image_raw_data = tf.gfile.FastGFile("../../datasets/cat.jpg",'r').read()

with tf.Session() as sess:
    img_data = tf.image.decode_jpeg(image_raw_data)
    
    # 输出解码之后的三维矩阵。
    print img_data.eval()

可视化图像

with tf.Session() as sess:
    plt.imshow(img_data.eval())
    plt.show()
编码
img_data = tf.image.convert_to_dtype(img_data, dtype=tf.float32)
encoded_image = tf.image.encode_jpeg(img_data)
with tf.gfile.GFile("/path/to/output", "wb") as f:
  f.write(encoded_image.eval())
2.图像大小调整
普通插值调整
with tf.Session() as sess:    
    resized = tf.image.resize_images(img_data, [300, 300], method=0)
method参数取值
对图像裁剪或填充
croped = tf.image.resize_image_with_crop_or_pad(img_data, 1000, 1000)
padded = tf.image.resize_image_with_crop_or_pad(img_data, 3000, 3000)
通过比例调整

截取中间50%

with tf.Session() as sess:   
    central_cropped = tf.image.central_crop(img_data, 0.5)
    plt.imshow(central_cropped.eval())
    plt.show()
裁剪或填充给定区域的图像
tf.image.crop_to_bounding_box
tf.image.pad_to_bounding_box
3.图像翻转
with tf.Session() as sess: 
    # 上下翻转
    flipped1 = tf.image.flip_up_down(img_data)
    # 左右翻转
    flipped2 = tf.image.flip_left_right(img_data)
    
    #对角线翻转
    transposed = tf.image.transpose_image(img_data)
    plt.imshow(transposed.eval())
    plt.show()
    
    # 以一定概率上下翻转图片。
    flipped = tf.image.random_flip_up_down(img_data)
    # 以一定概率左右翻转图片。
    flipped = tf.image.random_flip_left_right(img_data)
4.图像色彩调整

(1)亮度

with tf.Session() as sess:     
    # 将图片的亮度-0.5。
    adjusted = tf.image.adjust_brightness(img_data, -0.5)
    
    # 将图片的亮度-0.5
    adjusted = tf.image.adjust_brightness(img_data, 0.5)
    
    # 在[-max_delta, max_delta)的范围随机调整图片的亮度。
    adjusted = tf.image.random_brightness(img_data, max_delta=0.5)

(2)对比度

 # 将图片的对比度-5
    adjusted = tf.image.adjust_contrast(img_data, -5)
    
    # 将图片的对比度+5
    adjusted = tf.image.adjust_contrast(img_data, 5)
    
    # 在[lower, upper]的范围随机调整图的对比度。
    adjusted = tf.image.random_contrast(img_data, lower, upper)

(3)色相

 adjusted = tf.image.adjust_hue(img_data, 0.1)
 # 在[-max_delta, max_delta]的范围随机调整图片的色相。max_delta的取值在[0, 0.5]之间。
 adjusted = tf.image.random_hue(image, max_delta)

(4)饱和度

# 将图片的饱和度-5。
adjusted = tf.image.adjust_saturation(img_data, -5)
# 将图片的饱和度+5。
adjusted = tf.image.adjust_saturation(img_data, 5)
# 在[lower, upper]的范围随机调整图的饱和度。
adjusted = tf.image.random_saturation(img_data, lower, upper)

(5)自动图像标准化

# 将代表一张图片的三维矩阵中的数字均值变为0,方差变为1。
adjusted = tf.image.per_image_whitening(img_data)
5.处理标注框

tf.image.draw_bounding_boxes(batched, boxes)
batched:一batch的数据,多张图像组成的四维矩阵。
在只有单张图像时,需要将解码之后的图像矩阵加一维。
batched = tf.expand_dims(tf.image.convert_iamge_dtype(img_data, tf.float32), 0)
boxes:标注框集合,一个标注框有四个数字[ymin, xmin, ymax, xmax]。
boxes = tf.constant([[[0.05, 0.05, 0.9, 0.7], [0.35, 0.47, 0.5, 0.56]]])

添加标注框并裁剪

with tf.Session() as sess:         

    boxes = tf.constant([[[0.05, 0.05, 0.9, 0.7], [0.35, 0.47, 0.5, 0.56]]])

    begin, size, bbox_for_draw = tf.image.sample_distorted_bounding_box(
        tf.shape(img_data), bounding_boxes=boxes)

    batched = tf.expand_dims(tf.image.convert_image_dtype(img_data, tf.float32), 0) 
    image_with_box = tf.image.draw_bounding_boxes(batched, bbox_for_draw)
    
    distorted_image = tf.slice(img_data, begin, size)
    plt.imshow(distorted_image.eval())
    plt.show()

多线程输入数据处理框架

流程图

队列与多线程

队列操作

q = tf.FIFOQueue(2, "int32")
init = q.enqueue_many(([0, 10],))
x = q.dequeue()
y = x + 1
q_inc = q.enqueue([y])
with tf.Session() as sess:
    init.run()
    for _ in range(5):
        v, _ = sess.run([x, q_inc])
        print v

FIFOQueue 先进先出
RandomShuffleQueue 随机元素出队

在TensorFlow中,队列不仅仅是一种数据结构,还是异步计算张量取值的一个重要机制。

Tensorflow提供了两个类来完成多线程协同的功能。

1.tf.Coordinator

用于协同多个线程一起停止,提供了should_stop、request_stop和join三个函数。

2.tf.QueueRunner

用于启动多个线程来操作同一个队列。
Holds a list of enqueue operations for a queue, each to be run in a thread.

使用tf.train.QueueRunner时,需要明确调用tf.train.start_queue_runners来启动所有线程。
queue = tf.FIFOQueue(100,"float")
enqueue_op = queue.enqueue([tf.random_normal([1])])
#[enqueue_op * 5]表示需要启动5个线程,每个线程运行enqueue操作
qr = tf.train.QueueRunner(queue, [enqueue_op] * 5)
tf.train.add_queue_runner(qr)
out_tensor = queue.dequeue()
with tf.Session() as sess:
    coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(sess=sess, coord=coord)
    for _ in range(3): print sess.run(out_tensor)[0]
    coord.request_stop()
    coord.join(threads)

输入文件队列

1. tf.train.match_filenames_once

获取符合一个正则表达式的所有文件
使用这个函数,需要在session中初始化变量
tf.global_variables_initializer().run()

2. tf.train.string_input_producer

使用初始化时提供的文件列表创建一个输入队列,输入队列中原始元素为列表中的所有文件。

files = tf.train.match_filenames_once("Records/data.tfrecords-*")
filename_queue = tf.train.string_input_producer(files, shuffle=False)

例子

1、获取文件列表
files = tf.train.match_filenames_once("Records/data.tfrecords-*")
2、创建输入队列
filename_queue = tf.train.string_input_producer(files, shuffle=False)
3、读取并解析样本

reader = tf.TFRecordReader()
_, serialized_example = reader.read(filename_queue)

4、在session中声明coordinator类来协同不同线程,并启动线程

 coord = tf.train.Coordinator()
    threads = tf.train.start_queue_runners(sess=sess, coord=coord)

组合训练数据(batching)

1. tf.train.batch

example_batch, label_batch = tf.train.batch([example, label], batch_size=batch_size, capacity=capacity)

2. tf.train.shuffle_batch

不同线程读取同一个文件。
example_batch, label_batch = tf.train.shuffle_batch([example, label], batch_size=batch_size, capacity=capacity, min_after_dequeue=30)
min_after_dequeue参数提供了限制出队时最少元素的个数来保证随机打乱顺序的作用。

3. tf.train.shuffle_batch_join

从输入文件队列中获取不同文件分配给不同线程。

循环神经网络

主要用于处理和预测序列数据。
循环神经网络的总损失为所有时刻上的损失函数的总和。

LTSM(长短时记忆网络)

定义基本的lstm:
lstm = tf.contrib.rnn.BasicLSTMCell(lstm_hidden_size)
设置全为0的初始状态:
state = lstm.zero_state(batch_size, tf.float32)
每一步处理时间序列的一个时刻:
lstm_output, state = lstm(current_input, state)

bi RNN(双向循环神经网络)

deep RNN(深层循环神经网络)

# 定义使用LSTM结构及训练时使用dropout。
lstm_cell = tf.contrib.rnn.BasicLSTMCell(HIDDEN_SIZE)
if is_training:
lstm_cell = tf.contrib.rnn.DropoutWrapper(lstm_cell, output_keep_prob=KEEP_PROB)
cell = tf.contrib.rnn.MultiRNNCell([lstm_cell]*NUM_LAYERS)
        
# 初始化最初的状态。
self.initial_state = cell.zero_state(batch_size, tf.float32)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容

  • 简单线性回归 import tensorflow as tf import numpy # 创造数据 x_dat...
    CAICAI0阅读 3,534评论 0 49
  • 这篇文章是针对有tensorflow基础但是记不住复杂变量函数的读者,文章列举了从输入变量到前向传播,反向优化,数...
    horsetif阅读 1,151评论 0 1
  • 每日复盘 Objective 你对今天学的记得什么? 想做一件事决定好了就不要犹豫,不要左顾右盼坚定信心奋力前行 ...
    露易司董董董小姐阅读 204评论 0 0
  • 玉枝镜湖水晶宫, 羞梅初绽别样红。 如若此生能恣意, 便随风雪到桥东。
    拘影裁绳阅读 221评论 0 1