PyTorch實現用於文本生成的循環神經網絡

2020-12-14 人工智慧遇見磐創

自然語言處理(NLP)有很多有趣的應用,文本生成就是其中一個有趣的應用。

當一個機器學習模型工作在諸如循環神經網絡、LSTM-RNN、GRU等序列模型上時,它們可以生成輸入文本的下一個序列。

PyTorch提供了一組功能強大的工具和庫,這些工具和庫為這些基於NLP的任務增添了動力。它不僅需要較少的預處理量,而且加快了訓練過程。

在本文中,我們將在PyTorch中訓練幾種語言的循環神經網絡(RNN)。訓練成功後,RNN模型將預測屬於以輸入字母開頭的語言的名稱。

PyTorch實現

這個實現是在Google Colab中完成的,其中的數據集是從Google驅動器獲取的。所以,首先,我們將用Colab Notebook安裝Google驅動器。

from google.colab import drivedrive.mount('/content/gdrive')現在,我們將導入所有必需的庫。

from __future__ import unicode_literals, print_function, divisionfrom io import openimport globimport osimport unicodedataimport stringimport torchimport torch.nn as nnimport randomimport timeimport mathimport matplotlib.pyplot as pltimport matplotlib.ticker as ticker下面的代碼片段將讀取數據集。

all_let = string.ascii_letters + " .,;'-"n_let = len(all_let) + 1def getFiles(path): return glob.glob(path)# Unicode字符串到ASCIIdef unicodeToAscii(s): return ''.join( c for c in unicodedata.normalize('NFD', s) if unicodedata.category(c) != 'Mn' and c in all_let )# 讀一個文件並分成幾行def getLines(filename): lines = open(filename, encoding='utf-8').read().strip().split('\n') return [unicodeToAscii(line) for line in lines]# 建立cat_lin字典,存儲每個類別的行列表cat_lin = {}all_ctg = []for filename in getFiles('gdrive/My Drive/Dataset/data/data/names/*.txt'): categ = os.path.splitext(os.path.basename(filename))[0] all_ctg.append(category) lines = getLines(filename) cat_lin[categ] = linesn_ctg = len(all_ctg)在下一步中,我們將定義module類來生成名稱。該模塊將是一個循環神經網絡。

class NameGeneratorModule(nn.Module): def __init__(self, inp_size, hid_size, op_size): super(NameGeneratorModule, self).__init__() self.hid_size = hid_size self.i2h = nn.Linear(n_ctg + inp_size + hid_size, hid_size) self.i2o = nn.Linear(n_ctg + inp_size + hid_size, op_size) self.o2o = nn.Linear(hid_size + op_size, op_size) self.dropout = nn.Dropout(0.1) self.softmax = nn.LogSoftmax(dim=1) def forward(self, category, input, hidden): inp_comb = torch.cat((category, input, hidden), 1) hidden = self.i2h(inp_comb) output = self.i2o(inp_comb) op_comb = torch.cat((hidden, output), 1) output = self.o2o(op_comb) output = self.dropout(output) output = self.softmax(output) return output, hidden def initHidden(self): return torch.zeros(1, self.hid_size)以下函數將用於從列表中選擇隨機項,從類別中選擇隨機行

def randChoice(l): return l[random.randint(0, len(l) - 1)]def randTrainPair(): category = randChoice(all_ctg) line = randChoice(cat_lin[category]) return category, line以下函數將數據轉換為RNN模塊的兼容格式。

def categ_Tensor(categ): li = all_ctg.index(categ) tensor = torch.zeros(1, n_ctg) tensor[0][li] = 1 return tensordef inp_Tensor(line): tensor = torch.zeros(len(line), 1, n_let) for li in range(len(line)): letter = line[li] tensor[li][0][all_let.find(letter)] = 1 return tensordef tgt_Tensor(line): letter_indexes = [all_let.find(line[li]) for li in range(1, len(line))] letter_id.append(n_let - 1) # EOS return torch.LongTensor(letter_id)以下函數將創建隨機訓練示例,包括類別、輸入和目標張量。

