谈谈ChatGPT

春节期间,试用了ChatGPT,让我被惊艳到了。
大模型的涌现效果,能达到ChatGPT3.5的程度,着实让我有些吃惊,真是大力出奇迹啊。

在此之前,我一直认为本次AI技术革命已经接近尾声了:
1、在影像和视频方面,AI已经可以实现商业化:医疗影像AI诊断、自动驾驶、人脸识别、图像搜索、P图滤镜等;
2、在语音方面,语音识别和语音合成已经很成熟;
3、在NLP方面,简单重复任务可以较好完成,比如机器翻译、文本搜索等。但在复杂任务上,还处于有多少人工就有多少智能的尴尬阶段,距离商业化有较长的路需要走;
而且,无论是哪个领域,大家可以发现,AI还是只是一种能力、一个工具,也就是处于“业务X+AI”的模式。
就算AI是生产力,但想象空间也就那么大,因为领域已经被限制死了。

但ChatGPT改变了这个局面,聊天这个场景,可以让ChatGPT成为一个各种能力的插座。
也就是说,一个类似于ChatGPT的大模型,如果能快速整合各种外部能力,从“业务X+AI”,变成“AI+业务X、业务Y、业务Z”的模式,很可能会成为下一代互联网的入口,并从各种维度给人类带来全新体验。

钢铁侠的贾维斯(J.A.R.V.I.S.)还是保守了,我们有更广阔的空间,十分期待这个时代能尽快到来。

同时,国内大厂的大模型层出不穷,究竟谁能成功,还要看三个地方:
1、要有足够大量的数据
2、要有AI人才储备
3、要有足够算力,如果现在才去买显卡,就很难赶上了
国内满足这几点的有:质谱【从闭源到开源】、阿里【闭源到开源】、百度【已掉队】、字节【已掉队】

最近看了一些ChatGPT资料,整理了一些相关示例:
https://github.com/neohope/NeoDemosChatGPT

其中多数例子,来源于极客时间徐文浩老师的课程《AI大模型之美》:
https://time.geekbang.org/column/intro/100541001?tab=catalog

================
补充0812:
当前国内大模型厂商,在底层方面依赖英伟达,在模型技术层面无法相互拉开差距,只能继续向上做:
1、在基础模型层面,支持各类开源模型,弥补自家模型缺点
2、在行业领域,开展合作,把垂直领域模型吃掉
3、在应用层面,也开始逐步布局
加上外资撤出,投资方的钱更难拿,围剿之下,AI方向国内的创业氛围就比较差了。

Transformer03:自注意力机制

Transformer模型的核心是自注意力机制(Self-Attention),它允许模型在处理序列时,能够捕捉序列内部不同位置之间的依赖关系。自注意力机制的计算过程可以概括为以下几个步骤:

1. 查询(Query)、键(Key)、值(Value)的生成:
对于输入序列中的每个元素,模型会分别生成对应的查询(Q)、键(K)和值(V)。这通常是通过输入序列与三个不同的权重矩阵相乘来实现的。

2. 注意力分数的计算:
对于序列中的每个元素,计算其查询(Q)与序列中所有元素的键(K)的点积,然后除以一个缩放因子(通常是键向量维度的平方根),得到一个注意力分数。

Attention Score

其中,(Q)和(K)分别是查询和键的向量,\(d_k\) 是键向量的维度。

3. Softmax归一化:
使用Softmax函数对注意力分数进行归一化处理,使得所有元素的注意力分数之和为1。这表示每个元素对其他元素的注意力贡献是相对的。

Attention Weights

4. 加权求和:
将归一化后的注意力权重与对应的值(V)相乘,然后将所有元素的加权值相加,得到最终的输出。

Output

5. 多头注意力:
Transformer模型中的自注意力通常不是只计算一次,而是通过多头注意力(Multi-Head Attention)来实现。这意味着模型会并行地执行多次自注意力机制,每个头都有自己的查询、键和值权重矩阵。最后,这些头的输出会被拼接起来,并通过一个线性层来整合信息。

6. 残差连接和层归一化:
在自注意力层之后,通常会有一个残差连接,它将自注意力层的输入直接添加到输出上,然后通过一个层归一化(Layer Normalization)来稳定训练过程。

整个自注意力机制使得Transformer能够并行处理序列中的所有元素,并且能够捕捉到元素之间的长距离依赖关系,这是它在处理序列数据时非常有效的原因之一。

