pytorch命名实体识别模型

深度学习同传统机器学习一样,数据准备是一项耗时的工作,且数据准备没有一定之规。如果你去学习tensorflow,会发现五花八门的手法,看似给你最大的自由度,其实是无形中加重没必要的学习难度。

pytorch当然也没有限制,但是它提供了很好的DataSet和DataLoader,简单继承与实现。

只要自己实现__getitem__和__len__即可。

fromainlp.corpusimportdummy_dataset

fromtorch.utils.dataimportDataLoader

importunittest

classTestDataSet(unittest.TestCase):

defsetUp(self):

pass

deftest_dummy_dataset(self):

#100行,5列的随机数

rand_loader = DataLoader(dataset=dummy_dataset.RandomDataset(size=5,length=100),

batch_size=30,shuffle=True)

#100行5列,batch=30,可以取4次

fori_batch, sample_batchedinenumerate(rand_loader):

print(i_batch, sample_batched.size())

print(sample_batched)

一个epoch循环,读取4次,每batch=30。

0 torch.Size([30, 5])

1 torch.Size([30, 5])

2 torch.Size([30, 5])

3 torch.Size([10, 5])

我们使用这个格式,将CoNLL-2002数据加以封装。

importtorch

importnltk

importrandom

from.importutils

fromtorch.utils.dataimportDataset,DataLoader

classCoNLL2002Dataset(Dataset):

def__init__(self, b_train=True):

self.b_train = b_train

corpus = nltk.corpus.conll2002.iob_sents()

WINDOW_SIZE =2

windows = []

dummy = [''] * WINDOW_SIZE

all_words = []

all_tags = []

fori,corinenumerate(corpus):

#cor是一句话的序列标注结果[(word1,POS,NER),(),()]

data= []

words,POS,NER =list(zip(*cor))

all_words.extend(words)

all_tags.extend(NER)

#词序变成一个2-gram的窗口

window =list(nltk.ngrams(dummy +list(words) + dummy, WINDOW_SIZE *2+1))

windows.extend([[list(window[i]), NER[i]]foriinrange(len(words))])

#random.shuffle(windows)

self.train_data = windows[:int(len(windows) *0.9)]

self.test_data = windows[int(len(windows) *0.9):]

self.word2idx,self.idx2word = utils.word_to_index(all_words)

self.tag2idx,self.idx2tag = utils.tag_to_index(all_tags)

defget_batch(self,batch_size,is_train=True):

data =self.train_dataifis_trainelseself.test_data

returnutils.get_batch(batch_size, data)

defbatch_to_variable(self,data):

#这里是对应好的一个个window,和句子无关了

x, y =list(zip(*data))

inputs = torch.cat([utils.prepare_sequence(sent,self.word2idx).view(1, -1)forsentinx])

targets = torch.cat([utils.prepare_tag(tag,self.tag2idx)fortaginy])

returninputs,targets

是一个细致活,比较容易出错。

后面建模就相对容易了。

importtorch.nnasnn

classWindowClassifier(nn.Module):

def__init__(self, vocab_size, embedding_size, window_size, hidden_size, output_size):

super(WindowClassifier,self).__init__()

self.embed = nn.Embedding(vocab_size, embedding_size)

self.h_layer1 = nn.Linear(embedding_size * (window_size *2+1), hidden_size)

self.h_layer2 = nn.Linear(hidden_size, hidden_size)

self.o_layer = nn.Linear(hidden_size, output_size)

self.relu = nn.ReLU()

self.softmax = nn.LogSoftmax(dim=1)

self.dropout = nn.Dropout(0.3)

defforward(self, inputs, is_training=False):

embeds =self.embed(inputs)# BxWxD

concated = embeds.view(-1, embeds.size(1) * embeds.size(2))# Bx(W*D)

h0 =self.relu(self.h_layer1(concated))

ifis_training:

h0 =self.dropout(h0)

h1 =self.relu(self.h_layer2(h0))

ifis_training:

h1 =self.dropout(h1)

out =self.softmax(self.o_layer(h1))

returnout

关于作者:魏佳斌,互联网产品/技术总监,北京大学光华管理学院(MBA),特许金融分析师(CFA),资深产品经理/码农。偏爱python,深度关注互联网趋势,人工智能,AI金融量化。致力于使用最前沿的认知技术去理解这个复杂的世界。

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180315G0XF4Q00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券