python常用激活函数,python中的激活函数

从零开始用Python构建神经网络

从零开始用Python构建神经网络

创新互联建站主要业务有网站营销策划、网站制作、成都网站制作、微信公众号开发、微信小程序定制开发H5网站设计、程序开发等业务。一次合作终身朋友,是我们奉行的宗旨;我们不仅仅把客户当客户,还把客户视为我们的合作伙伴,在开展业务的过程中,公司还积累了丰富的行业经验、网络营销推广资源和合作伙伴关系资源,并逐渐建立起规范的客户服务和保障体系。 

动机:为了更加深入的理解深度学习,我们将使用 python 语言从头搭建一个神经网络,而不是使用像 Tensorflow 那样的封装好的框架。我认为理解神经网络的内部工作原理,对数据科学家来说至关重要。

这篇文章的内容是我的所学,希望也能对你有所帮助。

神经网络是什么?

介绍神经网络的文章大多数都会将它和大脑进行类比。如果你没有深入研究过大脑与神经网络的类比,那么将神经网络解释为一种将给定输入映射为期望输出的数学关系会更容易理解。

神经网络包括以下组成部分

? 一个输入层,x

? 任意数量的隐藏层

? 一个输出层,?

? 每层之间有一组权值和偏置,W and b

? 为隐藏层选择一种激活函数,σ。在教程中我们使用 Sigmoid 激活函数

下图展示了 2 层神经网络的结构(注意:我们在计算网络层数时通常排除输入层)

2 层神经网络的结构

用 Python 可以很容易的构建神经网络类

训练神经网络

这个网络的输出 ? 为:

你可能会注意到,在上面的等式中,输出 ? 是 W 和 b 函数。

因此 W 和 b 的值影响预测的准确率. 所以根据输入数据对 W 和 b 调优的过程就被成为训练神经网络。

每步训练迭代包含以下两个部分:

? 计算预测结果 ?,这一步称为前向传播

? 更新 W 和 b,,这一步成为反向传播

下面的顺序图展示了这个过程:

前向传播

正如我们在上图中看到的,前向传播只是简单的计算。对于一个基本的 2 层网络来说,它的输出是这样的:

我们在 NeuralNetwork 类中增加一个计算前向传播的函数。为了简单起见我们假设偏置 b 为0:

但是我们还需要一个方法来评估预测结果的好坏(即预测值和真实值的误差)。这就要用到损失函数。

损失函数

常用的损失函数有很多种,根据模型的需求来选择。在本教程中,我们使用误差平方和作为损失函数。

误差平方和是求每个预测值和真实值之间的误差再求和,这个误差是他们的差值求平方以便我们观察误差的绝对值。

训练的目标是找到一组 W 和 b,使得损失函数最好小,也即预测值和真实值之间的距离最小。

反向传播

我们已经度量出了预测的误差(损失),现在需要找到一种方法来传播误差,并以此更新权值和偏置。

为了知道如何适当的调整权值和偏置,我们需要知道损失函数对权值 W 和偏置 b 的导数。

回想微积分中的概念,函数的导数就是函数的斜率。

梯度下降法

如果我们已经求出了导数,我们就可以通过增加或减少导数值来更新权值 W 和偏置 b(参考上图)。这种方式被称为梯度下降法。

但是我们不能直接计算损失函数对权值和偏置的导数,因为在损失函数的等式中并没有显式的包含他们。因此,我们需要运用链式求导发在来帮助计算导数。

链式法则用于计算损失函数对 W 和 b 的导数。注意,为了简单起见。我们只展示了假设网络只有 1 层的偏导数。

这虽然很简陋,但是我们依然能得到想要的结果—损失函数对权值 W 的导数(斜率),因此我们可以相应的调整权值。

现在我们将反向传播算法的函数添加到 Python 代码中

为了更深入的理解微积分原理和反向传播中的链式求导法则,我强烈推荐 3Blue1Brown 的如下教程:

Youtube:

整合并完成一个实例

既然我们已经有了包括前向传播和反向传播的完整 Python 代码,那么就将其应用到一个例子上看看它是如何工作的吧。

神经网络可以通过学习得到函数的权重。而我们仅靠观察是不太可能得到函数的权重的。

让我们训练神经网络进行 1500 次迭代,看看会发生什么。 注意观察下面每次迭代的损失函数,我们可以清楚地看到损失函数单调递减到最小值。这与我们之前介绍的梯度下降法一致。

让我们看看经过 1500 次迭代后的神经网络的最终预测结果:

经过 1500 次迭代训练后的预测结果

我们成功了!我们应用前向和方向传播算法成功的训练了神经网络并且预测结果收敛于真实值。

注意预测值和真实值之间存在细微的误差是允许的。这样可以防止模型过拟合并且使得神经网络对于未知数据有着更强的泛化能力。

下一步是什么?

幸运的是我们的学习之旅还没有结束,仍然有很多关于神经网络和深度学习的内容需要学习。例如:

? 除了 Sigmoid 以外,还可以用哪些激活函数

? 在训练网络的时候应用学习率

