当前位置:   article > 正文

AI算法(机器学习)的基本原理_ai总结的原理

ai总结的原理

引言

图像识别、语音识别、自然语言处理、推荐系统、自动驾驶、ChatGPT大语言模型、Stable Diffusion图片生成等等,不知不觉AI算法已经应用到了生活的方方面面。但是AI算法模型的本质到底是什么,为什么AI有时候是人工智能,有时候又像人工智障?AI算法模型的工作原理是什么?

AI算法本质

如今的AI算法一般指的就是机器学习算法(目前主流的AI算法)。
在这里插入图片描述

何为机器学习,通俗点讲,机器学习就是:机器(计算机)从现有的复杂数据中学习规律,以预测未来的行为结果和趋势
从数学角度来讲,机器学习算法的本质就是一个数学求解的过程,就是假设存在一个函数f(x), 使得输入数据x,通过f这个函数的映射处理,能够得到想要的结果y

y = f(x) 即x 为输入数据, f为算法模型(目标函数),y为目标结果

机器学习的要素

上文提到,机器学习算法本质就是求一个目标函数, 那计算机是如何求的呢,一般至少包含以下要素:

数据表示

要想将数据用于数学求解,首先就得把数据表示成可以用于数学计算的形式。如:

  1. 天气预测:输入数据x可能是各种观测数据如气温26°C、风速3m/s、经纬度(113.5 , 37.8)等数值,那可表示为数组形式[26, 3, 113.5, 37.8]; 假设我们要预测是否下雨,则输出可表示为0或1的形式
  2. 图像识别:输入的是一张1920*1080彩色的图像数据,那可以表示为一个1920x1080的像素值数组格式,数组内每个元素的值为[r, g, b]颜色值数组的形式,即为一个三维数组;如果我们是要实现一个图像多分类的模型,则输出形式也可以表示为一个数组形式[c1,c2,c3,…] , 数组的每一个元素表示属于某个分类的概率
  3. 机器翻译:输入输出可能都是自然语言,这不利于数学计算,我们可以转化为文本向量的形式,如[0.78029002,0.77010974,0.07479124,0.4106988 ]

一般来说,原始数据并不会直接用于模型训练,而是要经过无量纲化、归一化、正则化等方式处理

模型定义

无论是简单的线性模型,还是复杂的神经网络,抑或是LLM大语言模型,其本质都是一个函数。
这个函数可能非常复杂,可能是非线性的,也可能是非连续的。
如目标函数是一个简单的线性函数f(x) = wx + b, 则w,b就是我们要求的函数的系数,也称模型的参数

模型训练

模型的训练就是我们利用已知的数据样本(训练样本)X,Y 求得函数系数(模型参数)的过程。
假设目标函数为线性函数:f(x)=wx + b
我们的训练数据有 X =(x1, x2, x3 …) Y = (y1, y2, y3 …)
如果是这种简单的线性函数,那我们其实带入(x1, y1), (x2, y2)两个数据即可求得模型的参数w,b。但是通常这个函数是非常复杂的(如GPT-3.5模型的参数量为1750亿个),甚至是没有解析解的,这时我们要直接求参数是非常困难的。因此可以转换为如下过程:
1. 计算误差
目标函数的参数难以直接求,为此我们引入误差计算,即模型的预测值f(x)与实际值y的误差,当这个误差足够小时,我们则认为这个f(x)即为我们的目标函数。
如使用均方误差计算:

均方误差(mean-square error, MSE)是反映估计量与被估计量之间差异程度的一种度量。

L = 1 n ∑ i = 1 n ( y i − f ( x i ) ) 2 L =\frac{1}{n}\sum_{i=1}^n (y_i - f(x_i))^2 L=n1i=1n(yif(xi))2
= 1 n ∑ i = 1 n ( y i − w x i − b ) 2 =\frac{1}{n}\sum_{i=1}^n (y_i-wx_i-b)^2 =n1i=1n(yiwxib)2
误差计算函数L可视为关于自变量w,b的一个函数,被称为损失函数
2. 误差最小化
要使误差尽可能小,即求损失函数L的极小值。极值问题可以转化为求导数,多元函数即为求偏导数
关于w的偏导数:
∂ L ∂ w = 1 n ∑ i = 1 n − 2 x i ( y i − ( w x i + b ) ) \frac{\partial L}{\partial w} =\frac{1}{n}\sum_{i=1}^n -2x_i (y_i -(wx_i + b)) wL=n1i=1n2xi(yi(wxi+b))
关于b的偏导数:
∂ L ∂ b = 1 n ∑ i = 1 n − 2 ( y i − ( w x i + b ) ) \frac{\partial L}{\partial b} =\frac{1}{n}\sum_{i=1}^n -2(y_i -(wx_i + b)) bL=n1i=1n2(yi(wxi+b))
偏导数组成的向量也被称为函数L的梯度: ∇ L = ( ∂ L ∂ w , ∂ L ∂ b ) \nabla L =(\frac{\partial L}{\partial w} ,\frac{\partial L}{\partial b}) L=(wL,bL)

