python_神经网络

前言

提醒:
文章内容为方便作者自己后日复习与查阅而进行的书写与发布,其中引用内容都会使用链接表明出处(如有侵权问题,请及时联系)。
其中内容多为一次书写,缺少检查与订正,如有问题或其他拓展及意见建议,欢迎评论区讨论交流。


分类与回归算法

机器学习中的分类与回归算法是两种主要的监督学习任务,它们分别用于解决不同类型的问题。以下是这两种算法的总结:

  1. 分类算法
    分类算法用于将数据分成不同的类别,适用于输出为离散标签的问题。常见的分类算法包括:

    1. 逻辑回归:使用逻辑函数来估计概率,用于二分类问题,也可以扩展到多分类问题。
    2. 支持向量机(SVM):通过找到最优的决策边界来最大化样本的分类准确率,适用于高维数据。
    3. 决策树:通过树结构来进行决策,每个节点代表一个特征的选择,叶子节点代表分类结果。
    4. 随机森林:由多个决策树组成的集成学习方法,通过投票来决定最终分类结果。
    5. 梯度提升决策树(GBDT):通过构建和结合多个弱学习器来形成强学习器,适用于分类和回归问题。
    6. 朴素贝叶斯:基于贝叶斯定理,假设特征之间相互独立,适用于文本分类等场景。
    7. K近邻(KNN):根据样本之间的距离进行分类,适用于小规模数据集。
    8. 神经网络:通过多层感知机学习数据的复杂模式,适用于图像、语音等复杂分类问题。
  2. 回归算法
    回归算法用于预测连续数值输出,适用于输出为连续变量的问题。常见的回归算法包括:

    1. 线性回归:通过拟合一条直线来预测目标变量的值,是最简单的回归方法。
    2. 岭回归:线性回归的扩展,通过引入L2正则化项来防止过拟合。
    3. Lasso回归:线性回归的另一种扩展,通过引入L1正则化项来进行特征选择。
    4. 弹性网回归:结合了岭回归和Lasso回归,同时引入L1和L2正则化项。
    5. 决策树回归:使用决策树结构来进行回归预测,适用于非线性关系。
    6. 随机森林回归:由多个决策树组成的集成学习方法,通过平均来决定最终回归结果。
    7. 梯度提升决策树回归(GBDT回归):通过构建和结合多个弱学习器来形成强学习器,适用于回归问题。
    8. 支持向量回归(SVR):支持向量机在回归问题上的应用,通过找到最优的决策边界来最大化样本的回归准确率。
    9. 神经网络回归:通过多层感知机学习数据的复杂模式,适用于复杂的回归问题。
  3. 分类与回归算法的比较

    • 输出类型:分类算法输出离散标签,回归算法输出连续数值。
    • 评估指标:分类算法常用准确率、召回率、F1分数等指标,回归算法常用均方误差(MSE)、均方根误差(RMSE)等指标。
    • 问题类型:分类算法适用于类别预测问题,如垃圾邮件检测;回归算法适用于数值预测问题,如房价预测。 在实际应用中,选择分类还是回归算法取决于问题的性质和需求。有时,可以将回归问题转化为分类问题,或者将分类问题转化为回归问题,具体取决于问题的特点和目标。

神经网络

B站大佬视频

从零设计并训练一个神经网络,你就能真正理解它了

原理分析

