从无监督构建词库看「最小熵原理」,套路是如何炼成的

2023-11-11

作者丨苏剑林

单位丨广州火焰信息科技有限公司

研究方向丨NLP,神经网络

个人主页丨kexue.fm


在深度学习等端到端方案已经逐步席卷 NLP 的今天,你是否还愿意去思考自然语言背后的基本原理?我们常说“文本挖掘”,你真的感受到了“挖掘”的味道了吗?


无意中的邂逅


前段时间看了一篇关于无监督句法分析的文章 [1],继而从它的参考文献中发现了论文 Redundancy Reduction as a Strategy for Unsupervised Learning,这篇论文介绍了如何从去掉空格的英文文章中将英文单词复原。对应到中文,这不就是词库构建吗?于是饶有兴致地细读了一番,发现论文思路清晰、理论完整、结果漂亮,让人赏心悦目。 


尽管现在看来,这篇论文的价值不是很大,甚至其结果可能已经被很多人学习过了,但是要注意:这是一篇 1993 年的论文。在 PC 机还没有流行的年代,就做出了如此前瞻性的研究。


虽然如今深度学习流行,NLP 任务越做越复杂,这确实是一大进步,但是我们对 NLP 原理的真正了解,还不一定超过几十年前的前辈们多少。 


这篇论文是通过“去冗余”(Redundancy Reduction)来实现无监督地构建词库的,从信息论的角度来看,“去冗余”就是信息熵的最小化。无监督句法分析那篇文章也指出“信息熵最小化是无监督的 NLP 的唯一可行的方案”。


我进而学习了一些相关资料,并且结合自己的理解思考了一番,发现这个评论确实是耐人寻味。我觉得,不仅仅是 NLP,信息熵最小化很可能是所有无监督学习的根本

何为最小熵原理?


读者或许已经听说过最大熵原理最大熵模型,现在这个最小熵原理又是什么?它跟最大熵不矛盾吗?


我们知道,熵是不确定性的度量,最大熵原理的意思就是说我们在对结果进行推测时,要承认我们的无知,所以要最大化不确定性,以得到最客观的结果。而对于最小熵原理,我们有两个理解角度:


1. 直观的理解:文明的演化过程总是一个探索和发现的过程,经过我们的努力,越多越多的东西从不确定变成了确定,熵逐渐地趋于最小化。因此,要从一堆原始数据中发现隐含的规律(把文明重演出来),就要在这个规律是否有助于降低总体的信息熵,因为这代表了文明演化的方向,这就是“最小熵原理”。


2. 稍严谨的理解:“知识”有一个固有信息熵,代表它的本质信息量。但在我们彻底理解它之前,总会有未知的因素,这使得我们在表达它的时候带有冗余,所以按照我们当前的理解去估算信息熵,得到的事实上是固有信息熵的上界,而信息熵最小化意味着我们要想办法降低这个上界,也就意味着减少了未知,逼近固有信息熵。


于是,我沿着“最小熵原理”这条路,重新整理了前人的工作,并做了一些新的拓展,最终就有了这些文字。读者将会慢慢看到,最小熵原理能用一种极具解释性和启发性的方法来导出丰富的结果来。


语言的信息


让我们从考究语言的信息熵开始,慢慢进入这个最小熵原理的世界。


信息熵=学习成本


“熵”不起:从熵、最大熵原理到最大熵模型(一)[2] 我们可以知道,一个对象的信息熵是正比于它的概率的负对数的,也就是:


640


如果认为中文的基本单位是字,那么中文就是字的组合,pc 就意味着对应字的概率,而 −logpc 就是该字的信息量。我们可以通过大量的语料估算每个汉字的平均信息:


640


如果 log 是以 2 为底的话,那么根据网上流传的数据,这个值约是 9.65 比特(我自己统计了一些文章,得到的数值约为 9.5,两者相当)。类似地,英文中每个字母的平均信息约是 4.03 比特。


这个数字意味着什么呢?一般可以认为,我们接收或记忆信息的速度是固定的,那么这个信息量的大小事实上也就相当于我们接收这个信息所需要的时间(或者所花费的精力,等等),从而也可以说这个数字意味着我们学习这个东西的难度(记忆负荷)。比如,假设我们每秒只能接收 1 比特的信息,那么按字来记忆一篇 800 字文章,就需要 9.65×800 秒的时间。


中英文孰优孰劣?


