PyTorch翻譯官網教程-NLP FROM SCRATCH: GENERATING NAMES WITH A CHARACTER-LEVEL RNN

官網鏈接

NLP From Scratch: Generating Names with a Character-Level RNN — PyTorch Tutorials 2.0.1+cu117 documentation

使用字符級RNN生成名字

這是我們關于“NLP From Scratch”的三篇教程中的第二篇。在第一個教程中</intermediate/char_rnn_classification_tutorial> 我們使用RNN將名字按其原始語言進行分類。這一次,我們將通過語言中生成名字。

> python sample.py Russian RUS
Rovakov
Uantov
Shavakov> python sample.py German GER
Gerren
Ereng
Rosher> python sample.py Spanish SPA
Salla
Parer
Allan> python sample.py Chinese CHI
Chan
Hang
Iun

我們仍然手工制作一個帶有幾個線性層的小型RNN模型。最大的區別在于,我們不是在讀取一個名字的所有字母后預測一個類別,而是輸入一個類別并每次輸出一個字母。經常預測字符以形成語言(這也可以用單詞或其他高階結構來完成)通常被稱為“語言模型”。

推薦閱讀:

我假設你至少安裝了PyTorch,了解Python,并且理解張量:

  • PyTorch 安裝說明
  • Deep Learning with PyTorch: A 60 Minute Blitz 來開始使用PyTorch
  • Learning PyTorch with Examples pytorch使用概述
  • PyTorch for Former Torch Users 如果您是前Lua Torch用戶

了解rnn及其工作原理也很有用:

  • The Unreasonable Effectiveness of Recurrent Neural Networks 展示了一些現實生活中的例子
  • Understanding LSTM Networks 是專門關于LSTM的,但也有關于RNN的信息

我還推薦上一篇教程, NLP From Scratch: Classifying Names with a Character-Level RNN

準備數據

從這里(here)下載數據并將其解壓縮到當前目錄。

有關此過程的更多細節,請參閱最后一篇教程。簡而言之,有一堆純文本文件data/names/[Language].txt 每行有一個名稱。我們將每行分割成一個數組,將Unicode轉換為ASCII,最后得到一個字典{language: [names ...]}.

from io import open
import glob
import os
import unicodedata
import stringall_letters = string.ascii_letters + " .,;'-"
n_letters = len(all_letters) + 1 # Plus EOS markerdef findFiles(path): return glob.glob(path)# Turn a Unicode string to plain ASCII, thanks to https://stackoverflow.com/a/518232/2809427
def unicodeToAscii(s):return ''.join(c for c in unicodedata.normalize('NFD', s)if unicodedata.category(c) != 'Mn'and c in all_letters)# Read a file and split into lines
def readLines(filename):with open(filename, encoding='utf-8') as some_file:return [unicodeToAscii(line.strip()) for line in some_file]# Build the category_lines dictionary, a list of lines per category
category_lines = {}
all_categories = []
for filename in findFiles('data/names/*.txt'):category = os.path.splitext(os.path.basename(filename))[0]all_categories.append(category)lines = readLines(filename)category_lines[category] = linesn_categories = len(all_categories)if n_categories == 0:raise RuntimeError('Data not found. Make sure that you downloaded data ''from https://download.pytorch.org/tutorial/data.zip and extract it to ''the current directory.')print('# categories:', n_categories, all_categories)
print(unicodeToAscii("O'Néàl"))

輸出

# categories: 18 ['Arabic', 'Chinese', 'Czech', 'Dutch', 'English', 'French', 'German', 'Greek', 'Irish', 'Italian', 'Japanese', 'Korean', 'Polish', 'Portuguese', 'Russian', 'Scottish', 'Spanish', 'Vietnamese']
O'Neal

創建網絡

這個網絡擴展了上一篇教程的RNN(the last tutorial’s RNN),為類別張量增加了一個額外的參數,它與其他參數連接在一起。category張量是一個獨熱向量就像輸入的字母一樣。

我們將把輸出解釋為下一個字母出現的概率。采樣時,最可能的輸出字母被用作下一個輸入字母。

