专栏首页灯塔大数据深度学习的数学理论与代码实战

深度学习的数学理论与代码实战

前言

在《FNN(DNN)的前向传播和反向梯度推导》中,我们学习了FNN(DNN)的前向传播和反向梯度求导,但知识仍停留在纸面。本篇章将基于深度学习框架tensorflow验证我们所得结论的准确性,以便将抽象的数学符号和实际数据结合起来,将知识固化。更多相关内容请见《深度学习的数学理论与代码实战》系列介绍。

正文

需要用到的库有tensorflow和numpy,其中tensorflow其实版本>=2.0.0就行。

import tensorflow as tf

import numpy as np

然后是定义下面两个要用到的函数,一个是计算mse,另外一个是计算sigmoid的导数:

# mse def get_mse(y_pred, y_true): return 0.5 * tf.reduce_sum((y_pred - y_true)**2) # sigmoid的导数 def d_sigmoid(x): """ sigmoid(x)的导数 = sigmoid(x) * (1-sigmoid(x)) :param x: :return: sigmoid(x)的导数 """ return tf.math.sigmoid(x) * (1 - tf.math.sigmoid(x))

接着是随便产生一条样本数据:

x = np.array([[1, 2]]).astype(np.float32) y_true = np.array([[0.3, 0.5, 0.2]]).astype(np.float32)

x的是2维的,输出y是3维的:

x.shape Out[5]: (1, 2) y_true.shape Out[6]: (1, 3)

有了一条样本之后,我们开始写前向传播的代码:

1 with tf.GradientTape(persistent=True) as t: 2 # -----hidden l1------------- 3# DNN layer1 4 l1 = tf.keras.layers.Dense(4) 5 6# 输入经过DNN layer1得到输出z_l1 7 z_l1 = l1(x) 8# 跟踪变量z_l1,用于随后计算其梯度 9 t.watch([z_l1]) 10 # DNN layer1的输出再经过激活函数sigmoid 11 a_l1 = tf.math.sigmoid(z_l1) 12 # 跟踪变量a_l1 ,用于随后计算其梯度 13 t.watch([a_l1]) 14 # ------hidden l2------------ 15 l2 = tf.keras.layers.Dense(3) 16 17 z_l2 = l2(a_l1) 18 t.watch([z_l2]) 19 a_l2 = tf.math.sigmoid(z_l2) 20 t.watch([a_l2]) 21 # -------计算loss----------- 22 loss = get_mse(a_l2, y_true)

上面是一个两层的FNN(DNN)网络,激活函数都是sigmoid

这里 tf.GradientTape(persistent=True) ,t.watch()是用于后面计算变量的导数用的,不太熟悉的可参考tensorflow官方给出的关于这部分的教程(自动微分)。

这里为方便起见我就直接用tf.keras.layers.Dense()来创建DNN层了,tensorflow官方的教程也推荐用这种方法快速定义layer。

如果要看某一层内部的weights和bias也比较容易:

l1.kernel Out[7]: <tf.Variable 'dense/kernel:0' shape=(2, 4) dtype=float32, numpy= array([[-0.96988726, -0.84827805, 0.312042 , 0.8871379 ], [ 0.6567688 , -0.29099226, -0.80029106, -0.15143871]], dtype=float32)> l1.bias Out[8]: <tf.Variable 'dense/bias:0' shape=(4,) dtype=float32, numpy=array([0., 0., 0., 0.], dtype=float32)>

前向传播的验证

下面来验证上面代码第7+11行代码是否符合DNN的前传规则:

tf.math.sigmoid(tf.matmul(x, l1.kernel) + l1.bias)

Out[14]: <tf.Tensor: shape=(1, 4), dtype=float32, numpy=array([[0.585077 , 0.19305778, 0.2161 , 0.64204717]], dtype=float32)>

a_l1

Out[15]: <tf.Tensor: shape=(1, 4), dtype=float32, numpy=array([[0.585077 , 0.19305778, 0.2161 , 0.64204717]], dtype=float32)>

看来tf.keras.layers.Dense确实是实现了下面的计算公式:

这里l1层激活函数默认是linear,sigmoid激活函数被我单独拿了出来(见前传部分的代码第11行),方便计算梯度的时候好做分解。

反向梯度计算的验证

接下来就是验证反向梯度求导公式的时候了:

1 # 注意的是,在tensorflow里,W变量矩阵和数学推导的是互为转置的关系,所以在验证的时候,要注意转置关系的处理 2 # ------dl_da2------ sigmoid(x)的导数 = sigmoid(x) * (1-sigmoid(x)) 3 dl_da2 = t.gradient(loss, a_l2) 4 my_dl_da2 = (a_l2 - y_true) 5 # ------dl_dz2--------- 6 dl_dz2 = t.gradient(loss, z_l2) 7 my_dl_dz2 = my_dl_da2 * d_sigmoid(z_l2) 8 # -------dl_dW2-------- 9 dl_dW2 = t.gradient(loss, l2.kernel) 10 my_dl_W2 = np.matmul(a_l1.numpy().transpose(), my_dl_dz2) 11 # -------dl_db2-------- 12 dl_db2 = t.gradient(loss, l2.bias) 13 my_dl_db2 = my_dl_dz2 14 # -------dl_dz1--------- 15 dl_dz1 = t.gradient(loss, z_l1) 16 my_dl_dz1 = np.matmul(my_dl_dz2, l2.weights[0].numpy().transpose()) * d_sigmoid(z_l1) 17 # -------dl_dW1--------- 18 dl_dW1 = t.gradient(loss, l1.kernel) 19 my_dl_dW1 = np.matmul(x.transpose(), my_dl_dz1) 20 # -------dl_db1---------- 21 dl_db1 = t.gradient(loss, l1.bias) 22 my_dl_db1 = my_dl_dz1

上面反向梯度计算的对象的顺序跟前先传播的顺序是正好相反的,因为这样方便进行梯度计算的时候,靠前的层的参数的梯度能够用得到靠后的层的梯度计算结果而不必从头开始计算,这也是反向梯度传播名字的由来,这点在上面代码中也能够体现出来。

代码验证的结果是:

t.gradient(loss, a_l2) Out[17]: <tf.Tensor: shape=(1, 3), dtype=float32, numpy=array([[ 0.1497804 , -0.05124322, 0.23775901]], dtype=float32)> a_l2 - y_true Out[18]: <tf.Tensor: shape=(1, 3), dtype=float32, numpy=array([[ 0.1497804 , -0.05124322, 0.23775901]], dtype=float32)>

代码验证的结果是:

t.gradient(loss, z_l2) Out[21]: <tf.Tensor: shape=(1, 3), dtype=float32, numpy=array([[ 0.03706735, -0.01267625, 0.05851868]], dtype=float32)> my_dl_da2 * d_sigmoid(z_l2) Out[22]: <tf.Tensor: shape=(1, 3), dtype=float32, numpy=array([[ 0.03706735, -0.01267625, 0.05851869]], dtype=float32)>

代码验证的结果是:

t.gradient(loss, l2.kernel) Out[23]: <tf.Tensor: shape=(4, 3), dtype=float32, numpy= array([[ 0.02168725, -0.00741658, 0.03423793], [ 0.00715614, -0.00244725, 0.01129749], [ 0.00801025, -0.00273934, 0.01264589], [ 0.02379899, -0.00813875, 0.03757175]], dtype=float32)> np.matmul(a_l1.numpy().transpose(), my_dl_dz2) Out[24]: array([[ 0.02168725, -0.00741658, 0.03423794], [ 0.00715614, -0.00244725, 0.01129749], [ 0.00801025, -0.00273934, 0.01264589], [ 0.02379899, -0.00813875, 0.03757175]], dtype=float32)

也没有问题。

剩下的大家可自行敲敲上面给出的验证代码看看是否跟推导的公式一致,这里就不再一一演示了。

