机器学习——tensorflow笔记

使用的TF前需要明白:
TF使用Graph计算任务,在Session上下文中执行Graph,使用tensor表示数据,通过variable维护状态,使用feed,fetch为任意操作赋值或获取数据。
图中的节点被称之为 op (operation),一个 op获得 0 个或多个 Tensor , 执行计算, 产生 0 个或多个 Tensor . 每个 Tensor 是一个numpy ndarray类型化的多维数组.
TensorFlow 将图形定义转换成分布式执行的操作, 以充分利用可用的计算资源(如 CPU 或 GPU). 一般不需要显式指定使用 CPU 还是 GPU, TensorFlow 能自动检测. 如果检测到 GPU, TensorFlow 会尽可能地利用找到的第一个 GPU 来执行操作.
程序通常包括一个构建阶段和一个执行阶段. 在构建阶段, op 的执行步骤被描述成一个图来表示和训练神经网络. 在执行阶段, 使用会话执行执行图中的 op.Tensorflow依赖于一个高效的C++后端来进行计算,与后端的这个连接叫做session。
格式如下:
      import tensorflow as tf
      构建图:各种op
      执行会话:启动(sess = tf.Session());执行(sess.run());关闭(sess,close()).
feed 使用一个 tensor 值临时替换一个操作的输出结果: sess.run([output], feed_dict={input1:[7.], input2:[2.]}),tf.placeholder() 为这些操作创建占位符.
变量初始化:变量需要通过seesion初始化后,才能在session中使用。这一初始化步骤为sess.run(tf.initialize_all_variables()),为初始值指定具体值,并将其分配给每个变量 ,可以一次性为所有变量完成此操作。
计算交叉熵:对于分类问题,cross_entropy = -tf.reduce_sum(y_*tf.log(y))表示所有图片目标类别和预测类别之间的交叉熵的和,一般情况下y_对应的那个label为1其余为0,假设有N个图片,yci为第i个图片预测为正确类别的概率,则交叉熵为-\sum_N^i\textup{log} y_{ci}=-log(y_{c1}y_{c2}...y_{ci}...y_{cN})即所有图片预测正确概率的积的负log值。最后预测类别的准确率计算为 argmax(yi)= label(y_)时, corr+=1, 正确率为corr/number*100.
优化算法
a.tf.train.GradientDescentOptimizer()使用随机梯度下降算法,使参数沿着梯度的反方向,即总损失减小的方向移动实现更新参数
tf.train.GradientDescentOptimizer(learning_rate, use_locking=False,name=’GradientDescent’)
learning_rate: 要使用的学习率use_locking: 要是True的话,就对于更新操作update operations使用锁
name: 名字,可选,默认是”GradientDescent”
函数有:minimize() 函数处理了梯度计算和参数更新两个操作;compute_gradients() 函数用于获取梯度;apply_gradients() 用于更新参数
b. tf.train.MomentumOptimizer()在更新参数时,利用了超参数,参数更新公式是d_i=\beta d_{i-1}+g(\theta_{i-1}); \theta_i=\theta_{i-1}-\alpha d_i.其中,?为学习率,超参数为?,?为参数,?(??−1 )为损失函数的梯度
tf.train.MomentumOptimizer(learning_rate,momentum,use_locking=False,use_nesterov=False,name='Momentum')
learning_rate: (学习率)张量或者浮点数;momentum: (动量)张量或者浮点数;use_locking: 为True时锁定更新;
use_nesterov:  为True时,使用 Nesterov Momentum;name:  梯度下降名称,默认为 "Momentum"
c.tf.train.AdamOptimizer()是利用自适应学习率的优化算法,Adam 算法和随 机梯度下降算法不同。随机梯度下降算法保持单一的学习率更新所有的参数,学 习率在训练过程中并不会改变。而 Adam 算法通过计算梯度的一阶矩估计和二 阶矩估计而为不同的参数设计独立的自适应性学习率。
tf.train.AdamOptimizer(learning_rate=0.001,beta1=0.9,beta2=0.999,epsilon=1e-08,use_locking=False,name='Adam')
Adam 这个名字来源于自适应矩估计Adaptive Moment Estimation),也是梯度下降算法的一种变形,但是每次迭代参数的学习率都有一定的范围,不会因为梯度很大而导致学习率(步长)也变得很大,参数的值相对比较稳定。
Adam 算法利用梯度的一阶矩估计和二阶矩估计动态调整每个参数的学习率。TensorFlow提供的tf.train.AdamOptimizer可控制学习速度,经过偏置校正后,每一次迭代学习率都有个确定范围,使得参数比较平稳。
learning_rate: 学习率, beta1:  一阶矩估计的指数衰减率,beta2:  二阶矩估计的指数衰减率
epsilon: 数值稳定性的一个小常数,  use_locking: 为True时锁定更新,name:  梯度下降名称,默认为 "Adam"
类别预测:把向量化后的图片x和权重矩阵W相乘加上偏置b,计算每个分类的softmax概率值y = tf.nn.softmax(tf.matmul(x,W) + b)
评估模型性能: correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1)),accuracy = tf.reduce_mean(tf.cast (correct_prediction, "float"))
网络构建:卷积-池化层-->卷积-池化层 --> 全连接层--> dropout层 --> softmax输出层
第一个卷积-池化层 (初始化w,b再利用初始化参数进行卷积和池化)
with tf.variables_scope("conv1") as scope:
    weight=tf.get_variable("weights",shape,dtype,initializer)
    bias=tf.get_variable("biases",shape,dtype,initializer)
    conv=tf.nn.conv2d(images.kernel,strides, padding,name)
    conv1 = tf.nn.relu(tf.nn.bias_add(conv,bias),name=scope.name)