我添加了第二個線性層o2o(在將hidden和output結合起來之后),讓其更有影響力。還有一個dropout層,它以給定的概率(這里是0.1)隨機地將部分輸入歸零,通常用于模糊輸入以防止過擬合。在這里,我們在網絡的末尾使用它來有意地增加一些混亂和增加采樣的多樣性。

import torch
import torch.nn as nnclass RNN(nn.Module):def __init__(self, input_size, hidden_size, output_size):super(RNN, self).__init__()self.hidden_size = hidden_sizeself.i2h = nn.Linear(n_categories + input_size + hidden_size, hidden_size)self.i2o = nn.Linear(n_categories + input_size + hidden_size, output_size)self.o2o = nn.Linear(hidden_size + output_size, output_size)self.dropout = nn.Dropout(0.1)self.softmax = nn.LogSoftmax(dim=1)def forward(self, category, input, hidden):input_combined = torch.cat((category, input, hidden), 1)hidden = self.i2h(input_combined)output = self.i2o(input_combined)output_combined = torch.cat((hidden, output), 1)output = self.o2o(output_combined)output = self.dropout(output)output = self.softmax(output)return output, hiddendef initHidden(self):return torch.zeros(1, self.hidden_size)


訓練

訓練準備

首先,輔助函數獲得(類別,行)的隨機對:

import random# Random item from a list
def randomChoice(l):return l[random.randint(0, len(l) - 1)]# Get a random category and random line from that category
def randomTrainingPair():category = randomChoice(all_categories)line = randomChoice(category_lines[category])return category, line

對于每個時間步(即對于訓練詞中的每個字母),網絡的輸入將是(category, current letter, hidden state),輸出將是(next letter, next hidden state)。對于每個訓練集,我們需要類別,一組輸入字母,和一組輸出/目標字母。

由于我們預測每個時間步當前字母的下一個字母,因此字母對是一行中連續字母的組-例如,"ABCD<EOS>" 我們將創建(“A”,“B”),(“B”,“C”),(“C”,“D”),(“D”,“EOS”)。

category張量是一個獨熱張量,大小為<1 x n_categories>. 當訓練時,我們在每個時間步向網絡提供它,這是一個設計選擇,它可以作為初始隱藏狀態的一部分或其他策略。

# One-hot vector for category
def categoryTensor(category):li = all_categories.index(category)tensor = torch.zeros(1, n_categories)tensor[0][li] = 1return tensor# One-hot matrix of first to last letters (not including EOS) for input
def inputTensor(line):tensor = torch.zeros(len(line), 1, n_letters)for li in range(len(line)):letter = line[li]tensor[li][0][all_letters.find(letter)] = 1return tensor# ``LongTensor`` of second letter to end (EOS) for target
def targetTensor(line):letter_indexes = [all_letters.find(line[li]) for li in range(1, len(line))]letter_indexes.append(n_letters - 1) # EOSreturn torch.LongTensor(letter_indexes)

為了在訓練過程中方便起見,我們將創建一個randomTrainingExample函數來獲取一個隨機的(category, line)對。并將它們轉換為所需的(category, input, target)張量。

# Make category, input, and target tensors from a random category, line pair
def randomTrainingExample():category, line = randomTrainingPair()category_tensor = categoryTensor(category)input_line_tensor = inputTensor(line)target_line_tensor = targetTensor(line)return category_tensor, input_line_tensor, target_line_tensor

訓練網絡

與只使用最后一個輸出的分類相反,我們在每一步都進行預測,因此我們在每一步都計算損失。

自動梯度的魔力讓你可以簡單地將每一步的損失加起來,并在最后進行反向調用。

criterion = nn.NLLLoss()learning_rate = 0.0005def train(category_tensor, input_line_tensor, target_line_tensor):target_line_tensor.unsqueeze_(-1)hidden = rnn.initHidden()rnn.zero_grad()loss = torch.Tensor([0]) # you can also just simply use ``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 += lloss.backward()for p in rnn.parameters():p.data.add_(p.grad.data, alpha=-learning_rate)return output, loss.item() / input_line_tensor.size(0)

為了跟蹤訓練需要多長時間,我添加了一個timeSince(timestamp)函數,它返回一個人類可讀的字符串:

import time
import mathdef timeSince(since):now = time.time()s = now - sincem = math.floor(s / 60)s -= m * 60return '%dm %ds' % (m, s)

