TensorFlow2 手把手教你避开梯度消失和梯度爆炸

  • 梯度消失 & 梯度爆炸
    • 梯度消失
    • 梯度爆炸
  • 张量限幅
    • tf.clip_by_value
    • tf.clip_by_norm
  • mnist 展示梯度爆炸
    • 完整代码
    • 输出结果

梯度消失 & 梯度爆炸


输出结果:

vanish: 0.025517964452291125
explode: 37.78343433288728

梯度消失

梯度消失问题 (Vanishing gradient problem). 如果导数小于 1, 随着网络层数的增加梯度跟新会朝着指数衰减的方向前进, 这就是梯度消失.


当导数小于 1 的时候, 层数越多, 梯度就越小, 即梯度消失.

梯度爆炸

梯度爆炸问题 (Exploding gradient problem). 如果导数大于 1, 随着网络层数的增加梯度跟新会朝着指数增加的方向前进, 这就是梯度爆炸.

当导数大于 1 的时候, 层数越多, 梯度就越大, 即梯度爆炸.

张量限幅

通过张量限幅, 我们可以有效解决梯度爆炸问题.

tf.clip_by_value

我们可以通过tf.clip_by_value函数来实现张量限幅.

格式:

tf.clip_by_value(t, clip_value_min, clip_value_max, name=None
)

参数:

  • t: 传入的张量
  • clip_value_min: 下限
  • clip_value_max: 上限
  • name: 数据名称

例子:

# clip_by_value
a = tf.range(10)
print(a)b = tf.maximum(a, 2)
print(b)c = tf.minimum(a, 8)
print(c)d = tf.clip_by_value(a, 2, 8)
print(d)

输出结果:

tf.Tensor([0 1 2 3 4 5 6 7 8 9], shape=(10,), dtype=int32)
tf.Tensor([2 2 2 3 4 5 6 7 8 9], shape=(10,), dtype=int32)
tf.Tensor([0 1 2 3 4 5 6 7 8 8], shape=(10,), dtype=int32)
tf.Tensor([2 2 2 3 4 5 6 7 8 8], shape=(10,), dtype=int32)

tf.clip_by_norm

tf.clip_by_norm可以对梯度进行裁剪, 防止梯度爆炸.

格式:

tf.clip_by_norm(t, clip_norm, axes=None, name=None
)

参数:

  • t: 传入的张量
  • clip_norm: 定义最大限幅
  • axes: 计算尺寸
  • name: 数据名称

例子:

# clip_by_normal
a = tf.random.normal([2, 2], mean=10)
print(a)
print(tf.norm(a))  # 范数b = tf.clip_by_norm(a, 15)
print(b)
print(tf.norm(b))  # 范数

输出结果:

tf.Tensor(
[[ 9.33037  10.703022][ 9.788097  9.713704]], shape=(2, 2), dtype=float32)
tf.Tensor(19.793266, shape=(), dtype=float32)
tf.Tensor(
[[7.070867  8.111109 ][7.417748  7.3613706]], shape=(2, 2), dtype=float32)
tf.Tensor(15.0, shape=(), dtype=float32)

mnist 展示梯度爆炸

为了实现梯度爆炸, 我们把学习率设为 0.1.

完整代码

# 读取训练集的特征值和目标值
(x, y), _ = tf.keras.datasets.mnist.load_data()# 转换为0~1的形式
x = tf.convert_to_tensor(x, dtype=tf.float32) / 255# 转换成one_hot编码
y = tf.one_hot(y, depth=10)# 批次分割
train_db = tf.data.Dataset.from_tensor_slices((x, y)).batch(256).repeat(30)def main():# 生成w1形状为[784, 512]的截断正态分布, 中心为0, 标差为0.1w1 = tf.Variable(tf.random.truncated_normal([784, 512], stddev=0.1))# 生成b1形状为[512]初始化为0b1 = tf.Variable(tf.zeros([512]))# 生成w2形状为[512, 256]的截断正态分布, 中心为0, 标差为0.1w2 = tf.Variable(tf.random.truncated_normal([512, 256], stddev=0.1))# 生成b2形状为[256]初始化为0b2 = tf.Variable(tf.zeros([256]))# 生成w3形状为[256, 10]的截断正态分布, 中心为0, 标差为0.1w3 = tf.Variable(tf.random.truncated_normal([256, 10], stddev=0.1))# 生成b3形状为[10]初始化为0b3 = tf.Variable(tf.zeros([10]))# 优化器optimizer = tf.keras.optimizers.SGD(learning_rate=0.1)  # 梯度下降for step, (x, y) in enumerate(train_db):# 把x平铺 [256, 28, 28] => [256, 784]x = tf.reshape(x, [-1, 784])with tf.GradientTape() as tape:# 第一个隐层h1 = x @ w1 + b1h1 = tf.nn.relu(h1)  # 激活# 第二个隐层h2 = h1 @ w2 + b2h2 = tf.nn.relu(h2)  # 激活# 输出层out = h2 @ w3 + b3# 计算损失函数loss = tf.square(y - out)loss = tf.reduce_mean(loss)# 计算梯度grads = tape.gradient(loss, [w1, b1, w2, b2, w3, b3])# 调试输出剪切前的范数print("================before===============")for g in grads:print(tf.norm(g))grads, _ = tf.clip_by_global_norm(grads, 15)# 调试输出剪切后的范数print("================after===============")for g in grads:print(tf.norm(g))optimizer.apply_gradients(zip(grads, [w1, b1, w2, b2, w3, b3]))  # 跟新权重if __name__ == '__main__':main()

