demm 2019-05-14
随着Tensorflow 2.0和Fast ai等的兴起,深度学习已经为更多人所接受,这有助于理解深度神经网络背后的基础知识。希望这篇文章能够帮助人们了解深层神经网络的学习之路。
回到我第一次了解神经网络并实现我的第一个神经网络时的那个时间段,它们总是被表示为单独的人工神经元,本质上是具有单独加权输入、求和输出和激活函数的节点。
当第一次回到深度神经网络的学习中时,这种等同于矩阵乘法的概念似乎并不明显。此外,与此相关的是图形处理单元(GPU)及其衍生产品,这是有助于推动深度学习成果的原因之一。
一个非常简单的神经网络与矩阵乘法相比
让我们以一个非常简单的网络为例,其中一个隐藏层包含两个神经元。每个神经元都有两个权重,每个输入都有一个单独的权值。每个权重乘以进入神经元的每个输入,然后将它们相加,并在通过激活函数馈送后形成神经元的输出。
一个非常简单的网络
这与应用两个矩阵乘法后跟激活函数相同。
第一个矩阵点乘积乘法。使用优秀的http://matrixmultiplication.xyz生成
第二个矩阵点乘积乘法。使用优秀的http://matrixmultiplication.xyz生成
GPU启用的进步
我们离开最后一个所谓的“AI冬天”的原因之一是人工智能和机器学习研究和兴趣放缓并变得“冰冷”,因为使用GPU在计算方面取得了进步。
传统上,GPU用于计算机图形和计算机视频游戏领域。计算机图形需要非常快速的矩阵乘法。计算机视频游戏行业对GPU计算能力的需求引起了GPU设计者和制造商的巨大进步。
值得注意的是,最大的GPU公司之一Nvidia发布了CUDA(一种用于Nvidia GPU编程的语言/ API)和cuDNN(一种使用CUDA构建的深度神经网络库)。这些允许在训练神经网络中的计算更容易地移动到GPU,其中这些被打包为PyTorch的一部分,并且安装在TensorFlow中相对容易。只要计算可以并行执行,就使计算时间减少了几个数量级。
矩阵乘法是一个线性函数
矩阵乘法是一个线性函数。许多线性函数层叠在一起仍然是线性函数,只是参数不同。因此,分层在一起的许多矩阵乘法仍然只是一个线性函数。
线性函数是仿射函数的子集,仿射函数是将值相乘并求和的函数,线性函数总是仿射的。
卷积神经网络(CNN)中使用的卷积是一种特殊的仿射函数,可以很好地处理自动相关数据,通常是图像,但也可以适用于其他领域,如蛋白质之间的相互作用、药物设计。这些卷积是元素乘积矩阵乘法,而不是点积乘法。此外,元素矩阵乘法也是线性的。
非线性激活功能
激活函数是非线性函数的一种形式。传统上,在神经网络中,使用sigmoid 函数作为非线性激活函数。在现代架构中,整流线性单元(ReLU)用作激活函数或其变体之一。
ReLU听起来很复杂,其维基百科页面显得它更为复杂:https://en.m.wikipedia.org/wiki/Rectifier_(neural_networks) - 如果值小于零,则ReLU表示将值四舍五入为零,这和ReLU一样复杂。
有一个称为Leaky ReLU的变体,它与ReLU相同,除非该值小于零,它乘以0.1而不是四舍五入为零。之所以这么说,是因为它允许少量的值泄漏到激活中。
某些时候激活函数的选择并不总是那么重要,只是它是非线性的。如果没有非线性激活函数,则神经网络不会被认为是深度的,因为它只是一个线性函数。线性函数永远不能执行复杂的任务,例如对电影评论进行分类或识别卫星图像中的地形类型。
这些任务可以用足够大的矩阵乘法执行,每个矩阵乘法后面都有一个非线性。当足够的这些线性和非线性层夹在一起时,网络变得非常深,可以产生任意形状或函数,近似于任何东西。
这些计算的结果或输出称为激活,通过训练网络来学习这些激活的原因,这些训练值是系数/参数,通常称为权重和偏差。
参数/权重
这些参数的值是随机初始化的,或者是从使用迁移学习的预训练模型中复制的。
使用反向传播作为梯度计算技术,使用随机梯度下降(SGD)或其他更快版本的SGD训练这些参数。 SGD是一种最小化损失函数的优化。
随机梯度下降(SGD)、损失函数和反向传播
损失函数评估训练期间预测输出与实际输出的距离。这可以是简单的数学计算或各种因素的复杂组合,基于正在执行的会话(例如分类或回归)使用不同的函数。
损失函数用于评估网络在训练期间的性能,损失变化的梯度是反向传播的,并用于更新权重以最小化损失。
计算每个节点的输出值,并在通过网络的正向传递中进行高速缓存。然后通过网络的计算图,计算出误差对各参数的偏导数。
根据误差的导数,它表明损失是增加还是减少,以及如何通过什么速率(多么陡峭),然后使用这一点来更新参数少量以减少损失。学习速率乘数用于缩小更新的幅度,以尝试确保训练不会在损失空间中采取太大的步骤,这有助于优化权重的更新量。
这个过程是SGD。
分类
对于用于分类的训练网络,使用的损失函数是交叉熵。交叉熵基于预测正确的类别以及预测正确的信心而提供损失。如果训练示例是一个类(值为1),则应用一个公式来实现这一点,如果训练示例不属于该类(值为0),则应用另一个公式来实现这一点。
假设预测在0和1之间,那么:
回归
如果使用网络用于回归,那么训练损失函数通常为零,通常将均方误差(MSE)或均方根误差(RMSE)用作损失函数内的度量。
最后一层激活函数
分类中的最后一个输出层表示类别得分,它们是任意实数值,或者是回归类型的实值目标。这些任务使用不同的激活函数。
二元分类
二元分类问题是将类别中的数据分类为一个类或不属于该类的问题,例如“有肿瘤”或“没有肿瘤”。 Sigmoid函数通常用作最后一层激活函数使用,因为它在两个类之间差别很大。
sigmoid函数的图形:f(x)= 1 /(1 + e ^ -x)
sigmoid函数的图:f(x)= 1 /(1 + e ^ -x)
sigmoid函数渐近为零,渐近为1,输出0到1之间的值。值大于或小于0.5,表示预测数据将被分类为这两个类中的哪一个。
利用来自sigmoid函数的输出的形状,其中激活小于0.5,则sigmoid函数将返回较低的概率值,并且如果激活大于0.5,则sigmoid函数将返回较高的概率值。
下面描述的Softmax函数可以在这里使用,而不是sigmoid函数。如果有两个输出,每个输出表示两个类中的一个。最好在这里使用sigmoid函数,因为它更快。
多级单标签分类
在多类单标签分类中,有许多类可以将数据分类为多个类,但只能使用这些类中的单个标签进行分类。这方面的一个例子是尝试对狗品种进行分类,代表狗的数据只能有一个品种。
Softmax函数用于多类单标签分类。给定类i的输出被视为e ^ i除以e ^ k的和,其中k是每个类。
Softmax函数非常适合挑选单个标签。它输出一个概率分布,其中输出总和为1。每个类的输出范围介于0和1之间。所有类的概率之和为1。
预测类具有最高的概率输出。
多类,多标签分类
在多类,多标签分类中,可以将数据分类为许多类,并且可以使用来自那些类的一个或多个标签对数据进行分类。
例如,卫星图像可以被标记为不同的天气和特征类别,例如云、森林、农业、水、湖泊和河流。图像很容易属于这些类中的许多类。
使用sigmoid函数是因为对于给定的数据项,可能有多个具有高概率的标签。
由于概率之和不等于1,每个类的概率都在0到1之间,不能有效地使用Softmax。即使是有经验的从业者,这也是一个常见的错误,
回归
使用回归,输出是一个数字还是一组数字,具体取决于问题。如果有一个以上的输出,则称为多元回归。
执行回归时的输出值通常是无限的。
通常使用回归时,没有最后一层激活函数,尽管在某些应用程序中偶尔使用Sigmoid函数可能是有益的,例如当使用回归进行协同过滤时。
编译出品