在人间漂流

厚德 求真 励学 笃行


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 公益404

python正则匹配match,search,findall,finditer区别

发表于 2020-10-31 | 分类于 language , python | 0 comments
阅读次数:
  |   字数统计: 283(字)   |   阅读时长: 1(分)

python正则匹配常用到的函数主要主要有:

  1. fullmatch/match,返回re.Match对象,Match对象调用group(0)返回整个匹配,调用group(1)或者group(2)等依次返回括号内的匹配
  2. search,返回re.Match对象
  3. findall,返回列表包含括号内的匹配
  4. finditer,返回re.Match迭代器

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import re

content = '333STR1666STR299'
regex = r'[A-Z]+(\d)'

if __name__ == '__main__':
print(re.match(regex, content)) ##content的开关不符合正则,所以结果为None。

##只会找一个匹配,match[0]是regex所代表的整个字符串,match[1]是第一个()中的内容,match[2]是第二对()中的内容。
match = re.search(regex, content)
print('\nre.search() return value: ' + str(type(match)))
print(match.group(0), match.group(1))

result1 = re.findall(regex, content)
print('\nre.findall() return value: ' + str(type(result1)))
print(result1)
for m in result1:
print(m)

result2 = re.finditer(regex, content)
print('\nre.finditer() return value: ' + str(type(result2)))
print(result2)
for m in result2:
print(m.group(0), m.group(1)) ##字符串

返回结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
None

re.search() return value: <class 're.Match'>
STR1 1

re.findall() return value: <class 'list'>
['1', '2']
1
2

re.finditer() return value: <class 'callable_iterator'>
<callable_iterator object at 0x7ffa374dfad0>
STR1 1
STR2 2
---------------- The End ----------------

作者: brooksjay
联系邮箱: jaypark@smail.nju.edu.cn
本文地址:
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布
转载请注明出处, 谢谢!

ELMo

发表于 2020-01-19 | 分类于 Machine Learning , NLP | 0 comments
阅读次数:
  |   字数统计: 752(字)   |   阅读时长: 3(分)

ELMo(Embeddings from Language Models)是发表在NAACL2018的论文Deep contextualized word representations提出来的模型,属于feature-based预训练语言模型,其后的ULM-fit与其模型基本一致,但在训练和迁移阶段使用了更多的分层适用的概念,属于fine-tuning预训练语言模型。

ELMo模型的简略模型结构图如下

主要分为两大模块:

  1. token representation
  2. Multi-BiLSTM

下面分别给出这两个模块的一些细节

token representation

ELMo模型的token representation采用了character embedding,拥有更强大的表示能力,并且使用多个不同跨度的卷积核进行一维卷积,不同kernel卷积得到的不同表示拼接在一起,然后经过两层highway network得到最终的预处理编码表示。下图是一维卷积获取character embedding的具体操作示意图

多跨度多kernel的卷积拼接获取character embedding的具体操作示意图如下

将拼接得到的character embedding输入到两层highway network进行处理,highway network其实就是CV领域著名的ResNet中使用的残差单元的原型,highway network模型结构图如下

highway network的表达式描述为

特别地,当$C=1-T$

其中$H,T,C$都是非线性转换,$W_H,W_T,W_C$分别为它们对应的参数。

Multi-BiLSTM

下图是LSTM的模型结构试图以及每个control gate的计算式

BiLSTM则是使用一个正向一个逆向的LSTM处理sequence得到每个token的hidden state进行拼接作为这个token最终的输出。而Multi-BiLSTM顾名思义就是多层的双向LSTM,将当前这一层BiLSTM的正反向hidden state拼接输出作为紧邻的上一层的输入,最后一层的输出才是token最终的输出。

downstream application

ELMo使用feature-based的方式应用到下游任务,就是将模型输出表示加入(一般是拼接)到任务模型中的某一层中或多层中以增强任务模型对文本的表示能力。具体方式在这里我直接引用原文更好理解:

a L-layer biLM computes a set of 2L + 1 representations

$h{k,0}^{LM}=[x{k}^{LM},x_{k}^{LM}]$  for token representation

$h{k,j}^{LM}=[\overrightarrow{\mathbf{h}}{k, j}^{L M}, \overleftarrow{\mathbf{h}}_{k, j}^{L M}],j \gt 1$  for each biLSTM layer, compute a task specific weighting of all LM layers

$s_{j}^{\text {task}}$are softmax-normalized weights and the scalar parameter $\gamma^{\text {task }}$allows the task model to scale the entire ELMo vector.

下游任务可以根据优化的目标函数对ELMo表示的权重$s_{j}^{\text {task}},\gamma^{\text {task }}$进行学习得到合适的权重。

---------------- The End ----------------

作者: brooksjay
联系邮箱: jaypark@smail.nju.edu.cn
本文地址:
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布
转载请注明出处, 谢谢!

Transformer

发表于 2019-12-06 | 分类于 Machine Learning , NLP | 0 comments
阅读次数:
  |   字数统计: 2.9k(字)   |   阅读时长: 11(分)

Introduction

在transformer model出现之前,主流的sequence transduction model是基于循环或者卷积神经网络,表现最好的模型也是用attention mechanism连接基于循环神经网络的encoder和decoder.

Transformer model是一种摒弃了循环及卷积结构,仅仅依赖于注意力机制的简洁的神经网络模型。我们知道recurrent network是一种sequential model,不能很好地解决长距离依赖的问题(序列过长时,信息在序列模型中传递时容易一点点丢失),并且阻碍了parallelism within train example.而transform最引人瞩目的一点正是很好地解决了长距离依赖的问题,通过引入自注意力机制(self-attention)使得对依赖的建模与输入输出序列的距离无关,并且支持train exmaple内部的并行化。注意力机制可以参考之前写的notes of cs224n lecture8.

Model Architecture

下图1是transformer的模型架构图

图1. The Transformer - model architecture

左边是encoder,右边是decoder,各有6层,下面我将讲解个人觉得比较重要的几个点。

Attention

图2. (left) Scaled Dot-Product Attention. (right) Multi-Head Attention consists of several attention layers running in parallel. 3.2.1

Scaled Dot-Producted Attention

如上图2左边所示即为dot-producted attention的一般形式,在transformer中,初始Q, K, V即为一个句子所有的subword编码构成的矩阵(seq_len, d_model),其中d_model是subword的编码长度。Deocder的第二个Multi-Head Attention中的Q, K, V会有所不同,在讲解Multi-Head Attention是提到。下面是dot-producted attention的数学表达形式

这里除以是因为在与additive attention(之前写的文章有提到)对比时发现较小时,这两种注意力机制表现相似,但是当较大时dot-producted attention不如additive attention。最后分析原因发现较大时点乘结果矩阵元素在数量级很大,使得softmax函数求导的梯度非常小。下面是原论文的一个解释

To illustrate why the dot products get large, assume that the components of q and k are independent random variables with mean 0 and variance 1. Then their dot product, , has mean 0 and variance dk.

Multi-Head Attention

如上图2右边所示即为Multi-Head Attention的结构图。它的中心思想就是将原来的转换成num_heads个shape为(seq_len, d_model/num_heads)的,然后再为每个head执行dot-producted attention的操作,最后再将所有head的输出在最后一个维度上进行拼接得到与对原始输入执行单个dot-producted attention操作后shape一致的结果。下面是Multi-Attention的数学表达形式

其中,,而

