跳转至

Hardware and Software

约 3303 个字 24 行代码 预计阅读时间 17 分钟

原文如下

内容列表:

  • 不用大脑做类比的快速简介
  • 单个神经元建模
    • 生物动机和连接
    • 作为线性分类器的单个神经元
    • 常用的激活函数
  • 神经网络结构 译者注:下篇翻译起始处
    • 层组织
    • 前向传播计算例子
    • 表达能力
    • 设置层的数量和尺寸
  • 小节

神经网络结构

灵活的组织层

  • 图形化神经网络算法

神经网络通过神经元(单元)进行建模,这些神经元相互连接,形成无环图结构。这意味着在网络中,每个神经元的输出可以作为其他神经元的输入,但不能形成循环路径,否则会导致前向传播中的无限循环问题。与生物神经元不同,人工神经网络的神经元是分层组织的,以便于执行矩阵乘法和其他线性代数操作。

  • 全连接层(Fully-Connected Layer): 在普通神经网络中,最常见的层类型是全连接层。在全连接层中,每个神经元都与前一层和后一层的所有神经元相连接,但在同一层内,神经元之间没有连接。下图展示了两个使用全连接层的神经网络结构:

img

左图展示了一个两层神经网络,包含一个4个神经元的隐层和一个2个神经元的输出层。右图展示了一个三层神经网络,包含两个4个神经元的隐层。请注意,层与层之间的神经元是全连接的,而层内的神经元没有连接。

  • 命名规则

当我们说到“N层神经网络”时,不包括输入层。例如,一个单层神经网络意味着没有隐层,输入直接映射到输出。基于此,逻辑回归和SVM可以看作是单层神经网络的特例。

研究者通常使用人工神经网络(Artificial Neural Networks, ANN)多层感知器(Multi-Layer Perceptrons, MLP)来指代神经网络。由于一些研究者不喜欢神经网络与人类大脑之间的类比,他们更倾向于使用单元(Unit)而不是“神经元”这个术语。

  • 输出层。 神经网络的输出层通常不会使用激活函数,或者使用等效于线性激活函数的恒等函数。这是因为输出层用于表示分类得分或回归预测值,这些值可以是任意的实数。

  • 确定网络尺寸。 用来度量神经网络的尺寸的标准主要有两个:一个是神经元的个数,另一个是参数的个数,用上面图示的两个网络举例:

  • 第一个网络有 \(4+2 = 6\)个神经元(输入层不算),\([3\times4]+[4\times2] = 20\) 个权重,还有 \(4+2 = 6\) 个偏置,共 26 个可学习的参数。

  • 第二个网络有 \(4+4+1 = 9\) 个神经元,\([3\times4]+[4\times4]+[4\times1] = 32\) 个权重,\(4+4+1 = 9\) 个偏置,共 41 个可学习的参数。

现代深度卷积神经网络(CNN)通常包含数亿个参数,并由10-20层组成,形成所谓的“深度学习”模型。然而,由于参数共享的存在,有效连接的数量大大增加。

前向传播计算举例

神经网络的前向传播过程是通过一系列矩阵乘法和激活函数应用实现的。网络被组织成层状结构,能够简化并高效地执行这些操作。以下通过一个三层神经网络的例子,详细说明前向传播的计算过程。

img

假设我们有一个三层神经网络:

  1. 输入层:维度为3(即3个输入特征)。输入是 [3x1] 的向量
  2. 第一个隐层:4个神经元。
  3. 第二个隐层:4个神经元。
  4. 输出层:1个神经元。

对于该网络,以下是权重矩阵和偏置向量的维度:

  • W1:形状为[4x3],用于第一个隐层的连接权重。矩阵乘法 np.dot(W1, x) 就能计算该层中所有神经元的激活数据
  • b1:形状为[4x1],用于第一个隐层的偏置。
  • W2:形状为[4x4],用于第二个隐层的连接权重。
  • b2:形状为[4x1],用于第二个隐层的偏置。
  • W3:形状为[1x4],用于输出层的连接权重。
  • b3:形状为[1x1],用于输出层的偏置。
import numpy as np