既然中文单字信息熵是 9.65,而英文字母信息熵才 4.03,这是不是意味着英文是一种更高效的表达呢? 


显然不能这么武断,难道背英语作文一定比背诵汉语作文要容易么? 


比如 800 字的中文作文翻译成英文的话,也许就有 500 词了,平均每个英文 4 个字母,那么信息量就是 4.03×500×4≈9.65×800,可见它们是相当的。换句话说,比较不同文字单元的信息量是没有意义的,有意义的是信息总量,也就是说描述同样的意思时谁更简练。 


当两句话的意思一样时,这个“意思”的固有信息量是不变的,但用不同语言表达时,就不可避免引入“冗余”,所以不同语言表达起来的信息量不一样,这个信息量其实就相当于记忆负荷,越累赘的语言信息量越大,记忆负荷越大。


就好比教同样的课程,有的老师教得清晰明了,学生轻松地懂了,有的老师教得哆里哆嗦,学生也学得很痛苦。同样是一节课程,本质上它们的知识量是一样的,而教得差的老师,表明授课过程中带来了过多的无关信息量,这就是“冗余”,所以我们要想办法“去冗余”。 


上述中英文的估计结果相当,表明中英文都经过长期的优化,双方都大致达到了一个比较优化的状态,并没有谁明显优于谁的说法。


套路之路


注意,上面的估算中,我们强调了“按字来记忆”,也许我们太熟悉中文了,没意识到这意味着什么,事实上这代表了一种很机械的记忆方式,而我们事实上不是这样做的。 


念经也有学问


回顾我们小时候背诵古诗、文言文的情景,刚开始我们是完全不理解、囫囵吞枣地背诵,也就是每个字都认识、串起来就不知道什么含义的那种,这就是所谓的“按字来阅读”了。很显然,这样的记忆难度是很大的。


后来,我们也慢慢去揣摩古文的成文规律了,逐渐能理解一些古诗或文言文的含义了,背诵难度就会降下来。到了高中,我们还会学习到文言文中“宾语前置”、“定语后置”之类的语法规律,这对我们记忆和理解文言文都是很有帮助的。 


重点来了! 


从古文的例子我们就能够感受到,像念经一样逐字背诵是很困难的,组词理解后就容易些,如果能找到一些语法规律,就更加容易记忆和理解了。但是我们接收(记忆)信息的速度还是固定的,这也就意味着分词、语法这些步骤,降低了语言的信息量,从而降低了我们的学习成本。


再细想一下,其实不单单是语言,我们学习任何东西都是这样的,如果只有少数的内容要学习,那么我们强行记住就行了,但学习的东西比较多时,我们就试图找出其中的“套路”,比如中国象棋中就分开局、中局、残局,每种局面都有很多“定式”,用来降低初学者的学习难度,而且也是在复杂局面中应变的基础;再好比我们有《孙子兵法》、《三十六计》,这些都是“套路大全”。通过挖掘“套路”来减轻逐一记忆的负担,“套路”的出现就是一个减少信息量的过程。 


说到底,念经念多了,也能发现经文的套路了。


以不变应万变


一言以蔽之,我们接收信息的速度是固定的,所以加快我们的学习进度的唯一方法就是降低学习目标的冗余信息量,所谓“去芜存菁”,这就是 NLP 中的最小熵原理了,也就是一开始所提到的“去冗余”,我们可以理解为是“省去没必要的学习成本”。 


事实上,一个高效的学习过程必定能体现出这个思想,同样地,教师也是根据这个思想来设计他们的教学计划的。在教学的时候,教师更倾向于讲授那些“通解通法”(哪怕步骤多一点),也不会选择每一题都讲一种独特的、巧妙的解法;在准备高考时,我们会努力摸索各种出题套路、解题套路。这些都是通过挖掘“套路”来降低信息熵、从而降低学习成本的过程,“套路”就是“去冗余”的方法。 


“套路”即“定式”,有了足够多的套路,我们才能以不变应万变。所谓“万变不离其宗”,这个“宗”,也就是套路了吧。当“套路”过多时,我们又会进一步寻找“套套路”——即套路的套路,来减轻我们记忆套路的负担,这是一个层层递进的过程。看来,将个体现象上升为套路,正是人类的智能的体现呢。


好了,空话不宜多说,接下来我们就正式走上修炼套路的旅途。