在transformer中使用h=8个parallel attention heads.对于每个head使用. 我看tf official tutorial of transformer实现中并没有为学习转换矩阵,而是先对作一个线性转换到的编码,然后将的编码表示划分成h份,然后输入到各自的head中进行处理。Multi-Head Attention机制允许模型在不同位置共同关注来自不同表示子空间的信息。

Decoder中包含两层的Multi-Head Attention(MHA),第二层的MHA不再使用初始的作为输入,而是使用上一层MHA的输出作为,Encoder最后一层(第6层)的输出作为.

Masking

无论encoder还是decoder都需要使用mask屏蔽掉不必要的信息干扰。

对于encoder,由于我们传入的数据是padded batch,因此需要对padded的信息进行mask,具体mask的位置放置在dot-producted attention的scale即之后softmax之前,对需要mask的位置赋值为-1e9,这样在softmax之后需要mask的位置就变成了0,就像是指定mask的位置进行dropout.

对于decoder,每一层包含两个Multi-Head Attention(MHA),第一个MHA同样需要对padded信息进行mask,除此之外还要对output中还未出现的词进行mask,保证只能根据前面出现的词信息来预测后面还未出现的词。将两个mask矩阵叠加之后输入到dot-producted attention单元中的scale之后用于屏蔽非必要信息。第二个MHA由于使用Encoder最后一层的输出作为,所以需要对Encoder初始输入的padded信息进行mask,同样是在dot-producted attention单元中的scale之后操作。

Embeddings

encoder和decoder的输入是两套独立的embedding(例如translation task,分别是原语和目标语subword的Embeddings),embedding的维度为,论文中的base model设为512,big model设为1024.在embedding输入模型前逐元素乘以,因为在dot-producted attention中 .

Positional Encoding

由于transform model不包含循环和卷积网络,为了使模型能利用sequence的顺序信息,必须加入序列中每个subword的相对或者绝对位置信息。因此引入了Positional Encoding,它保持和embedding一样维度,具体encoding的方式有很多种,主要分为学习的和固定的(learned and fixed)。在论文中使用了固定的无须学习的positional embedding,使用不同频率的cos和sin函数如下

其中,pos是token position in sequence,i是dimension position.之所以选择cos和sin函数是因为对于固定的偏置量能够表示为的线性函数,假设它可以很容易学习到相对位置引入的信息。使用cos和sin的另一个原因是它允许模型推断比训练过程中遇到的更长的序列。论文中作者表示也使用了learned positional embeddings,但是与上述的fixed positional embeddings结果基本一致,所以最终采用了fixed positional embedings,这种方式更高效,减少训练开销。

最终作为模型输入的是token embeddings + positional embeddings,然后套一层dropout.

Why Self-Attention

如上图所示,使用self-attention机制主要有三点原因

  • 相比convolutional和recurrent,当sequence length n比representation dimensionality d更小时(SOTA的机器翻译模型都符合),每一层的计算开销都更少
  • self-attention相比recurrent和convolutional更适合并行化,可并行化的粒度更小(measured by the minimum sequential operations required)
  • 最重要的一点self-attention解决了长距离依赖(long -range denpendency)的问题。对于sequence transduction task,影响这种依赖的关键因素就是前向或者后向信号要在网络中遍历的路径长度。而self-attention的Q(query)直接与K(key),V(value)中每个token直接产生联系,无须信号序列式传递,所以如上图中self-attention的sequential operations和maximum path length常数级别的。

由于self-attention的complexity per layer为,考虑非常长序列的极限情况,可以限制self-attention在计算时只考虑输入序列K,V中的r个邻居即可将complexity per layer限制在,这就是上图2中的Self-Attention(restricted).

Training

Dataset

WMT 2014 English-German datasset和WMT 2014 English-French dataset,数据集官网download,论文使用其中的newstest2013作为验证集(development dataset),newstest2014作为测试集(test dataset)。base model平均最后5个checkpoint的结果,big model平均最后20个checkpoint的结果。由于数据集太过庞大,训练代价很大。论文中使用8 NVIDIA P100 GPUs,base model训练100000 steps耗时12h,big model训练300000 steps耗时3.5 days.

Regularization

论文中主要使用了两种正则化手段来避免过拟合并加速训练过程。

Residual Dropout

在每一residual Multi-Head Attention之后,Add&Norm之前进行dropout,以及add(token embedding,positional encoding)之后进行dropout,FFN中没有dropout,base model的dropout rate统一设置为0.1,big model在wmt14 en-fr数据集上设置为0.1,在en-de数据集上设置为0.3

Label Smothing

Label Smothing Regularization(LSR)是2015年发表在CoRR的paper:Rethinking the inception architecture for computer vision中的一个idea,这个idea简单又实用。假设数据样本x的针对label条件概率的真实分布为

这使得模型对自己给出的预测太过自信,容易导致过拟合并且自适应能力差(easy cause overfit and hard to adapt)。解决方案:给label分布加入平滑分布,一般取均匀分布就好,于是得到

映射到损失函数cross entropy有

由上式可知,LSR使得不仅要最小化原来的交叉熵H(q,p),还要考虑预测分布与之间差异最小化,使得模型预测泛化能力更好。transformer的论文中指定。下表是使用LSR和未使用LSR在tensorflow datasets的ted_hrlr_translate/pt_to_en dataset上bleu score对比

表1. bleu score with LSR and without LSR
bleu on validation dataset bleu on test dataset
beam_search 0.415/41.5 0.420/42.0
beam_search + label_smooth_regualrization 0.473/47.3 0.468/46.8

可以看到使用了LSR在验证集和测试集上都取得了比更好的bleu score.但是LSR对perplexity不利,因为模型的学习目标变得更不确切了。

LayerNormalization

在multi-head attention之后使用layer normlization可以加速参数训练使得模型收敛,并且可以避免梯度消失和梯度爆炸。相比BatchNormalization,LayerNormalization更适用于序列化模型比如RNN等,而BatchNormalization则适用于CNN处理图像。

Learning Rate with Warmup

Transformer使用Adam optimizer with .学习率在训练过程中会变动,先有一个预热,学习率呈线性增长,然后呈幂函数递减如上图所示,下面是学习率的计算公式

论文中设置warmup_steps=4000.也就是说训练的前4000步线性增长,4000步后面呈幂函数递减。这么做可以加速模型训练收敛,先以上升的较大的学习率让模型快速落入一个局部收敛较优的状态,然后以较小的学习率微调参数慢慢逼近更优的状态以避免震荡。

Conclusion

Transformer是NLP在深度学习发展历程上的一座里程碑,目前主流的预训练语言模型都是基于transformer的,逐渐取代了LSTM的位置,深入理解transformer的细节对后续NLP的学习非常重要。

Transformer最大的亮点在于不依靠RNN和CNN,通过引入self-attention机制,很好地解决了让人头疼的长距离依赖问题,使得输入和输出直接关联,没有了RNN那样的序列传递信息损失,输入输出之间经过的的路径长为常数级,与输入序列长度无关,上下文信息保留更完整。因此tranformer是非常强大的文本生成模型,应用于MT, 成分句法分析(constituency parsing)等效果非常好。

---------------- The End ----------------

作者: brooksjay
联系邮箱: jaypark@smail.nju.edu.cn
本文地址:
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布
转载请注明出处, 谢谢!

Standford CS224n Notes

发表于 2019-12-01 | 分类于 Machine Learning , NLP | 0 comments
阅读次数:
  |   字数统计: 1.2k(字)   |   阅读时长: 4(分)

Lecture 08 Machine Translation, Seq2Seq and Attention

Statistical Machine Translation(SMT)