输出结果

================before===============
tf.Tensor(5.5961547, shape=(), dtype=float32)
tf.Tensor(0.87258744, shape=(), dtype=float32)
tf.Tensor(7.397964, shape=(), dtype=float32)
tf.Tensor(0.69156337, shape=(), dtype=float32)
tf.Tensor(9.840232, shape=(), dtype=float32)
tf.Tensor(0.8157242, shape=(), dtype=float32)
================after===============
tf.Tensor(5.5961547, shape=(), dtype=float32)
tf.Tensor(0.87258744, shape=(), dtype=float32)
tf.Tensor(7.397964, shape=(), dtype=float32)
tf.Tensor(0.69156337, shape=(), dtype=float32)
tf.Tensor(9.840232, shape=(), dtype=float32)
tf.Tensor(0.8157242, shape=(), dtype=float32)
================before===============
tf.Tensor(18.01539, shape=(), dtype=float32)
tf.Tensor(2.9375393, shape=(), dtype=float32)
tf.Tensor(21.330334, shape=(), dtype=float32)
tf.Tensor(2.1504176, shape=(), dtype=float32)
tf.Tensor(21.820374, shape=(), dtype=float32)
tf.Tensor(2.0918982, shape=(), dtype=float32)
================after===============
tf.Tensor(7.5730414, shape=(), dtype=float32)
tf.Tensor(1.2348388, shape=(), dtype=float32)
tf.Tensor(8.966527, shape=(), dtype=float32)
tf.Tensor(0.90396047, shape=(), dtype=float32)
tf.Tensor(9.172523, shape=(), dtype=float32)
tf.Tensor(0.8793609, shape=(), dtype=float32)
================before===============
tf.Tensor(0.5821787, shape=(), dtype=float32)
tf.Tensor(0.0859229, shape=(), dtype=float32)
tf.Tensor(0.7110027, shape=(), dtype=float32)
tf.Tensor(0.082481824, shape=(), dtype=float32)
tf.Tensor(0.51846975, shape=(), dtype=float32)
tf.Tensor(0.1655324, shape=(), dtype=float32)
================after===============
tf.Tensor(0.5821787, shape=(), dtype=float32)
tf.Tensor(0.0859229, shape=(), dtype=float32)
tf.Tensor(0.7110027, shape=(), dtype=float32)
tf.Tensor(0.082481824, shape=(), dtype=float32)
tf.Tensor(0.51846975, shape=(), dtype=float32)
tf.Tensor(0.1655324, shape=(), dtype=float32)... ...

