【NLP方向】【万时计划】51-57

GloVe词向量生成模型

import shutil
import gensim

def getFileLineNums(filename):
    f = open(filename, 'r')
    count = 0
    for line in f:
        count += 1
    return count

def prepend_line(infile, outfile, line):
    # To prepend lines using bash utilities in linux
    with open(infile, 'r') as old:
        with open(outfile, 'w') as new:
            new.write(str(line) + "\n")
            shutil.copyfileobj(old, new)

def load(filename):
    #输入GloVe模型文件
    glove_file = filename
    dimensions = 50
    num_lines =  getFileLineNums(filename)
    dims = int(dimensions[:-1])

    print(num_lines)
    gensim_file = 'glove_model.txt'
    gensim_file_line = "{} {}".format(num_lines, dims)
    prepend_line(glove_file, gensim_file, gensim_file_line)

    model = gensim.models.keyedvectors.load_word2vec_format(gensim_file, binary = False)
    model_name = gensim_file[6:-4]
    model.save(model_name)
    return model

if __name__ == '__main__':
    myfile = 'vectors.txt'
    model = load(myfile)

    print(len(model.vocab))
    word_list = [u'to',u'one']
    for word in word_list:
        print(word, '--')
        for i in model.most_similar(word, topn=10):
            print(i[0],i[1])
        print('')

LSTM单元

  1. Long-Short Term Memory RNN 长短时记忆模型循环神经网络,是RNN的一种特殊实现

  2. Long-Short Term Memory

    • short term memory

      相对于当前的任务,有时我们只需考虑最近的信息"the clouds are in the sky"

在这里插入图片描述

  • long term memory

    相关信息和需要它的点之间的距离很远。

    在这里插入图片描述

RNN在short-term上表现不错,但long-term就不理想了,所以有人提出了LSTM,它被广泛地运用,并在相当多的问题上表现很好

在这里插入图片描述

上图为含有四个交互层的LSTM重复模型

在这里插入图片描述

LSTM元素标注示意图

LSTM的关键是细胞状态

  • 顶部直线

在这里插入图片描述

穿过图标上方的水平直线,直接在整个链上运行,只有一些小的线性相互作用,让信息在流动的同时保持不变性。

  • 阀门

在这里插入图片描述

LSTM有能力向细胞状态中添加或移除信息,这种精细调整通过阀门的结构来实现。阀门可以让信息有选择地通过。它们由一个S形网络和一个逐点乘法操作组成。

S形网络层输出[0,1]的一个数,描述应该让每个组件通过多少信息。0就是什么也不让过,1就是每个信息都可以通过。

一个LSTM含有三个这样的阀门,来保护和控制细胞状态。

  • 忘记阀门层: f t = σ ( W f ⋅ [ h t − 1 , x t ] + b f ) {{f}_{t}}=\sigma ({{W}_{f}}\cdot [{{h}_{t-1}},{{x}_{t}}]+{{b}_{f}}) ft=σ(Wf[ht1,xt]+bf)

在这里插入图片描述

用于决定从细胞状态中扔掉哪些信息,这由一个叫做忘记阀门层的S形网络层实现。

  • 输入阀门层:KaTeX parse error: No such environment: align at position 7: \begin{̲a̲l̲i̲g̲n̲}̲ & {{i}_{t}}=…

在这里插入图片描述

在丢掉一些信息之后,下一步要决定把哪些信息存储在细胞状态中。由以下两部分组成。

  1. 决定要更新的值
  2. 创造新的候选值向量
  • 计算细胞状态: C t = f t ∗ C t − 1 + i t ∗ C ~ t {{C}_{t}}={{f}_{t}}*{{C}_{t-1}}+{{i}_{t}}*{{{\tilde{C}}}_{t}} Ct=ftCt1+itC~t

在这里插入图片描述

将旧的细胞状态 C t − 1 {{C}_{t-1}} Ct1更新为 C t {{C}_{t}} Ct

  • 输出阀门层:KaTeX parse error: No such environment: align at position 7: \begin{̲a̲l̲i̲g̲n̲}̲ & {{o}_{t}}=…

在这里插入图片描述