统计机器翻译(Statistical Machine Translation,SMT)出现并流行于1990s~2010s,1990s以前的MT工作大部分都是基于规则的(rule-based),使用双语词典作为映射,最早可以追溯到1950s。SMT的main idea如下图所示

SMT将模型划分为2部分进行学习,左部主要用于确保翻译后的句义保真度,尽可能学习到原句的真实含义。而右部主要用于确保翻译后句子的流畅度。机器翻译还有一个难题就是对齐(alignment),原句和目标语句之间的语法可能差异很大,使得词序排列分布差异很大,要学习原句词与目标句词之间的对齐方式是一件非常棘手的事。定位alignment关系非常复杂,因为alignment有一对多、多对一以及多对多的关系,SMT通过加入一隐变量a用于专门学习alignment,即将$P(x|y)$进一步划分为$P(x,a|y)$,其中a物理含义是原句与目标句之间word-level correspodence.

Nueral Machine Translation(NMT)

seq2seq model

seq2seq model的结构如下图所示

从上图看seq2seq应用于NMT的方式一目了然,这是一个auto-regressive model,通过历史序列信息学习预测当前词,loss为交叉熵。seq2seq无须对输入数据进行预特征提取,直接将原始序列输入即可得到目标序列输出,一个典型的端到端黑箱模型。正由于其简便易用,得到了很多应用,seq2seq model还能应用于

一般beam size设置越大,寻找到的结果更优,但不一定是最优,只有搜索所有路径才可以得到最优解,一直搜索直到预测到结束标记,概率值为language model的log probability的前缀和,因此序列越长log probability的和可能越小,结果要除以对应序列长度来比较候选序列。通常可以设置概率阈值、候选序列个数、预测序列长度限制来作为搜索的终止条件。由于beam search容易使用来自训练集中的常见短语和重复文本,因此Hierarchical Neural Story Generation这篇文章提出使用top-k random sample scheme的方法,简单概括就是先选出LM生成概率最高的k个词,然后从这top-k个词中随机采样一个词作为下一个序列生成词,重复上述步骤直到生成终止词。 MT task的评估一般采用BLEU,可以参考assignment4 handout或者paper bleu,NLTK提供了基于句子和语料库计算bleu score的API,注意计算整个corpus的bleu不是求corpus中每个句子bleu的均值,而是累加每个句子的ngrams统计信息到同一个分子分母中统一计算得来。bleu取值范围[0,1],但是论文中都习惯将bleu乘以100后保留一位小数来表示。

NMT相比SMT的优点如下

NMT缺点在于不可解释的黑箱,难以调试,有结果超乎预料的风险。

Attention Mechanism

seq2seq model简便以用,但是瓶颈也很明显如下图所示

最后一个词输出的hidden state需要囊括句子的所有信息,而LSTM对于长距离问题又无法很好地解决,因此最终的hidden state肯定丢失了很多的信息。为了能很好的提取前面所有词的编码信息,需要引入注意力机制

core idea: on each step of the decoder, use direct connection to the encoder to focus on a particular part of the source sequence

seq2seq引入attention的具体方式如下所示

如上,将原句编码后的hidden state向量与原句中每个词的编码向量作点积运算得到每个词的attention score(scalar),然后softmax所有词的attention scores得到attention distribution(上图可以看到attention在下一相关词上分布最多),然后再用attention distribution对词编码向量作加权求和得到attention output,然后concat到decoder的hidden state预测下一个词。下图是下一层的执行方式

将前一层的attention output和前一层的预测输出词向量concat作为这一层的输入,由于此时hidden state是拼接的要取原句子编码向量那一段输入到attention机制中,得到的attention output同样concat到当前的句子编码中用于预测下一词。

attention正是通过直接与句子中所有word embedding进行点积(direct connection),并将attention distribution用于句子中所有词向量的加权求和从而解决了LSTM无法解决的长距离依赖问题,使得hidden state包含了句子更丰富的信息,从而能更好得预测下一个词。

attention不仅是用于seq2seq model,它有更general的用途如下

attention mechanism有三种常见变体形式如下

---------------- The End ----------------

作者: brooksjay
联系邮箱: jaypark@smail.nju.edu.cn
本文地址:
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布
转载请注明出处, 谢谢!

Subword Models

发表于 2019-11-26 | 分类于 Machine Learning , NLP | 0 comments
阅读次数:
  |   字数统计: 2.3k(字)   |   阅读时长: 9(分)

随着深度神经网络的发展,深度学习在文本生成比如nueral machine translation(NMT)以及question answer(QA)等任务中突破了传统方法的瓶颈,在很多数据集上都取得了state-of-the-art(SOTA)的效果。

我们知道神经网络输入层必须接收数字形式的信息,所以必须将文本形式的词嵌入成向量。通常会设定一个词汇表大小,对于词汇表中所有词有对应的向量表示。而由于一种语言涵盖的词汇太多,以及处理的文本数据本身就不规范(比如web数据),从而无法覆盖所有的词汇,在对corpus中的词进行向量map时会出现out of vocabulary(OOV)的现象。以往的做法是设置一个特殊字段(比如UNK)来表示所有OOV的词汇,这种做法可谓相当粗糙,那有没有更细致微妙的处理方法呢?答案当然是有的,很多从事NLP研究的工作者在这个方面开展了不少的工作。一种方法是从word embedding扩展到character embedding,另外一种方法是将word拆分成有意义的更小的词素也就是wordpieces,两个word可能不相同,但是他们可能包含相同的wordpieces,这样对于OOV的word,找到其对应的wordpieces的向量added or averaged也可以蕴含该word的word sense。接下来分别介绍这两种方法。

Character Embedding

在没出现character embedding之前可能会觉得仅用少量的字符向量就可以表示含有丰富含义的词向量会有点不可思议,但借助于神经网络对特征强大的组合能力,使得这一切成为了可能。目前对word中的characters进行组合的方式目前主要有convolutional network和LSTM network两种。下面分别介绍这两种方法以及混合使用word-character embedding的模型。

Convolutional

Learning Character-level Representations for Part-of-Speech Tagging C´ıcero,这篇文章发表于JMLR2014,应该是最早的使用卷积神经网络处理char embedding的,模型主要分三层conv+fcn+maxpool,具体的结构图如下

LSTM

Finding Function in Form: Compositional Character Models for Open Vocabulary Word Representation,这篇文章发表于EMNLP2015,使用LSTM网络处理char embedding,并将其很好得应用于language model和POS tagging,具体的模型结构如下

模型使用双向LSTM对character embedding进行处理并将两个方向最终的隐状态向量拼接作为word embedding输出。

Hybrid Word-Character Models

character embedding与word embedding不同在于:word embedding是在巨大语料集上学习好的,然后再用于NLP的各种下游任务,而character embedding是随机初始化的,在学习下游任务目标的同时学习character embedding。考虑到word embedding和character embedding各自都包含了有用的信息,因此Christopher D. Manning等人提出了综合使用word embedding和character embedding的混合模型Achieving Open Vocabulary Neural Machine Translation with Hybrid Word-Character Models,这篇文章发表于ACL2016,模型使用单向LSTM网络,具体结构如下

对于输入序列中的OOV word使用双层LSTM处理其对应的char embedding得到的输出作为word embedding,对于输出序列中的\使用双层LSTM+beam search转换成有意义的word。

WordPieces

wordpieces这个名字取得很形象,说白了就是将词划分成片表示,但可不是随便划分。目前的划分方法主要有两种:

  • 基于频率计数的方法byte pair encoding(BPE)
  • 基于unigram language model的方法