#損失criterion = nn.NLLLoss()#學習率lr_rate = 0.0005def train(category_tensor, input_line_tensor, target_line_tensor): target_line_tensor.unsqueeze_(-1) hidden = rnn.initHidden() rnn.zero_grad() loss = 0 for i in range(input_line_tensor.size(0)): output, hidden = rnn(category_tensor, input_line_tensor[i], hidden) l = criterion(output, target_line_tensor[i]) loss += l loss.backward() for p in rnn.parameters(): p.data.add_(p.grad.data, alpha=-lr_rate) return output, loss.item() / input_line_tensor.size(0)為了顯示訓練期間的時間,定義以下函數。

def time_taken(since): now = time.time() s = now - since m = math.floor(s / 60) s -= m * 60 return '%dm %ds' % (m, s)在下一步中,我們將定義RNN模型。

model = NameGenratorModule(n_let, 128, n_let)我們將看到定義的RNN模型的參數。

print(model)

下一步,該模型將訓練10000個epoch。

epochs = 100000print_every = 5000plot_every = 500all_losses = []total_loss = 0 # 每次迭代時重置start = time.time()for iter in range(1, epochs + 1): output, loss = train(*rand_train_exp()) total_loss += loss if iter % print_every == 0: print('Time: %s, Epoch: (%d - Total Iterations: %d%%), Loss: %.4f' % (time_taken(start), iter, iter / epochs * 100, loss)) if iter % plot_every == 0: all_losses.append(total_loss / plot_every) total_loss = 0

我們將可視化訓練中的損失。

plt.figure(figsize=(7,7))plt.title("Loss")plt.plot(all_losses)plt.xlabel("Epochs")plt.ylabel("Loss")plt.show()

最後,我們將對我們的模型進行測試,以測試在給定起始字母表字母時生成屬於語言的名稱。

max_length = 20# 類別和起始字母中的示例def sample_model(category, start_letter='A'): with torch.no_grad(): # no need to track history in sampling category_tensor = categ_Tensor(category) input = inp_Tensor(start_letter) hidden = NameGenratorModule.initHidden() output_name = start_letter for i in range(max_length): output, hidden = NameGenratorModule(category_tensor, input[0], hidden) topv, topi = output.topk(1) topi = topi[0][0] if topi == n_let - 1: break else: letter = all_let[topi] output_name += letter input = inp_Tensor(letter) return output_name# 從一個類別和多個起始字母中獲取多個樣本def sample_names(category, start_letters='XYZ'): for start_letter in start_letters: print(sample_model(category, start_letter))現在,我們將檢查樣本模型,在給定語言和起始字母時生成名稱。

print("Italian:-")sample_names('Italian', 'BPRT')print("\nKorean:-")sample_names('Korean', 'CMRS')print("\nRussian:-")sample_names('Russian', 'AJLN')print("\nVietnamese:-")sample_names('Vietnamese', 'LMT')

因此,正如我們在上面看到的,我們的模型已經生成了屬於語言類別的名稱,並從輸入字母開始。

參考文獻:

Trung Tran, 「Text Generation with Pytorch」.「NLP from scratch: Generating names with a character level RNN」, PyTorch Tutorial.Francesca Paulin, 「Character-Level LSTM in PyTorch」, Kaggle.

