一、神经元与激活函数

2023-12-21 18:38:14

生物学家在20世纪初就发现了生物神经元的结构。一个生物神经元通常具有多个树突和一条轴突。树突用来接受信息,轴突用来发送信息。当神经元所获得的输入信号的积累超过某个阈值时,它就处于兴奋状态,产生电脉冲。轴突尾端有许多末梢可以给其他个神经元的树突产生连接(突触),并将电脉冲信号传递给其它神经元。 1943年,心理学家McCulloch和数学家Pitts根据生物神经元的结构,提出了一种非常简单的神经元模型,MP神经元1。现代神经网络中的神经元和 M-P 神经元的结构并无太多变化。

人工神经元

MP神经元

我们通过类比生物神经元的结构与信息传递机制,可以给出MP神经元如下的定义:

MP神经元本质上是一个处理一组输入信号并输出一个信号的非线性函数,即最终非线性函数过滤并作最终输出之前,是以线性函数的形式组合输入信号。

  1. 输入信号:MP神经元接收一组输入信号,通常表示为一个数值向量。这些输入信号可以理解为其他神经元的输出或外部刺激。

  2. 权重:每个输入信号都有一个相应的权重,这些权重可以是正的(激励性连接)或负的(抑制性连接)。权重决定了相应输入信号对神经元输出的影响程度。

  3. 加权求和:神经元计算所有输入信号与其对应权重的加权和。这相当于对输入信号进行线性组合。

  4. 偏置:通常会有一个偏置项加入到加权和中,用于调整神经元的激活阈值。

  5. 激活函数:MP神经元使用一个简单的阶跃函数作为激活函数。如果加权输入和(包括偏置)超过某个阈值,神经元就会被激活(输出1),否则不激活(输出0)。

  6. 输出:由于MP神经元使用阶跃函数作为激活函数,所以输出是二值的,通常为0(未激活)或1(激活)。

在这里插入图片描述

MP神经元模型虽然简单,但它在神经网络和计算神经科学的早期发展中发挥了重要作用。它为更复杂的神经网络模型和算法奠定了基础。下面,我们使用Python代码来实现一个MP神经元模型,来展现一个神经元的处理过程。

def mp_neuron(input_vector, weights, bias):
    """
    General implementation of a mp - neural network neuron.

    :param input_vector: List of input signals (numeric values).
    :param weights: Corresponding weights for each input signal.
    :param bias: Bias term.
    :return: Output of the neuron (0 or 1).
    """
    # Calculate the weighted sum of inputs and bias
    weighted_sum = sum(i * w for i, w in zip(input_vector, weights)) + bias

    # Activation (Step function)
    return 1 if weighted_sum > 0 else 0

人工神经元

于是,人工神经元的数学模型可以抽象成:

假设一个神经元接受 d d d个输入 x 1 , x 2 , ? ? ? , x d x_1,x_2,··· ,x_d x1?,x2?,???,xd?,令向量 x = [ x 1 , x 2 , ? ? ? , x d ] x = [x_1,x_2,··· ,x_d] x=[x1?,x2?,???,xd?]来表示这组输入,并用净输入 z ∈ R z ∈ R zR 表示一个神经元所获得的输入信号 x x x 的加权和,

z = ∑ i = 1 d w i x i + b = W T x + b z=\sum_{i=1}^d w_ix_i+b = W^Tx+b z=i=1d?wi?xi?+b=WTx+b

其中 x = [ x 1 , x 2 , ? ? ? , x d ] ∈ R d x = [x_1,x_2,··· ,x_d] ∈ \mathbb{R} ^d x=[x1?,x2?,???,xd?]Rd d d d维的权重向量, b ∈ R b ∈ \mathbb{R} bR 是偏置。

净输入 z z z在经过一个非线性函数 f ( ? ) f(~) f(?)后,得到神经元的活性值 a a a,即 a = f ( z ) a=f(z) a=f(z)

其中非线性函数 f ( ? ) f(~) f(?)被称为激活函数

于是,我们可以通过组合这些人工神经元来模拟人脑的神经网络,即而组成了人工神经网络,不同神经元之间的连接被赋予了不同的权重,每个权重代表了一个神经元对另一个神经元的影响大小。每个神经元代表一种特定函数,来自其他神经元的信息经过其相应的权重综合计算,输入到一个激活函数中并得到一个新的活性值(兴奋或抑制)。整体来看,人工神经元网络是由大量神经元通过极其丰富和完善的连接而构成的自适应非线性动态系统。而通过某种算法,调整这个系统中每个神经元的权重和偏置信息,以逼近目标模型的过程,就是神经网络的训练过程。