? 在面对图像分类任务的时候使用卷积神经网络

我很快会写更多关于这个主题的内容,敬请期待!

最后的想法

我自己也从零开始写了很多神经网络的代码

虽然可以使用诸如 Tensorflow 和 Keras 这样的深度学习框架方便的搭建深层网络而不需要完全理解其内部工作原理。但是我觉得对于有追求的数据科学家来说,理解内部原理是非常有益的。

这种练习对我自己来说已成成为重要的时间投入,希望也能对你有所帮助

如何用python激活指定窗口的输入框,方便下一步模拟输出

可以使用StringVar()对象来完成,把Entry的textvariable属性设置为StringVar(),再通过StringVar()的get()和set()函数可以读取和输出相应内容,以下为测试代码(python3.x):

from tkinter import *

def submit():

print(u.get())

p.set(u.get())

root = Tk()

root.title("测试")

frame = Frame(root)

frame.pack(padx=8, pady=8, ipadx=4)

lab1 = Label(frame, text="获取:")

lab1.grid(row=0, column=0, padx=5, pady=5, sticky=W)

#绑定对象到Entry

u = StringVar()

ent1 = Entry(frame, textvariable=u)

ent1.grid(row=0, column=1, sticky='ew', columnspan=2)

lab2 = Label(frame, text="显示:")

lab2.grid(row=1, column=0, padx=5, pady=5, sticky=W)

p = StringVar()

ent2 = Entry(frame, textvariable=p)

ent2.grid(row=1, column=1, sticky='ew', columnspan=2)

button = Button(frame, text="登录", command=submit, default='active')

button.grid(row=2, column=1)

lab3 = Label(frame, text="")

lab3.grid(row=2, column=0, sticky=W)

button2 = Button(frame, text="退出", command=quit)

button2.grid(row=2, column=2, padx=5, pady=5)

#以下代码居中显示窗口

root.update_idletasks()

x = (root.winfo_screenwidth() - root.winfo_reqwidth()) / 2

y = (root.winfo_screenheight() - root.winfo_reqheight()) / 2

root.geometry("+%d+%d" % (x, y))

root.mainloop()

效果如下:

原来ReLU这么好用!一文带你深度了解ReLU激活函数!

在神经网络中,激活函数负责将来自节点的加权输入转换为该输入的节点或输出的激活。ReLU 是一个分段线性函数,如果输入为正,它将直接输出,否则,它将输出为零。它已经成为许多类型神经网络的默认激活函数,因为使用它的模型更容易训练,并且通常能够获得更好的性能。在本文中,我们来详细介绍一下ReLU,主要分成以下几个部分:

1、Sigmoid 和 Tanh 激活函数的局限性

2、ReLU(Rectified Linear Activation Function)

3、如何实现ReLU

4、ReLU的优点

5、使用ReLU的技巧

一个神经网络由层节点组成,并学习将输入的样本映射到输出。对于给定的节点,将输入乘以节点中的权重,并将其相加。此值称为节点的summed activation。然后,经过求和的激活通过一个激活函数转换并定义特定的输出或节点的“activation”。

最简单的激活函数被称为线性激活,其中根本没有应用任何转换。 一个仅由线性激活函数组成的网络很容易训练,但不能学习复杂的映射函数。线性激活函数仍然用于预测一个数量的网络的输出层(例如回归问题)。

非线性激活函数是更好的,因为它们允许节点在数据中学习更复杂的结构 。两个广泛使用的非线性激活函数是 sigmoid 函数和 双曲正切 激活函数。

Sigmoid 激活函数 ,也被称为 Logistic函数神经网络,传统上是一个非常受欢迎的神经网络激活函数。函数的输入被转换成介于0.0和1.0之间的值。大于1.0的输入被转换为值1.0,同样,小于0.0的值被折断为0.0。所有可能的输入函数的形状都是从0到0.5到1.0的 s 形。在很长一段时间里,直到20世纪90年代早期,这是神经网络的默认激活方式。

双曲正切函数 ,简称 tanh,是一个形状类似的非线性激活函数,输出值介于-1.0和1.0之间。在20世纪90年代后期和21世纪初期,由于使用 tanh 函数的模型更容易训练,而且往往具有更好的预测性能,因此 tanh 函数比 Sigmoid激活函数更受青睐。

Sigmoid和 tanh 函数的一个普遍问题是它们值域饱和了 。这意味着,大值突然变为1.0,小值突然变为 -1或0。此外,函数只对其输入中间点周围的变化非常敏感。

无论作为输入的节点所提供的求和激活是否包含有用信息,函数的灵敏度和饱和度都是有限的。一旦达到饱和状态,学习算法就需要不断调整权值以提高模型的性能。

最后,随着硬件能力的提高,通过 gpu 的非常深的神经网络使用Sigmoid 和 tanh 激活函数不容易训练。在大型网络深层使用这些非线性激活函数不能接收有用的梯度信息。错误通过网络传播回来,并用于更新权重。每增加一层,错误数量就会大大减少。这就是所谓的 消失梯度 问题,它能有效地阻止深层(多层)网络的学习。

