Introduction

在本课中,我们将学习如何构建能够学习深度神经网络所擅长的复杂关系的神经网络。

这里的关键思想是模块化,即由更简单的功能单元构建复杂的网络。我们已经了解了线性单元如何计算线性函数——现在我们将学习如何组合和修改这些单个单元来模拟更复杂的关系。

Layers

神经网络通常将神经元组织成。当我们将具有共同输入集的线性单元聚集在一起时,我们就得到了一个密集层。

A stack of three circles in an input layer connected to two circles in a dense layer.两个线性单元的密集层接收两个输入和一个偏差。

你可以将神经网络中的每一层想象成执行某种相对简单的变换。通过深层的堆叠,神经网络可以以越来越复杂的方式转换其输入。在一个训练有素的神经网络中,每一层都是一种变换,让我们离解决方案更近一步。

多种类型的层
Keras 中的“层”是一种非常通用的概念。层本质上可以是任何类型的数据转换。许多层,例如卷积层循环层,通过使用神经元来转换数据,其主要区别在于它们形成的连接模式。而其他层则用于特征工程或仅仅简单的算术运算。还有各种各样的层等待您去探索——快来查看

The Activation Function

然而,事实证明,两个中间没有任何中间层的密集层并不比单独的一个密集层好。密集层本身永远无法让我们脱离线和平面的世界。我们需要的是“非线性”的东西。我们需要的是激活函数。

 如果没有激活函数,神经网络只能学习线性关系。为了拟合曲线,我们需要使用激活函数。

激活函数就是我们应用于每一层输出(其激活)的函数。最常见的是整流函数 max(0,x)。

A graph of the rectifier function. The line y=x when x>0 and y=0 when x<0, making a 'hinge' shape like '_/'.

整流函数的图形会移动一条直线,将负部分“整流”至零。将该函数应用于神经元的输出会使数据产生“弯曲”,使其不再是简单的直线。

当我们将整流器连接到线性单元时,我们会得到一个整流线性单元,即ReLU。(因此,通常将整流函数称为“ReLU 函数”。)将 ReLU 激活函数应用于线性单元意味着输出变为 max(0, w * x + b),我们可以将其绘制成如下图表:

Diagram of a single ReLU. Like a linear unit, but instead of a '+' symbol we now have a hinge '_/'. 整流线性单元。

Stacking Dense Layers

现在我们有了一些非线性,让我们看看如何堆叠层来获得复杂的数据转换。

An input layer, two hidden layers, and a final linear layer.多层密集层构成了一个“全连接”网络。

输出层之前的层有时被称为隐藏层,因为我们无法直接看到它们的输出。

现在,请注意,最后一层(输出层)是一个线性单元(也就是说,没有激活函数)。这使得该网络适合回归任务,我们试图预测任意数值。其他任务(例如分类)可能需要对输出使用激活函数。

Building Sequential Models

我们一直使用的“顺序”模型会将一系列层按从头到尾的顺序连接在一起:第一层获取输入,最后一层产生输出。这将创建上图中的模型:

from tensorflow import keras
from tensorflow.keras import layers

model = keras.Sequential([
# the hidden ReLU layers
layers.Dense(units=4, activation='relu', input_shape=[2]),
layers.Dense(units=3, activation='relu'),
# the linear output layer
layers.Dense(units=1),
])

请务必将所有层级以列表形式一起传递,例如 [layer, layer, layer, ...],而不是作为单独的参数。要向层级添加激活函数,只需在 activation 参数中提供其名称即可。