byte pair encoding

Neural Machine Translation of Rare Words with Subword Units,这篇文章发表于ACL2016。文章思路其实很简单,初始化所有的wordpieces为单个字符,就是统计相邻两个wordpieces在所有word中共现频率,然后合并出现频率最高的wordpieces,直到当前词汇表满足设定的大小。注意,合并起来的wordpieces的所有前缀都要包含进词汇表中。下面是BPE算法的python代码

代码一目了然,但正是这么简单的方法却在很多NLP下游任务上取得了很不错的效果,因而得到了广泛的应用,毕竟简单而又好用的谁不喜欢呢!!

unigram language model

Subword Regularization: Improving Neural Network Translation Models with Multiple Subword Candidates,这篇文章发表于ACL2018。文章基于输入语料库建立unigram model,使用EM算法迭代,每次保留去除该词后使得语言模型的perpelxity损失最大的前80%的词,迭代计算直到当前词汇表满足设定的大小。

Google’s SentencePiece

SentencePiece: A simple and language independent subword tokenizer and detokenizer for Neural Text Processing,这篇文章发表于EMNLP2018,在发表这篇文章之前,google也发表了一篇基于unigram language model的建立wordpieces词汇表的文章Japanese and Korean voice search,这篇文章发表于IEEE International Conference on Acoustics, Speech and Signal Processing (ICASSP)2012。但SentencePiece这篇文章可谓集大成者,Google在这篇文章基础上开源了github: SentencePiece Package,它不仅包含常用的character和word embedding,并且实现了前述2种subword segmentation algorithms即BPE和unigram language model,Google真乃良心啊,这就为后面所有NLPer的工作提供了提供了一个统一的输入预处理工具。并且该工具还可以保存构建wordpieces的model,便于论文实验结果的再现(reproducibility,因为很多NLP模型对输入极其敏感,输入稍有偏差将导致结果迥然不同)。SentencePiece Package上手使用非常简单,下面给出代码:

1
2
3
4
5
6
7
8
9
10
import sentencepiece as spm
# model_prefix是模型输出2个文件*.vocab,*.model前缀名
# model_type模型种类:unigram, bpe, char, word
# 为了支持跨语言处理,SentencePiece支持自定义character normalization,默认是使用NFKC的unicode编码转换
# input文件内容每行一个sentence,model_type为word时需要提前分好词,其它3种不需要,原始输入即可
spm.SentencePieceTrainer.Train('--input=newtext.txt \
--normalization_rule_name=nfkc \
--model_prefix=subword \
--vocab_size=1000 \
--model_type=unigram')

Train方法中的参数说明如下

  • --input: one-sentence-per-line raw corpus file. No need to run tokenizer, normalizer or preprocessor. By default, SentencePiece normalizes the input with Unicode NFKC, . You can pass a comma-separated list of files.
  • --model_prefix: output model name prefix. .model and .vocab are generated.
  • --vocab_size: vocabulary size, e.g., 8000, 16000, or 32000
  • --character_coverage: amount of characters covered by the model, good defaults are: 0.9995 for languages with rich character set like Japanse or Chinese and 1.0 for other languages with small character set.
  • --model_type: model type. Choose from unigram (default), bpe, char, or word. The input sentence must be pretokenized when using word type.

执行上面代码后会在当前目录下生成subword.vocab和subword.model两个文件,下面给出加载模型进行编码解码的代码示例

1
2
3
4
5
6
7
import sentencepiece as spm

sp = spm.SentencePieceProcessor()
sp.Load('unigram.model')
ids = sp.EncodeAsIds('I love you')
print(ids)
print(sp.DecodeIds(ids))

fastText embedding

wordpieces以很巧妙的思想解决了OOV的问题,后面出现了大量的使用wordpieces作为embedding的工作。这里不得不提一下fastText: Enriching Word Vectors with Subword Information,这篇文章是facebook ai团队发表于TACL2017,这篇文章使用和word2vector一样的学习embedding的方法skip-gram,但是它是学习word的subword n-grams(文章中n设为3~6,就是word的所有连续的3~6grams) embedding,这样其它任务使用词向量出现OOV现象即可使用该词n-grams的subword embeddig累加来合成。那么如何训练subword n-grams 的embedding呢?就skip-gram进行讨论,假设center word为$w_t$,window word为$w_c$,则围绕$w_t$的loss为

其中,$\mathcal{N}{t,c}$ is a set of negative examples sampled from the vocabulary. 我们用$\mathcal{G}w \subset {1,…,G}$ 表示出现在w中的n-grams集合(3~6 grams in paper),$z{g}$表示$w$每个n-gram的embedding,$w$的向量表示为$z_g$的和,因此可得$s(w,c)$

该方法异常高效,train cost非常低,不同以往的word embedding学习需要海量的文本数据进行学习,fastText只需要word2vec方法的5%甚至1%的数据即可在许多任务上达到一致的效果。下图是word2vec的cbow方法以及fastText的skip-gram方法使用不同大小数据集训练后在word similarity任务上spearman rank表现对比

其中,sisg-是fastText使用null vector表示OOV word,而sisg是fastText使用summing subword n-grams表示OOV word,可以看到sisg使用少量数据之后即可效果基本就饱和了。fastText对于复合词多、词尾变化丰富、多形态词的语言,以及包含大量生僻词的语料库效果更为明显,因为这些很难直接用word embedding直接覆盖,非常适合使用subword n-grams来拼接表示。但是对于常见词使用直接word embedding效果会比subword n-grams embedding效果更好,如下图所示,可以看到在word similarity任务上,fastText在WS353 dataset上表现不如word2vec的cbow,because words in the English WS353 dataset are common words for which good vectors can be obtained without exploiting subword information.

所以前面提到的Hybrid Word-Character Model也正是发现此问题后的进一步优化,能优先使用word embedding的就是用word embedding,否则使用character embedding或者wordpieces embedding。

---------------- The End ----------------

作者: brooksjay
联系邮箱: jaypark@smail.nju.edu.cn
本文地址:
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布
转载请注明出处, 谢谢!

Backpropagation

发表于 2019-11-13 | 分类于 Machine Learning | 0 comments
阅读次数:
  |   字数统计: 820(字)   |   阅读时长: 3(分)

后向传播(backpropagation)算法在深度学习中扮演了非常重要的角色,它能够从损失函数开始链式地对网络层中的权重进行梯度计算与更新。可以先参考维基百科: Backpropagation,文章很好地还原了深度神经网络(DNN)每一层网络从后往前的链式梯度计算关系。然后再结合下面这几张图理解每一层网络中每个单元的梯度具体计算与推导过程,假设前向计算公式$wx + b$.


举个例子

上图是一个两层的全连接神经网络,其中是输入,是输出,输出在softmax之后计算交叉熵损失。下面给出详细计算隐藏层对应的权重梯度的过程,其中是batch size,是真实标签,是softmax激活后的输出

又因为

所以

除此之外,还有一个问题,交叉熵损失函数计算值只与标签1对应的输出相关,那么标签0对应输出的相关权重就无需计算梯度并进行更新了么?跑了一下上图两层全连接神经网络的demo程序,发现无论输出对应标签是0还是1,其相关权重梯度都不为0。通过对权重梯度的核算发现,对于标签0对应输出,虽然在交叉熵损失函数计算结果中没有得到体现,但是在后向传播梯度计算过程中,会采用$-(1-y_0)\log{(1-O_0)}$作为0标签相关权重梯度计算的损失,这点类似于逻辑回归损失函数,其中$y_0$为0,$O_0$为对应softmax输出。demo程序如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import torch
import torch.nn as nn