让我们通过一个简单的例子来说明自注意力机制的计算过程。假设我们有一个由3个词组成的序列:[“I”, “love”, “coding”],并且每个词的词嵌入维度是4。

步骤1: 词嵌入
首先,我们将每个词转换为词嵌入向量。假设词嵌入矩阵已经预先训练好,我们可以直接获取每个词的词嵌入向量:

– “I” -> [0.1, 0.2, 0.3, 0.4]
– “love” -> [0.5, 0.6, 0.7, 0.8]
– “coding” -> [0.9, 1.0, 1.1, 1.2]

步骤2: 添加位置编码
接下来,我们为每个词嵌入向量添加位置编码。假设我们使用标准的正弦和余弦函数生成位置编码,并且序列的最大长度是3。位置编码向量如下:

– 位置1的编码:[sin(0), cos(0), sin(8), cos(8)] (这里8是4*2,因为每个词嵌入维度是4)
– 位置2的编码:[sin(1), cos(1), sin(9), cos(9)]
– 位置3的编码:[sin(2), cos(2), sin(10), cos(10)]

将位置编码向量与词嵌入向量相加:

– “I” (位置1): [0.1+sin(0), 0.2+cos(0), 0.3+sin(8), 0.4+cos(8)]
– “love” (位置2): [0.5+sin(1), 0.6+cos(1), 0.7+sin(9), 0.8+cos(9)]
– “coding” (位置3): [0.9+sin(2), 1.0+cos(2), 1.1+sin(10), 1.2+cos(10)]

步骤3: 自注意力计算
现在我们开始自注意力的计算过程。首先,我们需要为每个词生成查询(Q)、键(K)和值(V)向量。假设我们使用相同的词嵌入向量作为Q、K和V的初始输入,并通过不同的权重矩阵进行转换:

– Q = W^Q * 输入向量
– K = W^K * 输入向量
– V = W^V * 输入向量

这里W^Q、W^K和W^V是模型的可学习参数。

步骤4: 计算注意力分数
对于序列中的每个词,我们计算其查询向量与序列中所有词的键向量的点积,然后除以键向量维度的平方根进行缩放:

– 对于词”I”,其注意力分数是它自己的Q与所有词的K的点积:

Attention Score

步骤5: Softmax归一化
使用Softmax函数对每个词的注意力分数进行归一化处理:

– 对于词”I”,归一化后的注意力权重是:

Attention Weights

步骤6: 加权求和
最后,将归一化后的注意力权重与对应的值向量相乘,并求和得到最终的输出:

– 对于词”I”,其输出是:

Output

这个过程对于序列中的每个词都要重复执行,以计算整个序列的输出。自注意力机制允许模型在处理每个词时,都能够考虑到序列中其他所有词的信息,从而捕捉词与词之间的复杂关系。

请注意,这个例子是一个简化的版本,实际的Transformer模型可能会使用多头自注意力机制,并且会有多个层来进一步处理信息。此外,词嵌入和位置编码通常是通过预训练得到的,而不是从头开始训练。

Transformer02:词嵌入及位置编码的计算

一句话经过分词和嵌入之后,输入到Transformer模型的过程如下:

1. 构建输入序列:
将分词后得到的词或字符序列转换为对应的词嵌入向量。每个词或字符都有一个对应的嵌入向量,这些向量通常通过预训练的词嵌入模型获得。

2. 添加位置编码:
由于Transformer模型本身不包含递归或卷积结构,因此它无法直接捕捉序列中的位置信息。为了解决这个问题,需要为每个词嵌入向量添加一个位置编码。位置编码通常是根据词在序列中的位置生成的,它与词嵌入向量相加,使得模型能够利用位置信息。

3. 输入到Transformer:
将包含位置编码的词嵌入向量作为输入序列送入Transformer模型。在Transformer模型中,输入序列被处理为一系列向量,每个向量对应序列中的一个元素(词或字符)。

4. 多头自注意力:
Transformer模型使用多头自注意力机制来处理输入序列。在自注意力层中,每个元素的嵌入向量都会与序列中所有其他元素的嵌入向量进行比较,以计算注意力权重。这个过程在多个“头”中并行进行,每个头都有自己的查询(Q)、键(K)和值(V)权重矩阵。