神经网络分类算法讲解
一、神经网络的基本结构与数学公式
神经网络主要由神经元组成。一个神经元的计算过程可以表示为:

  1. 加权求和
    z = w 1 x 1 + w 2 x 2 + . . . + w n x n + b = ∑ i = 1 n w i x i + b z = w_1x_1 + w_2x_2 + ... + w_nx_n + b = \sum\limits_{i=1}^n w_ix_i + b z=w1x1+w2x2+...+wnxn+b=i=1nwixi+b
    其中, x i x_i xi 是输入数据, w i w_i wi 是对应的权重, b b b 是偏置项。
  2. 激活函数
    a = σ ( z ) a = \sigma(z) a=σ(z)
    这里的 a a a 是神经元的输出, σ \sigma σ 是激活函数。常用激活函数包括 Sigmoid 和 ReLU 等。以 Sigmoid 为例:
    σ ( z ) = 1 1 + e − z \sigma(z) = \frac{1}{1 + e^{-z}} σ(z)=1+ez1
    它将加权和 z z z 映射到区间 (0, 1),适用于二分类问题。
    二、分类算法中的前向传播
    以三层神经网络(输入层、隐藏层、输出层)为例:
  3. 输入层到隐藏层
    a j ( 1 ) = σ ( ∑ i = 1 n w j i ( 1 ) x i + b j ( 1 ) ) a^{(1)}_j = \sigma\left(\sum\limits_{i=1}^n w^{(1)}_{ji}x_i + b^{(1)}_j\right) aj(1)=σ(i=1nwji(1)xi+bj(1))
    其中, w j i ( 1 ) w^{(1)}_{ji} wji(1) 是输入层到隐藏层的权重, b j ( 1 ) b^{(1)}_j bj(1) 是隐藏层的偏置项。
  4. 隐藏层到输出层
    a k ( 2 ) = σ ( ∑ j = 1 m w k j ( 2 ) a j ( 1 ) + b k ( 2 ) ) a^{(2)}_k = \sigma\left(\sum\limits_{j=1}^m w^{(2)}_{kj}a^{(1)}_j + b^{(2)}_k\right) ak(2)=σ(j=1mwkj(2)aj(1)+bk(2))
    对于多分类问题,输出层常用 Softmax 函数:
    a k ( 2 ) = e z k ( 2 ) ∑ p = 1 p e z p ( 2 ) a^{(2)}_k = \frac{e^{z^{(2)}_k}}{\sum\limits_{p=1}^p e^{z^{(2)}_p}} ak(2)=p=1pezp(2)ezk(2)
    其中, z k ( 2 ) z^{(2)}_k zk(2) 是输出层的加权和。Softmax 函数将输出转换为类别概率。
    三、分类算法中的训练过程(基于反向传播和梯度下降)
  5. 损失函数
    • 二分类问题的交叉熵损失:
      H ( p , q ) = − [ y log ⁡ ( q ) + ( 1 − y ) log ⁡ ( 1 − q ) ] H(p, q) = -[y \log(q) + (1 - y) \log(1 - q)] H(p,q)=[ylog(q)+(1y)log(1q)]
    • 多分类问题的交叉熵损失:
      H ( p , q ) = − ∑ k = 1 p y k log ⁡ ( q k ) H(p, q) = -\sum\limits_{k=1}^p y_k \log(q_k) H(p,q)=k=1pyklog(qk)
  6. 反向传播
    • 输出层误差梯度:
      δ k ( 2 ) = a k ( 2 ) − y k \delta^{(2)}_k = a^{(2)}_k - y_k δk(2)=ak(2)yk
    • 隐藏层误差梯度:
      δ j ( 1 ) = σ ′ ( z j ( 1 ) ) ∑ k = 1 p w k j ( 2 ) δ k ( 2 ) \delta^{(1)}_j = \sigma'(z^{(1)}_j) \sum\limits_{k=1}^p w^{(2)}_{kj} \delta^{(2)}_k δj(1)=σ(zj(1))k=1pwkj(2)δk(2)
  7. 梯度下降
    • 权重更新:
      w j i ( ℓ ) = w j i ( ℓ ) − η ⋅ δ j ( ℓ ) ⋅ a i ( ℓ − 1 ) w^{(\ell)}_{ji} = w^{(\ell)}_{ji} - \eta \cdot \delta^{(\ell)}_j \cdot a^{(\ell-1)}_i wji()=wji()ηδj()ai(1)
    • 偏置更新:
      b j ( ℓ ) = b j ( ℓ ) − η ⋅ δ j ( ℓ ) b^{(\ell)}_j = b^{(\ell)}_j - \eta \cdot \delta^{(\ell)}_j bj()=bj()ηδj()
      通过迭代训练,使损失函数减小,得到有效分类模型。
      优势补充
  • 非线性拟合能力:自动学习复杂特征映射,适用于高维、非线性数据。
  • 自动特征学习:减少人工特征工程,提高泛化能力。
  • 泛化能力:通过正则化(如 L2 正则化)防止过拟合。L2 正则化公式:
    正则化项 = λ ⋅ ∑ w w 2 \text{正则化项} = \lambda \cdot \sum_{w} w^2 正则化项=λww2
    其中, λ \lambda λ 为正则化系数, w w w 为权重参数。

