办公室扫地僧的日常生活

独孤九剑 vs 辟邪剑谱


  • Home

  • Archives

  • Tags

词向量如何计算?

Posted on 2018-04-18 | In NLP

最近很多人问我词向量是怎么计算出来的,所以写一篇来解释一下。

什么是词向量?

词向量就是某一个多维向量能唯一代表某一个词。

举个例子:假设中文只有4个词【你、我、他、它】,如果用0或1去表示他们,【你】可以表示为(1,0,0,0),【我】可以表示为(0,1,0,0),以此类推。
这些0或1组成的向量就可以称之为词向量,但是这种模式的词向量并不好,主要原因有两点:第一中文中有非常多的词,如果每一个词就占一位,那么这样的词向量就会非常长,
同时如果添加了新的词汇,向量的维度就需要增加。第二这些词向量永远都是有一个唯一的1,其余都是0,这样的词向量只能代表这个词,但是不能代表这个词的意思,每个向量之间都是正交。
所以以上述onehot方式编码的向量,并没有什么意义。

为了解决上述这个问题呢,Mikolov就提出了一种模型叫Word Embeddings,这种模型可以把词投射到一个固定的多维空间,
每个词的词向量都是同样的长度且相近语义的词会聚集在一起。
词向量空间
实现这种模型,又分两种主流的方法,一个叫Continuous Bag-of-Words model(CBOW),一个叫skip-gram。

CBOW

CBOW认为一个词的语义可以通过其周边的词来表示,所以通过周边的词来预测被选词。
CBOW

这张图其实完整的描述了cbow的全部过程,但是并不好理解,所以我用一个例子一步一步解释这张图

假设在世界上只有一个句子”I love you”, 也就是说只有三个单词(用大写的V表示,V=3),通过onehot编码的方式,I可以表示为(1,0,0), love可以表示为(0,1,0), you可以表示为(0,0,1)。

cbow用周边n个词预测中间的词,假设n=1,我们的模型要通过(I,you)预测出love。

  1. 将I(1,0,0)和you(0,0,1)输入输入层,由于n=1,所以输入层由两个神经元组成。
  2. 每个输入向量乘以一个V*N的矩阵,V是上面说的词库的大小,在这里就是3,N则是隐藏层神经元的个数。
  3. 因为输入向量是一个1V的矩阵,所以相乘后的结果是一个1N的矩阵。
  4. 把所有的输入向量产生的乘积累加之后取平均值得到一个新的1*N的矩阵就是我们在隐藏层的输出。
  5. 把这个输出的向量再乘以一个NV的矩阵(与上述VN的矩阵没有任何关系),又会得到一个1*V的矩阵,可以把这一层叫做投影层,这层的作用就是把隐藏层的结果再映射到词库里。
  6. 我们把最终得到的1*V的矩阵通过softmax得到矩阵中最大概率的那个列,而这一列就应该对应love这个单词,如果不是,说明我们的隐藏层和投影层的矩阵并不符合要求。
  7. 我们通过cost function(代价函数)以及向后传播算法(这部分内容主要涉及神经网络,有兴趣可以自行查阅)去不断调整这两个矩阵的参数,直到其到达一个我们相对满意的程度。这就是训练模型的过程。
  8. 当这个模型达到一定的准确率后,我们通过每个词的onehot编码乘以隐藏层的矩阵得到的1*N矩阵,就是我们要得到的这个词的词向量了,所以隐藏层神经元的个数就决定了词向量的维度。

Skip-Gram

不同于CBOW,Skip-Gram模型通过选中词预测周围n个词。
Skip-Gram

还是按照CBOW的例子,在Skip-Gram模型下,当n=1时,我们的模型需要通过love预测出I和you。

Skip-Gram的训练过程基本与CBOW相同,唯一的区别就是CBOW需要输入向量是多个,需要把隐藏层的结果累加取平均值,
而Skip-Gram则不需要,直接计算就好。

工具

开源的词向量工具有很多,这里推荐两个

  1. facebook开源的fasttext,这个项目已经实现了算法,使用者只需要准备数据和调整参数即可,训练速度很快,很好用。
  2. tensorflow google开源的神经网络框架,可以再tutorial里自行搜索词向量相关的例子,可以实现自己的词向量算法。

kafka相关问题总结

Posted on 2018-03-27

一直在使用kafka,遇到过很多问题,总结一下

数据丢失???

很多人对比kafka和AMQP的时候,都会强调kafka会丢数据,感觉好像只要用kafka就会丢数据一样,从而排斥使用kafka,亦或者在使用的过程中,发现数据丢失就认定罪魁祸首是kafka,好像丢数据就是使用kafka的代价。悄悄的鄙视一下这些伪程序猿。