5. 层归一化和前馈网络:
自注意力层的输出会经过层归一化,然后送入前馈神经网络。前馈网络通常由两个线性变换和一个非线性激活函数组成。这个过程在每个Transformer层中重复进行。

6. 堆叠多个Transformer层:
Transformer模型通常由多个相同的层堆叠而成,每个层都包含自注意力机制和前馈网络。通过这种方式,模型可以在不同层捕捉不同级别的特征和依赖关系。

7. 输出处理:
经过多个Transformer层处理后,模型的输出可以用于各种NLP任务,如语言翻译、文本摘要、问答等。对于特定的任务,可能还需要在Transformer模型的顶部添加额外的层,如线性层或分类层。

总之,每个嵌入向量并不是有自己的Transformer,而是所有嵌入向量一起作为输入序列,被送入同一个Transformer模型中进行处理。通过多头自注意力机制,模型能够捕捉序列内部不同位置之间的依赖关系,从而实现对输入句子的深入理解。

通过一个简单的例子来说明词嵌入和位置编码的计算过程。

### 词嵌入(Word Embedding)

假设我们有一个句子:”I love natural language processing”。首先,我们需要将这个句子分词成单词列表:[“I”, “love”, “natural”, “language”, “processing”]。

接下来,每个单词将通过一个词嵌入矩阵转换成一个固定维度的向量。假设我们的词嵌入维度是4,那么每个单词将被映射到一个4维空间中。例如:

– “I” -> [0.1, 0.2, 0.3, 0.4]
– “love” -> [0.5, 0.6, 0.7, 0.8]
– “natural” -> [0.9, 1.0, 1.1, 1.2]
– “language” -> [1.3, 1.4, 1.5, 1.6]
– “processing” -> [1.7, 1.8, 1.9, 2.0]

这里的数字是随机生成的,实际的词嵌入向量是通过训练得到的,能够捕捉单词的语义信息。

### 位置编码(Positional Encoding)

Transformer模型不包含递归或卷积结构,因此无法直接捕捉序列中单词的顺序信息。为了解决这个问题,我们需要为每个词嵌入向量添加位置编码。

位置编码通常是通过正弦和余弦函数的组合来生成的,以确保不同维度的位置编码具有不同的频率。假设我们的词嵌入维度是4,我们可以为每个位置生成一个4维的位置编码向量:

– 位置1的编码:[sin(1/10000), cos(1/10000), sin(2/10000), cos(2/10000)]
– 位置2的编码:[sin(2/10000), cos(2/10000), sin(4/10000), cos(4/10000)]
– 以此类推…

将位置编码向量与相应的词嵌入向量相加,得到最终的输入向量:

– “I” (位置1): [0.1+sin(1/10000), 0.2+cos(1/10000), 0.3+sin(2/10000), 0.4+cos(2/10000)]
– “love” (位置2): [0.5+sin(2/10000), 0.6+cos(2/10000), 0.7+sin(4/10000), 0.8+cos(4/10000)]
– 以此类推…

这样,每个单词的嵌入向量都包含了其在句子中的位置信息,使得Transformer模型能够在处理序列时考虑到单词的顺序。

### 注意事项

– 词嵌入和位置编码的具体计算方法可能因不同的模型和实现而有所不同。
– 实际应用中,词嵌入通常是通过预训练模型(如Word2Vec、GloVe或BERT)得到的,而不是从头开始训练。
– 位置编码的生成方法在不同的Transformer变体中可能有所不同,例如Transformer-XL和XLNet采用了不同的方法来处理长序列。

这个例子展示了词嵌入和位置编码的基本计算过程,以及它们如何帮助Transformer模型理解和处理自然语言序列。

在实际应用中,词嵌入和位置编码可以预先计算并缓存,以提高效率。下面是一些具体的情况:

1. 词嵌入的缓存:
– 词嵌入通常是通过预训练语言模型得到的,这些模型在大规模语料库上训练,学习到的词嵌入向量能够捕捉丰富的语义信息。
– 一旦词嵌入矩阵训练完成,对于任何给定的单词,其对应的词嵌入向量就可以直接从预训练的模型中获取,而不需要每次重新计算。

2. 位置编码的缓存:
– 位置编码的生成方式是固定的,例如使用正弦和余弦函数的组合,这意味着对于给定的维度和最大序列长度,位置编码向量可以预先计算出来。
– 在模型初始化阶段,可以生成一个位置编码矩阵,其中每一行对应一个位置的位置编码。在处理输入序列时,只需根据序列中单词的位置索引来选择相应的位置编码向量。