这部分,我们介绍“套路宝典”第一式——“当机立断”


1. 导出平均字信息熵的概念,然后基于最小熵原理推导出互信息公式;


2. 并且完成词库的无监督构建、给出一元分词模型的信息熵诠释,从而展示有关生成套路、识别套路的基本方法和技巧。这既是最小熵原理的第一个使用案例,也是整个“套路宝典”的总纲。


由字到词


从上文可以看到,假设我们根本不懂中文,那么我们一开始会将中文看成是一系列“字”随机组合的字符串,但是慢慢地我们会发现上下文是有联系的,它并不是“字”的随机组合,它应该是“套路”的随机组合。于是为了减轻我们的记忆成本,我们会去挖掘一些语言的“套路”。第一个“套路”,是相邻的字之间的组合定式,这些组合定式,也就是我们理解的“词”。 


平均字信息熵


假如有一批语料,我们将它分好词,以词作为中文的单位,那么每个词的信息量是 −logpw,因此我们就可以计算记忆这批语料所要花费的时间为:


640


这里 w∈语料是对语料逐词求和,不用去重。如果不分词,按照字来理解,那么需要的时间为:


640


根据前一节的理解,分词其实就是为了减轻记忆负担,那么理论上应该有:


640


当然,很多词语是重复出现的,因此我们可以把相同项合并:


640


其中 Nw,Nc 分别是在语料中统计得到词和字的频数。对式 (2.4) 两边除以语料的总字数,那么右端就是


640


其中 Nc/总字数=pc 即为字 c 的频率,所以上式就是每个字的平均信息,而 (2.4) 左端可以变形为


640


其中 Nw/总词数=pw 是词 w 的频率,lw 是词 w 的字数,所以 H 是平均每个词的信息量,l 是每个词的平均字数:


640


因此 L 实际上是按词来记忆时平均每个字的信息量,是我们要比较和优化的终极目标。我们将总的信息量转化为平均到每个字的信息量,是为了得到一个统一的度量标准。


丰富你的词汇量


是不是真如期望一样,分词有助于降低了学习难度?我简单统计了一下,对微信公众号的文章做一个基本的分词后,H≈10.8 比特,每个词平均是 1.5 个字,也就是 l≈1.5,那么 L=7.2 比特,这明显小于逐字记忆的 9.65 比特。这就说明了在中文里边,按词来记忆确实比按字来记忆要轻松。 


“分词”这个操作,降低了中文的学习难度,这也是“分词”通常都作为中文 NLP 的第一步的原因。 


简单来想,对语言进行分词之后,我们需要记忆的词表变大了,但是每个句子的长度变短了,整体来说学习难度是降低了。所以这也就不难理解为什么要学好英语,就得去背单词,因为丰富我们的词汇量能降低学习语言的难度。


提炼套路


反过来,我们也可以由 L 的最小化,来指导我们无监督地把词库构建出来。这就是“套路是如何炼成的”这门课的重点内容了。 


套路之行,始于局部


首先我们将平均字信息熵 L 局部化。所谓局部化,是指考察怎样的两个基本元素合并成一个新的元素后,会导致 L 降低,这样我们就可以逐步合并以完成熵最小化的目标。这里用“基本元素”来描述,是为了将问题一般化,因为字可以合并为词,词可以合并为词组,等等,这个过程是迭代的,迭代过程中“基本元素”是变化的。 


“局部化”是接下来大部分内容的基础,其推导过程虽然冗长,但都是比较简单的运算,稍加思考即可弄懂。 


假设目前 i 的频数为 Ni,总频数为 N,那么可以估算 Pi=Ni/N,假设 i 的字数为 li,那么就可以算出当前的:


640


如果将两个相邻的 a,b 合并成一项呢?假设 (a,b) 的频数为 Nab,那么在合并前可以估计 Pab=Nab/N。如果将它们合并为一个“词”来看待,那么总频数实际上是下降了,变为 Ñ =N−Nab,而 Ña=Na−Nab,Ñb=Nb−Nab,其他频数不变,因此我们就可以重新估计各个频率:


640


于是:


640


其中:


640


而:


640


因此:


640


我们的目的是让640变小,所以很明显,一个好的“套路”应该要使得 Fab≫0。


简明优美的近似


Fab 的表达式过于复杂,以至于难以发现出规律来,我们可以做一些近似。Pab≤Pa,Pb 总是成立的,而很多时候甚至可以认为 Pab≪Pa,Pb,这样一来在使用自然对数时就有:


640


因为这个近似的条件是要使用自然对数(ln(1+x)≈x),所以我们将下面的 log 全部改为自然对数 ln。代入 Fab 的表达式并去掉 Pab 的二次以上的项,得到:

640


这个指标就比较简明漂亮了,其中640我们称之为点互信息。


640


上面讨论的是两个元素的合并,如果是 k 个基本元素 a=(a1,…,ak) 的合并,那么同样可以推得:


640


其近似公式为:


640


推导尽,词库现


现在我们可以看到,要使得目标让640变小,就应该要有 Fab≫0,而 Fab 的一个下界近似是 F∗ab,所以我们可以用 F∗ab≫0 来进行确定哪些元素是需要合并,而对应于词库构建的过程,F∗ab≫0 实际上告诉我们哪些字是需要合并成词的。 


根据 F∗ab 的特点不难看出,F∗ab≫0 的一个必要的条件是640,也就是说互信息至少要大于1,这个必要条件下,互信息越大越好,a,b 的共现频率也越大越好,这就告诉我们要从共现频率和互信息两个角度来判断是否要把元素合并。 


在词库构建这个事情上,还有一个巧妙的招数,那就是对 F∗ab 的“逆运用”:式 F∗ab 告诉我们满足 F∗ab≫0 时,两个元素就应该合并。那么反过来,F∗ab 小于某个 θ 时,是不是就应该切分呢?(逆向思维,从确定哪些要“合并”变为确定哪些要“切分”,所谓“当机立断”)。


这样的话我们只需要用两个元素合并的公式来指导我们对语料进行一个粗糙的切分,然后对切分结果进行统计筛选,就可以得到很多词了。 


这样,我们就得到一种简单有效的构建词库的算法:


640


以前三步得到的词典还是有冗余的,这体现为:直接用这个词典构建一个一元分词模型,那么词典中的有些词永远都不会被分出来,因为那些词可以用它们的子词表示出来,并且子词的概率乘积还大于它本身的概率


比如在实验中,因为“的、主”以及“主、要”的互信息都大于 1,所以词库中出现了“的主要”这个“词”,但统计发现 p (的主要)< p (的) p (主要),那么这个词在一元模型分词的时候是不会分出来的,这个“词”放在词库中只会浪费内存,所以要去掉“的主要”这个词,并且把“的主要”的频数加到“的”和“主要”这两个词上面。


因此,根据这个原则,我们可以过滤掉一部分的候选词:


640


“去冗”这一步的作用还是很明显的,可以去掉 30% 甚至 50% 以上的“不及格”的候选词,以下就是筛选出来的一部分(100 个):


640


可以发现,除了“中国人”这个外,其他确实都是我们认识中的“不及格”的词语。


PS:“去冗”这一步需要一些人工规则来对长词进行降权,因为有限的语料对长词的统计是很不充分的,因此长词的概率估计会偏高。而既然是“人工规则”,那就让读者自由发挥了,这里不明确给出。


难道就这么简单?


当然,哪怕是经过上述 4 步,这个算法看起来还是过于简单,以至于会让人怀疑它的效果。有读者应该会想到,640不意味着640呀,也就是相邻两个字的互信息很小,但三个字的互信息可能就大了,只根据两字的互信息来切分是不是过于武断了? 


确实有这样的例子,比如在某些语料中,“共和国”中的“和”、“国”,“林心如”中的“心”、“如”,两个字的互信息是比较小的,但三字的互信息就很大了。


然而事实上,落实到中文词库构建这个应用上,这种情况并不多,因为中文跟英文不同,英文基本单位是字母,也就是只有 26 个,它们两两组合才 676 个,甚至三三组合也才一万多个,而汉字本身就有数千个,而理论上汉字对(即 2-gram)就有数百万个了,所以只需要统计 2-gram 就能得到相对充分地反映汉字的组合特征。所以如果出现了这种错例,很大可能是因为这些词不是我们输入语料的显著词,说白了,错了就错了呗。 


因此我们基本上不必要讨论三个或三个以上元素合并的公式,用上述的邻字的判别算法即可,在很多情景下它都可以满足我们的需求了。如果要对它进行改进的话,都无法避免引入三阶或更高阶的语言模型,并且还可能需要引入动态规划算法,这会大大降低算法效率。也就是说,改进的思路是有的,但改进的代价会有点大。