kafka是一个强调高性能、高吞吐量的分布式消息中间件,在CAP中强调CP,当失去Broker Controller,选举新的Controller前服务处于不可用的状态,毕竟作为消息中间件对数据一致性还是有很高的要求。

大致解释一下kafka集群,kafka server一般叫broker,在集群里,各个broker通过zookeeper抢占broker controller,Controller的职责是管理所有的Partition和Replica的分布以及ISR列表并通知其他broker,如果controller宕机,其他broker又通过zk抢占Controller,在Controller选举的过程中,服务处于不可用的状态。

partition leader和partition replica:新建过topic的同学肯定知道,在新建topic的时候,我们一般会指定两个变量partition和replica,其实每个topic都是由多个partition组成的,一般情况下,partition的数量等于broker的数量,生产端产生数据存储在这些partition中。如果每个partition都没有备份,一旦服务器宕机,其中的数据都无法消费了,所以需要若干partition replica去备份这些partition, 而这些被备份的partition就称之为partition leader。这里再解释一下leader和replica切换的问题,leader与replica的数据copy肯定会有延迟的问题,不可能保证每时每刻replica的数据都与leader一致,所以就引入了一个ISR列表去维护哪些replica的数据是完整的,是值得信赖的,当replica中的数据与leader中的数据的延迟量超过一定的数值(可以自己设定的)或者卡住多少时间不返回的时候,这个replica就会被移除ISR列表,意味着此时如果leader宕机,当前这个replica是没有机会成为leader的,除非ISR列表里没有可用的replica。当这个replica的延迟或者返回时间恢复正常后,又会动态的把这个replica加入到ISR列表,总之ISR列表是动态的。

消息写入kafka的过程:producer会通过所连接的broker获取到当前kafka集群的状态例如broker地址、partition的分配等,producer通过消息中的key或者round robin选择要写入的partition, producer只会将消息写入partition leader, 再由leader分发给所有的replica。在这个过程中,producer可以指定消息写入的ack模型,acks=0时,意味着不在乎消息是否已经写入partition leader,只要发送了就好;acks=1,消息写入leader需要返回ack才算成功;acks=-1或者all,消息写入leader后且所有replica也都写入并返回leader ack后才算成功。producer发送消息的确认模式选择就可能导致数据丢失,例如:当acks=1时,数据成功写入partition leader,producer会认为消息投递成功啦,突然partition leader在通知replica备份之前挂了,这条数据就沉入大海了,即使这个leader在一段时间后恢复,其他的replica可能早就已经取代它,成为新的leader了。

消息持久化broker时也可能发生丢失,在未写入硬盘前,机器挂掉也可能丢失数据,这种情况就认命吧,或者让acks更严格,消息未确认写入成功时能够继续重试。

最后就是消费的时候也可能发生丢失,kafka的消费模式和传统的AMQP是完全不同的,传统AMQP通过broker推送从而由broker控制消息的消费,消费端处理消息后需要通知broker消费状态(例如rabbitmq的ack,nack)如果失败broker会重新将消息推给其他消费端;kafka则是通过pull的方式,由消费端从broker上拉取消息,而拉取哪些消息由消费端自己控制(存在zk也是自己控制),这就导致如果消费失败,且消费端没有做好相应处理,offset+1后,这条消息也就丢失了,所以对不允许数据丢失的业务,可以通过代码管理offset。

消费消息没有顺序???

kafka的消费端有两个概念consumer group和consumer, consumer group由多个consumer组成,partition只能被在同一个consumer group中的一个consumer消费,但是可以被多个不同consumer group的consumer同时消费,如果consumer group中只有一个consumer,那么这个consumer可以消费所有的partition,所以一般来说有多少partition就初始化多少consumer,这样消费效率最高。

既然kafka允许多个consumer对多个partition同时消费且producer投递的消息也落于不同的partition中,那么在这种情况下,消费这些消息的顺序肯定是不可控的。但是要知道kafka的partition是只能被一个consumer(同一group下)消费的,那么只要让消息全部都落入同一个partition不就好了,我们投递消息的过程中通过设定消息的key就能让kafka producer根据key进行hash选择要写入的partition,就能保证消息写入的顺序以及消费的顺序。

斐济游记(2018.02.19-2018.02.26)

Posted on 2018-02-27 | In travel

结束了7天的斐济之行,趁着最后一个休息日,写篇游记给想要去玩的同学提供参考。

从8个月前开始计划这次旅行。

签证

斐济对中国免签,只要有一本发放时间超过半年的护照就可以了