梯度指向函数在给定点上增长最快的方向,其方向是函数增长最快的方向,其反方向则是函数值下降最快的方向。

3. 梯度下降
如果是简单的函数,那么令偏导数为0即可求得极值点对应的参数w,b值。但是上文我们提过,函数可能非常复杂,同样难以直接求极值点。因此也要换一种思路,即梯度下降方法。
损失函数的梯度指示了损失函数在当前参数值处变化最快的方向。梯度的负方向表示了损失函数下降最快的方向。因此,先给参数w,b赋一个随机值,然后通过以梯度的负方向来更新参数,使得下一步的参数值更接近函数的局部最小值,这样在多次迭代后,损失函数值通常会逐渐减小。
具体的更新规则如下:
w : = w − α . ∂ L ∂ w w := w - \alpha.\frac{\partial L}{\partial w} w:=wα.wL
b : = b − α . ∂ L ∂ b b := b - \alpha.\frac{\partial L}{\partial b} b:=bα.bL
使用 α \alpha α乘以梯度(偏导数),然后减去这个值来更新参数, α \alpha α控制每次更新的程度(步长), α \alpha α也被称为学习率(模型的超参数)

梯度下降更新参数的方式可能有点不好理解,我们可以先考虑单变量的情况,假设
损失函数L(w)的图像如下:

w随机取一个值,计算此时的导数(斜率),斜率为负,减去斜率则w往右走
在这里插入图片描述如果导数(斜率)为负,减去斜率则w往左走
在这里插入图片描述
如此重复迭代,即可找到损失函数值L(w)最小值(最低点)时,w的取值。多个参数求解也是类似。当然,这并不能保证每个参数更新后总体值一定会最小,最终结果可能是局部最小值或者鞍点。因此要调整合适的学习率 α \alpha α
在这里插入图片描述

线性模型实现案例

以下python代码在不使用机器学习框架的情况下,实现一个简单的线性模型训练过程

# 训练数据
X = [1, 2, 3, 4, 5]  # 输入特征数据
Y = [2, 4, 5, 4, 5]  # 输出标签数据(标注数据)

# 假设模型函数f(x)= wx+b, 初始化模型参数w,b
w = 0  # 斜率
b = 0  # 截距
# 设置模型超参数
alpha = 0.01  # 学习率
epochs = 1000  # 迭代次数

# 训练模型
for epoch in range(epochs):
    # 计算预测值
    Y_pred = [w * x + b for x in X]
    # 损失函数
    loss = sum((y_pred - y) ** 2 for y_pred, y in zip(Y_pred, Y)) / len(Y)
    
    # 计算梯度
    dw = sum(2 * (Y_pred[i] - Y[i]) * X[i] for i in range(len(Y))) / len(Y)
    db = sum(2 * (Y_pred[i] - Y[i]) for i in range(len(Y))) / len(Y)
    
    # 更新参数
    w -= alpha * dw
    b -= alpha * db

# 输出最终模型参数值
print("斜率 w:", w)
print("截距 b:", b)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

机器学习算法分类

在这里插入图片描述

监督学习(分类、回归等)中的数据有标注,无监督学习(聚类、降维、分割等)的数据没有标注,强化学习中有反馈评估,但数据没有标注。

深度学习

深度学习是机器学习的子集,它基于人工神经网络。 学习过程之所以是深度性的,是因为人工神经网络的结构由多个输入、输出和隐藏层构成。 每个层包含的单元可将输入数据转换为信息,供下一层用于特定的预测任务。 得益于这种结构,机器可以通过自身的数据处理进行学习。
通俗的理解,深度学习就是使用了人工神经网络(可以理解为一个更复杂的函数)的机器学习算法。

最早的神经网络模型由Warren McCulloch和Walter Pitts在1943年就已经提出了,但由于早期缺少对非线性问题的训练算法,以及计算机性能不足,发展缓慢。随着计算机性能的提高和误差反向传播(BP)算法的发明,深度学习算法得以快速发展。2012年,深度学习在ImageNet竞赛(世界级大规模视觉识别挑战赛)上大获全胜,标志着神经网络再一次高潮起点

