| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> 人工智能 -> fasttext的原理剖析 -> 正文阅读 |
|
[人工智能]fasttext的原理剖析 |
fastText的原理剖析1. fastText的模型架构fastText的架构非常简单,有三层:输入层、隐含层、输出层(Hierarchical Softmax) 输入层:是对文档embedding之后的向量,包含有N-garm特征 隐藏层:是对输入数据的求和平均 输出层:是文档对应标签 如下图所示: 1.1 N-garm的理解1.1.1 bag of wordbag of word 又称为bow,称为词袋。是一种只统计词频的手段。 例如:在机器学习的课程中通过朴素贝叶斯来预测文本的类别,我们学习的countVectorizer和TfidfVectorizer都可以理解为一种bow模型。 1.1.2 N-gram模型但是在很多情况下,词袋模型是不满足我们的需求的。 例如: 为了解决这个问题,就有了N-gram模型,它不仅考虑词频,还会考虑当前词前面的词语,比如 N-gram模型的描述是:第n个词出现与前n-1个词相关,而与其他任何词不相关。(当然在很多场景下和前n-1个词也会相关,但是为了简化问题,经常会这样去计算) 例如: 在n=2的情况下,这个模型被称为Bi-garm(二元n-garm模型) 在n=3 的情况下,这个模型被称为Tri-garm(三元n-garm模型) 具体可以参考 ed3book chapter3 所以在fasttext的输入层,不仅有分词之后的词语,还有包含有N-gram的组合词语一起作为输入 2. fastText中的层次化的softmax-对传统softmax的优化方法1为了提高效率,在fastText中计算分类标签的概率的时候,不再是使用传统的softmax来进行多分类的计算,而是使用的哈夫曼树(Huffman,也成为霍夫曼树),使用层次化的softmax(Hierarchial softmax)来进行概率的计算。 2.1 哈夫曼树2.1.1 哈夫曼树的定义哈夫曼树概念:给定n个权值作为n个叶子结点,构造一棵二叉树,若该树的带权路径长度达到最小,称这样的二叉树为最优二叉树,也称为哈夫曼树(Huffman Tree)。 哈夫曼树是带权路径长度最短的树,权值较大的结点离根较近。 2.1.2 哈夫曼树的相关概念二叉树:每个节点最多有2个子树的有序树,两个子树分别称为左子树、右子树。有序的意思是:树有左右之分,不能颠倒 叶子节点:一棵树当中没有子结点的结点称为叶子结点,简称“叶子” 路径和路径长度:在一棵树中,从一个结点往下可以达到的孩子或孙子结点之间的通路,称为路径。通路中分支的数目称为路径长度。若规定根结点的层数为1,则从根结点到第L层结点的路径长度为L-1。 结点的权及带权路径长度:若将树中结点赋给一个有着某种含义的数值,则这个数值称为该结点的权。结点的带权路径长度为:从根结点到该结点之间的路径长度与该结点的权的乘积。 树的带权路径长度:树的带权路径长度规定为所有叶子结点的带权路径长度之和 树的高度:树中结点的最大层次。包含n个结点的二叉树的高度至少为log2 (n+1)。 2.1.3 哈夫曼树的构造算法
例如:圆圈中的表示每个词语出现的次数,以这些词语为叶子节点构造的哈夫曼树过程如下: 可见:
2.2 哈夫曼编码2.2.1 哈夫曼编码在数据通信中,需要将传送的文字转换成二进制的字符串,用0,1码的不同排列来表示字符。 例如,需传送的报文为 但是很明显,上述的编码的方式并不是最优的,即整理传送的字节数量并不是最少的。 为了提高数据传送的效率,同时为了保证 可用字符集中的每个字符作为叶子结点生成一棵编码二叉树,为了获得传送报文的最短长度,可将每个字符的出现频率作为字符结点的权值赋予该结点上,显然字使用频率越小权值越小,权值越小叶子就越靠下,于是频率小编码长,频率高编码短,这样就保证了此树的最小带权路径长度效果上就是传送报文的最短长度 因此,求传送报文的最短长度问题转化为求由字符集中的所有字符作为叶子结点,由字符出现频率作为其权值所产生的哈夫曼树的问题。利用哈夫曼树来设计二进制的前缀编码,既满足前缀编码的条件,又保证报文编码总长最短。 下图中 2.3 梯度计算上图中,红色为哈夫曼编码,即label5的哈夫曼编码为1001,那么此时如何定义条件概率 P ( L a b e l 5 ∣ c o n t e x ) ? P(Label5|contex)? P(Label5∣contex)?呢? 以Label5为例,从根节点到Label5中间经历了4次分支,每次分支都可以认为是进行了一次2分类,根据哈夫曼编码,可以把路径中的每个非叶子节点0认为是负类,1认为是正类(也可以把0认为是正类) 由机器学习课程中逻辑回归使用sigmoid函数进行2分类的过程中,一个节点被分为正类的概率是 δ ( X T θ ) = 1 1 + e ? X T θ \delta(X^{T}\theta) = \frac{1}{1+e^{-X^T\theta}} δ(XTθ)=1+e?XTθ1?,被分类负类的概率是: 1 ? δ ( X T θ ) 1-\delta(X^T\theta) 1?δ(XTθ),其中 θ \theta θ就是图中非叶子节点对应的参数 θ \theta θ。 对于从根节点出发,到达Label5一共经历4次2分类,将每次分类结果的概率写出来就是:
但是我们需要求的是
P
(
L
a
b
e
l
∣
c
o
n
t
e
x
)
P(Label|contex)
P(Label∣contex), 他等于前4词的概率的乘积,公式如下(
d
j
w
?
d_j^w?
djw??是第j个节点的哈夫曼编码) 其中: 或者也可以写成一个整体,把目标值作为指数,之后取log之后会前置: 在机器学习中的逻辑回归中,我们经常把二分类的损失函数(目标函数)定义为对数似然损失,即 式子中,求和符号表示的是使用样本的过程中,每一个label对应的概率取对数后的和,之后求取均值。 带入前面对
P
(
l
a
b
e
l
∣
c
o
n
t
e
x
t
)
?
P(label|context)?
P(label∣context)?的定义得到: 有了损失函数之后,接下来就是对其中的 X , θ X,\theta X,θ进行求导,并更新,最终还需要更新最开始的每个词语词向量 层次化softmax的好处:传统的softmax的时间复杂度为L(Labels的数量),但是使用层次化softmax之后时间复杂度的log(L) (二叉树高度和宽度的近似),从而在多分类的场景提高了效率 3. fastText中的negative sampling(负采样)-对传统softmax的优化方法2negative sampling,即每次从除当前label外的其他label中,随机的选择几个作为负样本。具体的采样方法: 如果所有的label为
V
?
V?
V?,那么我们就将一段长度为1的线段分成
V
?
V?
V?份,每份对应所有label中的一类label。当然每个词对应的线段长度是不一样的,高频label对应的线段长,低频label对应的线段短。每个label的线段长度由下式决定: 简单的理解就是,从原来所有的样本中,等比例的选择neg个负样本作(遇到自己则跳过),作为训练样本,添加到训练数据中,和正例样本一起来进行训练。 Negative Sampling也是采用了二元逻辑回归来求解模型参数,通过负采样,我们得到了neg个负例,将正例定义为 l a b e l 0 ? label_0? label0??,负例定义为 l a b e l i , i = 1 , 2 , 3... n e g ? label_i,i=1,2,3...neg? labeli?,i=1,2,3...neg? 定义正例的概率为 P ( l a b e l 0 ∣ context ) = σ ( x k T θ ) , y i = 1 ? P\left( label_{0}|\text {context}\right)=\sigma\left(x_{\mathrm{k}}^{T} \theta\right), y_{i}=1? P(label0?∣context)=σ(xkT?θ),yi?=1? 则负例的概率为: P ( l a b e l i ∣ context ) = 1 ? σ ( x k T θ ) , y i = 0 , i = 1 , 2 , 3.. n e g ? P\left( label_{i}|\text {context}\right)=1-\sigma\left(x_{\mathrm{k}}^{T} \theta\right), y_{i}=0,i=1,2,3..neg? P(labeli?∣context)=1?σ(xkT?θ),yi?=0,i=1,2,3..neg? 此时对应的对数似然函数为: 可以看出:一个neg+1个样本进行了训练,得到了总的损失。 之后会使用梯度上升的方法进行梯度计算和参数更新,仅仅每次只用一波样本(一个正例和neg个反例)更新梯度,来进行迭代更新 具体的更新伪代码如下: 其中内部大括号部分为w相关参数的梯度计算过程,e为w的梯度和学习率的乘积,具体参考:https://blog.csdn.net/itplus/article/details/37998797 好处:
|
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 | -2024/12/22 15:07:24- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |