![从零开始学TensorFlow2.0](https://wfqqreader-1252317822.image.myqcloud.com/cover/188/33692188/b_33692188.jpg)
3.4 自定义层
机器学习模型通常可以表示为简单网络层的堆叠与组合,TensorFlow提供了常见的网络层,TensorFlow 2.0推荐使用tf.keras来构建网络层,以提高可读性和易用性。
3.4.1 网络层的常见操作
TensorFlow 2.0推荐将tf.keras作为构建神经网络的高级API。本节对常见的网络层操作进行介绍。
(1)构建一个简单的全连接网络,代码如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_32_3.jpg?sign=1738861868-f6fKvQYQwN8lADWIAEy2P4uW5GnwI7HF-0-71e2d757e37ab2a4d6a1ebc072bd7d6b)
(2)代码的运行结果如下,包含权重和偏置信息。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_33_1.jpg?sign=1738861868-aiXgfCxdT6MvcF7bmeUhiLFm4FFvzUQv-0-195e29aee675b29128e366b901a04536)
(3)tf.keras非常灵活,还可以分别取出上例中的权重和偏置,代码如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_33_2.jpg?sign=1738861868-8IcEd66ytYWc1gb5ef9ksPEBnRwfz8Md-0-9a51c80f102410776f2595d9ccf3c49c)
(4)代码的运行结果如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_33_3.jpg?sign=1738861868-Rfl6Sovf1TXYiw3IDqj71Pkpzjdn7Mzb-0-c7322fe7024969e4f1300888b342bbcd)
3.4.2 自定义网络层
在实际中,经常需要扩展tf.keras.Layer类并自定义网络层。本节介绍如何自定义网络层。
(1)在自定义网络层的过程中主要使用3个函数,示例代码如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_34_1.jpg?sign=1738861868-asmCTA4ewdobQZA9lwyaB0jAeSsP9hvO-0-1314529b50ab5f57ab7f8738c374d2fe)
说明:调用build()函数构建网络并不是必要的,有时可以在__init__()中构建网络。但是,调用build()函数构建网络的优点是可以动态获取输入数据的shape,大大提高了运行效率。
(2)上述代码的运行结果如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_34_2.jpg?sign=1738861868-1QveuOH94481vdV63T735gQv3AMIimck-0-41901cb57e103fd5c8f1a79302dc5d54)
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_35_1.jpg?sign=1738861868-W8MX6DzYacK16qgsMOqRdxk1Twe6eG5b-0-6101e7878876b01f0959e88fe5ceee8b)
3.4.3 网络层组合
有很多机器学习模型是不同网络层的组合,网络层组合学习是加快学习速度和精度的重要方法。
(1)使用下面的代码在TensorFlow 2.0中构建一个包含多个网络层的模型。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_35_2.jpg?sign=1738861868-YA79QuHTTmNzFglYD7PTDAULbKvnIKT2-0-35c59a17fb65b391aacbf73d1678257d)
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_36_1.jpg?sign=1738861868-P5QjkLDs8bvx0xqGmzsmzTuTHYo5ZL9P-0-0d6b7aaed1adccb74c7fb2f69a8df759)
说明:该例子是resnet的一个残差块,是“卷积+批标准化+残差连接”的组合。
(2)代码的运行结果如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_36_2.jpg?sign=1738861868-fWRZRghXRc76ollEWZoyTTLAIiH5hNis-0-11b38786eb315b719f257df0d7abe50f)
(3)有时需要构建线性模型,可以直接用tf.keras.Sequential来构建,示例代码如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_36_3.jpg?sign=1738861868-qyJ3eL1LcnTxD8FtzcQgsmPR3yVv8loS-0-345c27d05ad7dfa1dfd364c1fd180621)
(4)代码的运行结果如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_36_4.jpg?sign=1738861868-dn2MZE1GsWhYdw1UXDI25YH3gFJfaINH-0-44b554819c727e7f606a9d7abde5c218)
3.4.4 自动求导
TensorFlow使用的求导方法被称为自动微分,它既不是符号求导也不是数值求导,而是两者的结合。
(1)TensorFlow 2.0利用tf.GradientTape API来实现自动求导功能,在tf.GradientTape()上下文中执行的操作都会被记录在“tape”中,然后TensorFlow 2.0使用反向自动微分来计算相关操作的梯度,示例代码如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_37_1.jpg?sign=1738861868-PSn6sOXRc7S6FEK10ZmKcYXgAR8Y9MLa-0-2c13262f23894b8f81205d25418374bd)
(2)代码的运行结果如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_37_2.jpg?sign=1738861868-SBncEJuYmuY2pJn29l5gTnTAI9PFN5WW-0-f0a792116889beb3038d4edb78fcde0c)
(3)输出中间变量的导数,代码如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_37_3.jpg?sign=1738861868-fbNcJyLnceEwurPXA1n8gKCADMuVdpzz-0-690985f6da450200f659a8400307617b)
(4)代码的运行结果如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_37_4.jpg?sign=1738861868-2CGuVT7DRSEKNcpMvlbNgONMV9Eo8WPu-0-94b0757a9100436e3cc540405afee0d2)
(5)在默认情况下,GradientTape的资源会在执行tf.GradientTape()后释放。如果希望多次计算梯度,需要创建一个持久的GradientTape。代码如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_37_5.jpg?sign=1738861868-PhWMha8FABKpZgtU9WpE1amsAdQ878QL-0-5ad159a6d12a9ab210358faeb940f187)
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_38_1.jpg?sign=1738861868-lLnQYKOU0ZNqJEnIaqaSqtlIclEW5ZQZ-0-4b29f538c6cb7af53d29d66974d1c072)
(6)代码的运行结果如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_38_2.jpg?sign=1738861868-xvjPo3pFC47MOAXAxoB3jdi629zx8CyU-0-b575c80ce67572528ac09e7df691f003)
(7)因为tape记录了整个操作,所以即使存在Python控制流(如if和while),也能正常处理梯度求导,示例代码如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_38_3.jpg?sign=1738861868-yq5x4n7pLYtd6uajdY07eg78mnjiC0e1-0-bc6b1f47ec40901d4acc54b3984c3f46)
(8)代码的运行结果如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_38_4.jpg?sign=1738861868-WlXpfcyMsPDepfEQdDLoZ1KyzraKLz1c-0-18bc05af22ddf67630f7f6a129d6b600)
(9)GradientTape上下文管理器在计算梯度时会保持梯度。因此,GradientTape也可以实现高阶梯度计算,示例代码如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_38_5.jpg?sign=1738861868-GKRXgBaRAdJzikBUwro420YiNdmA9T34-0-ffedc3951bb57d5ae82ec26cc0fdeef3)
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_39_1.jpg?sign=1738861868-SzxoF2sUN2tjUhbJymKWj5d92eeXoDJ4-0-b7a0f1a4236217200d945816f192d66c)
(10)代码的运行结果如下。
![](https://epubservercos.yuewen.com/938466/18002370308013906/epubprivate/OEBPS/Images/39376_39_2.jpg?sign=1738861868-giQ68QugqkBc9NuDNA6ruSS0IgULPl87-0-f9e236da32b42f3bd5b8677f0e94b9ba)
本章介绍了一些TensorFlow 2.0的基本概念并举例进行了说明,后面在使用到这些概念时,会举例对具体的使用方法进行介绍。