3.神经网络
神经网络
神经元与大脑
-
神经网络神经元的结构:
输入(Input):接收来自前一层神经元的信息。
权重(Weights):每个输入都有一个权重,表示其重要性。
加权和(Weighted Sum):神经元对所有输入信号进行加权求和。
偏置(Bias):调整加权和的结果,使得网络能更好地拟合数据。
激活函数(Activation Function):决定该神经元是否激活,通常使用像 ReLU、Sigmoid、Tanh 等函数。 -
信号传递:
神经元接收来自前一层的输入信号,并对这些信号进行加权求和(相当于神经元的“树突”部分),然后通过激活函数处理,输出传递给下一层的神经元。
-
激活函数:
激活函数的作用在于对输入进行非线性变换,使得神经网络可以学习复杂的模式。例如,ReLU(Rectified Linear Unit)函数会输出输入信号与0的较大值,帮助网络解决梯度消失问题
神经网络中的层
1. 基础层(通常用于前馈网络)
-
全连接层(Dense/Fully Connected Layer)
每个神经元与前一层的所有神经元连接,用于学习全局特征。
示例: 传统多层感知机(MLP)中的核心层。 -
激活函数层(Activation Layer)
引入非线性(如ReLU、Sigmoid、Tanh),使网络能够拟合复杂函数。
注意: 通常不单独作为一层,而是与其他层结合使用。
2. 卷积神经网络(CNN)专用层
2.1 卷积层(Convolutional Layer)
通过卷积核提取局部特征(如边缘、纹理),适用于图像、视频等网格数据。变体: 1D(时序数据)、2D(图像)、3D(视频/体数据)。
2.2 池化层(Pooling Layer)
降维并保留关键特征(如最大池化、平均池化),增强平移不变性。
2.3 转置卷积层(Transposed Convolution)
用于上采样(如图像生成、分割),扩大特征图尺寸。
2.4 空洞卷积(Dilated Convolution)
扩大感受野而不增加参数量,适用于语义分割等任务。
3. 循环神经网络(RNN)专用层
3.1 简单RNN层(Vanilla RNN)
处理序列数据,但存在梯度消失问题。
3.2 长短时记忆层(LSTM)
通过门控机制(输入门、遗忘门、输出门)解决长程依赖问题。
3.3 门控循环单元(GRU)
LSTM的简化版,合并部分门结构,计算效率更高。
3.4 双向层(Bidirectional RNN/LSTM/GRU)
同时捕捉前向和反向的序列依赖关系。
4. 注意力机制相关层
4.1 自注意力层(Self-Attention)
计算输入元素间的相关性(如Transformer的核心层)。
4.2 多头注意力(Multi-Head Attention)
并行多个自注意力机制,捕捉不同子空间的依赖关系。
4.3 交叉注意力(Cross-Attention)
用于处理两个序列间的交互(如编码器-解码器结构)。
5. 归一化与正则化层
5.1 批归一化(Batch Normalization, BN)
对每批数据归一化,加速训练并缓解梯度问题。
5.2 层归一化(Layer Normalization, LN)
适用于RNN或Transformer,沿特征维度归一化。
5.3 Dropout层
随机失活神经元,防止过拟合。
6. 输出层
6.1 Softmax层
多分类任务中输出概率分布。
6.2 Sigmoid层
二分类或概率输出。
6.3 线性输出层
回归任务(无激活函数)。
前向传播与反向传播
前向传播
定义:数据从输入层逐层传递到输出层,最终生成预测值的过程。每一层的输出是下一层的输入。
步骤:
1. 输入数据:将样本数据输入网络的第一层(如全连接层、卷积层等)。
2. 逐层计算:每一层对输入进行线性变换(如矩阵乘法、卷积运算)和非线性激活(如ReLU)。
从输出层开始,逐层计算损失对参数的梯度(链式法则)。
例如,全连接层的梯度计算:
z
(
l
)
=
W
(
l
)
⋅
a
(
l
−
1
)
+
b
(
l
)
,
a
(
l
)
=
σ
(
z
(
l
)
)
z^{(l)} = W^{(l)} \cdot a^{(l-1)} + b^{(l)}, \quad a^{(l)} = \sigma(z^{(l)})
z(l)=W(l)⋅a(l−1)+b(l),a(l)=σ(z(l))
其中,W是权重,b是偏置,a是激活值,σ是激活函数。
输出结果:最后一层(输出层)的激活值即为预测值(如分类概率或回归值)。
作用计算模型的预测输出。
为反向传播提供中间结果(如激活值、未激活值z)。
反向传播
定义:通过链式法则计算损失函数对每个参数的梯度,并从输出层反向传播误差信号至输入层,用于更新权重和偏置。
步骤:
- 计算损失:通过损失函数(如交叉熵、均方误差)比较预测值与真实值的误差。
L = Loss ( y , y ^ ) L = \text{Loss}(y, \hat{y}) L=Loss(y,y^) - 反向传播梯度:
从输出层开始,逐层计算损失对参数的梯度(链式法则)。
例如,全连接层的梯度计算:
∂
L
∂
W
(
l
)
=
∂
L
∂
a
(
l
)
⋅
∂
a
(
l
)
∂
z
(
l
)
⋅
∂
z
(
l
)
∂
W
(
l
)
\frac{\partial L}{\partial W^{(l)}} = \frac{\partial L}{\partial a^{(l)}} \cdot \frac{\partial a^{(l)}}{\partial z^{(l)}} \cdot \frac{\partial z^{(l)}}{\partial W^{(l)}}
∂W(l)∂L=∂a(l)∂L⋅∂z(l)∂a(l)⋅∂W(l)∂z(l)
3 . 更新参数:使用优化器(如SGD、Adam)根据梯度调整参数:
更新规则:
W
(
l
)
←
W
(
l
)
−
η
⋅
∂
L
∂
W
(
l
)
其中:
η
:
学习率
∂
L
∂
W
(
l
)
:
损失对第
l
层权重的梯度
\begin{aligned} \text{更新规则:} \\ W^{(l)} &\leftarrow W^{(l)} - \eta \cdot \frac{\partial L}{\partial W^{(l)}} \\ \text{其中:} \\ \eta &: \text{学习率} \\ \frac{\partial L}{\partial W^{(l)}} &: \text{损失对第 } l \text{ 层权重的梯度} \end{aligned}
更新规则:W(l)其中:η∂W(l)∂L←W(l)−η⋅∂W(l)∂L:学习率:损失对第 l 层权重的梯度
作用:
确定参数更新方向,最小化损失函数。
高效计算梯度(避免手动推导每一层的梯度)。
如何构建一个神经网络
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import Adam
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
import numpy as np
import matplotlib.pyplot as plt
# 1. 准备数据
#make_classification 是 scikit-learn (sklearn) 库提供的一个函数,用于生成随机的分类数据集
# 参一:样本个数 参2:每个样本的特征数 参3:几分类 参4:随机种子
X, y = make_classification(n_samples=1000, n_features=20, n_classes=2, random_state=42)
#test_size 表明将20%的数据用于测试
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 2. 构建模型
model = Sequential([
Dense(units = 64, activation='relu', input_shape=(20,)), # 第一隐藏层,表明有64个神经元,输出64维度的特征表示
Dense(units = 32, activation='relu'), # 第二隐藏层,表明有32个神经元,输出32维度的特征表示
Dense(units = 1, activation='sigmoid') # 输出层(二分类)
])
#如何计算参数数量
## 参数数 = (输入维度 × 神经元数量) + 偏置数 以第一层举例吧。 输入维度20 神经元数量 64 ,偏置数 64 all: 20* 64 + 64
# 3. 编译模型
#损失函数:使用的是二元交叉熵损失函数。
#使用的是 Adam(Adaptive Moment Estimation)优化器
#评估指标:这里用的是准确率(accuracy)。
model.compile(optimizer=Adam(learning_rate=0.001),
loss='binary_crossentropy',
metrics=['accuracy'])
# 4. 训练模型
#意思:epochs=50,整个训练数据会被“完整地”送入模型进行训练 50 次。
# batch_size=32, 每次更新权重和计算梯度的时候使用32个样本
# validation_split=0.2 把 20% 的训练数据自动拿出来作为验证集,20%的数据不参与计算,只用来评估模型
history = model.fit(X_train, y_train,
epochs=50,
batch_size=32,
validation_split=0.2)
# plt.plot(history.history['accuracy'], label='Train Accuracy')
# plt.plot(history.history['val_accuracy'], label='Val Accuracy')
# plt.legend()
# plt.show()
# 5. 评估模型
loss, accuracy = model.evaluate(X_test, y_test)
print(f"测试集准确率: {accuracy:.4f}")
# 6. 进行预测
sample = X_test[0:1] # 取第一个测试样本
prediction = model.predict(sample)
print(f"预测概率: {prediction[0][0]:.4f}")
print(f"实际结果:{y_test[0]}")
什么是 logits?
是指 没有经过 sigmoid 的原始输出值
比如模型最后输出的是 [-1.2, 0.5, 3.0] 这种线性值
✅ 什么是 概率?
是已经被 sigmoid “压缩”到 [0, 1] 范围内的结果
比如 sigmoid 后变成了 [0.23, 0.62, 0.95]
注: 在输出层没有sigmod 的情况下,我们需要将loss写为
loss = BinaryCrossentropy(from_logits=True),意思就是让你去给我做个sigmod,我需要拿到的是最终的一个概率值。而不是一堆线性值。
激活函数
Relu 激活函数
g
(
z
)
=
m
a
x
(
0
,
z
)
g(z) = max(0,z)
g(z)=max(0,z)
要么0,要么正值的一个输出
sigmod函数
g
(
z
)
=
1
1
+
e
−
z
g(z) = \frac{1}{1+e^{-z}}
g(z)=1+e−z1
二分类的一个预测
softmax函数
import numpy as np
def softmax(z):
z = z - np.max(z) # 稳定处理
exp_z = np.exp(z)
return exp_z / np.sum(exp_z)
print(softmax([2.0, 1.0, 0.1]))#[0.659, 0.242, 0.098] 概率和为1
场景:多分类
多类别的分类问题
特性:概率和为1 ,
常用的激活函数:softmax函数
假设有四个分类z1,z2,z3,z4.
z
1
=
w
1
x
+
b
1
z_{1} = \mathbf{w1} \mathbf{x} + b1
z1=w1x+b1
z
2
=
w
2
x
+
b
2
z_{2} = \mathbf{w2} \mathbf{x} + b2
z2=w2x+b2
z
3
=
w
3
x
+
b
3
z_{3} = \mathbf{w3} \mathbf{x} + b3
z3=w3x+b3
z
4
=
w
4
x
+
b
4
z_{4} = \mathbf{w4} \mathbf{x} + b4
z4=w4x+b4
这四个公式,经过softmax后
a
1
=
e
z
1
e
z
1
+
e
z
2
+
e
z
3
+
e
z
4
=
p
(
y
=
1
∣
x
)
a_{1} = \frac{e^{z_{1}}} {e^{z_{1}} + e^{z_{2}} +e^{z_{3}} +e^{z_{4}} } = p(y=1| \mathbf{x})
a1=ez1+ez2+ez3+ez4ez1=p(y=1∣x)
a
2
=
e
z
2
e
z
1
+
e
z
2
+
e
z
3
+
e
z
4
=
p
(
y
=
2
∣
x
)
a_{2} = \frac{e^{z_{2}}} {e^{z_{1}} + e^{z_{2}} +e^{z_{3}} +e^{z_{4}} } = p(y=2| \mathbf{x})
a2=ez1+ez2+ez3+ez4ez2=p(y=2∣x)
a
3
=
e
z
3
e
z
1
+
e
z
2
+
e
z
3
+
e
z
4
=
p
(
y
=
3
∣
x
)
a_{3} = \frac{e^{z_{3}}} {e^{z_{1}} + e^{z_{2}} +e^{z_{3}} +e^{z_{4}} } = p(y=3| \mathbf{x})
a3=ez1+ez2+ez3+ez4ez3=p(y=3∣x)
a
4
=
e
z
4
e
z
1
+
e
z
2
+
e
z
3
+
e
z
4
=
p
(
y
=
4
∣
x
)
a_{4} = \frac{e^{z_{4}}} {e^{z_{1}} + e^{z_{2}} +e^{z_{3}} +e^{z_{4}} } = p(y=4| \mathbf{x})
a4=ez1+ez2+ez3+ez4ez4=p(y=4∣x)
逻辑回归的损失函数:
l
o
s
s
(
a
1
,
.
.
.
a
n
)
=
−
l
o
g
a
n
loss(a_{1},...a_{n}) = -log_{a_{n}}
loss(a1,...an)=−logan
模型的评估
分类的模型
假设这里有个二分类的问题,一个正一个负的选择
TP: 真正(true positive)
TN: 真负(true negative)
FP: 假正(false positive)
FN: 假负(false negative)
准确率:
a
c
c
u
r
a
c
y
=
T
P
+
T
N
T
P
+
T
N
+
F
P
+
F
N
accuracy = \frac{TP + TN} {TP + TN + FP + FN}
accuracy=TP+TN+FP+FNTP+TN
精确率:
p
r
e
c
i
s
i
o
n
=
T
P
T
P
+
F
P
precision = \frac{TP} {TP + FP}
precision=TP+FPTP
召回率:
r
e
c
a
l
l
=
T
P
T
P
+
F
N
recall = \frac{TP} {TP + FN}
recall=TP+FNTP
F1分数:
F
1
=
2
∗
p
r
e
c
i
s
i
o
n
∗
r
e
c
a
l
l
p
r
e
c
i
s
i
o
n
+
r
e
c
a
l
l
F1 = 2 * \frac{precision * recall} {precision + recall}
F1=2∗precision+recallprecision∗recall
回归模型
均方误差:
MSE
=
1
n
∑
i
=
1
n
(
y
i
−
y
^
i
)
2
\text{MSE} = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2
MSE=n1i=1∑n(yi−y^i)2
平方误差,偏差大时惩罚更重
均方根误差:
RMSE
=
1
n
∑
i
=
1
n
(
y
i
−
y
^
i
)
2
\text{RMSE} = \sqrt{ \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 }
RMSE=n1i=1∑n(yi−y^i)2
平均绝对误差(MAE)
MAE
=
1
n
∑
i
=
1
n
∣
y
i
−
y
^
i
∣
\text{MAE} = \frac{1}{n} \sum_{i=1}^{n} |y_i - \hat{y}_i|
MAE=n1i=1∑n∣yi−y^i∣
决定系数:
R
2
=
1
−
∑
i
=
1
n
(
y
i
−
y
^
i
)
2
∑
i
=
1
n
(
y
i
−
y
ˉ
)
2
R^2 = 1 - \frac{ \sum_{i=1}^{n}(y_i - \hat{y}_i)^2 }{ \sum_{i=1}^{n}(y_i - \bar{y})^2 }
R2=1−∑i=1n(yi−yˉ)2∑i=1n(yi−y^i)2
越接近 1 越好,表示模型解释了多少方差(1 是完美预测)