识别套路


现在我们可以找出一些自然语言的“套路”——也就是词语了。接下来的问题是,给我们一句话,如何识别出这句话中的套路呢?而对于“词”这个套路,说白了,就是有了词库和词频后如何分词呢? 


一元分词新诠释


有了前述讨论,其实就很简单了,自始至终,我们找套路就是为了减轻记忆负担,降低语料总的信息量,而我们有:


640


也就是最小化总的信息量等价最小化每个句子的信息量。所以对于一个给定的句子,它的最好的分词方案——假设为 w1,w2,…,wn —— 那么应该使得该句子的总信息量:


640


最小,这其实就是一元分词模型——使得每个词的概率乘积最大,但这里我们通过最小熵原理赋予了它新的诠释。 


核心的动态规划


一元分词模型可以通过动态规划来求解。动态规划是 NLP 中的核心算法之一,它是求满足马尔可夫假设的图模型的最优路径的方法。 


一般的最优路径是一个复杂度很高的问题,然而由于马尔可夫假设的存在,使得这里存在一个高效的算法,效率为

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从无监督构建词库看「最小熵原理」,套路是如何炼成的 的相关文章

  • Element中el-select下拉框无法回显

    使用elementUI时 在页面编辑时 下拉框回显数据有问题 这里主题类型默认选中类型为1的主题 并显示主题类型
  • 将一个有序的链表转化为一个二叉搜索树

    题目 Given a singly linked list where elements are sorted in ascending order convert it to a height balanced BST 解题思路 解决这道
  • 解决SpringBoot jar包中的文件读取问题

    前言 SpringBoot微服务已成为业界主流 从开发到部署都非常省时省力 但是最近小明开发时遇到一个问题 在代码中读取资源文件 比如word文档 导出模版等 本地开发时可以正常读取 但是 当我们打成jar包发布到服务器后 再次执行程序时就
  • Qt--自定义搜索控件,QLineEdit带前缀图标

    写在前面 这里自定义一个搜索控件 通过自定义LineEdit的textChange信号 搜索指定内容 并以QCheckBox的方式显示在QListWidget中 开发版本 Qt 5 15 2 Qt Creator10 0 2 编译环境 ms
  • 解决Failed to connect to 127.0.0.1 port 1080: Connection refused 报错

    https www jianshu com p 13099813f23d 解决Failed to connect to 127 0 0 1 port 1080 Connection refused 报错 0 4842018 07 03 14
  • 零基础JAVA——黑马程序员课程笔记

    视频地址 点击访问 我这里开发工具有时候用eclipse有时候用IDEA 看每个人的习惯 文中代码部分不会和老师讲的一模一样 因为我都是在看到老师给的案例后自己尝试写的 推荐大家这样做 可以帮助大家掌握 文章目录 JAVA语言发展史 JAV
  • 阿里云centos7安装mongodb,并开启远程连接

    1 下载mongodb 使用命令 curl O https fastdl mongodb org linux mongodb linux x86 64 3 2 9 tgz 2 上传到服务器 我这里用的是阿里云的远程服务器 并解压和重命名 r
  • charles使用

    安装 HTTPS的SSL证书配置 windows电脑 管理员模式打开Charles gt help gt SSL Proxying gt Install Chrales Root Certificate 安装证书 gt 下一步 gt 选择证
  • Gradle自定义插件详解

    首先认识plugin plugin采用groovy语言来编写 如果你对groovy语言不是很熟悉 请首先过一下groovy语法结构 groovy是运行于JVM的敏捷脚本语言 其最后会被编译成标准的JAVA语言 groovy语言最核心的应该是
  • ZIGBEE抓包工具Ubiqua使用介绍

    一 软件安装 Ubiqua 软件下载链接 https download csdn net download m pfly fish 12050973 二 安装CC2531抓包驱动 驱动软件下载链接 https download csdn n
  • Android am命令启动Service,Activity,BroadcastReceiver

    m命令启动Service Activity BroadcastReceiver 在frameworks base cmds am src com android commands am 一 am命令启动Activity am start n
  • Vlc.DotNet播放本地文件时的路径编码

    在播放本地媒体文件时 VLC会对文件路径进行编码 将中文字符编码为utf 8 在程序中也需要如此 否则不能正常播放 C 中可以用 System Web HttpUtility UrlEncode string System Text Enc
  • LR安装遇到 Cannot save the license information because access to the registry is denied

    在安装LoadRunner11时 会出现多种问题 在此以我遇到的问题一一进行解决 1 在首先安装时导入注册文件会遇到一个错误 就是 此时你需要一个工具 deletelicense 清除注册表信息的一个工具 可以轻易下载到 然后把LoadeR
  • 深入理解C++中的move和forward!

    导语 在C 11标准之前 C 中默认的传值类型均为Copy语义 即 不论是指针类型还是值类型 都将会在进行函数调用时被完整的复制一份 对于非指针而言 开销及其巨大 因此在C 11以后 引入了右值和Move语义 极大地提高了效率 本文介绍了在
  • 保险智能理赔-医疗票据OCR识别解决方案

    基于对健康险理赔行业的深刻洞察和理解 以领先的医疗AI数智化能力打通健康险理赔全流程 通过RPA人机协作实现对理赔材料的智能录入和初审工作 释放大量的专业录单和审核人力 减少企业运营成本 面临痛点 1 人工录入成本高 涉及个人证件 保险单据
  • Visual Attention Network(VAN)

    Visual Attention Network阅读翻译笔记 原文 https arxiv org abs 2202 09741 代码 https github com Visual Attention Network 摘要 虽然最初是为自
  • oracle 排序后取中间的数据

    用minus取 3000和5000的差值 排序后取序列为3000 5000的数据 select from table name t where rownum lt 5000 order by t sn asc minus select fr
  • php event监听

  • linux挂马检测,检测网站挂马程序(Python)

    系统管理员通常从svn git中检索代码 部署站点后通常首先会生成该站点所有文件的MD5值 如果上线后网站页面内容被篡改 如挂马 等 可以比对之前生成MD5值快速查找去那些文件被更改 为了使系统管理员第一时间发现 可结合crontab或na
  • 树莓派的四种登陆方式

    参考 树莓派的4种登陆方式 作者 丶PURSUING 发布时间 2021 02 02 09 15 30 网址 https blog csdn net weixin 44742824 article details 113524929 spm