相關焦點

  • 教程 | 如何快速訓練免費的文本生成神經網絡
    ,包括兩種類型的文本生成模型:字符級別和單詞級別的文本生成網絡。文本生成是這一波神經網絡革命中誕生的一個有趣的應用。因此,在理論上,一個經過了充分訓練的網絡可以重現它的輸入源語料,但是由於經過適當訓練的神經網絡也不是十全十美的,因此輸出文本可能會變成一個很奇怪但是效果也很好的「恐怖谷」(和人的行為很相似但不完全相同)。許多文本生成神經網絡的網上教程只是簡單複製了一個現有的 char-rnn 實現同時對輸入數據集進行了更改。
  • PyTorch:Bi-LSTM的文本生成
    —歐內斯特·海明威本博客的目的是解釋如何通過實現基於LSTMs的強大體系結構來構建文本生成的端到端模型。如前所述,NLP領域解決了大量的問題,特別是在本博客中,我們將通過使用基於深度學習的模型來解決文本生成問題,例如循環神經網絡LSTM和Bi-LSTM。同樣,我們將使用當今最複雜的框架之一來開發深度學習模型,特別是我們將使用PyTorch的LSTMCell類來開發。問題陳述給定一個文本,神經網絡將通過字符序列來學習給定文本的語義和句法。
  • 庫、教程、論文實現,這是一份超全的PyTorch資源列表(Github 2.2K星)
    地址:https://github.com/eladhoffer/convNet.pytorch12.pytorch-generative-adversarial-networks:簡單的生成對抗網絡實現。
  • Facebook開源 PyTorch版 fairseq,準確性最高、速度比循環神經網絡...
    ,比循環神經網絡的速度快了9倍,而且準確性也是現有模型中最高的。該工具包能實現 Convolutional Sequence to Sequence Learning(地址:https://arxiv.org/abs/1705.03122)中描述的全卷積模型,並能在一臺機器上進行多GPU訓練,也能在CPU和GPU上快速產生束搜索(beam search)。在開源的數據中,他們提供了英譯法和英譯德的預訓練模型。
  • 全面解讀用於文本特徵提取的神經網絡技術:從神經概率語言模型到...
    https://arxiv.org/abs/1704.08531本論文的目標是促進有關使用神經網絡架構的文本特徵提取技術的討論。本論文中所討論的研究問題關注的是當前最佳的神經網絡技術,它們已經在語言處理、語言生成、文本分類和其它計算語言學任務中被證明是有用的工具。1 動機目前基於文本的特徵提取所使用的大部分方法都依賴於相對簡單的統計技術。
  • 教程 | 如何用PyTorch實現遞歸神經網絡?
    開始 SPINN連結中的文章(https://github.com/jekbradbury/examples/tree/spinn/snli)詳細介紹了一個遞歸神經網絡的 PyTorch 實現,它具有一個循環跟蹤器(recurrent tracker)和 TreeLSTM 節點,也稱為 SPINN——SPINN 是深度學習模型用於自然語言處理的一個例子
  • 獨家 :教你用Pytorch建立你的第一個文本分類模型!
    學習如何使用PyTorch實現文本分類理解文本分類中的關鍵點學習使用壓縮填充方法在我的編程歷程中,我總是求助於最先進的架構。現在得益於深度學習框架,比如說PyTorch,Keras和 TensorFlow,實現先進的架構已經變得更簡單了。這些深度學習框架提供了一種實現複雜模型架構和算法的簡單方式,不需要你掌握大量的專業知識和編程技能。
  • 輕鬆構建 PyTorch 生成對抗網絡(GAN)
    本文的課題是用機器學習方法『模仿手寫字體』,為了完成這個課題,您將親手體驗生成對抗網絡的設計和實現。『模仿手寫字體』與人像生成的基本原理和工程流程基本是一致的,雖然它們的複雜性和精度要求有一定差距,但是通過解決『模仿手寫字體』問題,可以為生成對抗網絡的原理和工程實踐打下基礎,進而可以逐步嘗試和探索更加複雜先進的網絡架構和應用場景。《生成對抗網絡》(GAN)由 Ian Goodfellow 等人在 2014年提出,它是一種深度神經網絡架構,由一個生成網絡和一個判別網絡組成。
  • Github 2.2K星的超全PyTorch資源列表
    地址:https://github.com/eladhoffer/convNet.pytorch12.pytorch-generative-adversarial-networks:簡單的生成對抗網絡實現。
  • 獨家 | 教你用Pytorch建立你的第一個文本分類模型!
    因此,在本文中,我們將介紹解決文本分類問題的關鍵點。然後我們將在PyTorch框架實現我們的第一個文本分類器!是否聽過,循環神經網絡用來解決變長序列的問題,有沒有疑惑它是怎麼實現的?PyTorch帶來了很有用的'Packed Padding sequence',來實現動態循環神經網絡。Padding(填充)是在句子的開頭或者結尾填充額外的token的過程。由於每個句子的詞的數量不同,我們把長度不同的句子輸入,增加padding tokens,擴充以使得句子等長。
  • 從零開始實現循環神經網絡(無框架)
    >背景循環神經網絡是深度神經網絡的一種,發展於二十世紀八九十年代,隨著二十一世紀一零年代後深度學習的復興,循環神經網絡的研究與應用也走上了快車道。循環神經網絡主要應用於序列問題,如機器翻譯、文本生成、語音識別、股票預測、天氣預測等,所謂序列問題指的是問題前後存在緊密關聯,前面的一系列信息有助於解決接下去的問題,比如說相聲,捧哏說了上一句,逗哏就知道下一句要接啥,比如天氣預測,知道了過去幾個小時的天氣狀況,大概就清楚接下來幾個小時天氣狀況如何。
  • 【深度學習】PyTorch:Bi-LSTM的文本生成
    —歐內斯特·海明威❞本文的目的是解釋如何通過實現基於LSTMs的強大體系結構來構建文本生成的端到端模型。如前所述,NLP領域解決了大量的問題,特別是在本博客中,我們將通過使用基於深度學習的模型來解決文本生成問題,例如循環神經網絡LSTM和Bi-LSTM。同樣,我們將使用當今最複雜的框架之一來開發深度學習模型,特別是我們將使用PyTorch的LSTMCell類來開發。
  • 雲計算必備知識-基於PyTorch機器學習構建生成對抗網絡
    模型通過框架中(至少)兩個模塊:生成模型(Generative Model)和判別模型(Discriminative Model)的互相博弈學習產生相當好的輸出。原始 GAN 理論中,並不要求 G 和 D 都是神經網絡,只需要是能擬合相應生成和判別的函數即可。但實用中一般均使用深度神經網絡作為 G 和 D 。
  • 神經網絡解析|RNN(循環神經網絡)
    RNN是兩種神經網絡模型的縮寫,一種是遞歸神經網絡(Recursive Neural Network),一種是循環神經網絡(Recurrent Neural Network)。雖然這兩種神經網絡有著千絲萬縷的聯繫,但是本文主要討論的是第二種神經網絡模型——循環神經網絡(Recurrent Neural Network)。
  • 循環神經網絡(RNN)簡介
    下面從循環神經網絡的記憶能力、單向循環神經網絡、參數學習、長期依賴問題、工作模式及應用領域幾個方面闡述RNN。       前饋神經網絡(如CNN)是一個靜態網絡,信息的傳遞是單向的,網絡的輸出只依賴於當前的輸入,不具備記憶能力。
  • 資源 | textgenrnn:只需幾行代碼即可訓練文本生成網絡
    只需幾行代碼即可訓練文本生成網絡。項目地址:https://github.com/minimaxir/textgenrnn?reddit=1通過簡簡單單的幾行代碼,使用預訓練神經網絡生成文本,或者在任意文本數據集上訓練你自己的任意規模和複雜度的文本生成神經網絡。
  • 手把手教你用 PyTorch 快速準確地建立神經網絡
    我們將不止學習理論-還包括編寫4個不同的用例,看看PyTorch的表現如何。建立深度學習模型從來沒有這麼有趣過!內容什麼是PyTorch?PyTorch是一個基於Python的科學計算包,類似於NumPy,它具備GPU附加功能。與此同時,它也是一個深度學習框架,為實現和構建深層神經網絡體系結構提供了最大程度的靈活性和速度。
  • Pytorch中的分布式神經網絡訓練
    隨著深度學習的多項進步,複雜的網絡(例如大型transformer 網絡,更廣更深的Resnet等)已經發展起來,從而需要了更大的內存空間。 經常,在訓練這些網絡時,深度學習從業人員需要使用多個GPU來有效地訓練它們。 在本文中,我將向您介紹如何使用PyTorch在GPU集群上設置分布式神經網絡訓練。通常,分布式訓練會在有一下兩種情況。
  • 輕鬆學Pytorch –構建循環神經網絡
    大家好,使用pytorch實現簡單的人工神經網絡跟卷積神經網絡的mnist手寫識別案例之後,今天給大家分享一下如何基於循環神經網絡實現mnist手寫數字識別。這裡基於pytorch提供的函數,簡單封裝分別實現了一個RNN跟LSTM的模型,然後分別使用這兩個模型完成了mnist數字識別。下面就來說說數據集跟模型實現部分。
  • pytorch專題前言 | 為什麼要學習pytorch?
    2.為什麼要學習pytorch呢?3.學習了pytorch我怎麼應用呢?4.按照什麼順序去學習pytorch呢?5.網上那麼多資料如何選擇呢?現在開始逐一的對以上問題提出自己的看法,可能想的不夠周全,歡迎討論區一起探討!1.生物學科的朋友需要學編程麼?需要!