一般神经网络的训练过程可分为两个阶段:第一阶段先通过前向传播算法计算得到预测值,并将预测值和真实值做对比,得出两者之间的距离;第二个阶段,通过反向传播算法计算损失函数对每一个参数的梯度,再根据梯度和学习率使用梯度下降算法更新每一个参数。

1. 基于梯度的优化

基于梯度的优化就是优化一个函数的最终取值,假设 x 是函数的输入参数,J(x) 是需要优化的函数,则基于梯度的优化就是改变 x 的值得到最小化或最大化的 J(x) (通常是最小化J(x),最大化可经由最小化算法 最小化 -J(x) 来实现)。

在具体的深度神经网络的设计中, J(x) 通常指网络在训练数据集上的损失函数,x 泛指神经网络的参数。使用梯度下降优化网络的大概思路就是寻找一个参数 x ,使得损失函数 J(x) 的值最小。 学习率  (Learning Rate,就相当于对输入所作的一个微小的变化)来定义每次参数更新的幅度。

学习率可以值观的理解为每次参数移动的幅度,通过计算函数在  处的梯度以及设定的学习率就能得到以下的参数更新公式:

如果损失函数非常复杂,比如含有许多不是最有的全局极小点,或者存在多个局部极小点等都将使我们的优化变得十分困难。因此,我们通常寻找使 J(x) 非常小的点,将这一点作为一个近似的最小点。对于一个深度学习任务,即使找到的点不是最优的点,但只要他们显著低于损失函数的绝大部分值,我们就能够接受这样的解。同时,梯度下降算法的计算时间太长,在实际训练时,参与训练的数据往往很多,并且损失函数 J(x) 是在所有训练数据上的损失和,这样计算速度太慢。

2. 随机梯度下降

加快每一轮参数更新的速度可以使用随机梯度下降算法(SGD),其优点在于并不会对全部训练数据上的损失函数进行优化,而是在每一轮迭代中随机选择某一个或多个训练数据上的损失函数进行梯度下降优化。

随机梯度下降算法也存在某些问题,即在某些训练数据上损失函数更小并不代表在全部训练数据上损失函数更小。为保持平衡梯度下降算法和随机梯度下降算法的性能,在实际应用中一般会每次计算一小部分训练数据的总损失函数,这一小部分数据就是一个batch。使用每次在一个batch上优化神经网络参数的方法并不会比每次优化单个数据慢太多,此外还可以大大减少收敛所需要的迭代次数,最终结果更加接近梯度下降的效果。

3. 反向传播

如果说梯度下降算法优化了单个参数的取值,那么反向出阿波算法则给出了一种高效地所有参数上使用梯度下降算法地方式。反向传播(Back Propagation) 算法 则允许来自损失函数的信息通过网络向后流动,以便计算梯度。

反向传播算法的实现需要递归地使用微积分中的链式法则,如果将输入、输出都为向量的函数的所有偏导数汇总为一个矩阵,那么得到的矩阵可以被称为 Jacobian矩阵。向量 x 的梯度可以通过 (Jocabian矩阵)和梯度   相乘而得到。

TensorFlow提供了一些优化器,这些优化器会帮助我们实现反向传播的过程。

4 自适应学习率算法

在使用基本的梯度下降优化算法时,会遇到一个困难——要优化的参数对于目标函数的依赖各不相同。对于不同参数,如果学习率太小,则梯度大的参数会有一个很慢的收敛速度;如果学习率太大,则已经优化得差不多得参数可能会出现不稳定的情况。

早期,Delta-ba-Delta算法实现了在训练时自适应模型的参数各自的学习率。该算法的思路大体上可以描述为:如果损失与某一指定参数的偏导符号相同,那么学习率应该增加;如果损失与该参数的偏导的符号不同,那么学习率应该减小。受到 Delta-ba-Delta 算法的起法,后续出现了许多优化算法:

