前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >[L4]实战语言模型~softmax与交叉熵

[L4]实战语言模型~softmax与交叉熵

作者头像
触摸壹缕阳光
发布于 2020-06-04 09:52:18
发布于 2020-06-04 09:52:18
1.1K00
代码可运行
举报
运行总次数:0
代码可运行

抱怨就像搬起石头砸自己的脚,于人无益,于己不利,于事无补。

全文字数:2448字

阅读时间:12分钟

前言

实战语言模型系列:

[L1]实战语言模型~语料词典的生成

[L2]实战语言模型~数据batching

[L3]实战语言模型~构建embedding层

a

Softmax层

在介绍完了如何处理数据以及如何构造样本之后,就可以构建我们的神经网络语言模型了,下面是使用LSTM构建的语言模型的大体结构:

▲使用循环神经网络实现自然语言模型的示意图

那可以看出上面着重写出来的两层:

  1. embedding层;
  2. softmax层;

那接下来介绍softmax层。使用循环神经网络训练语言模型,对于每个cell,其实都相当于是一个有监督的多分类任务,每个词汇表中的单词代表一个类别。如下图所示:

▲单步cell示意图

当训练的时候,我们要做的就是使得输出向量和期望向量(样本label)越接近越好,那交叉熵就是评判两个概率分布之间的距离的常用方法之一。然而神经网络的输出确不一定是一个概率分布,所以这就有了softmax,softmax能够将神经网络前向传播的结果变成一个概率分布,其实可以把softmax当成一个额外的处理层,他把神经网络的输出变成了一个概率分布,也就是每一个输出都是(0~1)之间的小数,并且所有输出的结果之和为1。通过这样的处理,我们就可以轻松的使用交叉熵损失函数来计算真实分布与期望分布的距离,并通过梯度下降算法通过降低交叉熵损失以拟合样本训练模型。

下面看一看softmax是怎么计算的:

▲softmax层

现在我的神经网络有四个输出

,那么经过softmax处理后的输出为:

,通过softmax我们可以计算出

的值。

通过上面的描述我们可以知道,加入softmax层是为了将神经网络的输出转换为概率分布,进而使用交叉熵来计算神经网络输出的概率分布和期望的概率分布之间的距离。

对于使用softmax层处理,可以分成两个步骤:

  1. 使用线性映射将循环神经网络的输出映射为一个维度与词汇表大小相同的向量,这一步的输出叫做logits,其实也就是神经网络实际的输出值(没有加入softmax时候的

);

  1. 调用softmax将logits转化为加和为1的概率,我们可以直接使用tf.nn.softmax(logits)来得到转换后的概率向量;

b

Softmax与交叉熵

在训练语言模型以及对训练好的语言模型的评估好坏(perplexity实际上也是一个交叉熵)的时候,都会用到交叉熵损失函数。而由于softmax和交叉熵损失函数经常一起使用,所以tensorflow对这两个功能进行了统一的封装,并提供了两个函数(当然你也可以分成两步写,先获得经过softmax层得到的结果,然后放入交叉熵的计算公式中进行计算):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(lables = y_,logits = y)
cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(lables = y_,logits = y)

那这两个函数有什么区别呢,我们现在一个个的介绍:

  • cross_entropy = tf.nn.softmax_cross_entropy_with_logits(lables = y_,logits = y)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import tensorflow as tf

word_prob_distribution = tf.constant([[0.0,0.0,1.0,0.0],[1.0,0.0,0.0,0.0]])
#假设模型对两个单词的预测时,产生logits分别是[2.0,-1.0,3.0,2.0],[1.0,0.0,-0.5,4.0]
#这个时候的predict_logits是没有经过softmax层处理的y1,y2,y3,y4
predict_logits = tf.constant([[2.0,-1.0,3.0,2.0],[1.0,0.0,-0.5,4.0]])
#使用softmax_cross_entropy_with_logits
loss = tf.nn.softmax_cross_entropy_with_logits(logits = predict_logits,labels = word_prob_distribution)

sess = tf.InteractiveSession()
print(loss.eval())
sess.close()

'''[ 0.56194139  3.07623076]'''
  • cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(lables = y_,logits = y)
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import tensorflow as tf