class mymodel(nn.Module):
def __init__(self):
super(mymodel, self).__init__()
self.l1 = nn.Linear(10, 20, bias=False)
nn.init.constant_(self.l1.weight, 0.1)
self.l2 = nn.Linear(20, 2, bias=False)
nn.init.constant_(self.l2.weight, 0.1)

def forward(self, x):
t = self.l1(x)
print(t)
y_out = self.l2(t)
print(y_out)
return y_out

x = torch.rand(1, 10)
y = torch.tensor([0])
m = mymodel()
optimizer = torch.optim.SGD(m.parameters(), lr=0.1)
loss_func = nn.CrossEntropyLoss()
print(x)
print(m.l1.weight)
print(m.l2.weight)
y_out = m(x)
loss = loss_func(y_out, y)
print(loss)
optimizer.zero_grad()
loss.backward()
optimizer.step()
for name, param in m.named_parameters():
print(name, param.grad, param)

Tips:

  1. 在实际应用场景中,可能由于硬件设备落后而无法支持大batch的数据训练,但是现在的深度学习框架一般都会支持梯度累积,可以用多个mini batch模拟big batch的训练,假设累积步数为k,那么每个mini batch在后向梯度计算之前要将loss除以k再做后向梯度计算。
---------------- The End ----------------

作者: brooksjay
联系邮箱: jaypark@smail.nju.edu.cn
本文地址:
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布
转载请注明出处, 谢谢!

pssh系列命令详解

发表于 2019-10-17 | 分类于 Linux | 0 comments
阅读次数:
  |   字数统计: 1.1k(字)   |   阅读时长: 4(分)

安装

pssh提供OpenSSH和相关工具的并行版本。包括pssh,pscp,prsync,pnuke和pslurp。该项目包括psshlib,可以在自定义应用程序中使用。pssh是python写的可以并发在多台机器上批量执行命令的工具,它的用法可以媲美ansible的一些简单用法,执行起来速度比ansible快它支持文件并行复制,远程命令执行,杀掉远程主机上的进程等等。杀手锏是文件并行复制,,当进行再远程主机批量上传下载的时候,最好使用它。pssh用于批量ssh操作大批量机器;pssh是一个可以在多台服务器上执行命令的工具,同时支持拷贝文件,是同类工具中很出色的;比起for循环的做法,更推荐使用pssh! (注意需要安装 python 2.4 或以上版本)

下面是直接从源码进行编译安装的步骤,安装过程很快

1
2
3
4
wget https://pypi.python.org/packages/60/9a/8035af3a7d3d1617ae2c7c174efa4f154e5bf9c24b36b623413b38be8e4a/pssh-2.3.1.tar.gz
tar xf pssh-2.3.1.tar.gz -C /usr/local
cd /usr/local/pssh-2.3.1/
python setup.py install

命令详解

pssh --help可以查看命令参数选项:

1
2
3
4
5
6
7
8
9
10
11
-l    远程机器的用户名
-p 一次最大允许多少连接
-o 输出内容重定向到一个文件
-e 执行错误重定向到一个文件
-t 设置命令执行的超时时间
-A 提示输入密码并且把密码传递给ssh(注意这个参数添加后只是提示作用,随便输入或者不输入直接回车都可以,可以结合sshpass -p password使用)
-O 设置ssh参数的具体配置,参照ssh_config配置文件
-x 传递多个SSH 命令,多个命令用空格分开,用引号括起来
-X 同-x 但是一次只能传递一个命令
-i 显示标准输出和标准错误在每台host执行完毕后
-I 读取每个输入命令,并传递给ssh进程 允许命令脚本传送到标准输入

pssh、pscp、prsync、pnuke和pslurp的具体使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#注:在使用工具前,确保主机间做了密钥认证,否则无法实现自动化,当然我们可以使用sshpass(yum install sshpass)配合pssh -A参数实现自动输入密码,但这要保证多台主机的密码相同,同时还要注意如果known_hosts没有信任远程主机,那么命令执行会失败,可以加上-O StrictHostKeyChecking=no参数解决,ssh能用的选项pssh也能用

# 集群刚装好系统处于原始状态,可以使用下面命令来生成其他机器的ssh秘钥并将各机器的rsa公钥添加到本机
sshpass -p password pssh -I -A -O StrictHostKeyChecking=no -h ip.txt -l brooksj -i "ssh-ketgen" # 然后本机回车10次帮助各机器生成ssh秘钥,password为其它机器的统一密码
sshpass -p password pssh -A -O StrictHostKeyChecking=no -h ip.txt -l brooksj -i "ssh-copy-id localhost-ip" # localhost-ip改成你本机的ip

#pssh 远程批量执行命令
pssh -h ip.txt -P "uptime"
#-h 后面接主机ip文件,文件数据格式[user@]host[:port]
#-P 显示输出内容
#如果没办法密钥认证.可以采用下面方法,但不是很安全
sshpass -p 123456 pssh -A -h ip.txt -i "uptime"

#pscp 并行传输文件到远端
#传文件,不支持远程新建目录
pscp -h ip.txt test.py /tmp/dir1/
#传目录
pscp -r -h ip.txt test/ /tmp/dir1/

#prsync 并行传输文件到远端
#传文件,支持远程新建目录,即目录不存在则新建
prsync -h ip.txt test.py /tmp/dir2/
#传目录
prsync -r -h ip.txt test/ /tmp/dir3/

#pslurp从远程拉取文件到本地,在本地自动创建目录名为远程主机ip的目录,将拉取的文件放在对应主机IP目录下
#格式:pslurp -h ip.txt -L <本地目录> <远程目录/文件> <本地重命名>
#拉取文件
pslurp -h ip.txt -L /root/ /root/1.jpg picture
ll /root/172.16.1.13/picture
-rw-r--r-- 1 root root 148931 Jan 9 15:41 /root/172.16.1.13/picture
#拉取目录
pslurp -r -h ip.txt -L /root/ /root/test temp
ll -d /root/172.16.1.13/temp/
drwxr-xr-x 2 root root 23 Jan 9 15:49 /root/172.16.1.13/temp/

#pnuke:远程批量killall
pnuke -h ip.txt nginx
---------------- The End ----------------

作者: brooksjay
联系邮箱: jaypark@smail.nju.edu.cn
本文地址:
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布
转载请注明出处, 谢谢!

卡特兰数(Catalan Number)

发表于 2019-09-23 | 分类于 Math | 0 comments
阅读次数:
  |   字数统计: 1.4k(字)   |   阅读时长: 5(分)

卡特兰数又称卡塔兰数,英文名Catalan number,是组合数学中一个常出现在各种计数问题中的数列。该数在计算机专业中比较重要,有一些具体的应用实例。这篇文章主要分三部分:

  1. 卡特兰数递归式的含义解释
  2. 卡特兰数表达式的证明过程
  3. 卡特兰数在计算机中的应用

Catalan Number递归式解释

假设h(0)=1,h(1)=1,catalan数满足递推式:

递归式背后有什么物理含义呢,这里以出栈序列问题进行说明:

问题描述:一个栈(无穷大)的进栈序列为1,2,3,…,n,有多少个不同的出栈序列?
含义解释:首先,我们设$h(n)$=序列个数为n的出栈序列种数。(我们假定,最后出栈的元素为k,显然,k取不同值时的情况是相互独立的,也就是求出每种k最后出栈的情况数后可用加法原则,由于k最后出栈,因此,在k入栈之前,比k小的值均出栈,此处情况有$h(k-1)$种,而之后比k大的值入栈,且都在k之前出栈,因此有$h(n-k)$种方式,由于比k小和比k大的值入栈出栈情况是相互独立的,此处可用乘法原则,$h(n-k)*h(k-1)$种,求和便是Catalan递归式。

Catalan Number表达式证明

第n个卡特兰数h(n)表达式如下 $$ h(n)=\frac{C_{2n}^{n}}{n+1}=C_{2n}^{n}-C_{2n}^{n-1} \tag{1.2} $$ 具体证明过程如下
为了便于编程实现,需要进一步推导$h(n)$与$h(n-1)$之间的关系 已知$h(n)$,易知 $$ h(n-1)=\frac{C_{2n-2}^{n-1}}{n} $$ 推导$h(n)$的$C_{2n}^{n}$和$h(n-1)$的$C_{2n-2}^{n-1}$之间的关系,由$kC_{n}^{k}=nC_{n-1}^{k-1}$知 $$ \begin{align} n*C_{2n}^{n}&=2nC_{2n-1}^{n-1} \\ C_{2n}^{n}&=2C_{2n-1}^{n-1} \\ C_{2n}^{n}&=2\frac{(2n-1)C_{2n-2}^{n-1}}{n} \\ C_{2n}^{n}&=2(2n-1)h(n-1) \\ \frac{C_{2n}^{n}}{n+1}&=\frac{2(2n-1)}{n+1}h(n-1) \\ h(n)&=\frac{2(2n-1)}{n+1}h(n-1) \end{align} $$ 最终得到$h(n)$和$h(n-1)$之间的递归式$h(n)=\frac{2(2n-1)}{n+1}h(n-1)$

Catalan Number应用实例

括号匹配问题

问题描述: 矩阵连乘 $P=A_1A_2...A_n$,依据乘法结合律,不改变其顺序,只用括号表示成对的乘积,问有几种括号化的方案?
问题转换一下就是n对括号的正确匹配方案,可以做一下LeetCode-22

出栈次序问题

问题描述: 一个栈(无穷大)的进栈序列为1,2,3,..n,有多少个不同的出栈序列?
出栈问题问题正是卡特兰数递归式$h(n)=h(0)h(n-1)+h(1)h(n-2)+...+h(n-1)h(0)$的由来

相关应用问题

1. 有2n个人排成一行进入剧场,入场费5元。其中只有n个人有一张5元钞票,另外n人只有10元钞票,剧院无其它钞票,问有多少种方法使得只要有10元的人买票,售票处就有5元的钞票找零?(将持5元者到达视作将5元入栈,持10元者到达视作使栈中某5元出栈)
2. n个1和n个0组成一个2n位的二进制数,要求从左到右扫描,0的累计数不小于1的累计数,求满足条件的的数。
3. 12个人排成两排,每排必须是从矮到高排列,而且第二排比对应的第一排的人高,问排列方式有多少种?
我们先把这12个人从低到高排列,然后,选择6个人排在第一排,那么剩下的6个肯定是在第二排。对问题进行转化:用0表示对应的人在第一排,用1表示对应的人在第二排,那么含有6个0,6个1的序列,并且任意前缀中0的个数大于等于1的个数就对应一种方案,转化后的问题就是问题2了。
4. 给定节点组成二叉树的问题:给定n个节点,能构成多少种形状不同的二叉树?
先取一个点作为顶点,然后左边依次可以取0至n-1个相对应的,右边是n-1到0个,两两配对相乘,就是$h(0)*h(n-1) + h(2)*h(n-2) + ... + h(n-1)h(0)=h(n)$能构成$h(n)$个,因此二叉树问题也可以解释卡特兰数递归式(1.1)式的由来
5. n*n棋盘从左上角(0,0)走到右下角(n,n)而不跨过主对角线的走法?
要从左上角(0,0)走到右下角(n,n)则必须向下走n步,向右n步,同时为了不跨过主对角线(允许在主对角线上),则走过的步数中向下走的步数必须大于等于向右走的步数,剖析之后发现这个问题与问题3是等价问题,走法有卡特兰数$h(n)$种。可以做一下下面两题练练手:
hdoj2067-小兔的棋盘
LeetCode62-Unique Paths
6. n个+1和n个-1构成的2n项序列,其部分和总满足:$a_1+a_2+...+a_n>=0$的序列的个数。
卡特兰数表达式(1.2)式就是以该问题模型为基础推导出来的

参考链接:
  1. https://blog.csdn.net/ACdreamers/article/details/7628667
---------------- The End ----------------

作者: brooksjay
联系邮箱: jaypark@smail.nju.edu.cn
本文地址:
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布
转载请注明出处, 谢谢!

ubuntu下安装nvidia driver, cuda10, cudnn7, tensorflow1.14

发表于 2019-09-18 | 分类于 Machine Learning , Tensorflow | 0 comments
阅读次数:
  |   字数统计: 1.8k(字)   |   阅读时长: 7(分)

安装nvidia driver

  • 查看本机显卡

    1
    lspci | grep -i VGA

    终端输出显卡名称,现在电脑一般都有集显+独显2块显卡,若都是nvidia公司的,后续如果安装openGL就不会冲突,因为openGL只支持nvidia的显卡,其他公司的会被openGL安装覆盖。我这里是intel集显,所以安装cuda的时候就不能安装openGL.

  • 查看本机nvidia GPU型号

    1
    lspci | grep -i nvidia

    到官网official nvidia driver下载对应自己系统版本和GPU型号的driver,cuda和nvidia driver的对应关系可以参考cuda vs nvidia-driver。我这里下载的GeForce GTX 1060,linux 64bit,game ready版本的driver。在真实安装之前还需要禁用系统现有的driver。

  • 禁用nouveau driver

    nouveau是ubuntu16.04默认安装的第三方开源驱动,安装cuda会跟nouveau冲突,需要事先禁掉,运行命令lsmod | grep nouveau后需要没有任何输出就代表禁掉了。具体禁用方法如下:

    在/etc/modprobe.d中创建文件blacklist-nouveau.conf,在文件中添加以下内容

    1
    2
    blacklist nouveau
    options nouveau modeset=0

    命令行下执行sudo update-initramfs –u,然后在执行lsmod | grep nouveau,若无内容输出,则禁用成功,若仍有内容输出,请检查操作,并重复上述操作。

  • 卸载已有nvidia driver

    可能本机上已安装过nvidia driver,但是安装更高版本的cuda需要安装更高版本的nvidia driver,查看系统是否已安装的nvidia driver

    1
    2
    sudo dpkg --list | grep nvidia-*  # dpkg安装的
    sudo apt list | grep nvidia-* # apt安装的

    如果包含nvidia-*开头的一系列文件则说明系统已安装过nvidia driver,执行以下命令下载已有驱动

    1
    2
    sudo dpkg purge nvidia-* # dpkg或.run安装的
    sudo /usr/bin/nvidia-uninstall # cuda打包安装的或者dpkg或.run安装的(建议)
  • 正式安装nvidia driver

    ctrl+alt+f1进入文字界面(ctrl+alt+f7回到图形桌面),执行以下命令关闭图形界面

    1
    sudo service lightdm stop

    进入到nvidia driver runfile所在目录执行

    1
    2
    chmod a+x NVIDIA-*.run
    ./NVIDIA-*.run --no-opengl-files # 务必加上--no-opengl-files,否则安装过后将处于登录界面而无法进入桌面

    参数解释:

    • –no-opengl-files:表示只安装驱动文件,不安装OpenGL文件。这个参数不可省略,否则会导致登陆界面死循环,英语一般称为”login loop”或者”stuck in login”。
    • –no-x-check:表示安装驱动时不检查X服务,非必需。
    • –no-nouveau-check:表示安装驱动时不检查nouveau,非必需。
    • -Z, --disable-nouveau:禁用nouveau。此参数非必需,因为之前已经手动禁用了nouveau(建议手动禁用)。
    • -A:查看更多高级选项。

    必选参数解释:因为NVIDIA的驱动默认会安装OpenGL,而Ubuntu的内核本身也有OpenGL、且与GUI显示息息相关,一旦NVIDIA的驱动覆写了OpenGL,在GUI需要动态链接OpenGL库的时候就引起问题。提示安装基本上都是accept,yes,当提示你nvidia-xconfig时,就视自己的电脑情况而定,如果电脑是双显卡(双独显、集显和独显)就选择不安装,如果只有一个显卡就选择安装。我的电脑是intel集显+nvidai独显,所以拒绝安装nvidia-xconfig。

安装cuda10

在官网nvidia cuda downloads下载对应版本的cuda,然后根据自己硬件和系统选择合适的cuda进行安装,我这里下载的cuda10,下载选项如下

下载好之后进入到所在目录进行安装

1
2
chmod a+x cuda-*.run
./cuda-*.run --no-opengl --tmpdir=/usr/local/tmp

安装过程中要借用/tmp目录,如果/tmp目录空间不足可以用—tmpdir指定一个tmp目录如上所示。安装过程中会询问你安装各种各样的东西,除了cuda toolkit,其它的都不需要安装,安装路径自己确定也可以保持默认,确认建立软连接到/usr/local/cuda。如果有补丁patch,则在安装完主模块之后再安装patch,方法一致。

安装cudnn7

在官网nvidia cudnn downloads下载对应cuda版本的cudnn,cudnn下载要求必须登录账户才可以,我这里下载最新的cuDNN v7.6.3 for cuda 10 .0,下载好之后解压,然后将其库文件copy到cuda中

1
2
3
4
5
6
7
cp	CUDNN_HOME/include/cudnn.h	CUDA_HOME/include
cp CUDNN_HOME/lib64/libcudnn* CUDA_HOME/lib64/
ln -sf CUDA_HOME/lib64/lincudnn.so.7.6.3 CUDA_HOME/lib64/libcudnn.so.7
ln -sf CUDA_HOME/lib64/libcudnn.so.7 CUDA_HOME/lib64/libcudnn.so
sudo mkdir /etc/ld.so.conf.d/nvidia.conf
sudo cat CUDA_HOME/lib64
sudo ldconfig

ldconfig要求.so文件是软链接,所以必须ln -sf之后再执行ldconfig上面命令中的CUDNN_HOME和CUDA_HOME分别是cudnn和cuda安装目录,安装好之后配置环境~/.bashrc

1
2
3
4
# CUDA
export CUDA_HOME=/home/liujian/cuda-9.0
export LD_LIBRARY_PATH=$CUDA_HOME/lib64:$CUDA_HOME/extras/CUPTI/lib64:$LD_LIBRARY_PATH
export PATH=$CUDA_HOME/bin:$PATH

source ~/.bashrc之后,执行nvcc -V查看cuda版本,测试cuda是否已可用

1
2
3
cd CUDA_HOME/samples/1_Utilities/deviceQuery
make
./deviceQuery

如果最后显示pass则表明cuda安装成功,否则不可用

源码编译安装tensorflow1.14

安装tensorflow之前查看cuda和cudnn版本号以安装相匹配版本的tensorflow

1
2
3
4
# 查看cuda版本
cat CUDA_HOME/version.txt
# 查看cudnn版本
cat cat /usr/local/cuda/include/cudnn.h | grep CUDNN_MAJOR -A 2

git clone tensorflow的官方仓库

1
git clone https://github.com/tensorflow/tensorflow.git

基于tag(版本)创建分支

1
2
3
git tag # 查看分支
git branch r1.14.0 v1.14.0 # 基于tagv1.14.0建立r1.14.0分之
git checkout r1.14.0

使用python3.6安装,tensorflow的源码编译安装还需要使用google的一款编译器bazel,具体安装教程以及tensoflow版本与cuda,cudnn,bazel的版本匹配请参考官网的tensorflow install.

Caution:

这里记录一下我安装过程中出现的几个问题及经验,在正式bazel编译之前执行./configure进行配置,配置过程中建议使用gcc而不是clang,这样编译过程中不容易出错,然后配置过程中可能会报以下错误

1
2
3
4
5
6
7
8
9
10
11
12
13
Traceback (most recent call last):
File "third_party/gpus/find_cuda_config.py", line 463, in <module>
main()
File "third_party/gpus/find_cuda_config.py", line 455, in main
for key, value in sorted(find_cuda_config().items()):
File "third_party/gpus/find_cuda_config.py", line 418, in find_cuda_config
_get_default_cuda_paths(cuda_version))
File "third_party/gpus/find_cuda_config.py", line 159, in _get_default_cuda_paths
] + _get_ld_config_paths()
File "third_party/gpus/find_cuda_config.py", line 139, in _get_ld_config_paths
match = pattern.match(line.decode("ascii"))
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc2 in position 27: ordinal not in range(128)
Asking for detailed CUDA configuration...