# 定义激活函数 (Sigmoid)
f = lambda x: 1.0 / (1.0 + np.exp(-x))

# 随机初始化输入向量
x = np.random.randn(3, 1)  # 输入向量,形状为 [3x1]

# 随机初始化权重矩阵和偏置向量
W1 = np.random.randn(4, 3)  # 第一层权重矩阵,形状为 [4x3]
b1 = np.random.randn(4, 1)  # 第一层偏置向量,形状为 [4x1]

W2 = np.random.randn(4, 4)  # 第二层权重矩阵,形状为 [4x4]
b2 = np.random.randn(4, 1)  # 第二层偏置向量,形状为 [4x1]

W3 = np.random.randn(1, 4)  # 输出层权重矩阵,形状为 [1x4]
b3 = np.random.randn(1, 1)  # 输出层偏置向量,形状为 [1x1]

# 前向传播过程
h1 = f(np.dot(W1, x) + b1)  # 第一个隐层激活
h2 = f(np.dot(W2, h1) + b2)  # 第二个隐层激活
out = np.dot(W3, h2) + b3  # 输出层的输出

print("输出结果:", out)
  1. 输入向量: 假设输入向量 x 的形状为[3x1],代表输入的三个特征。
  2. 第一个隐层计算: 计算第一个隐层的线性组合:z1 = np.dot(W1, x) + b1,其中 z1 形状为[4x1]。 应用激活函数(如 Sigmoid):h1 = f(z1),其中 h1 也是[4x1]。
  3. 第二个隐层计算: 计算第二个隐层的线性组合:z2 = np.dot(W2, h1) + b2,其中 z2 形状为[4x1]。 应用激活函数:h2 = f(z2),其中 h2 也是[4x1]。
  4. 输出层计算: 计算输出层的线性组合:out = np.dot(W3, h2) + b3,其中 out 形状为[1x1]。 输出层通常不包含激活函数,尤其是在回归任务或分类任务中的评分阶段。

全连接层的前向传播一般就是先进行一个矩阵乘法,然后加上偏置并运用激活函数。

表达能力

神经网络被认为是通用近似器,特别是对于具有至少一个隐层的网络。这个理论的基础来源于1989年的研究,这些研究证明了神经网络可以在一定条件下逼近任意的连续函数。具体而言,给定任意连续函数 \(f(x)\) 和任意 \(\epsilon > 0\),总能找到一个至少包含一个隐层的神经网络 \(g(x)\),使得对于所有的 \(x\),有 \(|f(x) - g(x)| < \epsilon\)。这表明,只要适当地选择网络结构和激活函数(如Sigmoid函数),神经网络就具备足够的表达能力来逼近几乎任何函数。

为什么需要更深的网络?

尽管理论上一个含有足够神经元的两层网络就可以近似任意连续函数,但在实践中,深度网络(具有多个隐层的网络)往往表现更好。这是因为:

  1. 平滑性与可学习性:深度网络能够学习到更平滑且更适合数据统计特性的函数,这使得它们不仅在逼近函数时表现出色,还能有效地进行推广。同时,网络通过最优化算法(例如梯度下降)能比较容易地学习到这个函数。
  2. 结构化数据:在处理图像、语音等具有层次化结构的数据时,深度网络的多层处理有助于逐级提取高层特征,这样能更好地捕捉数据的复杂模式。例如,卷积神经网络(CNN)中的多层结构在图像识别任务中取得了显著成功。

实际应用中的深度与性能

尽管理论上三层神经网络已经足以处理许多问题,实验证明增加网络深度(如扩展到4层或更多层)在某些任务中并没有显著的提升。然而,对于卷积神经网络等特殊结构,深度是至关重要的,能够显著提升识别系统的表现。这种效果的原因可能在于这些数据具有层次结构,深度网络能够逐层抽象出不同级别的特征。

设置层的数量和尺寸

在面对一个具体问题的时候该确定网络结构呢?到底是不用隐层呢?还是一个隐层?两个隐层或更多?每个层的尺寸该多大?

线性问题:如果问题是线性可分的,通常无需使用隐层。可以直接使用线性模型(例如线性回归、逻辑回归)解决问题。