訓練和往常一樣——調用train多次并等待幾分鐘,在每個print_every示例中打印當前時間和損失,并在all_losses中保存每個plot_every示例的平均損失,以便稍后繪制。

rnn = RNN(n_letters, 128, n_letters)n_iters = 100000
print_every = 5000
plot_every = 500
all_losses = []
total_loss = 0 # Reset every ``plot_every`` ``iters``start = time.time()for iter in range(1, n_iters + 1):output, loss = train(*randomTrainingExample())total_loss += lossif iter % print_every == 0:print('%s (%d %d%%) %.4f' % (timeSince(start), iter, iter / n_iters * 100, loss))if iter % plot_every == 0:all_losses.append(total_loss / plot_every)total_loss = 0

輸出

0m 37s (5000 5%) 3.1506
1m 15s (10000 10%) 2.5070
1m 55s (15000 15%) 3.3047
2m 33s (20000 20%) 2.4247
3m 12s (25000 25%) 2.6406
3m 50s (30000 30%) 2.0266
4m 29s (35000 35%) 2.6520
5m 6s (40000 40%) 2.4261
5m 45s (45000 45%) 2.2302
6m 24s (50000 50%) 1.6496
7m 2s (55000 55%) 2.7101
7m 41s (60000 60%) 2.5396
8m 19s (65000 65%) 2.5978
8m 57s (70000 70%) 1.6029
9m 35s (75000 75%) 0.9634
10m 13s (80000 80%) 3.0950
10m 52s (85000 85%) 2.0512
11m 30s (90000 90%) 2.5302
12m 8s (95000 95%) 3.2365
12m 47s (100000 100%) 1.7113

繪制損失

繪制all_losses的歷史損失圖顯示了網絡的學習情況:

import matplotlib.pyplot as pltplt.figure()
plt.plot(all_losses)

輸出

[<matplotlib.lines.Line2D object at 0x7fa0159af880>]

網絡采樣

為了進行示例,我們給網絡一個字母并詢問下一個字母是什么,將其作為下一個字母輸入,并重復直到EOS令牌。

  • 為輸入類別、起始字母和空隱藏狀態創建張量
  • 創建一個以字母開頭的字符串output_name
  • 最大輸出長度
    • 將當前的字母提供給網絡
    • 從最高輸出中獲取下一個字母,以及下一個隱藏狀態
    • 如果字母是EOS,就停在這里
    • 如果是普通字母,添加到output_name并繼續
  • 返回最終名稱

與其給它一個起始字母,另一種策略是在訓練中包含一個“字符串起始”標記,并讓網絡選擇自己的起始字母。

max_length = 20# Sample from a category and starting letter
def sample(category, start_letter='A'):with torch.no_grad():  # no need to track history in samplingcategory_tensor = categoryTensor(category)input = inputTensor(start_letter)hidden = rnn.initHidden()output_name = start_letterfor i in range(max_length):output, hidden = rnn(category_tensor, input[0], hidden)topv, topi = output.topk(1)topi = topi[0][0]if topi == n_letters - 1:breakelse:letter = all_letters[topi]output_name += letterinput = inputTensor(letter)return output_name# Get multiple samples from one category and multiple starting letters
def samples(category, start_letters='ABC'):for start_letter in start_letters:print(sample(category, start_letter))samples('Russian', 'RUS')samples('German', 'GER')samples('Spanish', 'SPA')samples('Chinese', 'CHI')

輸出

Rovaki
Uarinovev
Shinan
Gerter
Eeren
Roune
Santera
Paneraz
Allan
Chin
Han
Ion

練習

  • 嘗試使用不同數據集category -> line,例如,
    • Fictional series -> Character name
    • Part of speech -> Word
    • Country -> City
  • 使用“start of sentence”標記,這樣就可以在不選擇起始字母的情況下進行抽樣
  • 擁有一個更大的和/或更好的網絡,可以獲得更好的結果
    • 嘗試使用 nn.LSTM nn.GRU 網絡層
    • 將這些RNN組合成一個更高級的網絡

    ?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/38693.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/38693.shtml
英文地址,請注明出處:http://en.pswp.cn/news/38693.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ChatGPT爆火,會給教育帶來什么樣的影響或者沖擊?