TensorFlow2 手把手教你避开梯度消失和梯度爆炸相关推荐

  1. TensorFlow2 手把手教你实现自定义层

    TensorFlow2 手把手教你实现自定义层 概述 Sequential Model & Layer 案例 数据集介绍 完整代码 概述 通过自定义网络, 我们可以自己创建网络并和现有的网络串 ...

  2. 2.1.4 对梯度消失和梯度爆炸的近似解决方案

    梯度消失与梯度爆炸 如图所示 对于一个层数比较深的网络,如100层,如果w的参数设置的比1大,最后迭代训练的结果是wlwlw^l,将会是一个非常大的数,反之如果w的参数设置的比1小,经过迭代训练之后结 ...

  3. 1.10 梯度消失与梯度爆炸-深度学习第二课《改善深层神经网络》-Stanford吴恩达教授

    ←上一篇 ↓↑ 下一篇→ 1.9 归一化输入 回到目录 1.11 神经网络的权重初始化 梯度消失与梯度爆炸 (Vanishing/Expanding Gradients) 训练神经网络,尤其是深度神经 ...

  4. 【算法】梯度消失与梯度爆炸

    概念 梯度不稳定 在层数比较多的神经网络模型的训练过程中会出现梯度不稳定的问题. 损失函数计算的误差通过梯度反向传播的方式,指导深度网络权值的更新优化.因为神经网络的反向传播算法是从输出层到输入层的逐 ...

  5. 【深度学习】梯度消失和梯度爆炸问题的最完整解析

    作者丨奥雷利安 · 杰龙 来源丨机械工业出版社<机器学习实战:基于Scikit-Learn.Keras和TensorFlow> 编辑丨极市平台 1 梯度消失与梯度爆炸 正如我们在第10章中 ...

  6. sigmoid函数解决溢出_梯度消失和梯度爆炸及解决方法

    一.为什么会产生梯度消失和梯度爆炸? 目前优化神经网络的方法都是基于BP,即根据损失函数计算的误差通过梯度反向传播的方式,指导深度网络权值的更新优化.其中将误差从末层往前传递的过程需要链式法则(Cha ...

  7. 梯度消失和梯度爆炸_知识干货-动手学深度学习-05 梯度消失和梯度爆炸以及Kaggle房价预测...

    梯度消失和梯度爆炸 考虑到环境因素的其他问题 Kaggle房价预测 梯度消失和梯度爆炸 深度模型有关数值稳定性的典型问题是消失(vanishing)和爆炸(explosion). 当神经网络的层数较多 ...

  8. 普通RNN的缺陷—梯度消失和梯度爆炸

    之前的RNN,无法很好地学习到时序数据的长期依赖关系.因为BPTT会发生梯度消失和梯度爆炸的问题. RNN梯度消失和爆炸 对于RNN来说,输入时序数据xt时,RNN 层输出ht.这个ht称为RNN 层 ...

  9. 批量标准化BN方法简介【避免了梯度消失和梯度爆炸、加速网络的收敛、优化网络结构】

    一. 本文的内容包括: 1. Batch Normalization,其论文:https://arxiv.org/pdf/1502.03167.pdf 2. Layer Normalizaiton,其 ...

最新文章

  1. sicp第一章部分习题解答
  2. 深度学习之RetinaNet
  3. 组合数学中的项链计数
  4. linux工作笔记-linux之间文件传输图形界面工具gftp
  5. java map存储格式_java HashMap HashSet的存储方式
  6. 【数学分析新讲 笔记】第一章 实数
  7. 苹果服务器消息转发,好消息!微信语音也可以转发啦!不好的消息!目前苹果还不行!...
  8. 国产免费数据库建模工具EZDML3.24发布 支持生成和预览vue文件
  9. FileSplit简单使用
  10. coreldraw矫正两张图_CorelDRAW矫正图像方法-CDR中如何矫正图像_好特教程
  11. 【Python】24点 一行代码解决
  12. 用C#写一个微信登录软件(自己写协议)
  13. 【重装系统】Ubuntu系统重装为windows10
  14. 盘扣架市场持续低迷,春节后是否能“破圈”?
  15. blinker点灯开关组件
  16. 美国春季计算机硕士入学的学校,美国硕士春季入学学校推荐哪些?
  17. [供应链•案例篇] 天能集团:解读电池制造龙头实现盈利断层第一的关键
  18. VIVADO时序约束之Input Delay(set_input_delay)
  19. 使用Java实现简单的监控系统
  20. docker: Error response from daemon: driver failed programming external connectivity on endpoint

热门文章

  1. 女士学计算机适合从事什么工作,女生学计算机专业好吗 适合的岗位有哪些
  2. encode与decode讲解
  3. Day16 Java异常处理
  4. 下载和攻略之青空下的约定 この青空に約束を
  5. python基础练习(猜拳游戏、扎金花游戏、购物小程序)
  6. UNiSONSHIFT・ACCENT经典作品推荐 Chu×Chuアイドる和Chu×Chuぱらだいす~Encore Live~介绍(含下载和攻略)
  7. 优秀原型设计欣赏:社交类App原型制作分享-LinkedIn
  8. 更改无线网卡mac地址后,无法连接到此无线网卡分享的热点
  9. 网址转base64二维码图片
  10. Arcgis License Sever Administrator无法读取许可解决方法之一