这个问题可以参考github issue: find_cuda进行解决,具体做法:在third_party/gpus/find_cuda_config.py文件中找到match = pattern.match(line.decode(“ascii”)),并将其修改为match = pattern.match(line.decode(sys.stdin.encoding))即可,重新执行./configure就不会再报错了。

写在最后:

google提供了tensorflow多标签的docker镜像,使用docker容器安装使用tensorflow是最便捷且安全的,用户可以在tensorflow多版本之间自由切换,在服务器上使用也不用再受权限问题困扰了,而且最新的docker 19.03已经原生支持容器使用物理机上的gpu了,不再需要安装nvidia-docker来支持gpu使用了,用户只需在物理机上安装nvidia驱动,其它的都有镜像提供,喜大普奔。docker安装可以参考我之前写的一篇博客Linux下docker安装教程,至于docker下使用tensorflow镜像的教程可以参考tensorflow官方教程Docker。

---------------- The End ----------------

作者: brooksjay
联系邮箱: jaypark@smail.nju.edu.cn
本文地址:
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布
转载请注明出处, 谢谢!

Ubuntu18.04美化

发表于 2019-09-16 | 分类于 Linux | 0 comments
阅读次数:
  |   字数统计: 1.7k(字)   |   阅读时长: 6(分)

前言

ubuntu桌面比较简陋,这就驱使很多人想DIY自己的一套桌面主题,如果是从零开始配置和美化ubuntu18.04,可以建议先参考Ubuntu 18.04配置及美化

工具

工欲善其事,必先利其器

要对ubuntu进行美化就必定要用到神器gnome-tweak-tool,这是 Gnome 官方发布的一款 Gnome 调节软件, 借助这款软件, 我们可以更好地管理主题, 扩展, 字体 以及系统行为等设置项。安装方式很简单,命令行下执行

1
sudo apt install gnome-tweak-tool

安装tweak好之后打开界面如下

gnome扩展

Gnome Shell Extensions 是 Gnome 的一系列插件, 类似 Chrome 的插件, 可以起到系统增强的作用。借助chrome的插件可以方便的访问gnome扩展网站并实现一键添加或删除gnome扩展程序,具体安装过程两步

  • 安装 Chrome 扩展程序 GNOME Shell integration
  • 安装 主机连接器 sudo apt install chrome-gnome-shell