准备

  • 斐济对环境保护的力度很大,所以对入境的食品、水果、植物甚至鞋子上的泥土都有着严格的限制,
    入境前会填写一张入境卡,会申报你所携带的物品,记住如果都不确定自己有没有带违禁品,就全部勾选,让入关的工作人员来帮助你确定,
    如果没有申报被海关查到,就需要交纳500FJD的罚款,相当于1500RMB。
  • 烟一个人不能超过200根,酒不能超过2250ml
  • 建议带的东西
    • 万能插头转换器,大部分酒店是有中标的插座的,但是不排除有些是澳标,所以一定要带一个转换器,以防万一。
    • 带一个排插,酒店插座很少,带一个可以一起充。
    • 浮潜设备(snorkelling)最好自己带,你肯定不想用别人咬过的呼吸管,淘宝一套设备也就100,还能配近视镜片,浮潜基本天天都去(因为是真的太漂亮了),所以绝对物超所值
    • 水肺深潜(scuba、diving)斐济是世界上最好的深潜区域,所以最好再去之前能够去考PADI的OW和AOW证书,拥有OW证书,你可以独立下潜到水下18米的区域,拥有AOW证书,你可以下潜到水下30米的区域而且可以夜间潜水,斐济是可以看到鲨鱼的,而且没有防鲨网,意味着你可以摸鲨鱼,但是他们会不会咬你就看脸了,我没有license,所以没有看到鲨鱼,非常遗憾,打算弄到OWlicense后再去一次斐济,毕竟鲨鱼是真的好看啊。
    • 衣物带夏天的衣物就好了,不用太多,我带了7件短袖,结果就穿了3件。
    • 墨镜什么的就不说了,这些都是常规配置了。

机票

机票当然是越早买越便宜,我提前4个月买的机票,往返7300左右,香港直飞楠迪,10个小时左右。如果从香港走,建议直接在国泰官网上订,便宜一些。

酒店

同样,越早订越好,建议在booking订,但是要注意booking上的特价大部分是不能退的,且要提前付款的,所以如果能确认时间,最好就订特价的,我自己提前三个月订的特价,在yasawa群岛上,直面大海的高级滨海别墅6000元4天,还是非常划算的。
注意,因为斐济一般是一外岛一酒店,所以有些酒店是强制有meal plan的,三餐全包,一个人一天119FJD左右,订酒店的时候一定要看清楚了。

我的旅行

第一天

我们从深圳蛇口出发,直接坐船到香港机场,建议大家都这么走,很方便,一张船票还能退120港币,用来吃点东西
16:55起飞,楠迪当地时间7:30到达楠迪国际机场。
DAY1
DAY1
DAY1

我预约了酒店的船来接我们去外岛,大概60分钟的船程到达Octopus Resort酒店。
DAY1

11点30到达酒店,整理了一下行李,吃了午餐,睡了一下午,实在是太累了,这一天我拍到了如火焰一般的黄昏
DAY1
DAY1

第二天

一大早就被老妈拉着去拍照,这里是真的到处都是美景,随手一拍都是一张封面。
DAY2
DAY2
DAY2

下午雇了一艘小船去远一点沙滩浮潜,斐济真的是浮潜圣地,海星、珊瑚、鱼还有海蛇,真的太漂亮了,可惜没有设备,没法拍啦。

晚饭前是星空一样的晚霞(其实没这么漂亮,主要是俺技术好)
DAY2
DAY2

第三天

浮潜、拍照、晒太阳

第四天

mountain hike 徒步爬上岛上的最高点,彻底把我晒成了斐济人,但总归风景是极好的

DAY4
DAY4
DAY4
DAY4
DAY4

第五天

从Octopus Resort回到楠迪,一到楠迪第一件事就是找中餐馆,这四天吃西餐是真吃恶心了。
第一家餐馆叫品天下,老板是广东人,上过吃货俱乐部,但是真的不是很好吃,可能是椰子蟹本来就不好吃,也比较贵,400FJD
DAY5
DAY5
DAY5
DAY5

第六天