#假设词汇表的大小为4,语料中包含两个单词[2,0],单词在词汇表中的ID编号
word_prob_distribution = tf.constant([2,0])
#假设模型对两个单词的预测时,产生logits分别是[2.0,-1.0,3.0,2.0],[1.0,0.0,-0.5,4.0]
#这个时候的predict_logits是没有经过softmax层处理的y1,y2,y3,y4
predict_logits = tf.constant([[2.0,-1.0,3.0,2.0],[1.0,0.0,-0.5,4.0]])
#使用sparse_softmax_cross_entropy_with_logits
loss = tf.nn.sparse_softmax_cross_entropy_with_logits(logits = predict_logits,labels = word_prob_distribution)

sess = tf.InteractiveSession()
print(loss.eval())
sess.close()

'''[ 0.56194139  3.07623076]'''

会发现两个函数的输出结果是相同的,那这两个函数的唯一区别就在于表示真实单词分布的不同,在第一个函数中,我们使用one-hot的表示方式,而在第二个函数中我们使用单词在向量中的最大值的位置,从输出的结果相同也可以看出来,这两种表示方式其实是一样的,在我们的样例中在处理文本的时候,只是将其转换为了词汇表中的对应ID号,并没有将其转换为one-hot(其实他们是等价的),因为其实我们可以使用sparse_softmax_cross_entropy_with_logits函数通过对应单词的词汇表的ID编号也可以轻松的得到交叉熵的loss值。

那softmax + 交叉熵有什么效果呢?下面一个使用softmax+交叉熵的三个输出的神经网络计算流程,只需看最后一行,可以看出梯度下降更新的结果:

  1. 先将所有的logits值先减去对应的softmax的值,也就是推所有;
  2. 然后将真实标记中的对应位置的值加上1,也就是拉一个;

▲按比例推所有拉一个

顺便说一句,由于softmax层以及embedding层的参数占所有参数的比重很大,所以通常我们共享embedding层以及softmax层的参数,这样不仅可以大幅度的减少参数数量而且还能够提高最终模型的效果。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-06-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI机器学习与深度学习算法 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深入浅出话属性
程序的本质就是“数据+算法”,或者说用算法来操作数据来得到自己想要的结果。在程序中,数据表现为各种各样的变量,算法则表现为各种各样的函数(操作符是函数的简记法)。即使是到了面向对象时代有了类等数据结构的出现,这一本质仍然没有改变---类的作用只是将散落在程序中的变量和函数进行归档封装并控制对它们的访问而已。被封装在类中的变量称为字段,它表示的是类或实例的状态;被封装在类里的函数叫做方法,它表示的是类或实例的功能。字段和类构造出了最原始的面向对象封装,这时候的面向对象中还不包含事件,属性等概念。
莫问今朝
2018/08/31
9650
深入浅出话属性
剖析依赖属性
这节来讲一下WPF中的依赖属性 (Dependency Property)。
宿春磊Charles
2021/11/05
4810
[UWP]依赖属性1:概述
依赖属性(DependencyProperty)是UWP的核心概念,它是有DependencyObject提供的一种特殊的属性。由于UWP的几乎所有UI元素都是集成于DependencyObject的FramewordElement,并且这些UI元素的几乎所有属性及它们出现在XAML中的几乎所有属性都是依赖属性,所以可以说依赖属性是专门为UI设计的属性系统。
dino.c
2019/01/18
7130
[UWP]依赖属性1:概述
一站式WPF--依赖属性(DependencyProperty)一
  这段是MSDN上对依赖属性(DependencyProperty)的描述。主要介绍了两个方面,WPF中提供了可用于扩展CLR属性的服务;被这个服务支持的属性称为依赖属性。
JusterZhu
2023/09/18
8560
一站式WPF--依赖属性(DependencyProperty)一
WPF 桌面端开发 8-DependencyProperty
在Resources和Data binding中,XAML 提供了这样一种语法,来为属性赋值:
码客说
2020/05/09
7820
[WPF]浅析依赖属性(DependencyProperty)
在WPF中,引入了依赖属性这个概念,提到依赖属性时通常都会说依赖属性能节省实例对内存的开销。此外依赖属性还有两大优势。
czwy
2023/10/22
6060
[WPF]浅析依赖属性(DependencyProperty)
一站式WPF--依赖属性(DependencyProperty)二
 书接上文,前篇文章介绍了依赖属性的原理和实现了一个简单的DependencyProperty(DP),这篇文章主要探讨一下如何使用DP以及有哪些需要注意的地方。
