ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

深度学习1:基本概念,感知机,激活函数(阶跃,sigmoid,Tanh函数)

深度学习1:基本概念,感知机,激活函数(阶跃,sigmoid,Tanh函数)

建议看尚硅谷深度学习视频

      • 一、深度学习基本概念和结构
      • 二、感知机和激活函数的由来
      • 三、激活函数作用
        • 作用一: 没有激活函数,一万层网络也只等于一层线性回归,啥复杂问题都解决不了
        • 作用二: 决定神经元是否“放电”(特征过滤)
        • 作用三: 压缩数值范围,防止“梯度爆炸”
        • 思考:激活函数算出来是 0 这个数值,就不会被下一层加入计算吗?(是的,完全不会)
        • 插曲一些知识: 偏置 b 和激活函数真正放在一起,看看它们到底是怎么配合的。
      • 四、阶跃函数
      • 五、sigmoid
      • 六、Tanh函数

笔记来自尚硅谷 深度学习 截图

一、深度学习基本概念和结构

人工神经网络(Artificial Neural Network,ANN)简称 神经网络(NN),是一种模仿生物神经网络结构和功能的计算模型。大多数情况下人工神经网络能在外界信息的基础上改变内部结构,是一种自适应系统(adaptive system),通俗地讲就是具备学习功能。


相邻层的神经元相互连接(图中下一层每个神经元都与上一层所有神经元连接,称为 全连接),每个连接都会有一个 权重。

神经元中的信息逐层传递(一般称为 前向传播 forward),上一层神经元的输出作为下一层神经元的输入

二、感知机和激活函数的由来

感知器(perceptron)是二分类模型,接受多个信号,输出一个信号.感知机的信号只有0,1两种取值。


重要的事,打一遍字:不用一直线性下去吧
h(x)可以将输入信号的加权总和转换为输出信号,起到"激活神经元"的作用,所以被称为激活函数

三、激活函数作用

激活函数是连接感知机和神经网络的桥梁,在神经网络中起着至关重要的作用。

作用一: 没有激活函数,一万层网络也只等于一层线性回归,啥复杂问题都解决不了

如果没有激活函数,整个神经网络就等效于单层线性变换,不论如何加深层数,总是存在与之等效的“无隐藏层的神经网络”。激活函数必须是非线性函数,也正是激活函数的存在为神经网络引入了非线性,使得神经网络能够学习和表示复杂的非线性关系。

作用二: 决定神经元是否“放电”(特征过滤)

现实中大脑的神经元,只有当接收到的刺激超过一定阈值时,才会“放电”把信号传给下一个神经元。激活函数就是模拟这个机制。它把前一层的加权求和(a aa),映射成一个“激活程度”。比如大于某个值,才把信号传给下一层。

作用三: 压缩数值范围,防止“梯度爆炸”

你看图里的a = w 1 x 1 + w 2 x 2 + b a = w_1x_1 + w_2x_2 + ba=w1​x1​+w2​x2​+b。如果在深层网络里,每层算出来的值都越来越大(比如变成 1000、10000),计算机的浮点数会溢出,模型直接崩溃(这叫梯度爆炸)。
激活函数可以把这些无限大的数字“挤压”回一个安全范围(比如[ − 1 , 1 ] [-1, 1][−1,1]或[ 0 , ∞ ) [0, \infty)[0,∞)),让网络能稳定训练。

思考:激活函数算出来是 0 这个数值,就不会被下一层加入计算吗?(是的,完全不会)

我们以最经典的激活函数ReLU (Rectified Linear Unit, 线性整流函数)为例。它的公式极简单:
f ( x ) = m a x ( 0 , x ) f(x) = max(0, x)f(x)=max(0,x)。

  • 如果输入x > 0 x > 0x>0,输出还是x xx。
  • 如果输入x ≤ 0 x \le 0x≤0,输出直接强行变成 0。

“变成 0”在下一层计算时意味着什么?

