如何在mxnet gluon中使用预训练的embedding

如何在mxnet gluon中使用预训练的embedding

我们复现别人的论文的时候,往往发现nlp任务中大量使用预训练的word2vec作为word embedding的初始权值,如何对gluon.nn.Embedding()进行初始化也就成为了一个小问题。

gluon中没有像tensorflow中专门为embedding层设计了一个传参的方法,也就是说我们需要调用 mx.init 方法来对Embedding层进行初始化。

总体来说,一共有两种方法来实现使用预训练的word2vec进行初始化。

1.自定义init方法

#定义init方法

class MyInit(init.Initializer):
    def __init__(self):
        super(MyInit, self).__init__()
        self._verbose = True
    def _init_weight(self, _, arr):
        #word2vec是你初始化的embedding矩阵
        nd.array(word2vec)

注意到你的实现的init方法仅仅可以对embedding层进行初始化,如果直接在net.initialize()中使用该方法会引起其余层的出错。

#定义网络

def get_net():
    net = nn.Sequential()
    with net.name_scope():
        net.add(nn.Embedding(3000,400)
        net.add(nn.Dense(2))
    return net

#找到embedding层的权重名称

params = net.collect_params()
print(params)

#发现名称为sequential0_embedding0_weight,这一项一般不会改便

#对该参数使用改写的init方法进行初始化

params['sequential0_embedding0_weight'].initialize(MyInit())

2.暴力使用set_data方法进行参数改写

w = net[0].weight
w.set_data(nd.array(word2vec)) 



其实理论上来说使用mx.init.Load()可以完美解决这个问题,但是不知道用的时候为啥老是报错,总之两种方法都有点危险,尤其是第二种,coding的时候最好检查以下究竟是不是真正的初始化为了想要的矩阵。


Reference

1.gluon文档

初始化模型参数 - 动手学深度学习 0.6 documentation

2.如何使用gensim训练word2vec

gensim | 我爱自然语言处理

3.如何把训练得到的word2vec变成一个Emedding矩阵

github.com/MarkWuNLP/Mu

第78-98行


注:gensim处理的时候高频和低频词都会删去,没有对应的word2vec,应该是这样的

希望mxnet发展越来越好哦~


import gensim.downloader as api
model = api.load('glove-wiki-gigaword-100')

emb = np.zeros((13516+5,100))
count = 1
no_foung = 0
for line in sword2wid:
	try:
		emb[int(sword2wid[line])] = model[line]
	except:
		no_foung = no_foung + 1
		print(line)
	count = count + 1

print(no_foung)
np.savetxt('glove.txt',emb)

编辑于 2019-06-13 09:55