近來&#xff0c;人工智能聊天機器人ChatGPT連上熱搜&#xff0c;火爆全網。ChatGPT擁有強大的信息整合能力、自然語言處理能力&#xff0c;可謂是“上知天文&#xff0c;下知地理”&#xff0c;而且還能根據要求進行聊天、撰寫文章等。 ChatGPT一經推出&#xff0c;便迅速在社…

stop job is running for Advanced key-value store

今天虛擬機磁盤撐滿了&#xff0c;本來還能湊合運行&#xff0c;結果重啟了下&#xff0c;就報了這個 stop job is running for Advanced key-value store (1min 59s / no limit) 解決方式很簡單&#xff0c; 1、虛擬機關電源&#xff0c;任務管理器&#xff0c;關閉VM&#x…

OpenCV-Python中的圖像處理-圖像直方圖

OpenCV-Python中的圖像處理-圖像直方圖 圖像直方圖統計直方圖繪制直方圖Matplotlib繪制灰度直方圖Matplotlib繪制RGB直方圖 使用掩膜統計直方圖直方圖均衡化Numpy圖像直方圖均衡化OpenCV中的直方圖均衡化CLAHE 有限對比適應性直方圖均衡化 2D直方圖OpenCV中的2D直方圖Numpy中2D…

當Visual Studio遇到 “當前不會命中斷點.還沒有為該文檔加載任何符號“的情況

1.配置項目調試路徑&#xff1a; 2.問題解決方案&#xff1a; VS配置調試路徑不是默認路徑時&#xff0c;需要看生成的文件是否在配置路徑內&#xff0c;如果不在的話&#xff0c;可能發生"當前不會命中斷點.還沒有為該文檔加載任何符號"的情況&#xff1b; 右鍵項…

Kotlin語法

整理關鍵語法列表如下&#xff1a; https://developer.android.com/kotlin/interop?hlzh-cn官方指導鏈接 語法形式 說明 println("count ${countnum}")字符串里取值運算 val count 2 var sum 0 類型自動推導 val 定義只讀變量&#xff0c;優先 var定義可變變量…

計算機競賽 python+opencv+深度學習實現二維碼識別

0 前言 &#x1f525; 優質競賽項目系列&#xff0c;今天要分享的是 &#x1f6a9; pythonopencv深度學習實現二維碼識別 &#x1f947;學長這里給一個題目綜合評分(每項滿分5分) 難度系數&#xff1a;3分工作量&#xff1a;3分創新點&#xff1a;3分 該項目較為新穎&…

HotSpot虛擬機之字節碼執行引擎

目錄 一、棧幀 1. 棧幀結構 2. 基于棧的解釋執行過程 二、方法調用 1. 方法調用指令 2. 分派 三、動態類型語言 四、參考資料 一、棧幀 1. 棧幀結構 棧幀是Java虛擬機棧進行方法調用和執行的數據結構&#xff0c;是方法最基本的執行單元&#xff0c;是棧的元素。一個棧…

【環境配置】Windows10終端和VSCode下能夠直接打開Anaconda-Prompt

很多小伙伴在 Windows 下做深度學習開發的時候&#xff0c;遇到終端沒有在 Linux 那么方便&#xff0c;那么我們現在就可以來設置一下&#xff1b;這樣我們也可以在文件夾內部右鍵打開終端&#xff0c;也可以在 VS Code 里面新建一個虛擬環境的控制臺&#xff1b;這里主要是針對…

佛祖保佑,永不宕機,永無bug

當我們的程序編譯通過&#xff0c;能預防的bug也都預防了&#xff0c;其它的就只能交給天意了。當然請求佛祖的保佑也是必不可少的。 下面是一些常用的保佑圖&#xff1a; 佛祖保佑圖 ——————————————————————————————————————————…

【c語言】動態內存管理(超詳細)

他治愈了身邊所有人&#xff0c;唯獨沒有治愈他自己—超脫 csdn上的朋友你們好呀&#xff01;&#xff01;今天給大家分享的是動態內存管理 &#x1f440;為什么存在動態內存分配 我們定義的局部變量在棧區創建 int n 4;//在棧上開辟4個字節大小int arr[10] { 0 };//在棧上開…