本文分享自微信公众号 - 融智未来(DTbigdata),作者:刘心唯

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-12-28

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 【深度学习】迁移学习理论与实践

    在深度学习模型日益庞大的今天,并非所有人都能满足从头开始训练一个模型的软硬件条件,稀缺的数据和昂贵的计算资源都是我们需要面对的难题。迁移学习(Tran...

    黄博的机器学习圈子
  • 深度学习精要之CapsuleNets理论与实践(附Python代码)

    神经网络于上世纪50年代提出,直到最近十年里才得以发展迅速,正改变着我们世界的方方面面。从图像分类到自然语言处理,研究人员正在对不同领域建立深层神经网络模型并取...

    用户3578099
  • 实战深度强化学习DQN-理论和实践

    1、Q-learning回顾 Q-learning 的 算法过程如下图所示: ? 在Q-learning中,我们维护一张Q值表,表的维数为:状态数S * 动作数...

    石晓文
  • 浅入浅出深度学习理论与实践

    前言 之前在知乎上看到这么一个问题:在实际业务里,在工作中有什么用得到深度学习的例子么?用到 GPU 了么?,回头看了一下自己写了这么多东西一直围绕着tradi...

    机器学习AI算法工程
  • 深度学习与统计力学(I) :深度学习中的基础理论问题

    这是谷歌和斯坦福最新的一项合作研究综述报告,发表在物理学的顶级期刊“凝聚态物理年鉴”(Annual Review of Condensed Matter Phy...

    数据酷客
  • 深度学习介绍与TensorFlow实战

    2017国庆快乐,非常开心,难得有充足的时间,可以撸代码。最近人工智能的风口很火爆,基于我掌握的情况,可以先了解,最好复习下高中数学知识(矩阵,多维数据,多元N...

    孙寅
  • 机器学习与深度学习经典论文整理

    这篇文章整理出了机器学习、深度学习领域的经典论文。为了减轻大家的阅读负担,只列出了最经典的一批,如有需要,可以自己根据实际情况补充。

    SIGAI学习与实践平台
  • 【David Silver 深度强化学习教程代码实战07】 DQN的实现

    点击上方“专知”关注获取更多AI知识! 【导读】Google DeepMind在Nature上发表最新论文,介绍了迄今最强最新的版本AlphaGo Zero,不...

    WZEARW
  • 『深度概念』度量学习中损失函数的学习与深入理解

    度量学习(Metric Learning),也称距离度量学习(Distance Metric Learning,DML) 属于机器学习的一种。其本质就是相似度的...

    小草AI
  • 『深度概念』度量学习中损失函数的学习与深入理解

    度量学习(Metric Learning),也称距离度量学习(Distance Metric Learning,DML) 属于机器学习的一种。其本质就是相似度的...

    小宋是呢
  • 深度学习对话系统实战篇 -- 简单 chatbot 代码实现

    本文的代码都可以到我的 github 中下载:https://github.com/lc222/seq2seq_chatbot 前面几篇文章我们已经介绍了 s...

    AI研习社
  • 《深度学习原理与TensorFlow实践》学习笔记(一)

    作者 | 王清 目录: 深度学习与TensorFlow简介 深度学习简介 深度学习的由来 神经网络 深度学习(Deep Learning or Feature ...

    AI科技大本营
  • 深度学习的动机与挑战之-流形学习

    流形 (manifold) 指连接在一起的区域。数学上,它是指一组点,且每个点都有 其邻域。给定一个任意的点,其流形局部看起来像是欧几里得空间。日常生活中,我 ...

    用户1908973
  • 基于深度学习的花卉识别(附数据与代码)

    前几天,想必大家都忙着过女神节,但送礼物这件事情还是让不少直男苦恼,口红色号那么多,花还有那么多品种,一个不小心选错就容易踏入雷区,下面就教大家用机器学习来识别...

    Crossin先生
  • 深度学习(四)转--入门深度学习的一些开源代码

    没错这篇又是转发的,因为觉得学习深度学习难免要从别人的代码开始,所以就转发了。不过转发的时候没找到原作者是谁,所以原作者看到不要打我-------QAQ

    徐飞机
  • 文本分类实战: 机器学习vs深度学习算法对比(附代码)

    这几周因为在做竞赛所以没怎么看论文刷题写博客,今天抽时间把竞赛用到的东西总结一下。先试水了一个很小众的比赛–文因互联,由AI100举办,参赛队不足20个,赛题...

    机器学习AI算法工程
  • 【干货合集】深度学习入门与实战

    近年来,深度学习的概念十分火热,人工智能也由于这一技术的兴起,在近几年吸引了越来越多的关注。本文精选了分享在腾云阁技术社区深受开发者欢迎的深度学习的文章,轻松快...

    云加社区
  • 深度学习实战 numpy生成实数序列

    在利用python在进行数据分析的时候,经常需要按照某种规则快速生成实数序列,尤其是在学习matplotlib绘图的时候,需要模拟生成数据,然后开始绘制。

    算法与编程之美
  • 深度学习实战 图像数据集预处理总结

    (1) mnist数据集采用numpy的npz方式以一个文件的方式存储文件,加载后就可以直接得到四个数组,非常方便。

    算法与编程之美

扫码关注云+社区

领取腾讯云代金券