反向传播数学原理

  1. 损失函数
    假设损失函数为 C C C,例如均方误差损失:
    C = 1 2 ∑ k ( y k − a k ( 2 ) ) 2 C = \frac{1}{2}\sum_{k}(y_k - a^{(2)}_k)^2 C=21k(ykak(2))2
    其中, y y y 是真实标签, a ( 2 ) a^{(2)} a(2) 是模型的预测结果。

  2. 输出层误差
    计算输出层的误差 δ k ( 2 ) \delta^{(2)}_k δk(2)
    δ k ( 2 ) = ∂ C ∂ z k ( 2 ) = ( a k ( 2 ) − y k ) ⋅ σ ′ ( z k ( 2 ) ) \delta^{(2)}_k = \frac{\partial C}{\partial z^{(2)}_k} = (a^{(2)}_k - y_k) \cdot \sigma'(z^{(2)}_k) δk(2)=zk(2)C=(ak(2)yk)σ(zk(2))
    其中, σ ′ ( z ) = σ ( z ) ⋅ ( 1 − σ ( z ) ) \sigma'(z) = \sigma(z) \cdot (1 - \sigma(z)) σ(z)=σ(z)(1σ(z)) 是 Sigmoid 激活函数的导数。

  3. 隐藏层误差
    将误差从输出层传回到隐藏层,计算隐藏层的误差 δ j ( 1 ) \delta^{(1)}_j δj(1)
    δ j ( 1 ) = ∑ k δ k ( 2 ) ⋅ w k j ( 2 ) ⋅ σ ′ ( z j ( 1 ) ) \delta^{(1)}_j = \sum_{k} \delta^{(2)}_k \cdot w^{(2)}_{kj} \cdot \sigma'(z^{(1)}_j) δj(1)=kδk(2)wkj(2)σ(zj(1))
    其中, z j ( 1 ) z^{(1)}_j zj(1) 是隐藏层第 j j j 个神经元的加权和, σ ′ \sigma' σ 是激活函数的导数。

  4. 梯度计算
    计算损失函数对权重和偏置的梯度:

    • 输出层权重和偏置:
      ∂ C ∂ w k j ( 2 ) = δ k ( 2 ) ⋅ a j ( 1 ) \frac{\partial C}{\partial w^{(2)}_{kj}} = \delta^{(2)}_k \cdot a^{(1)}_j wkj(2)C=δk(2)aj(1)
      ∂ C ∂ b k ( 2 ) = δ k ( 2 ) \frac{\partial C}{\partial b^{(2)}_k} = \delta^{(2)}_k bk(2)C=δk(2)
    • 隐藏层权重和偏置:
      ∂ C ∂ w i j ( 1 ) = δ j ( 1 ) ⋅ x i \frac{\partial C}{\partial w^{(1)}_{ij}} = \delta^{(1)}_j \cdot x_i wij(1)C=δj(1)xi
      ∂ C ∂ b j ( 1 ) = δ j ( 1 ) \frac{\partial C}{\partial b^{(1)}_j} = \delta^{(1)}_j bj(1)C=δj(1)
  5. 参数更新
    使用梯度下降更新参数:

    • 输出层权重和偏置:
      w k j ( 2 ) = w k j ( 2 ) − η ⋅ δ k ( 2 ) ⋅ a j ( 1 ) w^{(2)}_{kj} = w^{(2)}_{kj} - \eta \cdot \delta^{(2)}_k \cdot a^{(1)}_j wkj(2)=wkj(2)ηδk(2)aj(1)
      b k ( 2 ) = b k ( 2 ) − η ⋅ δ k ( 2 ) b^{(2)}_k = b^{(2)}_k - \eta \cdot \delta^{(2)}_k bk(2)=bk(2)ηδk(2)
    • 隐藏层权重和偏置:
      w i j ( 1 ) = w i j ( 1 ) − η ⋅ δ j ( 1 ) ⋅ x i w^{(1)}_{ij} = w^{(1)}_{ij} - \eta \cdot \delta^{(1)}_j \cdot x_i wij(1)=wij(1)ηδj(1)xi
      b j ( 1 ) = b j ( 1 ) − η ⋅ δ j ( 1 ) b^{(1)}_j = b^{(1)}_j - \eta \cdot \delta^{(1)}_j bj(1)=bj(1)ηδj(1)
      其中, η \eta η 是学习率。
  6. 链式法则
    整个反向传播过程实际上是链式法则的运用,通过层层传递误差来计算梯度:
    ∂ C ∂ w = ∂ C ∂ a ⋅ ∂ a ∂ z ⋅ ∂ z ∂ w \frac{\partial C}{\partial w} = \frac{\partial C}{\partial a} \cdot \frac{\partial a}{\partial z} \cdot \frac{\partial z}{\partial w} wC=aCzawz

  7. 实际应用中的优化

    • 梯度消失和梯度爆炸:通过使用合适的激活函数(如 ReLU)、更好的权重初始化方法(如 He 初始化)和梯度校正算法(如 Adam)来解决。
    • 批处理和批标准化:通过批处理和批标准化减小内部协变量偏移,使梯度下降更加稳定。