Android Socket使用TCP協議實現手機投屏

本節主要通過實戰來了解Socket在TCP/IP協議中充當的是一個什么角色&#xff0c;有什么作用。通過Socket使用TCP協議實現局域網內手機A充當服務端&#xff0c;手機B充當客戶端&#xff0c;手機B連接手機A&#xff0c;手機A獲取屏幕數據轉化為Bitmap&#xff0c;通過Socket傳遞個…

Excel設置某列或者某行不某行不可以編輯,只讀屬性

設置單元格只讀的三種方式: 1、通過單元格只讀按鈕&#xff0c;設置為只為 設置行或者列的只讀屬性&#xff0c;可以設置整行或者整列只讀 2、設置單元格編輯控件為標簽控件(標簽控件不可編輯) 3、通過鎖定行&#xff0c;鎖定行的修改。鎖定的行與只讀行的區別在于鎖定的行不…

電子商務環境下旅游價值鏈

邁克爾 ? 波特(Michael E. Porter)在其《競爭優勢》一書中提出了“價值鏈” 的概念&#xff0c;并認為一家企業最核心的競爭優勢在于對價值鏈的設計。雖然邁克爾 ? 波 特提出的價值鏈主要是針對企業內部的價值鏈&#xff0c;但他視價值鏈為一系列連續完成的 活動&#xff…

openGauss學習筆記-40 openGauss 高級數據管理-鎖

文章目錄 openGauss學習筆記-40 openGauss 高級數據管理-鎖40.1 語法格式40.2 參數說明40.3 示例 openGauss學習筆記-40 openGauss 高級數據管理-鎖 如果需要保持數據庫數據的一致性&#xff0c;可以使用LOCK TABLE來阻止其他用戶修改表。 例如&#xff0c;一個應用需要保證表…

GPT垂直領域相關模型 現有的開源領域大模型

對于ToC端來說&#xff0c;廣大群眾的口味已經被ChatGPT給養叼了&#xff0c;市場基本上被ChatGPT吃的干干凈凈。雖然國內大廠在緊追不舍&#xff0c;但目前絕大多數都還在實行內測機制&#xff0c;大概率是不會廣泛開放的&#xff08;畢竟&#xff0c;各大廠還是主盯ToB、ToG市…

C/C++ 注意點補充

C/C 注意點補充 函數缺省 函數缺省 https://blog.csdn.net/xinger_28/article/details/83898804 // 是的&#xff0c;C語言中的函數不支持直接定義缺省參數。在你提供的代碼中&#xff0c;函數DelayXms沒有定義缺省參數。缺省參數只在一些高級編程語言中&#xff08;如C&…

flutter

1.dart語言學習 dart在線編輯器 //第一段dart代碼 void main() {ceshi c new ceshi(1,2);print(c.right);c.right 2;print(c.right);print(c.bottom);c.bottom 4;print(c.bottom); }class ceshi {num left, top;ceshi(this.left, this.top);num get right > left top;…

視頻集中存儲安防監控平臺EasyCVR優化AI硬件接入時的通道顯示異常問題

安防視頻監控平臺視頻集中存儲EasyCVR可拓展性強、視頻能力靈活、部署輕快&#xff0c;可支持的主流標準協議有國標GB28181、RTSP/Onvif、RTMP等&#xff0c;以及支持廠家私有協議與SDK接入&#xff0c;包括海康Ehome、海大宇等設備的SDK等。 安防監控視頻云存儲平臺EasyCVR既具…

【Python國內源】pip換源終極方法【Windows】

1、為什么要pip換源下載 安裝第三方庫時&#xff0c;很多庫來自于國外&#xff0c;下載速度慢得感人&#xff01; 2、常見的國內源 https://pypi.tuna.tsinghua.edu.cn/simple #清華 http://mirrors.aliyun.com/pypi/simple/ #阿里云 https://pypi.mirrors.ustc.e…

go_細節注意

go細節 一、使用指針接受者和不使用指針接受者1&#xff0c;不使用指針接受者&#xff1a;2&#xff0c;使用指針接受者3&#xff0c;區別與優劣勢 一、使用指針接受者和不使用指針接受者 1&#xff0c;不使用指針接受者&#xff1a; func (d dog) move() {fmt.Println("…