接下来我们就可以在网站 GNOME Shell Extensions 安装 gnome 扩展了。

通过搜索找到自己心仪的扩展程序,点击进入详情页面,切换详情页面的“OFF”按钮即可安装对应扩展,如下图红圈标示

点击红叉即可卸载该扩展程序。有了tweak和gnome shell extension之后就可以开始DIY自己的ubuntu桌面了。

安装gnome扩展

先安装一些好用的扩展程序以帮助我们提高工作效率,可参考简书:Ubuntu 18.10 美化

  • dash to dock 优化 Ubuntu 默认的 dock
  • User Themes 自定义 shell 主题
  • Coverflow Alt-Tab 优化 Ubuntu 默认窗口切换动作
  • Gnome Global Application Menu 将当前程序的菜单项提取到状态栏
  • NetSpeed 显示网速插件
  • Clipboard Indicator 提供剪切板历史记录功能
  • Drop Down Terminal 可以从屏幕上快速弹出一个终端
  • Recent Items 快速打开最近打开过的文件
  • Places Status Indicator 利用下拉菜单快速打开驱动器上的常用位置
  • Dynamic Top Bar 动态调整状态栏透明度
  • Hide top bar 隐藏顶栏, 可以设置为鼠标靠近屏幕上边沿时显示顶栏
  • Top Panel Workspace Scroll快速切换工作区
  • Gravatar 把你的 Ubuntu 用户头像设置成你的 Gravatar 头像.
  • TopIcons Plus 将传统托盘图标移动到顶部面板 (Wine 程序救星)

按下 Alt + F2,输入 r,回车重启 gnome。

安装theme和icon

有了便捷的扩展程序以后,再搭配一个让人赏心悦目的主题岂不美哉。maxOS的桌面风格很受程序猿的喜欢,所以先安利一款macOS主题桌面MCHigh Sierra,具体的制作过程可参考Ubuntu18.04主题更换为Mac OS high Sierra美化教程,按照里面的教程一步一步来即可制作出属于自己的macOS主题桌面。更多的MacOS主题安装教程可以参考给Ubuntu18.04(18.10)安装mac os主题

Caution:

Sierra的原始资源地址McHigh Sierra仅提供了gnome应用主题,没有提供图标风格icon,想要获取对应主题的icon可从Ubuntu18.04-tutorials-themes获取

除了macOS主题之外还有很多其它好看的主题,可以根据个人喜好在gnome-look中进行查找。比如我个人喜欢的一套主题是Vimx-beryl Theme及其配套iconVimx-beryl Icon,这套主题的具体安装教程可参考知乎:Ubuntu 18.04 LTS 安装、美化

Caution:

下载的theme可以放在系统themes目录/usr/share/themes下,也可以放在用户目录~/.themes下。而下载的icon可以放在系统icons目录/usr/share/icons下,也可以放在用户目录~/.icons下

安装gnome shell

Flat Remix个人挺喜欢的一款gnome shell风格,可以通过添加源在命令行下安装

1
2
3
4
sudo add-apt-repository ppa:daniruiz/flat-remix
sudo apt-get install flat-remix
sudo apt-get install flat-remix-gnome
sudo apt install gnome-shell-extensions

然后重新打开tweak,在扩展一栏中将User themes打开之后即可切换gnome shell的风格了

安装zsh

zsh是mac默认的shell,而ubuntu的默认shell是bash。相比bash,zsh配合oh-my-zsh拥有更丰富的主题,使得命令行更为美观。

1
2
3
sudo apt install zsh
# 切换到zsh
chsh -s /bin/zsh

重新登录shell即可转换到zsh,接下来在用户主目录下安装oh-my-zsh

1
sh -c "$(wget https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh -O -)"

接着安装插件highlight,高亮语法

1
2
cd ~/.oh-my-zsh/custom/plugins
git clone git://github.com/zsh-users/zsh-syntax-highlighting.git

在Oh-my-zsh的配置文件中~/.zshrc中添加插件

1
2
# 括号中的插件名以空格分隔
plugins=( [plugins...] zsh-syntax-highlighting)

设置zsh主题

1
2
# 个人觉得比较好看的zsh主题有: robbyrussell(default), agnoster, bira
ZSH_THEME="robbyrussell"
Caution:

其中agnoster主题比较像之前在bash下使用的powerline,由于包含特殊的字体符号,需要安装额外的字体 Powerline-patched font才能支持主题正常显示,ubuntu下可直接使用apt安装

1
2
sudo apt-get install fonts-powerline
fc-cache -vf /usr/share/fonts/ #更新系统的字体缓存

zsh主题定制可以参考oh-my-zsh终端用户名设置(PS1),zsh的一些主题例如agnoster会自动添加命令行头名user@host,如果觉得这种形式使得命令行看起来很臃肿,可以在~/.zshrc中可以设置DEFAULT_USER来避免

1
DEFAULT_USER=brooksj

避免命令行头名臃肿还可以通过prompt_context() {}来设置

1
2
3
4
5
6
7
8
9
# 隐藏用户名和主机名
prompt_context() {}

# 只保留用户名,隐藏主机名
prompt_context() {
if [[ "$USER" != "$DEFAULT_USER" || -n "$SSH_CLIENT" ]]; then
prompt_segment black default "%(!.%{%F{yellow}%}.)$USER"
fi
}

个人倾向于只保留用户名,最后使配置生效

1
source ~/.zshrc

安装background

backgound的图片可从壁纸网站wallhaven)下载,然后放到/usr/share/background中,右击桌面切换背景即可

个人配置展示

个人所使用的应用程序、光标、图标、shell在tweak中配置如下图所示

个人用到的扩展(gnome shell extensions)为

  1. Clipboard Indicator 提供剪切板历史记录功能
  2. dash to dock 优化 Ubuntu 默认的 dock
  3. User Themes 自定义 shell 主题
  4. Coverflow Alt-Tab 优化 Ubuntu 默认窗口切换动作
  5. Drop Down Terminal 可以从屏幕上快速弹出一个终端
  6. Gravatar 把你的 Ubuntu 用户头像设置成你的 Gravatar 账户头像.
  7. NetSpeed 显示网速插件
  8. Recent Items 快速打开最近打开过的文件
  9. Places Status Indicator 利用下拉菜单快速打开驱动器上的常用位置
  10. Top Panel Workspace Scroll快速切换工作区
参考链接:
  1. Ubuntu 18.04配置及美化—-从零开始配置的建议入手
  2. Ubuntu 18.04 LTS 安装、美化
  3. Ubuntu18.04主题更换为Mac OS high Sierra美化教程
  4. 给Ubuntu18.04安装mac os主题
  5. Ubuntu 18.10 美化
---------------- The End ----------------

作者: brooksjay
联系邮箱: jaypark@smail.nju.edu.cn
本文地址:
本文基于 知识共享署名-相同方式共享 4.0 国际许可协议发布
转载请注明出处, 谢谢!

12…4<i class="fa fa-angle-right"></i>
brooksj

brooksj

我听说虫洞可以穿梭时空

31 日志
15 分类
40 标签
GitHub E-Mail
Links
  • 博客旧址
  • 苏剑林's blog
  • Karpathy's Blog
  • Ruder's Blog
  • Edward Ma's Blog
  • Miskcoo's Blog
© 2023 brooksj
由 Hexo 强力驱动
|
主题 — NexT.Mist v5.1.4