JusterZhu
2023/09/18
6780
一站式WPF--依赖属性(DependencyProperty)二
【我们一起写框架】MVVM的WPF框架之绑定(二)
上一篇我们已经一起编写了框架的基础结构,并且实现了ViewModel反向控制Xaml窗体。
Kiba518
2018/09/28
2K0
【我们一起写框架】MVVM的WPF框架之绑定(二)
造轮子了!NETCore跨平台UI框架,CPF
CPF(暂时命名)(Cross platform framework),模仿WPF的框架,支持NETCore的跨平台UI框架,暂时不够完善,只用于测试,暂时只支持Windows和Mac。支持数据绑定,CSS,动画。。。
梁规晓
2019/11/07
1.8K0
造轮子了!NETCore跨平台UI框架,CPF
[WPF自定义控件]从ContentControl开始入门自定义控件
我去年写过一个在UWP自定义控件的系列博客,大部分的经验都可以用在WPF中(只有一点小区别)。这篇文章的目的是快速入门自定义控件的开发,所以尽量精简了篇幅,更深入的概念在以后介绍各控件的文章中实际运用到才介绍。
dino.c
2019/05/17
4.2K0
WPF 依赖属性绑定不上调试方法
在写 WPF 程序的时候会遇到依赖属性绑定了,但是值没有更新或者没有绑定上的问题,本文告诉大家可以如何调试
林德熙
2020/07/06
1.7K0
Silverlight:Dependency Property(依赖属性)学习笔记
学习SL/WPF,Dependency Properties(依赖属性)是一个全新(陌生)但又无法回避的概念。 http://www.wpftutorial.net/DependencyPropert
菩提树下的杨过
2018/01/23
7090
Silverlight:Dependency Property(依赖属性)学习笔记
学习WPF——WPF布局——了解布局容器
WPF布局工作内部原理 WPF渲染布局时主要执行了两个工作:测量和排列 测量阶段,容器遍历所有子元素,并询问子元素所期望的尺寸 排列阶段,容器在合适的位置放置子元素,并设置元素的最终尺寸 这是
liulun
2018/01/12
2.4K0
学习WPF——WPF布局——了解布局容器
WPF自学入门(七)WPF 初识Binding
今天记录一下Binding的基础和具体的使用方法,说起这个Binding,在WPF中,Binding是很重要的特征,在传统的Windows软件来看,大多数都是UI驱动程序的模式,也可以说事件驱动程序,这个程序模式在工作过几年的程序员中是根深蒂固的,WPF作为Winform的升级,它把UI驱动程序彻底改变了,核心回到了数据驱动程序的模式上面,这样,程序就回到了算法和数据。数据,才是真正需要重点处理的!
黄昏前黎明后
2019/09/11
1.7K0
WPF自学入门(七)WPF 初识Binding
WPF依赖属性(wpf 依赖属性)
依赖属性就是一种自己可以没有值,并且可以通过绑定从其他数据源获取值。依赖属性可支持WPF中的样式设置、数据绑定、继承、动画及默认值。
全栈程序员站长
2022/07/28
2.3K0
WPF依赖属性(wpf 依赖属性)
win10 uwp 依赖属性
本文告诉大家如何使用依赖属性,包括在 UWP 和 WPF 如何使用。 本文不会告诉大家依赖属性的好处,只是简单告诉大家如何使用。
林德熙
2018/09/19
8870
win10 uwp 依赖属性
WPF --- 如何以Binding方式隐藏DataGrid列
先在ViewModel创建数据源 People 和控制列隐藏的 IsVisibility,这里直接以 MainWindow 为 DataContext
Niuery Diary
2023/11/23
7480
WPF --- 如何以Binding方式隐藏DataGrid列
[翻译] WPF 中用户控件 DataContext/Binding 和依赖属性的问题
ProgrammingDude(asked Dec 8, 2015 at 21:24)
独立观察员
2022/12/06
1.1K0
WPF 让普通 CLR 属性支持 XAML 绑定(非依赖属性),这样 MarkupExtension 中定义的属性也能使用绑定了
如果你写了一个 MarkupExtension 在 XAML 当中使用,你会发现你在 MarkupExtension 中定时的属性是无法使用 XAML 绑定的,因为 MarkupExtension 不是一个 DependencyObject。
walterlv
2020/02/10
1.9K0
WPF快速入门系列(1)——WPF布局概览
  关于WPF早在一年前就已经看过《深入浅出WPF》这本书,当时看完之后由于没有做笔记,以至于我现在又重新捡起来并记录下学习的过程,本系列将是一个WPF快速入门系列,主要介绍WPF中主要的几个不同的特性,如依赖属性、命令、路由事件等。
zls365
2020/11/10
3.2K0
WPF快速入门系列(1)——WPF布局概览
推荐阅读
相关推荐
深入浅出话属性
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验