pool1=tf.nn.max_pool(conv1,ksize,strides,padding,name)
第二个卷积-池化层
with tf.variables_scope("conv2") as scope:
    weight=tf.get_variable("weights",shape,dtype,initializer)
    bias=tf.get_variable("biases",shape,dtype,initializer)
    conv=tf.nn.conv2d(images.kernel,strides, padding,name)
    conv2 = tf.nn.relu(tf.nn.bias_add(conv,bias),name=scope.name)
pool2=tf.nn.max_pool(conv2,ksize,strides,padding,name)
全连接层
with tf.variables_scope("local3") as scope:
     reshape = tf.reshape(pool2, [batch_size, -1])
     dim = reshape.get_shape()[1].value
     weight=tf.get_variable("weights",shape=[dim,n1],dtype,initializer)
     bias=tf.get_variable("biases",shape=[n1],dtype,initializer)
     fc1=tf.nn.relu(tf.matmul(reshape,weight)+bias,name=scope,name)
dropout层(可选)
keep_prob = tf.placeholder("float")
fc1_drop = tf.nn.dropout(fc1, keep_prob)
softmax输出层
with tf.variables_scope("softmax_linear") as scope:
     weight=tf.get_variable("weights",shape=[n1,n_classes],dtype,initializer)
     bias=tf.get_variable("biases",shape=[n_classes],dtype,initializer)
    softmax_linear=tf.add(tf.matmul(fc1,weight),bias,name=scope.name)
一个标准CNN训练测试的举例
1.训练/测试数据库预处理
1.1 获取图像和标签: get_files():如果从本地图片库中导入数据,  read_files(): 使用网上数据库
1.2 对图片进行裁减、翻转等操作:distorted_pic()
1.3 获取批量大小(batch_size)的图像数据和标签:get_batch()
2.构建阶段
2.1 网络构建函数: inference(): conv1-pool1-conv2-pool2-full1-full2-softmax,return logits
2.2 训练用的损失函数:loss(logits,labels)
2.3 实时监测验证数据准确率函数:evaluation()
3.训练阶段
sess=tf.Session()
对于每次step:计算损失率、优化损失率、计算训练结果。
通过tf的优化器(tf.train.GradientDescentOptimizer,tf.train.AdamOptimizer等)使损失率最小,
每隔一定的step,使用saver=tf.train.Saver()保存参数,saver.save(sess,checkpoint_path,global_step=step)
sess.close()
4.测试阶段 (通常是一个单独文件)
4.1获取图片并对图片进行预处理
4.2建立sess和saver,判断是否有网络训练模型的设置tf.train.get_checkpoint_state(dir)
4.3加载训练好的网络模型saver.restore(sess,ckpt.model_checkpoint_path)
4.4恢复模型数据后,计算图片的logits=tf.nn.softmax(inference(image)),并取出最大值对应索引,即为测试结果

