TensorFlow渐进学习《一》----第一个TensorFlow例子

题外话

学习TensorFlow想必是每一个机器学习爱好者从业者的一门必修课。从考研结束到现在3个多月的时间我拜读周志华教授、Ian等大家的机器学习圣书后,总觉得书上得来总觉浅。加上理论懂了个大概,也能够理解到工程上的一些操作的必要性,或者说能够有查阅资料的方向了。决定开始学习TensorFlow以期望利用平台特性快捷灵活的实现任务。
TensorFlow的官网上给出了多个简单例子,但我觉得还不够的简单。所以为了查看某些特性,我会自己写一些小例子,验证猜想。TenorFlow学习加法源码

结论:

  1. Q:Tensors和variable的区别?
    A:输入数据不需要训练,使用占位符placeholder,const表示的tensor.w,b都是需要训练的参数,所以使用变量variable。

  2. Q:参数更新的流程?
    使用tensor编程计算图,使用优化器optimizer最小化loss。如梯度下降优化器会计算参与的导数,乘上学习率作为参数的变化量,自动更新loss所涉及的variable型变量。

  3. Q:数据是否需要正则化?
    学习过程中为了避免大数乘法、或者不同维参数数量级相差太大,我们都应该对数据进行正则化。

    4.Q: 学习率改怎样设置?
    在参数正则化后学习率一般设置为0.1。但是我觉得学习率的设置和输入规模是有关系的,目的是让梯度的变化粒度小于期望参数多个数量级会比较好。但是小的越多,收敛速度越慢。

训练模型

为专注了解测试TensorFlow的特性,使用最简单的线性模型来习得加法。输入数据为Xi=[xi1,xi2],标签:Yi=xi1+xi2。预测结果p_y=Wx+b。使用欧式距离表示损失:loss = (Wx+b-Yi)**2。

#简单的线性函数y=wx+b
#损失函数使用简单的欧式距离
y_out = tf.matmul(trainIput,w)+b
loss = tf.reduce_sum((y_out-trainLabel)**2) #reduce_sum当数据为批量的时候才起作用,计算一个向量的元素和。

基本类型

在TensorFlow中使用Tensors来表达向量和矩阵。

A tensor is a generalization of vectors and matrices to potentially higher dimensions

Tensors有多种类型,tf.constant、tf.placeholder、tf.Variable等,我们将在以下的替代中用到。
tf.constant对应于编程语言中的常量 ,在训练当中不可以改变。与之相对应的则为tf.Variable,它的值可以多个session的中重复被使用,默认相当于全局变量,当然你可以设置起作用域。

A TensorFlow variable is the best way to represent shared, persistent state manipulated by your program. A tf.Variable represents a tensor whose value can be changed by running ops on it.

简而言之,就是需要训练的参数使用tf.Variable表示,不需要训练的输入可以使用tf.constant表示。

#输入数据不需要训练,使用占位符placeholder表示的tensor,用于接受feeddict的数据。
trainIput = tf.placeholder(tf.float32,shape=[batch_size,2])
trainLabel = tf.placeholder(tf.float32,shape=[batch_size])

#w,b都是需要训练的参数,所以使用变量variable。默认初始化,每次计算都会更新此变量
w = tf.get_variable("wights",dtype=tf.float32,shape=[2,1])
b = tf.get_variable("bias",[batch_size,1],dtype=tf.float32)

优化器

我们得到了损失函数后,我们的目标就是习得w、b以最小化loss。tf提供了梯度递减优化器GradientDescentOptimizer来最小化loss。

#使用梯度下降来最优化loss,设置参数为学习率为0.1。
with tf.name_scope("optimizer"):
    optimizer = tf.train.GradientDescentOptimizer(0.1).minimize(loss)

数据模拟

设置range_random=(0,10) 随机产生模拟数据的范围,之后我们会增大范围观察拟合情况。

#生成模拟数据,x1,x2,y,其中y=x1+x2
def generaate_data(size,isNormal):

    for i in  range(size):
        x1 = random.randint(range_random)
        x2 = random.randint(range_random)
        if isNormal:
            x1=x1/range_random[1]
            x2=x2/range_random[1]
        y = x1 + x2
        xlist.append([x1,x2])
        ylist.append(y)

运行计算图

这里用到了sess.run()函数,两个常用参数为数组类型的fetch和feed_dict。fetch中包含我们需要计算的Variable型变量,则返回对应的结果。我们首先的要执行优化器optimizer,则已经足以完成训练任务了。传入后面的w,b,y_out则是为了观察训练数据变化。

    for i in range(num_steps):
        batch_inputs,batch_label = generate_batch(batch_size,i*batch_size)
        feed_dict = {trainIput:batch_inputs,trainLabel:batch_label}
        #我们需要观察w,b的值变化,所以讲w,b传入fetch中并返回为wr,br。
        _, lossr,wr,br,y_outr= sess.run([optimizer,loss,w,b,y_out],feed_dict=feed_dict)

训练分析

config1:拟合10以内的加法,参数配置:range_random=(0,10),lr=0.1

抽取部分运行结果:

loss=1.759128
loss=89.073334
loss=178533.062500
loss=64864305501175808.000000
loss=287426062692858948260170863477138653184.000000
loss=inf
loss=nan

可以看到损失函数越来越大,为发散状态这是为什么呢?猜测为学习率过大调小lr=0.01

config2:拟合10以内的加法,参数配置:range_random=(0,10),lr=0.01

抽取部分运行结果:

loss=6.463652
loss=0.570989
loss=0.325448
loss=0.000063
loss=0.000000
end at 1460

可以看到在1460次训练后,损失函数收敛到了最小值。这说明学习率要足够的。

config3:拟合100以内的加法,参数配置:range_random=(0,100),lr=0.01或者 lr=0.001

抽取部分运行结果:

loss=4042.668945
loss=inf

无法拟合!

config4:拟合100以内的加法,参数配置:range_random=(0,100),lr=0.0001

loss=8552.422852
loss=0.009713
loss=0.022158
loss=0.001590
end at 3817

从congfig1、2、3、4、可以看出学习率和输入的规模是有关系的,输入规模越大则学习率应该越小。

config5:拟合100以内的加法,参数配置:range_random=(0,100),lr=0.0001,去掉线性模型中的偏差

#简单的线性函数y=wx
y_out = tf.matmul(trainIput,w)

运行效果:

loss=4301.073730
end at 94

只运行了94次,这说明4中训练缓慢是由b造成的。分析一下w、b的梯度下降过程:

若对w求导则,w’= 2(wx+b-y)*x 则更新后的update_w=lr*w’。对b求导:b=2(wx+b-y) update_b=lr*b’。可以看出如果x越大,则update_b比update_w小的更多。当update_w更新粒度合适时,update_b会小很多。所以我们应当减少w和b的差距,可以设置不同的学习率。问题来啦,在TensorFlow中怎样为不同的参数设置学习率?

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值