虽然非线性激活函数的使用允许神经网络学习复杂的映射函数,但它们有效地阻止了学习算法与深度网络的工作。在2000年代后期和2010年代初期,通过使用诸如波尔兹曼机器和分层训练或无监督的预训练等替代网络类型,这才找到了解决办法。

为了训练深层神经网络, 需要一个激活函数神经网络,它看起来和行为都像一个线性函数,但实际上是一个非线性函数,允许学习数据中的复杂关系 。该函数还必须提供更灵敏的激活和输入,避免饱和。

因此,ReLU出现了, 采用 ReLU 可以是深度学习革命中为数不多的里程碑之一 。ReLU激活函数是一个简单的计算,如果输入大于0,直接返回作为输入提供的值;如果输入是0或更小,返回值0。

我们可以用一个简单的 if-statement 来描述这个问题,如下所示:

对于大于零的值,这个函数是线性的,这意味着当使用反向传播训练神经网络时,它具有很多线性激活函数的理想特性。然而,它是一个非线性函数,因为负值总是作为零输出。由于矫正函数在输入域的一半是线性的,另一半是非线性的,所以它被称为 分段线性函数(piecewise linear function ) 。

我们可以很容易地在 Python 中实现ReLU激活函数。

我们希望任何正值都能不变地返回,而0.0或负值的输入值将作为0.0返回。

下面是一些修正的线性激活函数的输入和输出的例子:

输出如下:

我们可以通过绘制一系列的输入和计算出的输出,得到函数的输入和输出之间的关系。下面的示例生成一系列从 -10到10的整数,并计算每个输入的校正线性激活,然后绘制结果。

运行这个例子会创建一个图,显示所有负值和零输入都突变为0.0,而正输出则返回原样:

ReLU函数的导数是斜率。负值的斜率为0.0,正值的斜率为1.0。

传统上,神经网络领域已经不能是任何不完全可微的激活函数,而ReLU是一个分段函数。从技术上讲,当输入为0.0时,我们不能计算ReLU的导数,但是,我们可以假设它为0。

tanh 和 sigmoid 激活函数需要使用指数计算, 而ReLU只需要max(),因此他 计算上更简单,计算成本也更低 。

ReLU的一个重要好处是,它能够输出一个真正的零值 。这与 tanh 和 sigmoid 激活函数不同,后者学习近似于零输出,例如一个非常接近于零的值,但不是真正的零值。这意味着负输入可以输出真零值,允许神经网络中的隐层激活包含一个或多个真零值。这就是所谓的稀疏表示,是一个理想的性质,在表示学习,因为它可以加速学习和简化模型。

ReLU看起来更像一个线性函数,一般来说,当神经网络的行为是线性或接近线性时,它更容易优化 。

这个特性的关键在于,使用这个激活函数进行训练的网络几乎完全避免了梯度消失的问题,因为梯度仍然与节点激活成正比。

ReLU的出现使得利用硬件的提升和使用反向传播成功训练具有非线性激活函数的深层多层网络成为可能 。

很长一段时间,默认的激活方式是Sigmoid激活函数。后来,Tanh成了激活函数。 对于现代的深度学习神经网络,默认的激活函数是ReLU激活函数 。

ReLU 可以用于大多数类型的神经网络, 它通常作为多层感知机神经网络和卷积神经网络的激活函数 ,并且也得到了许多论文的证实。传统上,LSTMs 使用 tanh 激活函数来激活cell状态,使用 Sigmoid激活函数作为node输出。 而ReLU通常不适合RNN类型网络的使用。

偏置是节点上具有固定值的输入,这种偏置会影响激活函数的偏移,传统的做法是将偏置输入值设置为1.0。当在网络中使用 ReLU 时, 可以将偏差设置为一个小值,例如0.1 。

在训练神经网络之前,网络的权值必须初始化为小的随机值。当在网络中使用 ReLU 并将权重初始化为以零为中心的小型随机值时,默认情况下,网络中一半的单元将输出零值。有许多启发式方法来初始化神经网络的权值,但是没有最佳权值初始化方案。 何恺明的文章指出Xavier 初始化和其他方案不适合于 ReLU ,对 Xavier 初始化进行一个小的修改,使其适合于 ReLU,提出He Weight Initialization,这个方法更适用于ReLU 。

在使用神经网络之前对输入数据进行缩放是一个很好的做法。这可能涉及标准化变量,使其具有零均值和单位方差,或者将每个值归一化为0到1。如果不对许多问题进行数据缩放,神经网络的权重可能会增大,从而使网络不稳定并增加泛化误差。 无论是否在网络中使用 ReLU,这种缩放输入的良好实践都适用。

ReLU 的输出在正域上是无界的。这意味着在某些情况下,输出可以继续增长。因此,使用某种形式的权重正则化可能是一个比较好的方法,比如 l1或 l2向量范数。 这对于提高模型的稀疏表示(例如使用 l 1正则化)和降低泛化误差都是一个很好的方法 。

.


分享标题:python常用激活函数,python中的激活函数
URL地址:http://ybzwz.com/article/dsidcog.html