深度学习模型结构

深度学习有着非常多的模型结构,如卷积神经网络(CNN)循环神经网络(RNN)长短期记忆神经网络(LSTM)生成对抗网络(GAN) 等等。
以一个神经元模型结构为例:
在这里插入图片描述

人工神经元模拟生物神经元的工作原理,接收一个或多个输入(代表神经树突处的兴奋性突触后电位和抑制性突触后电位)并将它们相加以产生输出(或激活,代表沿其轴突传递的神经元的动作电位)。通常每个输入都单独加权,总和通过一个非线性函数,称为激活函数或传递函数。
在这里插入图片描述

生物胞体内部的电势达到某个阈值时,就会沿着轴突向下传输一个脉冲。激活函数正是模拟这种特性,给神经元引入了非线性因素,使得神经网络可以任意逼近任何非线性函数,这样神经网络就可以应用到众多的非线性模型中。

如Sigmoid激活函数:
f ( x ) = 1 1 + e − x f(x)= \frac{1}{1+e^{-x}} f(x)=1+ex1
在这里插入图片描述

大量的神经元就构成了一个神经网络,连接神经元的每一条边都有对应的权重系数,也就是我们需要求解的模型参数。深度学习求模型参数的方式和上文提到的线性模型类似,也是基于梯度下降的方式更新模型参数。

由于神经网络通常是多层级结构,因此在深度学习模型训练时,通常采用反向传播方式,它通过链式法则从损失函数开始逐层计算梯度,然后利用梯度下降来逐层更新神经网络中的参数。

在这里插入图片描述

深度学习与传统机器学习

传统机器学习深度学习
数据量可以使用少量的数据做出预测。需要使用大量的训练数据做出预测。
硬件依赖项可在低端机器上工作。 不需要大量的计算能力。依赖于高端机器。 本身就能执行大量的矩阵乘法运算。 GPU 可以有效地优化这些运算。
特征化过程需要可准确识别且由用户创建的特征。从数据中习得高级特征,并自行创建新的特征。
学习方法将学习过程划分为较小的步骤。 然后,将每个步骤的结果合并成一个输出。通过端到端地解决问题来完成学习过程。
执行时间花费几秒到几小时的相对较少时间进行训练。通常需要很长的时间才能完成训练,因为深度学习算法涉及到许多层。

深度学习由于其强大的表达能力和高度自动化的特点,在计算机视觉、语音识别、自然语言处理等领域有着独特的优势

强化学习

强化学习(Reinforcement Learning, RL),又称奖励学习、评价学习或增强学习,是机器学习的范式和方法论之一,用于描述和解决智能体(agent)在与环境的交互过程中通过学习策略以达成回报(奖励)最大化或实现特定目标的问题。
在这里插入图片描述

2016年,基于强化学习训练的AlphaGo战胜了世界围棋冠军李世石,2019年,AlphaStar 在《星际争霸2》中以 10:1 击败了人类顶级职业玩家,同时,腾讯 AI Lab 开发的王者荣耀 AI 智能体「绝悟」,战胜了职业选手赛区联队,并升级至王者荣耀电竞职业水平。基于强化学习训练的AI智能体已经在游戏AI、自动驾驶、机器人学等领域取得了重大发展

强化学习模型