3. 缓存的优势:
– 缓存词嵌入和位置编码可以显著减少模型在每次前向传播时的计算量,特别是对于大型模型和长序列。
– 缓存还可以减少模型的延迟,因为从内存中读取预先计算好的向量比实时计算要快得多。

4. 实际应用:
– 在实际的深度学习框架中,如TensorFlow或PyTorch,词嵌入和位置编码通常作为模型的参数或静态变量存储,以便在模型训练和推理过程中重复使用。

5. 灵活性:
– 虽然位置编码通常是固定的,但在某些情况下,如果模型需要处理可变长度的序列,位置编码也可以动态生成。但即使如此,对于常见的序列长度,位置编码的计算可以预先完成,并存储在查找表中以供快速访问。

通过这种方式,词嵌入和位置编码的预先计算和缓存,可以使得Transformer模型更加高效地处理输入数据,特别是在处理大量数据或需要快速响应的应用场景中。

Transformer01:总论

在处理自然语言处理(NLP)任务时,输入一句话通常需要经过以下步骤:

1. 分词(Tokenization):
首先,输入的句子需要被分词,即将句子拆分成更小的单元,这些单元可以是单词、字符或者其他语言单位。分词是处理自然语言的第一步,因为大多数模型都是基于离散的词或字符进行操作的。

2. 词嵌入(Embedding):
分词之后,每个词或字符会被转换成词嵌入(Word Embedding)。词嵌入是将离散的词或字符映射到连续的向量空间中的一种表示方法。这些向量能够捕捉词的语义信息,并且通常通过预训练模型(如Word2Vec、GloVe或BERT等)来获得。

3. 位置编码(Positional Encoding):
对于Transformer模型,由于其自注意力机制无法捕捉序列中元素的顺序信息,因此需要添加位置编码。位置编码是一种向量,它与词嵌入相加,以提供序列中每个元素的位置信息。

4. 序列化(序列化处理):
在某些情况下,如果输入序列超过了模型的最大长度限制,可能还需要进行序列化处理,如截断或填充。

5. 模型处理:
经过上述步骤处理后,得到的序列化、嵌入化和编码后的输入数据就可以被送入模型进行进一步的处理和学习了。

因此,当输入一句话时,通常是先进行分词,然后计算词嵌入,最后将分词后的词嵌入与位置编码相结合,形成模型的输入。这个过程使得模型能够理解句子的结构和语义信息,并在此基础上进行各种NLP任务。

知识图谱03:JENA

1、下载apache-jena-fuseki和apache-jena
https://jena.apache.org/download/index.cgi

2、将上一篇教程的nt文件转换为tdb格式

cd apache-jena-3.9.0\bat
tdbloader.bat --loc="PATH_TO_TDB\tdb" "PATH_TO_NT\movies_mapping.nt"

3、切换到apache-jena-fuseki-3.9.0目录,启动一次服务,然后退出

4、将教程1里面的Movies.owl,拷贝到apache-jena-fuseki-3.9.0\run\databases路径下面,并重命名为Movies.ttl

5、创建配置文件apache-jena-fuseki-3.9.0\run\configuration\fuseki_conf.ttl

@prefix fuseki: <http://jena.apache.org/fuseki#> . 
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . 
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> . 
@prefix tdb: <http://jena.hpl.hp.com/2008/tdb#> . 
@prefix ja: <http://jena.hpl.hp.com/2005/11/Assembler#> . 
@prefix : <http://base/#> . 

<#service> rdf:type fuseki:Service ; 
    fuseki:name "movies" ;
    fuseki:serviceQuery "sparql" ;
    fuseki:dataset <#dataset> ; 
    fuseki:serviceReadGraphStore      "get" ;
    fuseki:serviceReadWriteGraphStore "data" ;
    fuseki:serviceUpdate              "update" ;
    fuseki:serviceUpload              "upload"
    . 

<#dataset> rdf:type ja:RDFDataset ;
	ja:defaultGraph <#modelInf> ;
	.