Tensorflow中的一些常用函数
tf.nn.conv2d (input, filter, strides, padding, use_cudnn_on_gpu=None, data_format=None, name=None)
input : 输入的要做卷积的图片,shape为 [batch, height, weight, channel],其中batch为图片的数量,height为图片高度,weight为图片宽度,channel为图片的通道数,灰度图该值为1,彩色图为3。
filter: 卷积核,也是一个张量,shape为[filter_height, filter_weight, in_channel, out_channels],其中 filter_height,filter_weight为卷积核高度和宽度,in_channel 是图像通道数 ,和 input的in_channel 要保持一致,out_channel 是卷积核数量。[filter_height, filter_weight ,in_channel]与image的[height, weight, channel]相乘,最终输出尺寸[batch,fheigh,fweight,out_channels]
strides: 卷积时在图像每一维的步长,这是一个一维的向量,[ 1, strides, strides, 1],第一位和最后一位固定必须是1.
padding: string类型,值为“SAME” 和 “VALID”,表示的是卷积的形式,是否考虑边界。"SAME"是考虑边界,不足的时候用0去填充周围,"VALID"则不考虑.
use_cudnn_on_gpu: bool类型,是否使用cudnn加速,默认为true.
卷积后图片大小计算公式:N=(W-F+2P)/S+1, W图片尺寸,F卷积核大小,S步长,P零填充数
tf.nn.max_pool
(value,ksize,strides,padding,name=None)参数是四个,和卷积很类似:
value:需要池化的输入,一般为卷积结果,[batch, height, width, channels]这样的shape
ksize:池化窗口的大小,一般是[1, height, width, 1],因为不想在batch和channels上做池化,所以这两个维度设为了1
strides:和卷积类似,窗口在每一个维度上滑动的步长,一般也是[1, stride,stride, 1]
padding:和卷积类似,可以取'VALID'或者'SAME',返回一个Tensor,shape仍然是[batch, height, width, channels]这种形式
最终输出的尺寸为[batch,pheigh,pweight,out_channels],可见,卷积可以改变通道数,而池化只改变图片大小。。
池化后图片大小计算公式:N=(W-F)/S+1
tf.nn.relu
(features, name = None) 作用是计算激活函数relu,即max(features, 0)将大于0的保持不变,小于0的数置为0,一般与卷积连用,features是(卷积核,图像)的卷积后加上bias。线性整流函数(Rectified Linear Unit, ReLU),又称修正线性单元,是一种人工神经网络中常用的激活函数(activation function),通常指代以斜坡函数及其变种为代表的非线性函数。

图片处理函数
tf.image.resize_images(image,[height,width,3],method)调整图像的大小,大变小,小变大
tf.image.resize_image_with_crop_or_pad()裁减,小截部分大填充0
tf.random_crop(image,[height,width,3])随机裁减,把大图片裁减成小图片
tf.image.random_flip_left_right()随机水平翻转
tf.image.random_brightness()在某范围内随机调整图片亮度
tf.image.random_contrast()在某范围内随机调整图片对比度
tf.image.per_image_standardization()对图像进行标准化
tf.image.non_max_suppression()删除掉那些与之前的选择的边框具有很高的IOU的边框
交叉熵计算数:tf.nn.sparse_softmax_cross_entropy_with_logits(_sentinel=None,labels=None,logits=None,name=None)将softmax和cross_entropy放在一起计算,对于分类问题而言,最后一般都是一个单层全连接神经网络,比如softmax分类器居多,对这个函数而言,tensorflow神经网络中是没有softmax层,而是在这个函数中进行softmax函数的计算。这里的logits通常是最后的全连接层的输出结果,labels是具体哪一类的标签,这个函数是直接使用标签数据的,而不是采用one-hot编码形式。

从队列中读取数据函数:tf.train.batch与tf.train.shuffle_batch
tf.train.batch() 按顺序读取队列中的数据,队列中的数据始终是一个有序的队列.队头一直按顺序补充,队尾一直按顺序出队.
    tensors:排列的张量或词典.
    batch_size:从队列中提取新的批量大小.
    num_threads:线程数量.若批次是不确定 num_threads > 1.
    capacity:队列中元素的最大数量.
    enqueue_many:tensors中的张量是否都是一个例子.
    shapes:每个示例的形状.(可选项)
    dynamic_pad:在输入形状中允许可变尺寸.
    allow_smaller_final_batch:为True时,若队列中没有足够的项目,则允许最终批次更小.(可选项)
    shared_name:如果设置,则队列将在多个会话中以给定名称共享.(可选项)
    name:操作的名称.(可选项)
如队列的capacity=20,开始队列内容为0,1,..,19=>读取10条记录后,队列剩下10,11,..,19,然后又补充10条变成=>10,11,...,29,
队头一直按顺序补充,队尾一直按顺序出队,到了第100条记录后,又重头开始补充0,1,2...
若enqueue_many为False,则认为tensors代表一个示例.输入张量形状为[x, y, z]时,则输出张量形状为[batch_size, x, y, z].
若enqueue_many为True,则认为tensors代表一批示例,其中第一个维度为示例的索引,并且所有成员tensors在第一维中应具有相同大小.若输入张量形状为[*, x, y, z],则输出张量的形状为[batch_size, x, y, z].
tf.train.shuffle_batch() 将队列中数据打乱后再读取出来.函数是先将队列中数据打乱,然后再从队列里读取出来,因此队列中剩下的数据也是乱序的.
    min_after_dequeue-出队后队列中元素的最小数量,确保元素的混合级别.一般设置capacity=min_after_dequeue+3*batch_size
    seed:队列内随机乱序的种子值.