强化学习的模型也是种类繁多,如DQN、DDPG、A2C/A3C、PPO、TRPO等等。基于神经网络结构的强化学习模型也叫深度强化学习
强化学习的目标是最大化长期累积的奖励(或最小化成本),而不是简单地预测目标变量。为了达到这个目标,强化学习中通常使用的是累积奖励或价值函数来衡量行为的好坏。
在这里插入图片描述
以Q-Learning算法为例:

  1. 先假设存在一个状态动作价值函数:Q(s,a),表示在环境状态s时采取动作a之后,可以获得的奖励的期望值。Q(s,a) 越大表示在agent在看到环境状态s 时采取动作a 比较好。
  2. 先初始化这个Q值函数Q(s,a),如任何状态下,采取任何动作默认都返回0
  3. 智能体agent根据当前的策略(通常是ε-greedy策略,即以一定概率进行探索(随机选择),以一定概率选择Q值最高的动作)选择动作a,并与环境进行交互。
  4. 根据环境状态s和动作a交互得到的实际奖励 r r r ,以及下一个状态的最大Q值 m a x a ′ Q ( s ′ , a ′ ) max_{a′}Q(s′,a′) maxaQ(s,a),可使用使用时序差分算法(TD) 更新Q值函数,更新公式如下:
    Q ( s , a ) n e w = Q ( s , a ) o l d + α [ r + γ m a x a ′ Q ( s ′ , a ′ ) − Q ( s , a ) o l d ] Q(s,a)^{new}=Q(s,a)^{old}+\alpha[r + \gamma max_{a′}Q(s′,a′)−Q(s,a)^{old}] Q(s,a)new=Q(s,a)old+α[r+γmaxaQ(s,a)Q(s,a)old]
    α \alpha α是学习率, γ \gamma γ是折扣因子(对未来奖励的价值进行衰减),属于模型的超参数 r + γ m a x a ′ Q ( s ′ , a ′ ) r + \gamma max_{a′}Q(s′,a′) r+γmaxaQ(s,a)为目标估计值, Q ( s , a ) o l d Q(s,a)^{old} Q(s,a)old为当前估计值, 两者之差被称为时序差分误差(TD-error)。 也可采用上文提到的基于误差计算的损失函数梯度下降的方式来更新函数参数

时序差分的理解,比如模型预测从“广州-上海-北京”整条路线需要花费的时间为 t t t, 假设已知“广州-上海”需要花费时间为 r r r,用模型预测剩下路程“上海-北京”所需时间为 t ′ t^′ t, 那么如果模型预测是准确的,则应该 t = r + t ′ t = r + t^′ t=r+t,而 t − ( r + t ′ ) t - (r + t^′) t(r+t)的差值就是时序差分误差,模型训练的目的就是使这个误差尽可能小

  1. 重复上述步骤,与环境交互、更新Q值函数Q(s,a)。在训练完成后,通过Q值函数可以选择在每个状态下具有最大Q值的动作,得到最优策略。

虽然强化学习在解决复杂任务方面取得了显著的成就,但它也存在着一些根本性的缺陷。其一是“样本低效性”。由于智能体需要通过大量的试错和奖励反馈来优化策略,因此所需的样本数量通常更多(如王者荣耀绝悟AI使用了320个GPU 和35000 个CPU来训练),特别是如果在真实环境中试错,成本高昂且风险较大,因此还需要搭建模拟环境。其二就是“安全性与伦理问题”的挑战,如强化学习应用于自动驾驶车辆时,一个不完善的智能体可能会做出危险的决策,威胁到行人和其他车辆的安全。

深度学习模型实现案例

下面是一个简单的 基于PyTorch 框架训练模型的案例,用于创建一个简单的全连接神经网络(多层感知器,MLP),并用它来训练一个简单的分类任务。

import torch
import torch.nn as nn
import torch.optim as optim

# 准备训练数据
# 输入数据为包含两种特征维度的数据
inputs = torch.tensor([[0, 0], [0, 1], [1, 0], [1, 1]], dtype=torch.float32)
# 输出为0或1的分类数据
targets = torch.tensor([[0], [1], [1], [0]], dtype=torch.float32)

# 定义一个简单的神经网络模型
class SimpleNet(nn.Module):
    def __init__(self):
        super(SimpleNet, self).__init__()
        self.fc1 = nn.Linear(2, 4)  # 输入层到隐藏层
        self.fc2 = nn.Linear(4, 1)  # 隐藏层到输出层

    def forward(self, x):
        x = torch.sigmoid(self.fc1(x))  # 使用 sigmoid 作为激活函数
        # 即目标函数为 f(x) = sigmoid(fc2(sigmoid(fc1(x))))
        x = torch.sigmoid(self.fc2(x))
        return x

# 初始化模型和损失函数、优化器
model = SimpleNet()
criterion = nn.MSELoss()  # 使用均方误差作为损失函数
optimizer = optim.SGD(model.parameters(), lr=0.1)  # 使用随机梯度下降优化器

# 训练模型
epochs = 10000
for epoch in range(epochs):
    # 前向传播(计算预测值f(x))
    outputs = model(inputs)
    # 计算损失函数值
    loss = criterion(outputs, targets)
    
    # 反向传播与优化(梯度下降更新模型参数)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    
    if epoch % 1000 == 0:
        print(f"Epoch {epoch+1}/{epochs}, Loss: {loss.item()}")

# 测试模型
with torch.no_grad():
    test_outputs = model(inputs)
    predicted = (test_outputs > 0.5).float()
    print("Predicted:", predicted)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/558792
推荐阅读
相关标签
  

闽ICP备14008679号