<#modelInf> 
    rdf:type ja:InfModel ;
    #ja:reasoner [ja:reasonerURL <http://jena.hpl.hp.com/2003/OWLFBRuleReasoner>]  
    ja:reasoner [ 
        ja:reasonerURL <http://jena.hpl.hp.com/2003/GenericRuleReasoner> ; 
        ja:rulesFrom <file:///D:/ProjectsMy/KG/apache-jena-fuseki-3.9.0/run/databases/Rules.ttl> ] ; 
    ja:baseModel <#baseModel> ; 
    . 

<#baseModel> rdf:type tdb:GraphTDB ; 
    tdb:location "D:/ProjectsMy/KG/workspace/data/tdb" ; 
    tdb:unionDefaultGraph true ; 
    .

6、创建规则文件apache-jena-fuseki-3.9.0\run\databases\Movies.ttl
这个规则规定了,演过喜剧的演员,叫做喜剧演员(Comedian)

@prefix xsd: <XML Schema> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix : <https://www.neohope.com/hansen/ontologies/2018/movies#> .

[ruleComedian: (?aPerson :hasActedIn ?aMovie) (?aMovie :hasGenre ?aGenre) (?aGenre :genreName '喜剧') -> (?aPerson rdf:type :Comedian)]
[ruleInverse: (?aPerson :hasActedIn ?aMove) -> (?aMovie :hasActor ?aPerson)]

7、启动apache-jena-fuseki-3.9.0

8、访问http://localhost:3030/

9、进行查询,上一篇的例子也都可以用
http://localhost:3030/dataset.html?tab=query&ds=/movies

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix : <https://www.neohope.com/hansen/ontologies/2018/movies#>

SELECT ?name WHERE {
?aComedian rdf:type :Comedian.
?aComedian :personName ?name.
}
LIMIT 10

10、通过python访问
https://github.com/neohope/kg-demo-for-movie/tree/master/src/query-jena.py

参考链接:
https://zhuanlan.zhihu.com/knowledgegraph
https://github.com/SimmerChan/KG-demo-for-movie

PS:
参考教程中,原作者通过结巴分词+正则匹配+Jena,实现了一个简单的问答系统,感兴趣的话,大家可以看下。

知识图谱02:RDF

1、安装MySQL5,并新建movies库

2、导入数据
https://github.com/neohope/kg-demo-for-movie/tree/master/data/movies.sql

3、下载d2rq,并配置好JDK环境变量
http://d2rq.org/

4、利用d2rq生成mapping

generate-mapping -u movie -p password -o movies_mapping.ttl jdbc:mysql:///movies

5、手工编辑ttl,任务如下
设置正确的域名
修正类名与属性名
删除一些不需要的字段
修改前后的数据可以在这里找到
https://github.com/neohope/kg-demo-for-movie/tree/master/data/movies_mapping.ttl
https://github.com/neohope/kg-demo-for-movie/tree/master/data/movies_mapping_ok.ttl

6、输出RDF文件,用于后续的教程

dump-rdf.bat -o movies_mapping.nt movies_mapping_ok.ttl

7、启动d2r服务

d2r-server.bat movies_mapping_ok.ttl

8、访问及浏览数据
http://localhost:2020/

9、查询
http://localhost:2020/snorql/

#周星驰演过的电影
SELECT ?title WHERE {
  ?aPerson rdf:type :Person.
  ?aPerson :personName '周星驰'.
  ?aPerson :hasActedIn ?aMovie.
  ?aMovie :movieTitle ?title
}
LIMIT 10


#英雄的演员
SELECT ?actor WHERE {
  ?aMovie rdf:type :Movie.
  ?aMovie :movieTitle '英雄'.
  ?aPerson :hasActedIn ?aMovie.
  ?aPerson :personName ?actor
}
LIMIT 10


#巩俐参演的,评分高于7的电影
SELECT ?title WHERE {
  ?aPerson rdf:type :Person.
  ?aPerson  :personName '巩俐'.
  ?aPerson  :hasActedIn ?aMovie.
  ?aMovie :movieTitle ?title.
  ?aMovie :movieRating ?rating.
  FILTER (?rating>=7)
}
LIMIT 10

10、通过python访问
https://github.com/neohope/kg-demo-for-movie/tree/master/src/query-d2rq.py

参考链接:
https://zhuanlan.zhihu.com/knowledgegraph
https://github.com/SimmerChan/KG-demo-for-movie

知识图谱01:本体建模

1、下载Protege工具

https://protege.stanford.edu/

2、安装JDK,并在配置好JDK环境变量

3、打开Protege

4、在Active Ontology页面,填写两个IRI,我分别填写了下面的数值

#Ontology IRI
https://www.neohope.com/hansen/ontologies/2018/movies
#Ontology Version IRI
https://www.neohope.com/hansen/ontologies/2018/movies/1.0.0

5、在Entities页面,切换到Classes,新建三个Class

Genre
Movie
Person

6、Entities页面,切换到Data properties,新建以下属性

genereId{Domain=Genre,Ranges=xsd:string}
genereName{Domain=Genre,Ranges=xsd:string}
movieId{Domain=Movie,Ranges=xsd:string}
movieIntroduction{Domain=Movie,Ranges=xsd:string}
movieRating{Domain=Movie,Ranges=xsd:string}
movieReleaseDate{Domain=Movie,Ranges=xsd:string}
movieTitile{Domain=Movie,Ranges=xsd:string}
personAppellation{Domain=Person,Ranges=xsd:string}
->personEnglishName{Domain=Person,Ranges=xsd:string}
->personName{Domain=Person,Ranges=xsd:string}
personBiography{Domain=Person,Ranges=xsd:string}
personbirthDay{Domain=Person,Ranges=xsd:string}
personBirthPlace{Domain=Person,Ranges=xsd:string}
personDeathDay{Domain=Person,Ranges=xsd:string}
personId{Domain=Person,Ranges=xsd:string}

7、Entities页面,切换到Object Properties,新建以下属性

hasActedIn{Domain=Person,Range=Movie,InverseOf=hasActor}
hasActor{Domain=Movie,Range=Person}
hasGenre{Domain=Person,Range=Genre}

8、保存为Movies.owl,这个文件可以在后面jena的例子中用到

9、建模后的结果,可以在这里获取:
https://github.com/neohope/kg-demo-for-movie/tree/master/protege

参考链接:
https://zhuanlan.zhihu.com/knowledgegraph
https://github.com/SimmerChan/KG-demo-for-movie

利用Speech Recognition进行语音识别

首先说明一下,我用的是MacOS,多数命令Linux可用,但部分相关命令要进行调整。不建议用Windows。

1、安装环境

#安装pyaudio
brew install portaudio
pip install pyaudio

#安装Sphinx
pip install PocketSphinx

#安装tensorflow
pip install tensorflow

#安装SpeechRecognition
pip install SpeechRecognition

2、测试

#提示你进行语音输入
#默认用Google Speech Recognition
#所以需要梯子,才能用这个命令哦
python -m speech_recognition

3、建议大家看一下自带例子
https://github.com/Uberi/speech_recognition/tree/master/examples
这个库,可以支持多种语音引擎,只有PocketSphinx是离线的,其余都是在线的。
而PocketSphinx的识别率,实在是有些差,需要一些辅助才能达到较好的效果。

PS:
tensorflow需要2018年(3.8.1以后,不包括3.8.1)以后的版本才支持。

利用Face Recognition进行人脸识别

首先说明一下,我用的是MacOS,多数命令Linux可用,但部分相关命令要进行调整。不建议用Windows。

1、安装环境

#安装cmake
brew install cmake
#安装boost
brew install boost-python
#设置boost环境
export CMAKE_PREFIX_PATH="/usr/local:/usr/local/Cellar/boost/1.61.0:$PATH"
#安装pip
sudo easy_install pip
#安装fc
pip install face_recognition
#安装opencv
pip install opencv-python

2、测试

#将已知单人照片,放到iknow文件夹中,而且照片名称就是人名,比如zhangsan.jpg等
#将需要识别的照片,放到unknown文件夹中,照片可以是多人的
#tolerance是精确度,感觉默认的库是以欧美人标准进行训练的,不太适用于亚洲人,建议将tolerance设置到0.5-0.6之间
#命令行会通过iknow的照片,识别unknown中的图片,并输入每幅图片中有哪些人
face_recognition --tolerance 0.56 ./iknow/ ./unknown/

3、建议大家去看一下项目自带的example
https://github.com/ageitgey/face_recognition/tree/master/examples

4、建议大家去看一下作者写的文章,真的写的很通俗易懂
https://medium.com/@ageitgey

可能遇到的问题:
1、如果安装环境时,遇到下面的问题

OSError: [Errno 1] Operation not permitted: '/PATH/XXX-info'

解决步骤如下:
1.1、重启电脑,按command+R进入恢复模式
1.2、点击菜单【实用工具】,打开【终端】,输入csrutil disable,关闭System Integrity Protection
1.3、重启电脑,正常开机
1.4、打开【终端】输入csrutil status,验证配置已生效

Windows下编译word2vec

首先要声明,如果条件允许,不要在windows下做类似的事情,我这里是在折腾。

如果只需要下载代码,相应的代码,我已经上传了github,可以在这里下载到:
word2vec_win32

编译工具为:VS2013

具体的做法为:

1、到google code下载代码https://code.google.com/p/word2vec/

2、根据makefile,创建VS2013工程

3、进行调整,保证编译成功
3.1、所有c文件,添加下面的宏定义

#define _CRT_SECURE_NO_WARNINGS

3.2、将部分const修改为define,比如

    #define MAX_STRING 100

3.3、用_aligned_malloc函数,替换posix_memalign函数

    #define posix_memalign(p, a, s) (((*(p)) = _aligned_malloc((s), (a))), *(p) ?0 :errno)

3.4、下载windows下的pthread库,pthreads-win32,并修改include及link配置

3.5、编译成功

4、可执行文件说明
word2vec:词转向量,或者进行聚类
word2phrase:词转词组,用于预处理,可重复使用(运行一遍则生成2个词的短语,运行两遍则形成4个词的短语)
compute-accuracy:校验模型精度
distance:输入一个词A,返回最相近的词(A=》?)
word-analogy:输入三个词A,B,C,返回(如果A=》B,C=》?)

5、进行测试
5.1下载测试资料
http://mattmahoney.net/dc/text8.zip

5.2建立模型

>word2vec -train text8 -output vectors.bin -cbow 1 -size 200 -window 8 -negative 25 -hs 0 -sample 1e-4 -threads 20 -binary 1 -iter 15
Starting training using file text8
Vocab size: 71291
Words in train file: 16718843
Alpha: 0.000005  Progress: 100.10%  Words/thread/sec: 13.74k

5.3校验模型精度

>compute-accuracy vectors.bin 30000 < questions-word
s.txt
capital-common-countries:
ACCURACY TOP1: 80.83 %  (409 / 506)
Total accuracy: 80.83 %   Semantic accuracy: 80.83 %   Syntactic accuracy: -1.#J
 %
capital-world:
ACCURACY TOP1: 62.65 %  (884 / 1411)
Total accuracy: 67.45 %   Semantic accuracy: 67.45 %   Syntactic accuracy: -1.#J
 %
currency:
ACCURACY TOP1: 23.13 %  (62 / 268)
Total accuracy: 62.01 %   Semantic accuracy: 62.01 %   Syntactic accuracy: -1.#J
 %
city-in-state:
ACCURACY TOP1: 46.85 %  (736 / 1571)
Total accuracy: 55.67 %   Semantic accuracy: 55.67 %   Syntactic accuracy: -1.#J
 %
family:
ACCURACY TOP1: 77.45 %  (237 / 306)
Total accuracy: 57.31 %   Semantic accuracy: 57.31 %   Syntactic accuracy: -1.#J
 %
gram1-adjective-to-adverb:
ACCURACY TOP1: 19.44 %  (147 / 756)
Total accuracy: 51.37 %   Semantic accuracy: 57.31 %   Syntactic accuracy: 19.44
 %
gram2-opposite:
ACCURACY TOP1: 24.18 %  (74 / 306)
Total accuracy: 49.75 %   Semantic accuracy: 57.31 %   Syntactic accuracy: 20.81
 %
gram3-comparative:
ACCURACY TOP1: 64.92 %  (818 / 1260)
Total accuracy: 52.74 %   Semantic accuracy: 57.31 %   Syntactic accuracy: 44.75
 %
gram4-superlative:
ACCURACY TOP1: 39.53 %  (200 / 506)
Total accuracy: 51.77 %   Semantic accuracy: 57.31 %   Syntactic accuracy: 43.81
 %
gram5-present-participle:
ACCURACY TOP1: 40.32 %  (400 / 992)
Total accuracy: 50.33 %   Semantic accuracy: 57.31 %   Syntactic accuracy: 42.91
 %
gram6-nationality-adjective:
ACCURACY TOP1: 84.46 %  (1158 / 1371)
Total accuracy: 55.39 %   Semantic accuracy: 57.31 %   Syntactic accuracy: 53.88
 %
gram7-past-tense:
ACCURACY TOP1: 39.79 %  (530 / 1332)
Total accuracy: 53.42 %   Semantic accuracy: 57.31 %   Syntactic accuracy: 51.00
 %
gram8-plural:
ACCURACY TOP1: 61.39 %  (609 / 992)
Total accuracy: 54.11 %   Semantic accuracy: 57.31 %   Syntactic accuracy: 52.38
 %
gram9-plural-verbs:
ACCURACY TOP1: 33.38 %  (217 / 650)
Total accuracy: 53.01 %   Semantic accuracy: 57.31 %   Syntactic accuracy: 50.86
 %
Questions seen / total: 12227 19544   62.56 %

5.4查找关系最近的单词

>distance vectors.bin
Enter word or sentence (EXIT to break): china

Word: china  Position in vocabulary: 486

                                              Word       Cosine distance
------------------------------------------------------------------------
                                            taiwan              0.649276
                                             japan              0.624836
                                            hainan              0.567946
                                          kalmykia              0.562871
                                             tibet              0.562600
                                               prc              0.553833
                                              tuva              0.553255
                                             korea              0.552685
                                           chinese              0.545661
                                            xiamen              0.542703
                                              liao              0.542607
                                             jiang              0.540888
                                         manchuria              0.540783
                                             wuhan              0.537735
                                            yunnan              0.535809
                                             hunan              0.535770
                                          hangzhou              0.524340
                                              yong              0.523802
                                           sichuan              0.517254
                                         guangdong              0.514874
                                             liang              0.511881
                                               jin              0.511389
                                             india              0.508853
                                          xinjiang              0.505971
                                         taiwanese              0.503072
                                              qing              0.502909
                                          shanghai              0.502771
                                          shandong              0.499169
                                           jiangxi              0.495940
                                           nanjing              0.492893
                                         guangzhou              0.492788
                                              zhao              0.490396
                                          shenzhen              0.489658
                                         singapore              0.489428
                                             hubei              0.488228
                                            harbin              0.488112
                                          liaoning              0.484283
                                          zhejiang              0.484192
                                            joseon              0.483718
                                          mongolia              0.481411
Enter word or sentence (EXIT to break):

5.5根据A=>B,得到C=>?

>word-analogy vectors.bin
Enter three words (EXIT to break): china beijing canada

Word: china  Position in vocabulary: 486

Word: beijing  Position in vocabulary: 3880

Word: canada  Position in vocabulary: 474

                                              Word              Distance
------------------------------------------------------------------------
                                           toronto              0.624131
                                          montreal              0.559667
                                            mcgill              0.519338
                                           calgary              0.518366
                                           ryerson              0.515524
                                            ottawa              0.515316
                                           alberta              0.509334
                                          edmonton              0.498436
                                           moncton              0.488861
                                            quebec              0.487712
                                          canadian              0.475655
                                      saskatchewan              0.460744
                                       fredericton              0.460354
                                           ontario              0.458213
                                       montrealers              0.435611
                                         vancouver              0.429893
                                         saskatoon              0.416954
                                            dieppe              0.404408
                                           iqaluit              0.401143
                                         canadians              0.398137
                                          winnipeg              0.397547
                                            labatt              0.393893
                                              city              0.386245
                                      bilingualism              0.386245
                                          columbia              0.384754
                                        provincial              0.383439
                                             banff              0.382603
                                             metro              0.382367
                                            molson              0.379343
                                           nunavut              0.375992
                                             montr              0.373883
                                      francophones              0.373512
                                         brunswick              0.364261
                                          manitoba              0.360447
                                               bec              0.359977
                                       francophone              0.358556
                                             leafs              0.353035
                                        ellensburg              0.352787
                                           curling              0.351973
                                               cdn              0.347580
Enter three words (EXIT to break):

5.6进行聚类,输出结果(classes为0时,就是向量输出了)

>word2vec -train text8 -output classes.txt -cbow 1 -size 200 -window 8 -negative 25 -hs 0 -sample 1e-4 -threads 20 -iter 15 -classes 500
Starting training using file text8
Vocab size: 71291
Words in train file: 16718843
Alpha: 0.000005  Progress: 100.10%  Words/thread/sec: 14.72k

5.7原来程序中,还有三个测试脚本,是处理词组的,由于要用到linux命令sed,awk等,大家还是到Cygwin或MinGW下运行吧