通过这些步骤,反向传播算法能够有效地优化神经网络的权重和偏置,使得模型在训练数据上达到更好的拟合效果。

代码实现

手动实现

代码解释:
神经网络结构
输入层:2个神经元(特征)
隐藏层:3个神经元,使用Sigmoid激活函数
输出层:1个神经元,使用Sigmoid激活函数
示例问题
使用神经网络分类以下两个类别的数据:
类别0:点集 {(0,0), (0,1)}
类别1:点集 {(1,0), (1,1)}

import numpy as np

# 激活函数和其导数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def sigmoid_derivative(x):
    return x * (1 - x)

# 初始化权重和偏置
input_size = 2
hidden_size = 3
output_size = 1

np.random.seed(0)
weights_input_hidden = np.random.uniform(size=(input_size, hidden_size))
bias_hidden = np.random.uniform(size=(1, hidden_size))
weights_hidden_output = np.random.uniform(size=(hidden_size, output_size))
bias_output = np.random.uniform(size=(1, output_size))

# 训练数据
X = np.array([[0,0], [0,1], [1,0], [1,1]])
y = np.array([[0], [0], [1], [1]])

# 学习率
learning_rate = 0.1

# 训练神经网络
for epoch in range(10000):
    # 前向传播
    hidden_input = np.dot(X, weights_input_hidden) + bias_hidden
    hidden_output = sigmoid(hidden_input)
    final_input = np.dot(hidden_output, weights_hidden_output) + bias_output
    final_output = sigmoid(final_input)
    
    # 计算损失
    loss = y - final_output
    
    # 反向传播
    d_output = loss * sigmoid_derivative(final_output)
    error_hidden_layer = d_output.dot(weights_hidden_output.T)
    d_hidden_layer = error_hidden_layer * sigmoid_derivative(hidden_output)
    
    # 更新权重和偏置
    weights_hidden_output += hidden_output.T.dot(d_output) * learning_rate
    bias_output += np.sum(d_output, axis=0, keepdims=True) * learning_rate
    weights_input_hidden += X.T.dot(d_hidden_layer) * learning_rate
    bias_hidden += np.sum(d_hidden_layer, axis=0, keepdims=True) * learning_rate

# 测试神经网络
print("测试结果:")
for i in range(len(X)):
    hidden_input = np.dot(X[i], weights_input_hidden) + bias_hidden
    hidden_output = sigmoid(hidden_input)
    final_input = np.dot(hidden_output, weights_hidden_output) + bias_output
    final_output = sigmoid(final_input)
    print(f"输入:{X[i]},预测输出:{final_output}, 真实输出:{y[i]}")

运行结果:
在这里插入图片描述

python函数库实现

使用Tensorflow,使用GPU训练,配置可参见:
【深度学习】TensorFlow(cuda版)安装以及对应第三方库安装流程

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import Adam

# 定义模型
model = Sequential([
    Dense(units=3, activation='sigmoid', input_shape=(2,)),  # 隐藏层
    Dense(units=1, activation='sigmoid')  # 输出层
])

# 编译模型
model.compile(optimizer=Adam(learning_rate=0.1), loss='binary_crossentropy', metrics=['accuracy'])

# 训练数据
X = np.array([[0,0], [0,1], [1,0], [1,1]])
y = np.array([[0], [0], [1], [1]])

# 训练模型
model.fit(X, y, epochs=10000, verbose=0)

# 测试模型
print("测试结果:")
predictions = model.predict(X)
for i in range(len(X)):
    print(f"输入:{X[i]},预测输出:{predictions[i].round()}, 真实输出:{y[i]}")

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值