首先会运行一个S网络层,用于决定细胞状态的哪些部分会被输出,然后将细胞状态做tanh运算,得到[-1,1]的值。

LSTM的大体结构

相比于原始的RNN的隐藏层(hidden state),LSTM增加了一个细胞状态(cell state)

在这里插入图片描述

LSTM在t时刻的输入与输出:首先,输入有三个:细胞状态 C t − 1 {{C}_{t-1}} Ct1,隐藏层状态 h t − 1 {{h}_{t-1}} ht1,t时刻输入向量 X t {{X}_{t}} Xt,而输出有两个:细胞状态 C t {{C}_{t}} Ct,隐藏层状态 h t {{h}_{t}} ht。其中 h t {{h}_{t}} ht还作为t时刻的输出。

  1. 细胞状态 C t − 1 {{C}_{t-1}} Ct1的信息一直在上面那条线上传递,t时刻的隐藏层状态 h t − 1 {{h}_{t-1}} ht1,t时刻输入向量 X t {{X}_{t}} Xt会对 C t {{C}_{t}} Ct进行适当修改,然后传到下一时刻去。
  2. C t − 1 {{C}_{t-1}} Ct1会参与t时刻输出 h t {{h}_{t}} ht的计算。
  3. 隐藏层状态 h t − 1 {{h}_{t-1}} ht1的信息,通过LSTM的门结构,对细胞状态进行修改,并参与输出的计算。

LSTM也是RNN的一种,输入基本没什么差别。通常我们需要一个时序结构喂给LSTM,数据会被分为t个部分,也即 X t {{X}_{t}} Xt X t {{X}_{t}} Xt可以看作是一个向量,在实际训练的时候,我们会用batch来训练,通常它的shape是**(batch_size, input_dim)**。

两个隐藏层的初始值: C 0 {{C}_{0}} C0 h 0 {{h}_{0}} h0一般是用全0初始化。两个隐藏层同样是响亮的形式,在定义LSTM的时候会定义隐层大小,输出的维度与对应输入是一致的。

遗忘门

[ h t − 1 , x t ] [{{h}_{t-1}},{{x}_{t}}] [ht1,xt]表示把两个向量连接起来, f t {{f}_{t}} ft为输出。$\sigma 表 示 s i g m o i d 函 数 , 它 的 输 出 是 在 0 到 1 之 间 的 , 这 个 输 出 表示sigmoid函数,它的输出是在0到1之间的,这个输出 sigmoid01{{f}{t}} 逐 位 与 逐位与 {{C}{t-1}} 的 元 素 相 乘 , 当 的元素相乘,当 {{f}{t}} 的 某 一 位 值 为 0 的 时 候 , 的某一位值为0的时候, 0{{C}{t-1}}$对应的那一位信息就被干掉了,而值为(0,1)时,对应位的信息就保留了一部分,只有值为1的时候,对应信息才会完整保留。

更新门

这个门有两个部分

KaTeX parse error: No such environment: align at position 7: \begin{̲a̲l̲i̲g̲n̲}̲ & {{i}_{t}}=\s…

一个是 C ~ t {{{\tilde{C}}}_{t}} C~t这里看作是新的输入带来的信息,tanh这个激活函数将内容归一化到[-1,1]。另一个是 i t {{i}_{t}} it,此结构与遗忘门结构相同,可以看作新的信息保留哪些部分。
在这里插入图片描述

C t = f t ∗ C t − 1 + i t ∗ C ~ t {{C}_{t}}={{f}_{t}}*{{C}_{t-1}}+{{i}_{t}}*{{{\tilde{C}}}_{t}} Ct=ftCt1+itC~t表示对 C t {{C}_{t}} Ct进行更新,图左侧,遗忘门给出的 f t {{f}_{t}} ft这个值乘 C t − 1 {{C}_{t-1}} Ct1,表示过去的信息有选择地遗忘(保留)。右侧同理,新的信息 C ~ t {{{\tilde{C}}}_{t}} C~t i t {{i}_{t}} it表示新的信息有选择地遗忘,最后再把这两部分信息加起来,即新的状态 C t {{C}_{t}} Ct.

GRU单元

import shutil

shutil库作为os模块的补充,提供了复制、移动、删除、压缩等操作,对压缩包的处理是调用ZipFile和TarFile这两个模块来进行的。