非线性问题:如果问题较为复杂且具有非线性特征,则至少需要一个隐层来捕捉非线性关系。

根据数据特征选择层数

  • 一个隐层:对于一般的非线性问题,一个隐层的网络(即两层网络,包括输入层)就足以近似任何连续函数。通常,这个隐层包含较少的神经元(如10到100个)即可解决简单或中等复杂度的问题。
  • 多个隐层:对于更复杂的任务,如图像分类、语音识别、自然语言处理等,使用多个隐层的深度网络可能更合适。深度网络可以捕捉数据的层次化结构,有效处理更复杂的模式。

img

更大的神经网络可以表达更复杂的函数。数据是用不同颜色的圆点表示他们的不同类别,决策边界是由训练过的神经网络做出的。你可以在[ConvNetsJS demo__][26]上练练手。

当神经网络模型过大(即神经元数量和层数较多)时,网络可能会非常灵活,能够精确地拟合训练数据中的所有细节,包括噪声和异常点。虽然这会使训练误差很低,但也会导致模型的泛化能力下降,即在测试集或新数据上的表现较差。

举个例子,如果我们训练一个有20个神经元隐层的网络,它可能会过度拟合训练数据,导致决策边界变得非常复杂,出现许多不相连的区域,这些区域可能只是在特定数据点附近划分出来的。相反,如果我们使用一个有3个神经元的隐层模型,它的决策边界会更加平滑,即使无法完美地分类所有训练数据,但它更有可能在测试集上表现良好,因为它更倾向于捕捉数据的整体模式,而不是特定数据点的噪声。

防止过拟合的有效方法包括:

  • L2 正则化:通过添加惩罚项来抑制过大的权重值。
  • Dropout:在训练过程中随机丢弃部分神经元,减少网络对特定路径的依赖。
  • 数据增强和输入噪声:通过人为增加数据的多样性,提升模型的泛化能力。

在实际应用中,正则化方法如 L2 正则化和 Dropout 是防止大网络过拟合的有效手段。正则化通过在损失函数中引入惩罚项或随机丢弃神经元,减少了模型对训练数据中噪声的依赖,从而提高了模型的泛化能力。如下图所示,随着正则化强度的增加,决策边界变得更加平滑,从而降低了过拟合的风险。

img

在非凸的神经网络损失函数中,局部极小值的存在是不可避免的。较小的网络由于容量限制,可能会更快地收敛到这些局部极小值,但这些极小值的损失值通常较高,导致模型的最终表现不佳。相反,较大的网络虽然也面临局部极小值的问题,但由于它们有更高的容量和更复杂的表达能力,往往能找到更好的局部极小值,从而实现更低的损失值。

这一现象解释了为什么大网络通常表现更稳定:它们在不同的初始化条件下训练时,即使最终的解不同,损失值也不会相差太大。较大的网络往往能够收敛到多个较好的局部极小值,使得它们的最终表现更一致且更优。

综上所述,面对具体问题时,不应因担心过拟合而限制网络的大小。相反,应优先选择较大的网络,并通过正则化等技术手段来控制过拟合。这样的策略不仅能确保模型有足够的容量来学习复杂的模式,还能避免陷入表现不佳的局部极小值,最终实现更好的泛化能力和更稳定的性能表现。

小结

小结如下:

  • 神经网络结构:介绍了神经网络的基本架构,强调了神经元通过全连接层相连,层间神经元两两相连,而层内神经元不相连的特点。
  • 分层结构的优势:理解了神经网络的分层结构有助于高效执行矩阵乘法和激活函数运算,从而提高网络的计算效率。
  • 通用函数近似器:理解了神经网络具有通用函数近似能力,但这一性质并非其广泛使用的主要原因。神经网络被广泛应用,是因为它们能够对实际问题中的函数形式做出合理的假设。
  • 网络容量与正则化:讨论了网络容量与模型性能的关系,明确了更大容量的网络在理论上表现更优,但需要通过加强正则化(如权重衰减)来防止过拟合。后续章节将进一步探讨正则化技术,特别是 dropout。