TensorFlow学习笔记——(4)神经网络优化过程

文章目录

      • 1、预备知识
          • (1)tf.where()
          • (2)np.random.RandomState.rand()
          • (3)np.vstack()
          • (4)np.mgrid[] / np.ravel() / np.c_[]
      • 2、神经网络(NN)复杂度
          • (1)网络复杂度的计算
          • (2)学习率的设置
            • 1)指数衰减学习率
      • 3、激活函数
          • (1)Sigmoid函数
          • (2)Tanh函数
          • (3)Relu函数
          • (4)Leaky Relu函数
          • (5)总结
      • 4、损失函数(loss)
          • (1)均方误差
          • (2)自定义损失函数
          • (3)交叉熵损失函数
          • (4)softmax与交叉熵结合
      • 5、缓解过拟合
          • (1)解决方法
          • (2)正则化缓解过拟合
      • 6、参数优化器
          • (1)更新参数的流程
          • (2)SDG(随机梯度下降)
          • (3)SGDM
          • (4)Adagrad
          • (5)RMSProp
          • (6)Adam

1、预备知识

目标:学会神经网络优化过程,使用正则化减少过拟合,使用优化器更新网络参数

这里先介绍几个需要掌握的函数

(1)tf.where()

条件语句为真返回A,假返回B

tf.where(条件语句,真返回A,假返回B)

例子
TensorFlow学习笔记——(4)神经网络优化过程_第1张图片

(2)np.random.RandomState.rand()

返回一个[0,1]之间的随机数,若维度为空,则返回标量

np.random.RandomState.rand(维度)

例子
TensorFlow学习笔记——(4)神经网络优化过程_第2张图片
TensorFlow学习笔记——(4)神经网络优化过程_第3张图片

(3)np.vstack()

将两个数组按垂直方向叠加

np.vstack(数组1,数组2)

例子
TensorFlow学习笔记——(4)神经网络优化过程_第4张图片

(4)np.mgrid[] / np.ravel() / np.c_[]

三个函数经常一起使用,生成网格坐标线
.mgrid[] 返回若干组维度相同的等差数组,每一组有起始值、结束值和步长,起始值和结束值是前闭后开区间
.ravel() 把多维数组变成一维数组,相当于把点前的数组拉直

np.mgrid[起始值:结束值:步长 , 起始值:结束值:步长 , ...]
x.ravel()  #把多维数组变成一维数组,相当于把点前的数组拉直
np.c_[数组1 , 数组2 , ...] #使返回的间隔数值点配对

例子
为了使维度相同,x,y都是两行四列
TensorFlow学习笔记——(4)神经网络优化过程_第5张图片

2、神经网络(NN)复杂度

(1)网络复杂度的计算

TensorFlow学习笔记——(4)神经网络优化过程_第6张图片

(2)学习率的设置

在实际应用中,可以先用较大的学习率,快速找到较优值,然后逐步减小学习率,使模型找到最优解,在训练后期稳定。

1)指数衰减学习率

在这里插入图片描述
当前轮数:是一个变量,可以用当前迭代了多少次数据集(epoch),或者当前一共迭代了多少次batch(global_step)表示
多少轮衰减一次:是迭代多少次数据集/迭代多少次batch更新一次学习率,决定了学习率更新频率

例子
TensorFlow学习笔记——(4)神经网络优化过程_第7张图片

3、激活函数

激活函数就是模型中的非线性函数
TensorFlow学习笔记——(4)神经网络优化过程_第8张图片
优秀的激活函数

  • 非线性:激活函数非线性时,多层神经网络可逼近所有函数
  • 可微性:优化器大多用梯度下降更新参数
  • 单调性:当激活函数是单调的,能保证单层网络的损失函数是凸函数
  • 近似恒等性:f(x)约等于x,当参数初始化为随机小知识,神经网络更稳定

激活函数输出值的范围

  • 激活函数输出为有限值时,基于梯度的优化方法更稳定
  • 激活函数输出为无限值时,建议调小学习率
(1)Sigmoid函数

TensorFlow学习笔记——(4)神经网络优化过程_第9张图片
特点

  • 易造成梯度消失
  • 输出非0均值,收敛慢
  • 幂运算复杂,训练时间长
(2)Tanh函数

TensorFlow学习笔记——(4)神经网络优化过程_第10张图片
特点

  • 输出是0均值
  • 易造成梯度消失
  • 幂运算复杂,训练时间长
(3)Relu函数

TensorFlow学习笔记——(4)神经网络优化过程_第11张图片
优点

  • 解决了梯度消失问题(在正区间)
  • 只需判断输入是否大于零,计算速度快
  • 收敛速度远快于sigmoid和tanh

缺点

  • 输出非0均值,收敛慢,
  • Dead Relu问题:某些神经元可能永远不被激活,导致相应的参数永远不能被更新
(4)Leaky Relu函数

为解决Relu函数负区间为0,引起神经元死亡问题而设计的。
TensorFlow学习笔记——(4)神经网络优化过程_第12张图片
理论上来讲,Leaky Relu有Relu的所有优点,外加不会有Dead Relu问题,但是在实际操作当中并没有完全证明Leaky Relu总是好于Relu

(5)总结
  • 首选relu激活函数
  • 学习率设置较小值
  • 输入特征标准化,即让输入特征满足以0为均值,1为标准差的正态分布
  • 初始参数中心化,即让随机生成的参数满足以0为均值,√(2/当前层输入特征个数)为标准差的正态分布

