Tensorflow的应用(三)

         主要是两部分内容:代价函数和优化器

一、代价函数

1、二次代价函数

      二次代价函数计算公式如下:

                         

       其中,其中, C表示代价 函数 ,x表示样本, y表示实际值, 表示实际值, 表示实际值, a表示输出值, 表示输出值, n表示样本的总数。为简单起见 表示样本的总数。为简单起见 表示样本的总数。为简单起见 表示样本的总数。为简单起见 表示样本的总数。为简单起见 ,同样一个本为例进行说明,此时二次代价函数:


其中,a=σ(z), z=∑W a=σ(z), σ()是激活函数

       假如我们使用梯度下降法 (Gradient descent) (Gradient descent) (Gradient descent) (Gradient descent) (Gradient descent) 来调整权值 参数的大小,w和偏置 和偏置 b的梯度推导 的梯度推导 的梯度推导如下:

                                        

       其中, z表示神经元的输入, σ表示激活函数。 w和b的梯度跟激活函数成正比,梯度越大, w和b的大小调整得越快。

       假设我们的激活函数是sigmoid函数,假设目标值是求最小损失,离目标较远的时候,梯度下降速度较慢,离目标较近时,梯度下降较快,这是不合理的,所以在使用激活函数为sigmoid函数的情况下,二次代价函数不适合。

2、交叉熵代价函数

其公式如下所示:

                     

其中, C表示代价 函数 ,x表示样本, y表示实际值, a表示输出值, n表示样本的总数。





       权值和偏置值的调整与无关,另外,梯度公式中的表示输出值与实际值的误差。所以当误差越大时,梯度就越大,参数w和b的调整越快。如果输出神经元是线性的,那么二次代价函数就是一种合适的选择。如果输出神经元是S型函数,那么比较适合用交叉熵代价函数。

3、对数似然函数

        对数释然函常用来作为 softmax 回归的代价函数,如果输出层神经元是sigmoid函数,可以采用交叉熵代价函数,而深度学习中更普遍的做法是将softmax作为最后一层,此时常用的代价函数是对数似然代价函数。

       对数似然代价函数与softmax的组合和交叉熵与sigmoid函数的组合非常相似。对数似然代价函数在二分类时可以简化为交叉熵代价函数的形式。

        tf.sigmoid_cross_entropy_with_logits表示跟sigmoid搭配使用的交叉熵, tf.softmax_cross_entropy_with_logits表示跟softmax搭配使用的交叉熵

4、解决过拟合问题

(1)增加数据集

(2)正则化方法,有L1正则化和L2正则化,就是在代价函数中加入L1正则项和L2正则项,L1正则化是全部权重的绝对值平均,L2正则化是全部权重的均方,某些神经元的权重会被设置得特别小,甚至接近0,以减小过拟合情况。

(3)dropout方法,就是每次训练时,每层隐藏层只允许部分神经元工作。

二、优化器

1、Tensorflow的优化器如下:

tf.train.GradientDescentOptimizer
tf.train.AdadeltaOptimizer
tf.train.AdagradOptimizer
tf.train.AdagradDAOptimizer
tf.train.MomentumOptimizer
tf.train.AdamOptimizer
tf.train.FtrlOptimizer
tf.train.ProximalGradientDescentOptimizer
tf.train.ProximalAdagradOptimizer
tf.train.RMSPropOptimizer

2、各种优化器对比:
标准梯度下降法:
标准梯度下降先计算所有样本汇总误差,然后根据总误差来更新权值
随机梯度下降法:
随机梯度下降随机抽取一个样本来计算误差,然后更新权值
批量梯度下降法:
批量梯度下降算是一种折中的方案,从总样本中选取一个批次(比如一共有10000个样本,随机选取100个样本作为一个batch),然后计算这个batch的总误差,根据总误差来更新权值。

3、常用的几种优化器介绍

(1)SGD

W =W−η⋅∇WJ(W;x(i);y(i))

(2) Momentun

γ:动力,通常设置为0.9
vt = γvt−1 + η∇WJ(W)
W = W−vt
当前权值的改变会受到上一次权值改变的影响,类似于小球向下滚动的时候带上了惯性。这样可以加快小球的向下的速度。

(3)NAG

vt = γvt−1 + η∇WJ(W−γvt−1)
W = W−vt

       NAG在TF中跟Momentum合并在同一个函数tf.train.MomentumOptimizer中,可以通过参数配置启用。
在Momentun中小球会盲目地跟从下坡的梯度,容易发生错误,所以我们需要一个更聪明的小球,这个小球提前知道它要去哪里,它还要知道走到坡底的时候速度慢下来而不是又冲上另一个坡。γvt−1会用来修改W的值,计算W−γvt−1可以表示小球下一个位置大概在哪里。从而我们可以提前计算下一个位置的梯度,然后使用到当前位置。

(4)Adagrad

i:代表第i个分类
t:代表出现次数
ϵ:的作用是避免分母为0,取值一般为1e-8
η:取值一般为0.01
gt,i = ∇WJ(Wi)