AdaGrad算法:在实验中发现该算法容易导致学习率过早和过量的减小;

RMSProp算法:在优化深度神经网络时有效且实用;

Adam算法:依据RMSProp算法所改良的优化算法。

5 TensorFlow提供的优化器

5.1 train.Optimizer()

这是一个基本的优化器类,通常使用其子类:AdagradOptimizer、GradientDescentOptimizer等。对于一个具体的优化器类,我们一般会调用在基本优化器类中的 minimize()函数来指定最小化的目标。

5.2 train.GradientDescentOptimizer()

该函数是梯度下降优化器,用得较为普遍,不过训练速度很慢,因为需要计算全部的训练样本。

train.AdagradOptimizer() :Adagrad自适应学习率优化器;

train.RMSPropOptimizer():RMSProp自适应学习率优化器

train.AdamOptimizer():Adam算法;

train.AdagradDAOptimizer():Adagrad升级版本;

train.AdadeltaOptimizer():Adadelta算法的优化器;

train.ProximalGradientDescentOptimizer():Optimizer类的子类;

train.ProximalAdagradOptimizer():Optimizer类的子类;

train.FtrlOptimizer():FTRL算法的优化器

6 学习率的独立设置

学习率通常用于控制梯度下降中参数更新的幅度。

6.1 指数衰减的学习率

学习率既不能过大,也不能过小。为了更好的设置学习率,我们可逐步减小已经设好的学习率。TensorFlow提供了 train.exponential_decay()函数,可以对学习率进行指数形式的衰减。

exponential_decay(learning_rate,global_step,decay_steps,decay_rate,staircase,name)
#learning_rate是初是学习率
#global_step是当前训练的轮数
#decay_steps是衰减速度
#decay_rate是衰减系数
#staircase参数指定了衰减方式

学习率如果连续的衰减,那么不同的训练数据就有不同的学习率。下面代码展示exponential_decay()函数使用:

import tensorflow as tf
#这里设training_rate代表目前正在进行的训练轮数
training_step = tf.Variable(0)
#使用exponential_decay()函数设置学习率
decayed_learning_rate = tf.train.exponential_decay(0.8, training_step, 100, 0.9, staircase=True)
#使用一个梯度下降优化器,其中损失函数loss是目标函数
learning_step = tf.train.GradientDescentOptimizer(decayed_learning_rate).minimize(loss, global_step=training_step)

6.2 其他优化学习率方法

train.inverse_time_decay():反时限学习率衰减;

train.natrual_exp_decay():自然指数衰减学习率;

train.piecewise_constant():分片常数学习率衰减;

train.polynomial_decay():多项式学习率衰减。

7 拟合

7.1 过拟合和欠拟合

可以通过调整机器学习算法模型的容量来控制模型是否偏向于过拟合或欠拟合。模型的容量是指其拟合各种函数的能力,如果容量适合于任务的复杂度和所提供的训练数据的规模,算法会表现出不错的效果。容量不足的模型因为难以拟合训练集而出现欠拟合的现象;容量高得模型能够解决复杂的任务,但是其当容量高于任务所需时,可能会因为很好地记忆了每一个训练数据中随机噪音的分布,导致忽略了对训练数据中通用趋势的学习,从而出现过拟合现象。

7.2 正则化的方法

正则化是避免过拟合问题而采用的方法,其思想就是在损失函数中加入被称为正则化项(Regularizer)的惩罚。假设模型在训练集上的损失函数是 J(w) (注意这里的 w 表示的是整个神经网络的所有参数,包括边上的权重w和偏置项b),那么在优化时不是直接优化 J(w),而是优化  

就是我们在损失函数中加入的正则化项,他通过对权重参数求解范数的方式对模型的复杂程度进行了刻画(一般而言权重w决定了模型的复杂程度)。 是提前挑选的值,控制我们偏好小范数权重的程度(越大的   偏好范数越小的权重)。