import numpy as np

def neural_network_neuron(input_vector, weights, bias, activation_function):
    """
    General implementation of a neural network neuron.

    :param input_vector: numpy array representing the input vector [x1, x2, ..., xd].
    :param weights: numpy array representing the weights for each input [w1, w2, ..., wd].
    :param bias: Bias term (scalar).
    :param activation_function: The activation function to be applied.
    :return: The activity value (output) of the neuron.
    """
    # Calculate the weighted sum of inputs and bias (net input z)
    z = np.dot(weights, input_vector) + bias

    # Apply the activation function to get the activity value (a)
    a = activation_function(z)

    return a

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

在这里的代码示例中,该神经元调用的激活函数是Sigmoid函数,这是最常用的激活函数之一,后面将进行更深入的讨论。

在这里我们可以看出,无论从生物学方面来看,还是数学方面来讲,激活函数在神经元中的作用都是十分重要的。因为:

  1. 如果没有激活控制(激活函数),生物神经网络中就无法控制每个神经元选择性地将信号传递给下一个神经元,也就无法模拟出神经元的兴奋状态。
  2. 如果激活函数,数学神经网络模型变退化成了若干线性函数的线性组合,那么最终仍然等效于一个线性函数,这也就无法实现复杂的模型功能了。

因此,如何正确的设计和使用激活函数变得尤为重要,我们不难看出,激活函数首先应该具备以下的性质:

  • 激活函数必须是一个非线性函数;
  • 一般一个神经网络要包含大量的神经元,那么激活函数就要设计的尽可能的简单,以有利于提高整个网络的计算效率;
  • 激活函数的定义域一般设定为 R \mathbb{R} R,这是为了考虑能够处理所有可能的输入,但是值域要设定在一个合适的区间,不能太大也不能太小,否则会影响整个网络系统的计算时的效率和稳定性。

激活函数

Sigmoid型函数

Sigmoid 型函数是指一类 S 型曲线函数,为两端饱和函数。这里的两端饱和指的是在整个函数 f ( x ) f(x) f(x)在趋于无穷大时,它的导数趋于 0 0 0,函数图像如下图所示。
常用的 Sigmoid型函数有 Logistic 函数Tanh 函数
在这里插入图片描述
Logistic 函数

Logistic 函数定义为:

σ ( x ) = 1 1 + e ? x \sigma(x)=\frac{1}{1+e^{-x}} σ(x)=1+e?x1?

Logistic 函数将整个实数域 R \mathbb{R} R 映射到 ( 0 , 1 ) (0,1) (0,1) 这个区间里,因此该函数的输出可以直接看作是一个概率分布,在概率上更好获得解释。同时,与阶跃函数相比,Logistic函数更加缓和,输入越小,输出越接近 0 0 0,输入越大,输出越接近 1 1 1,并且在输入为 0 0 0的附近,Sigmoid函数近似于线性函数。

Tanh 函数

Tanh 函数可以看作是放大并平移过的Logistic函数,其定义为:

t a n h ( x ) = e x ? e ? x e x + e ? x = 2 σ ( 2 x ) ? 1 tanh(x)=\frac{e^x-e^{-x}}{e^x+e^{-x}} =2\sigma (2x)-1 tanh(x)=ex+e?xex?e?x?=2σ(2x)?1

与Logistic 函数相比,Tanh 函数的输出并不是那么符合“生物学直觉”,因为它是将整个实数域 R \mathbb{R} R 映射到 ( ? 1 , 1 ) (-1,1) (?1,1) 这个区间里。但是Tanh 函数是 “零中心化函数” ,即当输入是 0 0 0时,输出也是 0 0 0,且输出的数据在正负方向上分布均匀,但Logistic 函数的输出始终是正的。

这也就导致了在大量神经元信息传递的过程中,上一级的神经元输出都是正值,那么下一级的神经元的输入将被推向正方向,导致偏移。这种偏移可能会对之后的神经网络训练造成影响,这部分将在后面进行讨论。

Hard-Logistic 函数和 Hard-Tanh函数