假设下一层的计算是y = w 1 ⋅ a 1 + w 2 ⋅ a 2 + b y = w_1 \cdot a_1 + w_2 \cdot a_2 + by=w1​⋅a1​+w2​⋅a2​+b。
如果上一层传过来的a 1 a_1a1​经过激活函数变成了 0。那么:
y = w 1 ⋅ 0 + w 2 ⋅ a 2 + b = w 2 ⋅ a 2 + b y = w_1 \cdot 0 + w_2 \cdot a_2 + b = w_2 \cdot a_2 + by=w1​⋅0+w2​⋅a2​+b=w2​⋅a2​+b

你看,w 1 w_1w1​和a 1 a_1a1​直接从公式里消失了。
在神经网络和矩阵运算中,0 就代表“此路不通”。这就引出了深度学习中极其重要的一种现象:

1. 产生“稀疏性 (Sparsity)”(极度省算力)
图片里有大量的像素点、一句话里有大量无用的介词,它们对最终结果没贡献。ReLU 让这些无用特征直接变成 0。下一层遇到 0 就不用算了,大大节省了 GPU 的算力。这种“断舍离”不仅省算力,还是让神经网络变得聪明和高效的秘诀

2. 强迫网络只关注“重点”(抗噪)
如果输入的是无用的噪声,算出来的值大概率小于 0,被 ReLU 激活成 0 后,等于告诉后面的网络:“这全是废话,不用管它了”。这极大地提高了模型提取核心特征的效率。

3. 避免梯度消失(ReLU 的绝活)
早期的激活函数(比如 Sigmoid)在输入极大或极小时,曲线是平的。曲线平 = 导数为 0 = 训练时权重无法更新(这叫梯度消失)。
而 ReLU 只要输入大于 0,它的导数永远是 1。这意味着误差可以畅通无阻地传回前面的层,极大加速了深层网络的训练。(早期的 Transformer 和现在的很多 CNN,中间层都在疯狂使用 ReLU 或者它的变体 GELU)。

那为 0 有啥坏处吗?
有。如果输入永远小于 0,输出永远为 0,导数也为 0。那个神经元就“死”了(Dead Neuron),参数永远无法更新。
为了防这个,工程师后来发明了Leaky ReLU,让小于 0 的部分不是 0,而是0.01 x 0.01x0.01x(保留一点点微弱信号,不让它彻底死掉)。

插曲一些知识: 偏置 b 和激活函数真正放在一起,看看它们到底是怎么配合的。

真相:偏置b bb的作用,就是用来“控制”激活函数的!

结合公式,我们把流程排好:

  1. 第一步(线性计算):a = w 1 x 1 + w 2 x 2 + b a = w_1x_1 + w_2x_2 + ba=w1​x1​+w2​x2​+b(这一步把输入加权求和,并加上偏置b bb)
  2. 第二步(激活函数):y = f ( a ) y = f(a)y=f(a)(把算出来的a aa塞进激活函数)

为什么非要在进激活函数之前,加一个b bb呢?

你想,如果没有偏置b bb。那么输入信号x 1 x_1x1​和x 2 x_2x2​哪怕全等于 0,算出来的a aa也是 0。这就意味着,当没有输入信号时,这个神经元绝对不可能被激活,它永远死气沉沉。

加了偏置b bb,就相当于给神经元设定了一个“门槛(或基础活跃度)”。