常用的刻画模型复杂度的函数  有两种,一种是 L1正则化;另一种是L2 正则化。

最小化   意味着需要在偏好小范数权重和拟合训练数据之间找到一个平衡,其基本思想是通过限制权重的大小,降低模型拟合训练集中存在的噪音的概念,从而减轻过拟合。

Tensorflow提供了计算L2正则化的函数——contrib.layers.l2_regularizer()函数,这个函数可以计算一个给定参数的L2正则化项的值。也提供了计算L1正则化的函数——contrib.layers.l1_regularizer()函数,他可以返回一个函数,该函数可以计算一个给定参数的L1正则化的值。以下代码给出使用这两个函数的样例:

import tensorflow as tfweights = tf.constant([[1.0,2.0],[-3.0,-4.0]])
#.5 表示正则化项的权重,对应 λ
regularizer_l2 = tf.contrib.layers.l2_regularizer(.5)regularizer_l1 = tf.contrib.layers.l1_regularizer(.5)with tf.Session() as sess:print (sess.run(regularizer_l2(weights)))print (sess.run(regularizer_l1(weights)))

只要能够达到模型优化的目的,都可以根据公式 自定义损失函数,Tensorflow当然也可以优化带正则化项的损失函数。假设  代表了交叉熵损失函数,λ=0.01, 参数为 weight1 和 weight2, 则计算总损失的过程大概就如下面的代码所示:

#求解平均交叉熵损失
cross_entropy_mean = tf.reduce_mean(cross_entropy)
#返回L2正则化计算函数
regularizer_l2 = tf.contrib.layers.l2_regularizer(.01)
#需要计算L2正则化的参数为weight1和weight2
regularization = regularizer_l2(weight1)+regularizer_l2(weight2)
#总损失定义为交叉熵损失和正则化损失
loss = cross_entropy_mean + regularization

当神经网络的参数增多后,使用计算图和张量来计算总损失。以下代码实现了一个4层全连接神经网络带L2正则化损失函数的功能:

import tensorflow as tf
import numpy as np
#定义训练轮数
training_steps = 30000
#定义输入的数据和对应的标签并在for循环内进行填充
data = []
label = []
for i in range(200):x1 = np.random.uniform(-1, 1)x2 = np.random.uniform(0, 2)#这里对产生的x1和x2进行判断,如果产生的点落在半径为1的圆内,则label值为0,否则为1if x1**2 + x2**2 <= 1:data.append([np.random.normal(x1,0.1),np.random.normal(x2,0.1)])label.append(0)else:data.append([np.random.normal(x1,0.1),np.random.normal(x2, 0.1)])label.append(1)#numpy的hstack()函数用于在水平方向将元素堆起来
#函数原型numpy.hstack(tup),参数tup可以是元组、列表或者numpy数组
#返回结果为numpy的数组,reshape()函数的参数为-1表示行列进行翻转
#这样处理的结果是data变成了200*2大小的数组,而label是200*1
data = np.hstack(data).reshape(-1,2)
label = np.hstack(label).reshape(-1,1)#定义完成前向传播的隐层
def hidden_layer(input_tensor,weight1,bias1,weight2,bias2,weight3,bias3):layer1 = tf.nn.relu(tf.matmul(input_tensor,weight1)+bias1)layer2 = tf.nn.relu(tf.matmul(layer1, weight2)+bias2)return tf.nn.relu(tf.matmul(layer2, weight3)+bias3)x = tf.placeholder(tf.float32, shape=(None, 2),name="x-input")
y_ = tf.placeholder(tf.float32, shape=(None, 1), name="y-output")#定义权重参数和偏置参数
weight1 = tf.Variable(tf.truncated_normal([2,10], stddev=0.1))
bias1 = tf.Variable(tf.constant(0.1, shape=[10]))weight2 = tf.Variable(tf.truncated_normal([10,10], stddev=0.1))
bias2 = tf.Variable(tf.constant(0.1, shape=[10]))weight3 = tf.Variable(tf.truncated_normal([10, 1], stddev=0.1))
bias3 = tf.Variable(tf.constant(0.1, shape=[1]))#用len()函数计算data数组的长度
sample_size = len(data)#得到隐层前向传播的结果
y = hidden_layer(x, weight1, bias1,weight2,bias2,weight3,bias3)
#自定义损失函数,pow()函数用于计算幂函数
#返回结果为x的y次幂,这里返回结果为(y_ - y)^2,用于衡量计算值与实际值的差距
error_loss = tf.reduce_sum(tf.pow(y_ - y, 2)) / sample_size
tf.add_to_collection("losses",error_loss)  #加入集合的操作#在权重参数上的实现L2正则化
regularizer = tf.contrib.layers.l2_regularizer(0.01)
regularization = regularizer(weight1)+regularizer(weight2)+regularizer(weight3)
tf.add_to_collection("losses", regularization)   #加入集合操作#get_collection()函数获取指定集合中的所有个体,这里是获取所有损失值
#并在add_n()函数中进行加和运算
loss = tf.add_n(tf.get_collection("losses"))#定义一个优化器,学习率固定为0.01,注意在实际应用中这个学习率数值应该大于0.01
train_op = tf.train.AdamOptimizer(0.01).minimize(loss)with tf.Session() as sess:tf.global_variables_initializer().run()#在for循环内进行30000轮训练for i in range(training_steps):sess.run(train_op, feed_dict={x:data, y_:label})#训练30000轮,但每隔2000轮就输出一次loss值if i % 2000 == 0:loss_value = sess.run(loss, feed_dict={x:data, y_:label})print ("After %d steps, mes_loss: %f"%(i, loss_value))