由于Logistic 函数和Tanh 函数都是饱和性激活函数,也就意味着如果输入值过大或过小,输出就会非常接近边界值(Logistics 中的 0 0 0 1 1 1,Tanh 中的 ? 1 -1 ?1 1 1 1),那么在之后的神经网络训练过程(调整神经元内权重和偏置以近似目标模型)中,前后输出的差异非常小,这样就消耗了一定的计算资源,但这些计算对于学习过程来说几乎是无用的,即对整个训练贡献较小。因此,我们可以通过使用分段函数近似这两个激活函数,来减轻这方面的负担。

Hard-Logistic 函数

Logistics 函数在 0 0 0附近的一阶泰勒展开为:

g L ≈ σ ( 0 ) + x σ ′ ( 0 ) = 0.25 x + 0.5 g_L\approx \sigma (0)+x\sigma '(0)=0.25x+0.5 gL?σ(0)+xσ(0)=0.25x+0.5

于是使用分段函数近似Logistics 函数,可以表示为:

H a r d L o g i s t i c ( x ) = { 1 g L ( x ) ≥ 1 g L 0 < g L ( x ) < 1 0 g L ( x ) ≤ 0 = m a x ( m i n ( g L ( x ) , 1 ) , 0 ) HardLogistic(x)=\left\{\begin{matrix} 1 & g_L(x)\ge 1\\ g_L & 0<g_L(x)<1\\ 0 & g_L(x)\le 0 \end{matrix}\right. =max(min(g_L(x),1),0) HardLogistic(x)=? ? ??1gL?0?gL?(x)10<gL?(x)<1gL?(x)0?=max(min(gL?(x),1),0)

Hard-Tanh 函数

Tanh 函数在 0 0 0附近的一阶泰勒展开为:

g T ≈ t a n h ( 0 ) + x t a n h ′ ( 0 ) = x g_T\approx tanh (0)+xtanh '(0)=x gT?tanh(0)+xtanh(0)=x

于是使用分段函数近似Tanh 函数,可以表示为:

H a r d T a n h ( x ) = { 1 g T ( x ) ≥ 1 g T 0 < g T ( x ) < 1 0 g T ( x ) ≤ 0 = m a x ( m i n ( g T ( x ) , 1 ) , 0 ) HardTanh(x)=\left\{\begin{matrix} 1 & g_T(x)\ge 1\\ g_T & 0<g_T(x)<1\\ 0 & g_T(x)\le 0 \end{matrix}\right. =max(min(g_T(x),1),0) HardTanh(x)=? ? ??1gT?0?gT?(x)10<gT?(x)<1gT?(x)0?=max(min(gT?(x),1),0)

ReLU 激活函数

由于前面提到的Sigmoid 函数计算资源会有一定的浪费以及可能存在的训练时带来的问题,而针对这些问题设计的Hard-Sigmoid 函数也会导致额外的计算开销,如函数分段。于是,在大规模的神经网络中,我们更倾向于使用另一种激活函数:ReLU(修正线性单元)

修正线性单元(Rectified Linear Unit,ReLU),本质上是一个斜坡函数,定义为:

R e L U ( x ) = m a x ( 0 , x ) ReLU(x)=max(0,x) ReLU(x)=max(0,x)

在这里插入图片描述

通过ReLU 函数的图像更加直观的可以看到,该函数具有以下的优点:

  1. 计算高效性,ReLU函数的计算只需要设计基本的加法和比较操作,而前面的Sigmoid 函数涉及到复杂的指数,乘除等运算;
  2. 单侧抑制性,ReLU 函数虽然值域不像Sigmoid 函数在一个有限的范围内,但仍然在生物学中找到对应的解释。因为,有些生物神经元表现出类似于该函数的,刺激达到一定阈值以上才可以被激活,即 “单侧抑制性”,这些神经元一旦被激活,输出可以非常高,这种想象被称为“宽兴奋边界”;
  3. 兴奋神经元稀疏性,人脑中生物神经元只有很少一部分是处于兴奋状态的。与Sigmoid 函数大部分神经元处于被激活状态不同,ReLU 函数可以控制被激活的神经元数量处于 约50% 左右,更贴近人脑神经网络;
  4. 与Sigmoid 函数两端饱和相比,RuLU 函数只有左侧饱和,可以一定程度上减轻饱和带来的各种问题。

但是,由于ReLU 函数仍然是一个 “非零中心化” 的函数,其仍然会出现一定程度的偏置偏移现象,以及如果在神经网络训练过程中,某些神经元的权重出现不恰当的更新,那么可能神经元可能永远不会被激活,这也就是 “ReLU死亡问题”


  1. [McCulloch and Pitts, 1943] ??

文章来源:https://blog.csdn.net/garker/article/details/135129276
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。