它是基于SGD的一种算法,它的核心思想是对比较常见的数据给予它比较小的学习率去调整参数,对于比较罕见的数据给予它比较大的学习率去调整参数。它很适合应用于数据稀疏的数据集(比如一个图片数据集,有10000张狗的照片,10000张猫的照片,只有100张大象的照片)。
Adagrad主要的优势在于不需要人为的调节学习率,它可以自动调节。它的缺点在于,随着迭代次数的增多,学习率也会越来越低,最终会趋向于0。

(5)RMSprop

RMS(Root Mean Square)是均方根的缩写。
γ:动力,通常设置为0.9
η:取值一般为0.001
E[g2]t:表示前t次的梯度平方的平均值
gt= ∇WJ(W)
E[g2]t= γE[g2]t-1+ (1-γ)g
2t


       RMSprop借鉴了一些Adagrad的思想,不过这里RMSprop只用到了前t-1次梯度平方的平均值加上当前梯度的平方的和的开平方作为学习率的分母。这样RMSprop不会出现学习率越来越低的问题,而且也能自己调节学习率,并且可以有一个比较好的效果。

(6)Adadelta


使用Adadelta我们甚至不需要设置一个默认学习率,在Adadelta不需要使用学习率也可以达到一个非常好的效果。

(7) Adam:


就像Adadelta和RMSprop一样Adam会存储之前衰减的平方梯度,同时它也会保存之前衰减的梯度。经过一些处理之后再使用类似Adadelta和RMSprop的方式更新参数。

三、代码实例

      依然是tensorflow应用(二)中的手写识别字体的例子,但增加了dropout,改变了优化器。

import tensorflow as tf
from tensorflow.examples.tutorials.mnist import input_data


#载入数据集
mnist = input_data.read_data_sets("MNIST_data",one_hot=True)


#每个批次的大小
batch_size = 100
#计算一共有多少个批次
n_batch = mnist.train.num_examples // batch_size


#定义两个placeholder
x = tf.placeholder(tf.float32,[None,784])
y = tf.placeholder(tf.float32,[None,10])
keep_prob=tf.placeholder(tf.float32)


#创建一个简单的神经网络
W1 = tf.Variable(tf.truncated_normal([784,2000],stddev=0.1))
b1 = tf.Variable(tf.zeros([2000])+0.1)
L1 = tf.nn.tanh(tf.matmul(x,W1)+b1)
L1_drop = tf.nn.dropout(L1,keep_prob) #使用dropout解决过拟合


W2 = tf.Variable(tf.truncated_normal([2000,2000],stddev=0.1))
b2 = tf.Variable(tf.zeros([2000])+0.1)
L2 = tf.nn.tanh(tf.matmul(L1_drop,W2)+b2)
L2_drop = tf.nn.dropout(L2,keep_prob) 


W3 = tf.Variable(tf.truncated_normal([2000,1000],stddev=0.1))
b3 = tf.Variable(tf.zeros([1000])+0.1)
L3 = tf.nn.tanh(tf.matmul(L2_drop,W3)+b3)
L3_drop = tf.nn.dropout(L3,keep_prob) 


W4 = tf.Variable(tf.truncated_normal([1000,10],stddev=0.1))
b4 = tf.Variable(tf.zeros([10])+0.1)
prediction = tf.nn.softmax(tf.matmul(L3_drop,W4)+b4)


#二次代价函数
# loss = tf.reduce_mean(tf.square(y-prediction))
loss = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(labels=y,logits=prediction))#交叉熵代价函数
#使用梯度下降法
#train_step = tf.train.GradientDescentOptimizer(0.2).minimize(loss)
train_step = tf.train.AdamOptimizer(1e-2).minimize(loss)#使用adam优化器


#初始化变量
init = tf.global_variables_initializer()


#结果存放在一个布尔型列表中
correct_prediction = tf.equal(tf.argmax(y,1),tf.argmax(prediction,1))#argmax返回一维张量中最大的值所在的位置
#求准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))


with tf.Session() as sess:
    sess.run(init)
    for epoch in range(31):

            sess.run(tf.assign(lr, 0.001 * (0.95 ** epoch)))#一开始赋予比较高的学习率,当其越来越接近最低点的时候,降低其学习率,防止其在最低点震荡。
        for batch in range(n_batch):
            batch_xs,batch_ys = mnist.train.next_batch(batch_size)
            sess.run(train_step,feed_dict={x:batch_xs,y:batch_ys,keep_prob:0.7})
        learning_rate = sess.run(lr)
        test_acc = sess.run(accuracy,feed_dict={x:mnist.test.images,y:mnist.test.labels,keep_prob:1.0})
        train_acc = sess.run(accuracy,feed_dict={x:mnist.train.images,y:mnist.train.labels,keep_prob:1.0})
        print("Iter " + str(epoch) + ",Testing Accuracy " + str(test_acc) +",Training Accuracy " + str(train_acc)+",Learning Rate= " + str(learning_rate))


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值