随机推荐

  • 大厂被裁5个月,boss招聘上12000次打招呼,终于拿到offer了

    你可能不相信 但这是一个小伙伴最近的真实经历 他是一个有着5年工作经验的滴滴非核心项目运营 曾经在一家知名的互联网公司工作 收入也不错 但就在今年年初 因为后疫情的影响 公司进行了一轮大规模的裁员 他就成了其中的一员 从那以后 他就开始了漫
  • Android OpenGLES2.0(十六)——3D模型贴图及光照处理(obj+mtl)

    在Android OpenGLES2 0 十四 Obj格式3D模型加载中实现了Obj格式的3D模型的加载 加载的是一个没有贴图 没有光照处理的帽子 为了呈现出立体效果 手动 加了光照 拥有贴图的纹理及光照又该怎么加载呢 模型文件 本篇博客例
  • 【JVM】JVM调优(基础篇)

    一 概述 先来说下JVM调优主要是在调啥 调优就是调节JVM运行时内存大小 gc垃圾回收细节 要想调整JVM运行时内存大小 需要我们知道JVM内存划分知识以及要想调整gc垃圾回收的细节 需要我们知道垃圾回收器工作原理以及它们使用的垃圾回收算
  • FlinkCDC第三部分-同步mysql到mysql,ctrl就完事~(flink版本1.16.2)

    本文介绍了 来源单表 gt 目标源单表同步 多来源单表 gt 目标源单表同步 注 1 16版本 1 17版本都可以使用火焰图 生产上最好关闭 详情见文章末尾 Flink版本 1 16 2 环境 Linux CentOS 7 0 jdk1 8
  • cocos2d-x 源码分析 总目录

    这篇博客用来整理与cocos2d x相关的工作 只要有新的分析 扩展或者修改 都会更改此文章 祝大家愉快 1 源码分析 1 CCScrollView源码分析 http blog csdn net u011225840 article det
  • Python破解12306图片验证码

    不知从何时起 12306的登录验证码竟然变成了按字找图 可以说是又提高了一个等次 竟然把图像识别都用上了 不过有些图片 不得不说有些变态 图片的清晰图就更别说了 明显是从网络上的图库中搬过来的 谁知没多久 网络就惊现破解12306图片验证码
  • 删除 GitHub 提交记录中的文件或敏感数据

    BFG Repo Cleaner 是一个简单 快速的 10 720 倍 工具 代替 git filter branch 在你的 Git 存储库中清除不想要的文件或敏感数据 GitHub 地址 https github com rtyley
  • 代码审计-strpos数组绕过

    ereg 函数用指定的模式搜索一个字符串中指定的字符串 如果匹配成功返回true 否则 则返回false 搜索字母的字符是大小写敏感的 strpos 函数查找字符串在另一字符串中第一次出现的位置
  • CloudOS:物联网开发平台,云上开发,边端交付

    文章目录 一 CloudOS概述 二 CloudOS主要功能 1 云上开发 2 边端交付 3 数据管理 4 安全保障 三 CloudOS应用场景 1 智能家居 2 智慧城市 3 工业物联网 四 总结 欢迎来到云计算技术应用专栏 CloudO
  • 工作中如何做好技术积累(摘自美团点评技术团队博客)

    引言 古人云 活到老 学到老 互联网算是最辛苦的行业之一 加班 对工程师来说已是 家常便饭 同时互联网技术又日新月异 很多工程师都疲于应付 叫苦不堪 以至于长期以来流传一个很广的误解 35岁是程序员工作的终点 如何在繁忙的工作中做好技术积累
  • 由于设备驱动程序的前一个实例仍在内存中,Windows 无法加载这个硬件的设备驱动

    感谢这位 sizzg7796 网友
  • 【Jenkins】部署vue项目(多种方式部署)

    文章目录 Jenkins部署vue项目 先安装node js 上传到linux并解压 配置Jenkins 环境变量 jenkins 创建任务 部署方式 第一种 npm run build 打包的形式 执行脚本 build Steps 第二种
  • Detr代码解读(一)数据加载

    文章目录 导读 数据加载 dataset train 数据源文件不存在报错解决 CocoDetection 采样 数据处理 处理 target 处理 img 收集策略 collate fn batch 导读 源码 Detr Detr用的数据
  • 深入理解React Hooks与闭包:提升你的React开发技能

    深入理解React Hooks与闭包 提升你的React开发技能 深入理解React Hooks与闭包 提升你的React开发技能 深入理解React Hooks与闭包 提升你的React开发技能 前言 1 React Hooks 简介 2
  • PID双环控制(速度环和位置环)

    PID双环的控制过程 PID双环控制的前期准备 代码实现步骤 效果图 位置环做为外环 速度环作为内环 可以看到外环的输出值作为内环的目标值 外环计算一次pid 我们根据pid公式可以知道 当离位置目标越来越近时 第一个误差 外环误差 就越来
  • python输出结果去掉引号_从二维数组python中删除引号

    我目前正在尝试执行对具有大指数的幂进行赋值的代码 而不对其进行计算 而是对其进行记录 我有一个包含1000行的file 每行包含两个由逗号分隔的iteger 我被困在试图从数组中删除引号的位置 我尝试了许多方法 但都无济于事 这是我的代码
  • 转---30 分钟学会 Flex 布局

    正文从这开始 Flex 基本概念 在 flex 容器中默认存在两条轴 水平主轴 main axis 和垂直的交叉轴 cross axis 这是默认的设置 当然你可以通过修改使垂直方向变为主轴 水平方向变为交叉轴 这个我们后面再说 在容器中的
  • 使用three.js加载obj+mtl模型

    已经有比较好的博客介绍如何加载模型 使用three js加载obj mtl模型完整案例 有一点小问题 会导致模型加载不成功 需要修改两处地方 1 将 Detector js 替换为 WebGL js 根据Three js中Detector
  • 自动登录远程服务器脚本,iTerm2使用脚本自动登录远程服务器

    在iTerm2下ssh不能自动登录 不自动登录每次输入命令太麻烦了 这里介绍一个采取expect脚本的方式实现iTerm2下ssh自动登录 新建一个expect脚本 login exp usr bin expect if llength a
  • 从无监督构建词库看「最小熵原理」,套路是如何炼成的

    作者丨苏剑林 单位丨广州火焰信息科技有限公司 研究方向丨NLP 神经网络 个人主页丨kexue fm 在深度学习等端到端方案已经逐步席卷 NLP 的今天 你是否还愿意去思考自然语言背后的基本原理 我们常说 文本挖掘 你真的感受到了 挖掘 的