我们以ReLU 激活函数(公式是f ( a ) = m a x ( 0 , a ) f(a) = max(0, a)f(a)=max(0,a),即负数变0,正数保留)为例,来看看b bb的魔法:

  • 情况 1:假设b bb是一个负数(比如b = − 5 b = -5b=−5)
    哪怕你给了输入信号(比如w 1 x 1 + w 2 x 2 = 3 w_1x_1 + w_2x_2 = 3w1​x1​+w2​x2​=3),算出来的a = 3 − 5 = − 2 a = 3 - 5 = -2a=3−5=−2。
    然后a = − 2 a = -2a=−2进了激活函数,ReLU 一看是负数,直接把它变成 0。

    • 结果:这个神经元非常“高冷”,它觉得信号太弱了,不值得兴奋,所以不激活(输出 0,后面的层就不计算它了)。
  • 情况 2:假设b bb是一个正数(比如b = 5 b = 5b=5)
    哪怕你根本没给任何输入信号(输入全是 0),算出来的a = 0 + 5 = 5 a = 0 + 5 = 5a=0+5=5。
    然后a = 5 a = 5a=5进了激活函数,ReLU 一看是正数,原样输出 5。

    • 结果:这个神经元非常“敏感”,一点点风吹草动(或者没动静)它也会被激活。
  • 情况 3:训练过程中,网络在调整b bb
    网络在“学习”时,如果发现某个神经元太容易激活了(老是输出非 0 值,导致模型预测错误),反向传播算法就会把它的b bb调小一点(往负数方向调),让它冷静一下;如果发现它太死板了(总是输出 0,啥特征也学不到),就会把b bb调大一点,让它更容易被激活。

记住一句话:b 是给激活函数打辅助的,它决定了神经元被激活的难易程度

四、阶跃函数


#阶跃函数(输入是一个标量)importnumpyasnpdefstep_function0(x):ifx>0:return1else:return0defstep_function(x):returnnp.array(x>0,dtype=int)if__name__=='__main__':x=np.array([0,1,2,3,4,5,-1,-2,-3,-4,-5])print(step_function(x))

五、sigmoid

下面是函数和导函数图片,从第二张导函数能看出来再等0是到了拐点
靠近0是开始急剧增大,过了拐点开始慢慢增大减速
导函数下降,不代表原函数就会下降。只要导函数的值(也就是斜率)还是正数,原函数就一直在上升。

核心概念:导函数的“正负”决定原函数的“升降”

  • 导函数 (f’(x) > 0)(在 x 轴上方):原函数 f(x) 就在上升。
  • 导函数 (f’(x) < 0)(在 x 轴下方):原函数 f(x) 就在下降。

你看右图(Sigmoid 的导函数图像),它在 x=0之后确实开始下降了(从最高点 0.25 往下掉)。但是,它下降归下降,它依然在 x 轴的上方,数值依然是正数! 所以原函数 f(x) 依然在增加,只是增加的速度变慢了。

S i g m o i d SigmoidSigmoid(也叫 Logistic 函数)是平滑的、可微的,能将任意输入映射到区间(0,1),常用于二分类的输出层。但因其涉及指数运算,计算量相对较高。

S i g m o i d SigmoidSigmoid的输入在[-6,6]之外时,其输出值变化很小,可能导致信息丢失。

S i g m o i d SigmoidSigmoid的输出并非以 0 为中心,其输出值均>0,导致后续层的输入始终为正,可能影响后续梯度更新方向。

S i g m o i d SigmoidSigmoid的导数范围为(0,0.25),梯度较小。当输入在[-6,6]之外时,导数接近 0,此时网络参数的更新将会极其缓慢。使用 Sigmoid 作为激活函数,可能出现梯度消失(在逐层反向传播时,梯度会呈指数级衰减)。

别的不说 ,先搞定求导回忆基础复合求导

s i g m o i d sigmoidsigmoid求导过程σ ( x ) \sigma(x)σ(x)和 f(x) 一个意思,所以下面ai用σ ( x ) \sigma(x)σ(x)计算求导

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

代码(包含测试阶跃函数)

# Sigmoid函数defsigmoid(x):return1/(1+np.exp(-x))if__name__=='__main__':x=np.array([0,1,2,3,4,5,-1,-2,-3,-4,-5])print(step_function(x))print(sigmoid(x))

六、Tanh函数

Tanh函数就是sigmoid的平移和缩放
原来sigmoid 的值是 0到1
这里2 sigmoid(2x) 的值是 0到2
又减去1 所以值变成-1 到 1

importnumpyasnp x=np.array([0,1,2,3,4,5,-1,-2,-3,-4,-5])np.tanh(x)
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进