shutil.copy(src,dst) #复制文件
shutil.copytree(src,dst) #复制文件夹
shutil.move(src,dst) #移动文件或文件夹
shutil.rmtree(src) #删除文件夹

zipobj.write() #创建一个压缩包
zipobj.namelist() #读取压缩包中的文件信息
zipobj.extract() #将压缩包中的单个文件解压出来
zipobj.extractall() #将压缩包中所有文件解压出来
import gensim

gensim是一款强大的自然语言处理工具,包括很多常见的模型

基本的语料处理工具

LSI

LDA

HDP

DTM

DIM

TF-IDF

word2vec

训练模型:

from gensim.models import word2vec
sentences = word2vec.Text8Corpus(u'分词后的爽肤水评论.txt')

model = word2vec.Word2Vec(sentences, size=50)
#model = word2vec.Word2Vec(sentences, mincount=5, size=50)
#首参是训练语料,二参是小于该数的单词会被剔除,默认为5,三参是神经网络的隐藏层单元数,默认100
y2 = model.similarity(u"好", u"还行")
print(y2)

for i in model.most_similar(u"滋润"):
    print i[0],i[1]

模型导出

word2vec = gensim.models.word2vec.Word2Vec(sentences(), size=256, window=10, min_count=64,sg=1,hs=1,iter=10,workers=25)
word2vec.save('word2vec_wx')

模型导入

import numpy
model = gensim.models.Word2Vec.load('word2vec_wx')
pd.Series(model.most_similar(u'微信',topn=360000))
word_2x = numpy.load('word2vec_wx.wv.syn0.npy')

不能对已生成的模型进行再训练

.format

format作为python的格式字符串函数,主要通过字符串中的花括号{}来识别替换字段,从而完成字符串的格式化。

print("我叫{},今年{}岁。".format("小蜜"18))
#花括号个数决定了参数的个数,但花括号个数可以少于参数,当花括号多时,会报错。

通过数字参数传入位置参数,传入参数需注意以下事项:

  • 数字须是大于0的整数
  • 带数字的替换字段可以重复
  • 数字形式的简单字段名相当于把字段当成一个序列形式。通过索引的形式进行一一取值
print("名字{0},家住{1}".format("橙留香""水果村"))
print("我爱{0}.\n他爱{1}。\n{0}爱{1}".format("红太狼","灰太狼"))

用关键字传递

print("我今年{age}岁,我在读{college}".format(age="18",college="大学"))
#关键字顺序可以随便放置

关键字和数字可以混合使用传递参数,但关键字参数须位于位置参数之后,混合使用的时候可以省略数字

可以使用元组和字典传参,两者可以混合使用,当混合使用的时候。位置参数要在关键字参数前面,元组要在字典前面

a=["鸣人","火影", "雏田"]
print("我是 {},我要当{}的男人".format(*a))
print("我是 {1},我要当{2}的男人".format(*a))

v={"name":"孙悟空","skill":"龟派气功"}
print("我是{name},我的绝招是{skill}".format(**v))

复合字段名的使用

  • format使用数字和变量名两种形式,这就是符合字段

  • 复合字段名支持两种操作符

    [] 方括号

    . 点号

class Person:
    def __init__(self,name,addr):
        self.name = name
        self.addr = addr
p = Person("孙悟空","包子山")
print("我是{0.name},家在{0.addr}".format(p))
#当只有一个字段时,就可以省略数字
print("我是{.name}".forname(q))

传递文件的属性

f = open("out.txt","w")
print("文件名为:"{.name}.format(f))

传递关键字

print("我是{p.name},家在{p.addr}".format(p=p))
print("我是{girl.name},家在{girl.addr}".format(girl=p))

rson(“孙悟空”,“包子山”)
print(“我是{0.name},家在{0.addr}”.format§)
#当只有一个字段时,就可以省略数字
print(“我是{.name}”.forname(q))


传递文件的属性

```python
f = open("out.txt","w")
print("文件名为:"{.name}.format(f))

传递关键字

print("我是{p.name},家在{p.addr}".format(p=p))
print("我是{girl.name},家在{girl.addr}".format(girl=p))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值