第二章 感知机
感知机是神经网络与深度学习的基础算法,是一种接收多个输入、输出单个二值信号的简单模型。
1. 感知机的基本原理
感知机的核心单元是神经元(节点):输入信号 x1,x2 会被赋予对应的权重 w1,w2(也叫参数),神经元对加权后的输入求和,当求和结果超过某个阈值 θ 时,输出 1(神经元被激活),否则输出 0。

原始数学表达式:

引入偏置 b:将阈值 θ 移项并替换为 −b,公式改写为更通用的形式:

权重 w:控制输入信号的重要性,权重越大,对应输入对结果的影响越强。
偏置 b:控制神经元被激活的难易程度,b 越大,神经元越容易输出 1。
2. 单层感知机实现基础逻辑门
通过调整权重和偏置,单层感知机可以实现与门(AND)、与非门(NAND)、或门(OR)等线性可分的逻辑电路。
python
import numpy as np
# 与门
def AND(x1, x2):
x = np.array([x1, x2])
w = np.array([0.5, 0.5])
b = -0.7
tmp = np.sum(w * x) + b
return 1 if tmp > 0 else 0
# 与非门
def NAND(x1, x2):
x = np.array([x1, x2])
w = np.array([-0.5, -0.5])
b = 0.7
tmp = np.sum(w * x) + b
return 1 if tmp > 0 else 0
# 或门
def OR(x1, x2):
x = np.array([x1, x2])
w = np.array([0.5, 0.5])
b = -0.2
tmp = np.sum(w * x) + b
return 1 if tmp > 0 else 0
3. 感知机的局限性:无法实现异或门
异或门(XOR)属于非线性可分问题,单层感知机无法处理:
与门、或门的决策边界是一条直线,可以把二维空间分为两个线性区域,属于线性可分问题。
当w1=w2=1,b=-0.5,感知机会生成由直线−0.5 + x1 + x2 = 0分割开的两个空 间。其中一个空间输出1,另一个空间输出0,可表示或门

异或门的正负样本无法用一条直线分割,需要曲线 / 折线作为决策边界,属于非线性空间问题。单层感知机只能表示线性分割,因此无法单独实现异或门。

4. 多层感知机解决非线性问题
通过叠加感知机层(构建多层结构),可以实现非线性分割,解决异或门问题。
原理:组合与非门、或门、与门,通过「输入层 → 隐藏层 → 输出层」的 2 层感知机结构实现异或。

真值表:

python
def XOR(x1, x2):
s1 = NAND(x1, x2)
s2 = OR(x1, x2)
y = AND(s1, s2)
return y
结论:多层感知机可以表示复杂的非线性空间,理论上 2 层感知机就能够拟合任意函数。
第三章 神经网络
神经网络在感知机的基础上,引入平滑可导的激活函数与多层结构,支持通过梯度法自动学习参数,是深度学习的核心载体。
1. 神经网络的基本概念
神经网络由输入层、隐藏层、输出层构成,信号从输入向输出单向传递(前向传播)。
和感知机的核心差异:感知机使用阶跃函数(二值离散输出),神经网络使用连续可导的激活函数,支持通过梯度更新参数完成学习。
核心能力:通过叠加层与非线性激活函数,拟合任意复杂的非线性关系。
2. 激活函数
激活函数会将输入信号的总和转换为输出信号,比如感知机实现的与门x1,x2均为1,输出y为1
激活函数的作用是为神经网络引入非线性。如果没有激活函数,无论叠加多少层网络,都等价于单层线性变换,无法拟合复杂模式。
(1) 阶跃函数
感知机使用的激活函数,输入大于 0 时输出 1,否则输出 0。
python
def step_function(x):
return np.array(x > 0, dtype=np.int32)
特点:输出离散、存在突变点,几乎处处导数为 0,无法用于梯度学习。

(2) sigmoid 函数
经典的平滑激活函数,将输入压缩到 (0,1) 区间。
公式:

代码实现:
python
def sigmoid(x):
return 1 / (1 + np.exp(-x))

sigmoid 与 阶跃函数的异同:
| 对比维度 | 阶跃函数 | sigmoid 函数 |
|---|---|---|
| 输出形式 | 0/1 离散二值 | 0~1 之间的连续值 |
| 平滑性 | 存在突变跳变,不光滑 | 曲线平滑,处处可导 |
| 梯度可用性 | 几乎处处导数为 0,无法支持梯度学习 | 导数连续,可用于反向传播更新参数 |
| 共性 | 都是 S 型曲线,输入越大输出越接近 1,输入越小越接近 0,都具备非线性 |
(3) ReLU 函数
目前深度学习最常用的激活函数,输入为正时原样输出,负时输出 0。
公式:

代码实现:
python
def relu(x):
return np.maximum(0, x)
特点:计算简单高效,能有效缓解深层网络的梯度消失问题。
3. 多维数组的矩阵运算
神经网络的前向传播可以通过矩阵乘积(点积)高效实现,避免逐元素循环。
矩阵乘法要求:第一个矩阵的列数 = 第二个矩阵的行数。
简单示例(输入层到隐藏层的加权计算):
python
X = np.array([1.0, 0.5]) # 输入,形状(2,)
W = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]]) # 权重,形状(2,3)
B = np.array([0.1, 0.2, 0.3]) # 偏置,形状(3,)
A = np.dot(X, W) + B # 加权和,形状(3,)
Z = sigmoid(A) # 激活后输出
4. 三层神经网络的前向传播实现
以「输入层 (2 神经元)→隐藏层 1 (3 神经元)→隐藏层 2 (2 神经元)→输出层 (2 神经元)」为例,完整前向传播代码:
python
def init_network():
network = {}
network['W1'] = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
network['b1'] = np.array([0.1, 0.2, 0.3])
network['W2'] = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
network['b2'] = np.array([0.1, 0.2])
network['W3'] = np.array([[0.1, 0.3], [0.2, 0.4]])
network['b3'] = np.array([0.1, 0.2])
return network
def forward(network, x):
W1, W2, W3 = network['W1'], network['W2'], network['W3']
b1, b2, b3 = network['b1'], network['b2'], network['b3']
a1 = np.dot(x, W1) + b1
z1 = sigmoid(a1)
a2 = np.dot(z1, W2) + b2
z2 = sigmoid(a2)
a3 = np.dot(z2, W3) + b3
y = identity_function(a3)
return y
5. 输出层的设计
输出层的激活函数根据任务类型选择:
(1) 恒等函数
适用场景:回归问题(预测连续数值,如房价、温度)。
定义:输入原样输出,h(x)=x。
python
def identity_function(x):
return x
(2) softmax 函数
适用场景:分类问题(输出每个类别的概率,所有类别概率和为 1)。
公式:

溢出问题:当输入数值很大时,ex^x会指数级增长,导致数值溢出。
优化方案:减去输入中的最大值,不改变计算结果但避免溢出。下图的C取ai的最大值

优化后代码:
python
def softmax(a):
c = np.max(a)
exp_a = np.exp(a - c) # 减去最大值防止溢出
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return y
性质:输出值都在 0~1 之间,并且所有输出的和为 1,可以直接解释为每个类别的概率。