4、损失函数(loss)

TensorFlow学习笔记——(4)神经网络优化过程_第13张图片

(1)均方误差

TensorFlow学习笔记——(4)神经网络优化过程_第14张图片

loss_mse = tf.reduce_mean(tf.square(y_-y))
(2)自定义损失函数

TensorFlow学习笔记——(4)神经网络优化过程_第15张图片

(3)交叉熵损失函数

在这里插入图片描述

tf.losses.categorical_crossentropy(y_,y)
(4)softmax与交叉熵结合

在执行分类问题时,通常先用softmax函数让结果符合概率分布,然后再计算交叉熵损失函数,这里给出一个可以同时计算概率分布和交叉熵的函数。(也就是输出先过softmax函数,再计算y和y_的交叉熵损失函数)

tf.nn.softmax_cross_entropy_with_logits(y_,y)

例子
y_pro+loss_ce1 == loss_ce2
TensorFlow学习笔记——(4)神经网络优化过程_第16张图片

5、缓解过拟合

欠拟合:模型不能有效拟合数据集,对现有数据集学习的不够彻底
过拟合:模型对当前数据拟合的太好,但对从未见过的新数据,难以做出正确的判断,模型缺乏泛化力。
TensorFlow学习笔记——(4)神经网络优化过程_第17张图片

(1)解决方法

欠拟合解决方法

  • 增加输入特征项
  • 增加网络参数
  • 减少正则化参数

过拟合解决方法

  • 数据清洗
  • 增大训练集
  • 采用正则化
  • 增大正则化参数
(2)正则化缓解过拟合

TensorFlow学习笔记——(4)神经网络优化过程_第18张图片
其中,loss(w)的计算方法有如下两种:
TensorFlow学习笔记——(4)神经网络优化过程_第19张图片

6、参数优化器

首先明确几个参数

  • 待优化参数w
  • 损失函数loss
  • 学习率lr
  • 每次迭代一个batch
  • t表示当前batch迭代的总次数
(1)更新参数的流程

TensorFlow学习笔记——(4)神经网络优化过程_第20张图片

  • 一阶动量:与梯度相关的函数
  • 二阶动量:与梯度平方相关的函数

下面介绍五种参数优化器

(2)SDG(随机梯度下降)

不含动量时,一阶动量恒等于梯度,二阶动量等于1
TensorFlow学习笔记——(4)神经网络优化过程_第21张图片
代码

#sgd
w1.assign_sub(lr * grads[0])  #参数w自更新
b1.assign_sub(lr * grads[1])  #参数b自更新
(3)SGDM

在SGD基础上增加了一阶动量
TensorFlow学习笔记——(4)神经网络优化过程_第22张图片
代码
beta是超参数,经验值0.9

m_w,m_b = 0,0
beta = 0.9
# sgd-momentun
m_w = beta * m_w + (1 - beta) * grads[0]
m_b = beta * m_b + (1 - beta) * grads[1]
w1.assign_sub(lr * m_w)
b1.assign_sub(lr * m_b)
(4)Adagrad

在SGD基础上增加了二阶动量
TensorFlow学习笔记——(4)神经网络优化过程_第23张图片
代码

v_w,v_b = 0,0
# adagrad
v_w += tf.square(grads[0])
v_b += tf.square(grads[1])
w1.assign_sub(lr * grads[0] / tf.sqrt(v_w))
b1.assign_sub(lr * grads[1] / tf.sqrt(v_b))
(5)RMSProp

在SGD基础上增加了二阶动量
TensorFlow学习笔记——(4)神经网络优化过程_第24张图片
代码

v_w,v_b = 0,0
beta = 0.9
# rmsprop
v_w = beta * v_w + (1 - beta) * tf.square(grads[0])
v_b = beta * v_b + (1 - beta) * tf.square(grads[1])
w1.assign_sub(lr * grads[0] / tf.sqrt(v_w))
b1.assign_sub(lr * grads[1] / tf.sqrt(v_b))
(6)Adam

同时结合SGDM一阶动量和RMSProp二阶动量
有修正公式
TensorFlow学习笔记——(4)神经网络优化过程_第25张图片
代码

m_w,m_b = 0,0
v_w,v_b = 0,0
beta1,beta2 = 0.9,0.999
delta_w,delta_b = 0,0
global_step = 0
# adam
m_w = beta1 * m_w + (1 - beta1) * grads[0]
m_b = beta1 * m_b + (1 - beta1) * grads[1]
v_w = beta2 * v_w + (1 - beta2) * tf.square(grads[0])
v_b = beta2 * v_b + (1 - beta2) * tf.square(grads[1])

m_w_correction = m_w / (1 - tf.pow(beta1,int(global_step)))
m_b_correction = m_b / (1 - tf.pow(beta1,int(global_step)))
v_w_correction = v_w / (1 - tf.pow(beta2,int(global_step)))
v_b_correction = v_b / (1 - tf.pow(beta2,int(global_step)))

w1.assign_sub(lr * m_w_correction / tf.sqrt(v_w_correction))
b1.assign_sub(lr * m_b_correction / tf.sqrt(v_b_correction))

你可能感兴趣的:(TensorFlow学习笔记,神经网络,深度学习,python,tensorflow,人工智能)