其他与tf.train.batch()类似。
这种按batch读取的,最后会自动在前面添加一个维度,比如数据的维度是[1],batch_size是10,那么读取出来的shape就是[10,1].
模型的保存与恢复函数tf.train.Saver()
保存模型:先要创建一个Saver对象:如saver=tf.train.Saver(),它有一个参数 max_to_keep,这个是用来设置保存模型的个数,默认为5,即 max_to_keep=5,保存最近的5个模型。
保存每一次训练:可以将 max_to_keep设置为None或者0。
保存最后一代: max_to_keep=1,保存最后一代的模型。
创建完saver对象后,就可以保存训练好的模型saver.save(sess,'ckpt/mnist.ckpt',global_step=step),第二个参数设定保存的路径和名字,第三个参数将训练的次数作为后缀加入到模型名字中。
保存精度最高:
      saver=tf.train.Saver(max_to_keep=1) 
      max_acc=0
      for i in range(maxstep):
             val_loss,val_acc=sess.run(........)
             if val_acc>max_acc:
                 max_acc=val_acc
                 saver.save(sess,'ckpt/mnist.ckpt',global_step=i+1)
恢复模型:restore(sess, save_path),save_path指的是保存的模型路径。使用tf.train.latest_checkpoint()来自动获取最后一次保存的模型。saver.restore(sess,'ckpt.model_checkpoint_path'),ckpt.model_checkpoint_path:表示模型存储的位置,不需要提供模型的名字,它会去查看checkpoint文件,看看最新的是谁,叫做什么。
global_step=tf.Variable(0, trainable=False)
global_step是指图中看到的批次数量。每次提供一个批处理时,权重都会按照最小化损失的方向更新。global_step只是跟踪到目前为止看到的批数。当在minimum()参数列表中传递该变量时,该变量将增加1。查看optimizer. minimum(),你可以使用tf.train. global_step()获得global_step值。global_step的初始化值是0。global_step在训练中是计数的作用,每训练一个batch就加1。在滑动平均、优化器、指数衰减学习率等方面都有用到,这个变量的实际意义非常好理解:代表全局步数,比如在多少步该进行什么操作,现在神经网络训练到多少轮等等,类似于一个钟表。损失函数优化器的minimize()中global_step=global_steps能够提供global_step自动加一的操作。
tf.Variable是一个Variable类。通过变量维持图graph的状态,以便在sess.run()中执行;可以用Variable类创建一个实例在图中增加变量;initial_value:Tensor或可转换为Tensor的Python对象,它是Variable的初始值。除非validate_shape设置为False,否则初始值必须具有指定的形状。也可以是一个可调用的,没有参数,在调用时返回初始值。在这种情况下,必须指定dtype。
trainable:如果为True,则会默认将变量添加到图形集合GraphKeys.TRAINABLE_VARIABLES中。此集合用于优化器Optimizer类优化的的默认变量列表【可为optimizer指定其他的变量集合】,可就是要训练的变量列表。
collections:一个图graph集合列表的关键字。新变量将添加到这个集合中。默认为[GraphKeys.GLOBAL_VARIABLES]。也可自己指定其他的集合列表;
tf.get_variable(name,shape,dtype,initializer,regularizer,trainable,collections,caching_device,partitioner,validate_shape,use_resource,custom_getter,constraint)用它来获取weights,biases的初始值
name:变量的名称。
shape:变量的形状。
dtype:变量的类型(默认为DT_FLOAT)。
ininializer:如果创建了则用它来初始化变量。
初始化的方式有以下几中:
tf.constant_initializer:常量初始化函数
tf.random_normal_initializer:正态分布
tf.truncated_normal_initializer:截取的正态分布
tf.random_uniform_initializer:均匀分布
tf.zeros_initializer:全部是0
tf.ones_initializer:全是1
tf.reduce_mean(input_tensor,axis=None,keep_dims=False,name=None)用于计算张量tensor沿着指定的数轴(tensor的某一维度)上的的平均值,主要用作降维或者计算tensor(图像)的平均值。input_tensor: 输入的待降维的tensor;  axis: 指定的轴,如果不指定,则计算所有元素的均值; keep_dims:是否降维度,设置为True,输出的结果保持输入tensor的形状,设置为False,输出结果会降低维度,name: 操作的名称。

****************************本文参考《tensorflow官方文档》等

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值