沉睡的巨人花园(Garden of Sleeping Giant和火山温泉泥浴(Mud Hot Spring)
切记不要在酒店订车去这两个地方,酒店真的很黑,开价要150FJD3个人,我砍到120FJD,以为还可以了,结果回来去镇上的taxi一问,80FJD就够了
不过这两个地方还是值得去的,推荐大家去,火山泥有一种很重的硫磺味,晒干洗完,皮肤很滑很软。

DAY6
DAY6

中午去了另一家中餐馆,渤海(Bo Hai)这家是东北老板,味道价格都不错,也有很多当地人来这里吃,总之比品天下更推荐。

最后一天在斐济,天也很给面子,下了点小雨,出了两道彩虹。
DAY6

我没拍出两道彩虹,借用Judy的照片
DAY6

第七天

从楠迪回到香港,推荐还是坐船回深圳,如果要去中环买东西,可以做机场快线直接到中环,24分钟就到了。
再从中环做地铁到东铁,从福田或者罗湖过关。

总结

斐济真的很漂亮,消费水平偏高,但是还是值得去的。
我们一家三个人,加上机票,人均16、7k左右,供大家参考。

Eureka

Posted on 2018-02-09 | In java

总结一下 eureka 和 zookeeper

zk的目标是一个分布式的协调系统,用于进行资源的统一管理,为了满足CP而进行设计。
eureka的目标是一个服务注册发现系统,专门用于微服务的服务发现注册,按照满足AP而进行设计。

zk在用于服务发现的问题

zk将数据一致性作为自己设计的首要目标,从而不保证服务的可用性,因为当节点crash后,需要
进行leader的选举,在这个期间内,zk服务是不可用的。
对于服务的注册发现来说,对数据一致性并没有很大的需求,因为就算获取到不可用的服务,也会返回相应的
错误response,但是如果从注册中心中获取不到服务,就会是一个很大的问题。zk的leader选举时间有非常长,
所以用于服务发现,不是一个很好选择

eureka的思考

eureka是按照AP的设计目标去实现的,当节点宕机后,并不会影响服务的获取和注册,client会从别的节点中获取服务信息,
同时当eureka的服务端发现85%以上的服务都没有心跳的话,它就会认为自己的网络出了问题,就不会从服务列表中删除这些
失去心跳的服务,同时eureka的客户端也会缓存服务信息。eureka对于服务注册发现来说是非常好的选择。

提一个小疑问,我自己在搭eureka集群的时候,发现每一个eureka实例都要配置其他实例的地址,这样的话,如果加一台机器,
已经启动的机器要怎么发现这台新的节点,好像节点之前没有转播功能,不知道是不是我配置的不对。先记下来,解决了再更新。

Entropy-熵?

Posted on 2018-01-31

ConcurrentHashMap原理 java7 vs java8

Posted on 2018-01-12 | In java

JAVA7

在java7中,ConcurrentHashMap中核心结构是一个Segment数组,
每个Segment中都有一个HashEntry数组,也就是把一个HashMap分成
了很多个HashMap,当对ConcurrentHashMap进行操作的时候,会通过Hash计算出要操作的segment,
每一个segment都继承了ReentrantLock从而实现对segment进行加锁,保证线程安全,
同时又因为存在多个segment,减少了对同一个Segment频繁加锁的次数,提高了并发,有多少segment就能有多少并发。

JAVA8

在java8中,ConcurrentHashMap放弃了Segment,直接对Node(java8,HashEntry变成了Node)数组中元素通过synchronized进行加锁,从而将加锁的粒度变细,更加减少了冲突加锁的次数。
这样在扩容的时候,直接能将并发量提高一倍(java7的实现中,Segment是无法扩容的,只能扩容segment中的HashEntry数组)

为什么要用Synchronised呢?

  1. 假设使用可重入锁来获得同步支持,那么每个节点都需要通过继承AQS来获得同步支持。但并不是每个节点都需要获得同步支持的,只有链表的头节点(红黑树的根节点)需要同步,这无疑带来了巨大内存浪费。
  2. synchronized则是JVM直接支持的,JVM能够在运行时作出相应的优化措施:锁粗化、锁消除、锁自旋等等。这就使得synchronized能够随着JDK版本的升级而不改动代码的前提下获得性能上的提升。

cnn-卷积神经网络

Posted on 2017-12-28 | In machine learning

最近一直在看神经网络相关的知识,看了很多资料,加上自己的理解,打算把他们都记录下来,以供自己以后参考

什么是卷积?

相信很多人在第一次听到卷积神经网络的时候,都会很费解卷积是个什么鬼?
是把什么东西卷起来吗?当我第一次接触它的时候也是这种感觉,不知道高数老师会不会骂我:(
所以为了弄清楚卷积神经网络在做什么,我们先要弄明白卷积

卷积的物理意义

我们可以想象这么一个画面,你拿着一块石头丢入到一片湖面,当石头击中湖面的时候,
湖水上就会激起一道涟漪,再拿一块石头丢进去,就又产生了一道涟漪,而这些涟漪的叠加就是卷积了!

卷积的数学意义

我们将上面丢石头到湖面的例子变成数学上表示,我们假设石头冲击湖面的冲击函数为f(n),
假设湖面的水波为函数g(t),那么第一块石头撞击水面我们可以表示为f(1)g(t),是第一次的涟漪,
而第二块石头撞击水面我们可以表示为f(2)
g(t),是第二次涟漪,把他们两者加起来就是这两次撞击f(n):n=1,2对g(t)的卷积,这个时候f(n)是一个离散的函数。

那当f(n)是一个连续的函数的时候我们要怎么理解呢?大家可以把它想象成自己对着水坑里尿尿,
尿撞击到水面上是一个连续的影响,这时候水面上的波动就是一个连续函数f(n)对g(t)的卷积。

总结一下,通俗点说,卷积就是一个函数(先后顺序的石头)在另一个函数(水面)上的加权叠加。

卷积在图像处理上的意义

喜欢自拍或者看过最近很火的白夜追凶的同学肯定都知道图像处理,有一段剧情是关队将照片送去鉴定中心做锐化处理,从而能从原本不清楚的照片中
将某一部分的影像变得更清晰(剧中是一把匕首和手表吧,我记得是~~~),这个锐化的处理就是卷积在图片处理上的一个例子。那锐化是怎么做到的呢?
我们都知道图片其实本质上就是一个点阵,如果是黑白图片的话,每个点的值就是0或者1,如果是RGB彩色图片的话,每个点就是一个三维数组,数组中的每个值都在0-255,
为了能够突出图像中的特征,就必须增强中心像素的影响,弱化周围的像素的影响,要做到这一点,就需要有一个东西,增加中心像素点的权重,降低周围像素点的权重再进行叠加产生一个新的值,
是不是很像上面讲的例子,图片点阵就是g(t),这个东西就是f(n),我们把这个东西叫做滤波器。滤波器图片
锐化的滤波器:锐化滤波器
我们可以很清楚看到,当前这个滤波器的周围像素点的权重都是-1,中心点为9,所以就产生了锐化的效果
那如果我们想要把轮廓变的更清晰呢:轮廓滤波器
这个滤波器的权重就和上面锐化的完全相反。

神经网络也要卷积?

在图像识别的领域上,使用普通神经网络所能到达的精度已经接近极限,很难在提高了,所以受到卷积在图像处理上的启发,就产生了卷积神经网络。
通过上面的例子,不难发现,通过不同的滤波器,就能让同一张图像产生不同的效果。但是这些滤波器的参数,其实更多是根据人们的需求以及经验知识来设定的。
而对于图像识别来讲,我们并不知道什么样的滤波器对某一类图像对机器来说是有效的,所以卷积神经网络所要训练的就是这些卷积层的滤波器

JAVA I/O

Posted on 2017-12-18 | In java

Blocking I/O

BIO顾名思义就是阻塞式IO的,accept、read、write三个方法都是阻塞的,这就造成一个问题,如果是单线程去处理BIO,那么线程必然大部分时间是挂起的,
为了能充分利用CPU,很自然就会想到开启多个线程去处理每一个连接。这样的设计在小规模的系统上的确可行,但是当单台机器要处理大量请求的时候,线程的数量就会成为很大的瓶颈。
线程是很贵的自然,java中一个线程默认需要开启1m的内存,加上线程切换,创建,销毁以及调度等等系统操作,可见线程是一种很贵的资源,所以通过增加线程来增加服务的并发量的代价是很高的。

Non-Blocking I/O

NIO中单个线程可以处理所有连接的建立、读写和关闭操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
Channel channel;
while(channel=Selector.select()){
if(channel.event==accept){
// do something
}
if(channel.event==write){
// do something
}
if(channel.event==read){
// do someting
}
}
}

通过轮询Selector获取准备就绪的channel(select()方法是一个阻塞方法,所以不用担心while造成CPU空转),
针对不同的类型的channel做相应的读写操作,利用NIO,单线程就具备了处理所有I/O请求的能力,并最大程度上利用CPU资源

NIO.2

NIO.2 也叫AIO,实际上呢就是把NIO中的读写操作变成异步,当读写完成后再回调其对应的处理方法。在Windows中利用IOCP可以实现AIO,
但是在Linux上目前还没有支持AIO。

B-Tree 与mysql索引

Posted on 2017-12-18

completableFuture

Posted on 2017-11-20 | In java

(CompletableFuture??)[http://www.jianshu.com/p/6f3ee90ab7d3]

123
Carl Zhu

Carl Zhu

21 posts
11 categories
19 tags
© 2018 Carl Zhu
Powered by Hexo
Theme - NexT.Muse