丁香五月天婷婷久久婷婷色综合91|国产传媒自偷自拍|久久影院亚洲精品|国产欧美VA天堂国产美女自慰视屏|免费黄色av网站|婷婷丁香五月激情四射|日韩AV一区二区中文字幕在线观看|亚洲欧美日本性爱|日日噜噜噜夜夜噜噜噜|中文Av日韩一区二区

您正在使用IE低版瀏覽器,為了您的雷峰網(wǎng)賬號(hào)安全和更好的產(chǎn)品體驗(yàn),強(qiáng)烈建議使用更快更安全的瀏覽器
此為臨時(shí)鏈接,僅用于文章預(yù)覽,將在時(shí)失效
人工智能開(kāi)發(fā)者 正文
發(fā)私信給AI研習(xí)社
發(fā)送

0

簡(jiǎn)單有趣的 NLP 教程:手把手教你用 PyTorch 辨別自然語(yǔ)言(附代碼)

本文作者: AI研習(xí)社 2017-06-20 15:41
導(dǎo)語(yǔ):自然語(yǔ)言處理入門(mén)。

雷鋒網(wǎng)按:本文作者甄冉冉,原載于作者個(gè)人博客,雷鋒網(wǎng)已獲授權(quán)。

最近在學(xué)pyTorch的實(shí)際應(yīng)用例子。這次說(shuō)個(gè)簡(jiǎn)單的例子:給定一句話,判斷是什么語(yǔ)言。這個(gè)例子是比如給定一句話:

Give it to me

判斷是 ENGLISH

me gusta comer en la cafeteria

判斷是 SPANISH

就是這么簡(jiǎn)單的例子。

來(lái)看怎么實(shí)現(xiàn):

準(zhǔn)備數(shù)據(jù) 格式 [(語(yǔ)句,類(lèi)型),...]

data是train的時(shí)候用的語(yǔ)句,test_data是test的時(shí)候用的語(yǔ)句

data = [ ("me gusta comer en la cafeteria".split(), "SPANISH"),

         ("Give it to me".split(), "ENGLISH"),

         ("No creo que sea una buena idea".split(), "SPANISH"),

         ("No it is not a good idea to get lost at sea".split(), "ENGLISH") ]

test_data = [("Yo creo que si".split(), "SPANISH"),

              ("it is lost on me".split(), "ENGLISH")]

因?yàn)槲谋居?jì)算機(jī)室識(shí)別不出來(lái)的,他們只認(rèn)識(shí)01串,也就是數(shù)字。所以我們得把文本映射到數(shù)字上。

word_to_ix = {}

for sent, _ in data + test_data:

    for word in sent:

        if word not in word_to_ix:

            word_to_ix[word] = len(word_to_ix)

print(word_to_ix)

輸出word_to_ix (意思是word to index)是:

{'me': 0, 'gusta': 1, 'comer': 2, 'en': 3, 'la': 4, 'cafeteria': 5, 'Give': 6, 'it': 7, 'to': 8, 'No': 9, 'creo': 10, 'que': 11, 'sea': 12, 'una': 13, 'buena': 14, 'idea': 15, 'is': 16, 'not': 17, 'a': 18, 'good': 19, 'get': 20, 'lost': 21, 'at': 22, 'Yo': 23, 'si': 24, 'on': 25}

這里先提前設(shè)置下接下來(lái)要用到的參數(shù)

VOCAB_SIZE = len(word_to_ix)

NUM_LABELS = 2#只有兩類(lèi) ENGLISH  SPANISH

固定模板

def init(self, num_labels, vocab_size):初始化,就是輸入和輸出的大小。這里我們要輸入是一個(gè)句子,句子最大就是擁有所有字典的詞,這里也就是vocab_size(下面再說(shuō)怎么將一句話根據(jù)字典轉(zhuǎn)換成一個(gè)數(shù)字序列的),輸出就是分類(lèi),這里分為2類(lèi),即num_labels。這里我們用的是線性分類(lèi) ,即nn.Linear()。

def forward(self, bow_vec):bow_vec是一個(gè)句子的數(shù)字化序列,經(jīng)過(guò)self.linear()得到一個(gè)線性結(jié)果(也就是預(yù)測(cè)結(jié)果),之后對(duì)這個(gè)結(jié)果進(jìn)行softmax(這里用log_softmax是因?yàn)橄旅娴膿p失函數(shù)用的是NLLLoss() 即負(fù)對(duì)數(shù)似然損失,需要log以下)

class BoWClassifier(nn.Module):#nn.Module 這是繼承torch的神經(jīng)網(wǎng)絡(luò)模板

    def __init__(self, num_labels, vocab_size): 

        super(BoWClassifier, self).__init__()

        self.linear = nn.Linear(vocab_size, num_labels)

    def forward(self, bow_vec):

        return F.log_softmax(self.linear(bow_vec))

def make_bow_vector(sentence, word_to_ix)

大概能看懂什么意思吧。就是把一個(gè)句子sentence通過(guò)word_to_ix轉(zhuǎn)換成數(shù)字化序列.比如 sentence=我 是 一只 小 小 鳥(niǎo) word_to_id={你:0,我:1,他:2,不:3,是:4,大:5,小:6,豬:7,鳥(niǎo):8,,} make_bow_vector之后的結(jié)果是[0,1,0,0,1,0,2,0,1]。view()就是改變下向量維數(shù)。

這里是講len(word_to_ix)1->1len(word_to_ix)

def make_bow_vector(sentence, word_to_ix):

    vec = torch.zeros(len(word_to_ix))

    for word in sentence:

        vec[word_to_ix[word]] += 1

    return vec.view(1, -1)

這個(gè)就不用說(shuō)了吧 一樣。(如果想知道torch.LongTensor啥意思的話??梢钥纯?。Torch中,Tensor主要有ByteTensor(無(wú)符號(hào)char),CharTensor(有符號(hào)),ShortTensor(shorts), IntTensor(ints), LongTensor(longs), FloatTensor(floats), DoubleTensor(doubles),默認(rèn)存放為double類(lèi)型,如果需要特別指出,通過(guò)torch.setdefaulttensortype()方法進(jìn)行設(shè)定。例如torch.setdefaulttensortype(‘torch.FloatTensor’)。 )

def make_target(label, label_to_ix):

    return torch.LongTensor([label_to_ix[label]])

這里再介紹下model.parameters()這個(gè)函數(shù)。他的返回結(jié)果是model里的所有參數(shù)。這里我們用的是線性函數(shù),所以就是f(x)=Ax+b中的A和b(x即輸入的數(shù)據(jù)),這些參數(shù)在之后的反饋和更新參數(shù)需要的。

model = BoWClassifier(NUM_LABELS, VOCAB_SIZE)

for param in model.parameters():

    print("param:", param)

可以看出A是2len(vocab_size),b是21

param: Parameter containing:


Columns 0 to 9 

 0.0786  0.1596  0.1259  0.0054  0.0558 -0.0911 -0.1804 -0.1526 -0.0287 -0.1086

-0.0651 -0.1096 -0.1807 -0.1907 -0.0727 -0.0179  0.1530 -0.0910  0.1943 -0.1148


Columns 10 to 19 

 0.0452 -0.0786  0.1776  0.0425  0.1194 -0.1330 -0.1877 -0.0412 -0.0269 -0.1572

-0.0361  0.1909  0.1558  0.1309  0.1461 -0.0822  0.1078 -0.1354 -0.1877  0.0184


Columns 20 to 25 

 0.1818 -0.1401  0.1118  0.1002  0.1438  0.0790

 0.1812 -0.1414 -0.1876  0.1569  0.0804 -0.1897

[torch.FloatTensor of size 2x26]


param: Parameter containing:

 0.1859

 0.1245

[torch.FloatTensor of size 2]

我們?cè)倏纯磎odel的def forward(self, bow_vec):怎么用。這里就想下面的代碼一樣,直接在mode()填一個(gè)參數(shù)即可,就調(diào)用forward函數(shù)。

sample = data[0]

bow_vector = make_bow_vector(sample[0], word_to_ix)

log_probs = model(autograd.Variable(bow_vector))

print("log_probs", log_probs)

輸出是:(就是log_softmax后的值)

log_probs Variable containing:

-0.6160 -0.7768

[torch.FloatTensor of size 1x2]

我們這里看看在test上的預(yù)測(cè)

label_to_ix = { "SPANISH": 0, "ENGLISH": 1 }

for instance, label in test_data:

    bow_vec = autograd.Variable(make_bow_vector(instance, word_to_ix))

    log_probs = model(bow_vec)

    print log_probs

print next(model.parameters())[:,word_to_ix["creo"]]

結(jié)果是

Variable containing:

-0.5431 -0.8698

[torch.FloatTensor of size 1x2]


Variable containing:

-0.7405 -0.6480

[torch.FloatTensor of size 1x2]


Variable containing:

-0.0467

 0.1065

[torch.FloatTensor of size 2]

下面就該進(jìn)行重要的部分了。

循環(huán)訓(xùn)練和更新參數(shù)

這里我們用的損失函數(shù)是nn.NLLLoss()負(fù)對(duì)數(shù)似然損失,優(yōu)化依然用的最常見(jiàn)的optim.SGD() 梯度下降法,一般訓(xùn)練5-30次最終優(yōu)化基本不再變化。

每一步過(guò)程:

a. 首先都要model.zero_grad(),因?yàn)榻酉聛?lái)要極端梯度,得清零,以防問(wèn)題

b. 將數(shù)據(jù)向量化(也可以說(shuō)是數(shù)字序列化,轉(zhuǎn)成計(jì)算機(jī)能看懂的形式)

c. 得到預(yù)測(cè)值

d. 求損失loss_function

e. 求梯度loss.backward()

f. 更新參數(shù)optimizer.step()

loss_function = nn.NLLLoss()

optimizer = optim.SGD(model.parameters(), lr=0.1)


for epoch in range(100):

    for instance, label in data:

        model.zero_grad()


        bow_vec = autograd.Variable(make_bow_vector(instance, word_to_ix))

        target = autograd.Variable(make_target(label, label_to_ix))


        log_probs = model(bow_vec)


        loss = loss_function(log_probs, target)

        loss.backward()

        optimizer.step()

在測(cè)試集上測(cè)試

for instance, label in test_data:

    bow_vec = autograd.Variable(make_bow_vector(instance, word_to_ix))

    log_probs = model(bow_vec)

    print log_probs

我們?cè)诮Y(jié)果上很容易看到第一個(gè)例子預(yù)測(cè)是SPANISH最大,第二個(gè)是ENGLISH最大。成功了。

Variable containing:

-0.0842 -2.5161

[torch.FloatTensor of size 1x2]


Variable containing:

-2.4886 -0.0867

[torch.FloatTensor of size 1x2]

雷鋒網(wǎng)相關(guān)閱讀:

不是你無(wú)法入門(mén)自然語(yǔ)言處理(NLP),而是你沒(méi)找到正確的打開(kāi)方式

從NLP到“自然語(yǔ)言理解”,F(xiàn)acebook如何讓Messenger更懂人類(lèi)?

雷峰網(wǎng)版權(quán)文章,未經(jīng)授權(quán)禁止轉(zhuǎn)載。詳情見(jiàn)轉(zhuǎn)載須知。

簡(jiǎn)單有趣的 NLP 教程:手把手教你用 PyTorch 辨別自然語(yǔ)言(附代碼)

分享:

編輯

聚焦數(shù)據(jù)科學(xué),連接 AI 開(kāi)發(fā)者。更多精彩內(nèi)容,請(qǐng)?jiān)L問(wèn):yanxishe.com
當(dāng)月熱門(mén)文章
最新文章
請(qǐng)?zhí)顚?xiě)申請(qǐng)人資料
姓名
電話
郵箱
微信號(hào)
作品鏈接
個(gè)人簡(jiǎn)介
為了您的賬戶安全,請(qǐng)驗(yàn)證郵箱
您的郵箱還未驗(yàn)證,完成可獲20積分喲!
請(qǐng)驗(yàn)證您的郵箱
立即驗(yàn)證
完善賬號(hào)信息
您的賬號(hào)已經(jīng)綁定,現(xiàn)在您可以設(shè)置密碼以方便用郵箱登錄
立即設(shè)置 以后再說(shuō)