7.3 Bagging方法

Bagging思想:会分别训练几个不同的模型(假设为k个),之后使用相同的测试集在这些模型上进行测试,并收集所有模型在测试集上的输出。

7.4 Dropout方法

Dropout集成方法需要训练的是从原始网络去掉一些不属于输出层的单元后形成的子网络。丢弃(删除)某些单元并不是指真的构建出这种结构的网络,为了能有效地删除一个单元,我们需要将该单元地输出乘以0即可(结果就是该单元的值变为了0)。

TensorFlow提供了实现Dropout功能的函数,即 nn.dropout()函数,以下代码演示使用:

import tensorflow as tfx = tf.Variable(tf.ones[10, 10])dro = tf.placeholder(tf.float32)y = tf.nn.dropout(x, dro)init = tf.initialize_all_variables()with tf.Session() as sess:sess.run(init)print (sess.run(y, feed_dict={dro: 0.5}))

(四)优化网络的方法相关推荐

  1. 面向弹载图像的深度学习网络压缩方法研究

    这里写自定义目录标题 源自:航空兵器 作者:高一博 杨传栋 陈栋 凌冲 摘 要 针对基于深度学习目标识别算法具有网络结构复杂.参数量大.计算延迟高等特点,难以直接应用于弹载任务的问题,对网络轻量化方法 ...

  2. 网络推广方法中浅谈网站中的内容如何优化好?

    网络推广方法介绍在网站整体的优化中,内容优化也占据着很大的比重,网站内容优化做的好,能有效地帮助网站带来更多的流量和权重,但很多网络推广方法优化人员也要更注重些内容优化的细节才能让网站优化排名得到更好 ...

  3. 企业网络推广方法教你如何精准避免网站过度优化问题?

    在网站优化中,企业网络推广方法中的网站优化人员们很害怕网站过度优化,因为它会给网站带来更多的负面效果,导致关键词排名下降,严重的甚至会被搜索引擎降权.那么我们该如何更好地避免网站过度优化呢?下面企业网 ...

  4. 多传感器融合定位十四-基于图优化的定位方法

    多传感器融合定位十四-基于图优化的定位方法 1. 基于图优化的定位简介 1.1 核心思路 1.2 定位流程 2. 边缘化原理及应用 2.1 边缘化原理 2.2 从滤波角度理解边缘化 3. 基于kitt ...

  5. 优化网络方法思维导图总结

    最近在学习cs231n相关的课程,在进入下一阶段前,想对学习进行一下归纳整理.一方面强制让自己进行回忆和复习,另一方面从全局上换个角度来学习这些知识,也方便以后查阅.由于思维导图比较大,后文会拆分成不 ...

  6. virtualbox四种网络连接方式及其设置方法

    VirtualBox中有4种网络连接方式: ①NAT ②Bridged Adapter ③Internal ④Host-only Adapte 废话不多说,直接上图! (注:此图直接取至Finalbu ...

  7. [转帖]ASP.NET中常用的优化性能的方法

    ASP.NET中常用的优化性能的方法(转贴,Icyer收集整理) 1.       数据库访问性能优化     数据库的连接和关闭 访问数据库资源需要创建连接.打开连接和关闭连接几个操作.这些过程需要 ...

  8. 网络推广方法教大家提升网站页面收录的技巧!

    网络推广方法优化人员在做好优化同时,还要盯紧优化效果,比如网站的收录情况,权重情况以及排名情况等,但有时候网站页面不收录也很困扰优化人员,下面网络推广方法就带大家了解一下提升网站页面收录的技巧,帮助网 ...

  9. 网管心得:优化网络性能给局域网提速[好文章]

    网管心得:优化网络性能给局域网提速 目前,几乎任何稍微大一点的企业和学校都会建立一个局域网供使用,网络已经无处不在了.作为局域网络的网管人员,对于网络速度是非常在乎的,如何有效的利用带宽,避免不必要的 ...

最新文章

  1. 在测试时用到的一些mysql的小技巧(持续更新)
  2. 利用飞信给自己发短信的shell脚本
  3. MATLAB crc.generato,matlab中CRC的函数使用
  4. STM32使用J-LINK下载HEX文件
  5. 麻省理工学院计算机工程专业排名,2020美国计算机工程研究生专业排名TOP20
  6. 总结】Android辅助功能(一)-AccessibilityEvent的分发
  7. wait/waitpid函数与僵尸进程、fork 2 times
  8. 字符串中最后一个单词长度
  9. 网贷申请技巧,提高90%通过率
  10. php 判断两个数组差集,php array_udiff_assoc 计算两个数组的差集实例
  11. 【转载】dotnet 线程同步
  12. Can't connect to MySQL server on 'ip' (13)
  13. 【C语言】在线OJ题 BC7-BC52-牛客网编程初学者入门训练
  14. si4463 api 寄存器中文
  15. 番外篇 之 实现Unity和Android进行交互(基于Android Studio 3.1.1以及Jar包方式)
  16. Meet Hadoop
  17. vue 文字无缝滚动_vue文字横向滚动公告
  18. Nodejs开发微信公众号--获取access_token
  19. 基于Debezium 1.6和Oracle 11g 的 Debezium-Oracle实战
  20. 雅马哈音乐会钢琴-e-Instruments Session Keys Grand Y Kontakt

热门文章

  1. meshroom入门
  2. 删除excel中的空白区域,增加滚动条长度
  3. 使用sqlserver management studio创建新用户
  4. 计算机上缺少vsix安装程序,【VS2015】安装完成,显示缺几个包,以后应该怎么补按装?...
  5. WIN10 Hyper_v安装Ubuntu进行分辨率调整。
  6. mybatisplus之Wrappers.lambdaQuery常用写法
  7. 测试用例、测试流程模型、测试方法详解 超详细分解
  8. Python 计算混淆矩阵,计算Kappa系数,总体精度
  9. Qt(三)窗口分割、停靠、堆叠
  10. 数据库查询优化技术(一):数据库与关系代数