0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

PyTorch教程-15.6. 子詞嵌入

jf_pJlTbmA9 ? 來源:PyTorch ? 作者:PyTorch ? 2023-06-05 15:44 ? 次閱讀

在英語中,諸如“helps”、“helped”和“helping”之類的詞是同一個詞“help”的變形形式?!癲og”與“dogs”的關(guān)系與“cat”與“cats”的關(guān)系相同,“boy”與“boyfriend”的關(guān)系與“girl”與“girlfriend”的關(guān)系相同。在法語和西班牙語等其他語言中,許多動詞有超過 40 種變形形式,而在芬蘭語中,一個名詞可能有多達(dá) 15 種格。在語言學(xué)中,形態(tài)學(xué)研究詞的形成和詞的關(guān)系。然而,word2vec 和 GloVe 都沒有探索單詞的內(nèi)部結(jié)構(gòu)。

15.6.1。fastText 模型

回想一下單詞在 word2vec 中是如何表示的。在skip-gram模型和連續(xù)詞袋模型中,同一個詞的不同變形形式直接由不同的向量表示,沒有共享參數(shù)。為了使用形態(tài)信息,fastText 模型提出了一種子詞嵌入方法,其中一個子詞是一個字符n-gram (Bojanowski等人,2017 年)。與學(xué)習(xí)詞級向量表示不同,fastText 可以被視為子詞級 skip-gram,其中每個中心詞由其子詞向量的總和表示。

讓我們舉例說明如何使用單詞“where”為 fastText 中的每個中心詞獲取子詞。首先,在單詞的首尾添加特殊字符“<”和“>”,以區(qū)別于其他子詞的前綴和后綴。然后,提取字符n-克從字。例如,當(dāng)n=3,我們得到所有長度為 3 的子詞:“”,以及特殊子詞“”。

在 fastText 中,對于任何單詞w, 表示為Gw其所有長度在 3 到 6 之間的子字及其特殊子字的并集。詞匯表是所有詞的子詞的并集。出租zg是子詞的向量g在字典中,向量vw為詞w作為 skip-gram 模型中的中心詞的是其子詞向量的總和:

(15.6.1)vw=∑g∈Gwzg.

fastText 的其余部分與 skip-gram 模型相同。與skip-gram模型相比,fastText中的詞匯量更大,導(dǎo)致模型參數(shù)更多。此外,為了計算一個詞的表示,必須將其所有子詞向量相加,從而導(dǎo)致更高的計算復(fù)雜度。然而,由于具有相似結(jié)構(gòu)的詞之間的子詞共享參數(shù),稀有詞甚至詞匯表外的詞可能會在 fastText 中獲得更好的向量表示。

15.6.2。字節(jié)對編碼

在 fastText 中,所有提取的子詞都必須具有指定的長度,例如3到6,因此無法預(yù)定義詞匯量大小。為了允許在固定大小的詞匯表中使用可變長度的子詞,我們可以應(yīng)用一種稱為字節(jié)對編碼(BPE) 的壓縮算法來提取子詞 ( Sennrich et al. , 2015 )。

字節(jié)對編碼對訓(xùn)練數(shù)據(jù)集進(jìn)行統(tǒng)計分析,以發(fā)現(xiàn)單詞中的常見符號,例如任意長度的連續(xù)字符。從長度為 1 的符號開始,字節(jié)對編碼迭代地合并最頻繁的一對連續(xù)符號以產(chǎn)生新的更長的符號。請注意,為了提高效率,不考慮跨越單詞邊界的對。最后,我們可以使用子詞這樣的符號來分詞。字節(jié)對編碼及其變體已用于流行的自然語言處理預(yù)訓(xùn)練模型中的輸入表示,例如 GPT-2 (Radford等人,2019 年)和 RoBERTa (Liu等人,2019 年). 下面,我們將說明字節(jié)對編碼的工作原理。

首先,我們將符號詞匯表初始化為所有英文小寫字符、一個特殊的詞尾符號'_'和一個特殊的未知符號'[UNK]'。

import collections

symbols = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
      'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
      '_', '[UNK]']

import collections

symbols = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
      'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
      '_', '[UNK]']

由于我們不考慮跨越單詞邊界的符號對,我們只需要一個字典raw_token_freqs將單詞映射到它們在數(shù)據(jù)集中的頻率(出現(xiàn)次數(shù))。請注意,特殊符號'_'附加到每個單詞,以便我們可以輕松地從輸出符號序列(例如,“a_ tall er_ man”)中恢復(fù)單詞序列(例如,“a taller man”)。由于我們從僅包含單個字符和特殊符號的詞匯表開始合并過程,因此在每個單詞中的每對連續(xù)字符之間插入空格(字典的鍵token_freqs)。換句話說,空格是單詞中符號之間的分隔符。

raw_token_freqs = {'fast_': 4, 'faster_': 3, 'tall_': 5, 'taller_': 4}
token_freqs = {}
for token, freq in raw_token_freqs.items():
  token_freqs[' '.join(list(token))] = raw_token_freqs[token]
token_freqs

{'f a s t _': 4, 'f a s t e r _': 3, 't a l l _': 5, 't a l l e r _': 4}

raw_token_freqs = {'fast_': 4, 'faster_': 3, 'tall_': 5, 'taller_': 4}
token_freqs = {}
for token, freq in raw_token_freqs.items():
  token_freqs[' '.join(list(token))] = raw_token_freqs[token]
token_freqs

{'f a s t _': 4, 'f a s t e r _': 3, 't a l l _': 5, 't a l l e r _': 4}

我們定義了以下get_max_freq_pair函數(shù),該函數(shù)返回單詞中出現(xiàn)頻率最高的一對連續(xù)符號,其中單詞來自輸入字典的鍵token_freqs。

def get_max_freq_pair(token_freqs):
  pairs = collections.defaultdict(int)
  for token, freq in token_freqs.items():
    symbols = token.split()
    for i in range(len(symbols) - 1):
      # Key of `pairs` is a tuple of two consecutive symbols
      pairs[symbols[i], symbols[i + 1]] += freq
  return max(pairs, key=pairs.get) # Key of `pairs` with the max value

def get_max_freq_pair(token_freqs):
  pairs = collections.defaultdict(int)
  for token, freq in token_freqs.items():
    symbols = token.split()
    for i in range(len(symbols) - 1):
      # Key of `pairs` is a tuple of two consecutive symbols
      pairs[symbols[i], symbols[i + 1]] += freq
  return max(pairs, key=pairs.get) # Key of `pairs` with the max value

作為一種基于連續(xù)符號頻率的貪婪方法,字節(jié)對編碼將使用以下merge_symbols函數(shù)合并最頻繁的一對連續(xù)符號以產(chǎn)生新的符號。

def merge_symbols(max_freq_pair, token_freqs, symbols):
  symbols.append(''.join(max_freq_pair))
  new_token_freqs = dict()
  for token, freq in token_freqs.items():
    new_token = token.replace(' '.join(max_freq_pair),
                 ''.join(max_freq_pair))
    new_token_freqs[new_token] = token_freqs[token]
  return new_token_freqs

def merge_symbols(max_freq_pair, token_freqs, symbols):
  symbols.append(''.join(max_freq_pair))
  new_token_freqs = dict()
  for token, freq in token_freqs.items():
    new_token = token.replace(' '.join(max_freq_pair),
                 ''.join(max_freq_pair))
    new_token_freqs[new_token] = token_freqs[token]
  return new_token_freqs

現(xiàn)在我們在字典的鍵上迭代執(zhí)行字節(jié)對編碼算法token_freqs。在第一次迭代中,出現(xiàn)頻率最高的一對連續(xù)符號是't'和'a',因此字節(jié)對編碼將它們合并以產(chǎn)生新的符號'ta'。在第二次迭代中,字節(jié)對編碼繼續(xù)合并'ta'并 'l'產(chǎn)生另一個新符號'tal'。

num_merges = 10
for i in range(num_merges):
  max_freq_pair = get_max_freq_pair(token_freqs)
  token_freqs = merge_symbols(max_freq_pair, token_freqs, symbols)
  print(f'merge #{i + 1}:', max_freq_pair)

merge #1: ('t', 'a')
merge #2: ('ta', 'l')
merge #3: ('tal', 'l')
merge #4: ('f', 'a')
merge #5: ('fa', 's')
merge #6: ('fas', 't')
merge #7: ('e', 'r')
merge #8: ('er', '_')
merge #9: ('tall', '_')
merge #10: ('fast', '_')

num_merges = 10
for i in range(num_merges):
  max_freq_pair = get_max_freq_pair(token_freqs)
  token_freqs = merge_symbols(max_freq_pair, token_freqs, symbols)
  print(f'merge #{i + 1}:', max_freq_pair)

merge #1: ('t', 'a')
merge #2: ('ta', 'l')
merge #3: ('tal', 'l')
merge #4: ('f', 'a')
merge #5: ('fa', 's')
merge #6: ('fas', 't')
merge #7: ('e', 'r')
merge #8: ('er', '_')
merge #9: ('tall', '_')
merge #10: ('fast', '_')

在字節(jié)對編碼的 10 次迭代之后,我們可以看到該列表 symbols現(xiàn)在包含 10 個以上的符號,這些符號是從其他符號迭代合并而來的。

print(symbols)

['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '_', '[UNK]', 'ta', 'tal', 'tall', 'fa', 'fas', 'fast', 'er', 'er_', 'tall_', 'fast_']

print(symbols)

['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '_', '[UNK]', 'ta', 'tal', 'tall', 'fa', 'fas', 'fast', 'er', 'er_', 'tall_', 'fast_']

對于在字典的鍵中指定的相同數(shù)據(jù)集 raw_token_freqs,數(shù)據(jù)集中的每個單詞現(xiàn)在都被子詞“fast_”、“fast”、“er_”、“tall_”和“tall”分割為字節(jié)對編碼的結(jié)果算法。例如,單詞“faster_”和“taller_”分別被分割為“fast er_”和“tall er_”。

print(list(token_freqs.keys()))

['fast_', 'fast er_', 'tall_', 'tall er_']

print(list(token_freqs.keys()))

['fast_', 'fast er_', 'tall_', 'tall er_']

請注意,字節(jié)對編碼的結(jié)果取決于所使用的數(shù)據(jù)集。我們還可以使用從一個數(shù)據(jù)集學(xué)習(xí)的子詞來分割另一個數(shù)據(jù)集的詞。作為一種貪婪的方法,以下 segment_BPE函數(shù)嘗試將輸入?yún)?shù)中的單詞分解為最長可能的子詞symbols。

def segment_BPE(tokens, symbols):
  outputs = []
  for token in tokens:
    start, end = 0, len(token)
    cur_output = []
    # Segment token with the longest possible subwords from symbols
    while start < len(token) and start < end:
      if token[start: end] in symbols:
        cur_output.append(token[start: end])
        start = end
        end = len(token)
      else:
        end -= 1
    if start < len(token):
      cur_output.append('[UNK]')
    outputs.append(' '.join(cur_output))
  return outputs

def segment_BPE(tokens, symbols):
  outputs = []
  for token in tokens:
    start, end = 0, len(token)
    cur_output = []
    # Segment token with the longest possible subwords from symbols
    while start < len(token) and start < end:
      if token[start: end] in symbols:
        cur_output.append(token[start: end])
        start = end
        end = len(token)
      else:
        end -= 1
    if start < len(token):
      cur_output.append('[UNK]')
    outputs.append(' '.join(cur_output))
  return outputs

在下文中,我們使用symbols從上述數(shù)據(jù)集中學(xué)習(xí)的列表中的子詞來分割tokens代表另一個數(shù)據(jù)集。

tokens = ['tallest_', 'fatter_']
print(segment_BPE(tokens, symbols))

['tall e s t _', 'fa t t er_']

tokens = ['tallest_', 'fatter_']
print(segment_BPE(tokens, symbols))

['tall e s t _', 'fa t t er_']

15.6.3。概括

fastText 模型提出了一種子詞嵌入方法。基于 word2vec 中的 skip-gram 模型,它將中心詞表示為其子詞向量的總和。

字節(jié)對編碼對訓(xùn)練數(shù)據(jù)集進(jìn)行統(tǒng)計分析,以發(fā)現(xiàn)單詞中的常見符號。作為一種貪婪的方法,字節(jié)對編碼迭代地合并最頻繁的一對連續(xù)符號。

子詞嵌入可以提高罕見詞和詞典外詞的表示質(zhì)量。

15.6.4。練習(xí)

例如,大約有3×108可能的 6-英語克。當(dāng)子詞太多時會出現(xiàn)什么問題?如何解決這個問題?提示:參考 fastText 論文(Bojanowski et al. , 2017)第 3.2 節(jié)的結(jié)尾。

如何設(shè)計基于連續(xù)詞袋模型的子詞嵌入模型?

獲得尺寸詞匯表m, 當(dāng)初始符號詞匯量為n?

如何擴(kuò)展字節(jié)對編碼的思想來提取短語?

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • pytorch
    +關(guān)注

    關(guān)注

    2

    文章

    794

    瀏覽量

    13010
收藏 人收藏

    評論

    相關(guān)推薦

    Pytorch入門之的基本操作

    Pytorch入門之基本操作
    發(fā)表于 05-22 17:15

    PyTorch如何入門

    PyTorch 入門實戰(zhàn)(一)——Tensor
    發(fā)表于 06-01 09:58

    Pytorch代碼移植嵌入式開發(fā)筆記,錯過絕對后悔

    @[TOC]Pytorch 代碼移植嵌入式開發(fā)筆記目前在做開發(fā)完成后的AI模型移植到前端的工作。 由于硬件設(shè)施簡陋,需要把代碼和算法翻譯成基礎(chǔ)加乘算法并輸出每個環(huán)節(jié)參數(shù)。記錄幾點實用技巧以及項目
    發(fā)表于 11-08 08:24

    Pytorch模型如何通過paddlelite部署到嵌入式設(shè)備?

    Pytorch模型如何通過paddlelite部署到嵌入式設(shè)備?
    發(fā)表于 12-23 09:38

    Pytorch AI語音助手

    想做一個Pytorch AI語音助手,有沒有好的思路呀?
    發(fā)表于 03-06 13:00

    如何安裝TensorFlow2 Pytorch?

    如何安裝TensorFlow2 Pytorch
    發(fā)表于 03-07 07:32

    ch582做的藍(lán)牙鍵盤,無法連iphone手機(jī)怎么解決?

    用ch582做的藍(lán)牙鍵盤鼠標(biāo),無法連iphone12、13.但是iphone6、7可以。ios版本都是最新15.6.看看是否LIB庫問題。我現(xiàn)在用的是你們最新的7月15號發(fā)布的最新LIB庫
    發(fā)表于 09-21 07:35

    通過Cortex來非常方便的部署PyTorch模型

    該框架的 python 風(fēng)格,其學(xué)習(xí)曲線的溫和性,以及它對快速和簡單原型的方便實現(xiàn),使 PyTorch 明顯成為研究人員的最愛。因此,它正在推動一些最酷的機(jī)器學(xué)習(xí)項目:Transformers
    發(fā)表于 11-01 15:25

    如何往星光2板子里裝pytorch?

    如題,想先gpu版本的pytorch只安裝cpu版本的pytorch,pytorch官網(wǎng)提供了基于conda和pip兩種安裝方式。因為咱是risc架構(gòu)沒對應(yīng)的conda,而使用pip安裝提示也沒有
    發(fā)表于 09-12 06:30

    駐留特征在電話語音確認(rèn)中的應(yīng)用

    語速和插入刪除錯誤是導(dǎo)致自動電話轉(zhuǎn)接系統(tǒng)發(fā)生錯誤的重要原因。該文給出一種基于似然比(LLR)和駐留特征融合的語音確認(rèn)方法減少上述錯誤。提出基于最小分類錯誤準(zhǔn)則
    發(fā)表于 04-02 08:37 ?17次下載

    關(guān)于GN-GloVe的嵌入技術(shù)詳解

    帶有這樣的偏見的嵌入模型,會給下游的NLP應(yīng)用帶來嚴(yán)重問題。例如,基于嵌入技術(shù)的簡歷自動篩選系統(tǒng)或工作自動推薦系統(tǒng),會歧視某種性別的候選人(候選人的姓名反映了性別)。除了造成這種明
    的頭像 發(fā)表于 09-23 09:25 ?3761次閱讀

    PyTorch教程15.5之帶全局向量的嵌入(GloVe)

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程15.5之帶全局向量的嵌入(GloVe).pdf》資料免費下載
    發(fā)表于 06-05 11:01 ?0次下載
    <b class='flag-5'>PyTorch</b>教程15.5之帶全局向量的<b class='flag-5'>詞</b><b class='flag-5'>嵌入</b>(GloVe)

    PyTorch教程15.6之子嵌入

    電子發(fā)燒友網(wǎng)站提供《PyTorch教程15.6之子嵌入.pdf》資料免費下載
    發(fā)表于 06-05 11:02 ?0次下載
    <b class='flag-5'>PyTorch</b>教程<b class='flag-5'>15.6</b>之子<b class='flag-5'>詞</b><b class='flag-5'>嵌入</b>

    PyTorch教程-15.5。帶全局向量的嵌入 (GloVe)

    15.5。帶全局向量的嵌入 (GloVe)? Colab [火炬]在 Colab 中打開筆記本 Colab [mxnet] Open the notebook in Colab
    的頭像 發(fā)表于 06-05 15:44 ?406次閱讀

    2.0優(yōu)化PyTorch推理與AWS引力處理器

    2.0優(yōu)化PyTorch推理與AWS引力處理器
    的頭像 發(fā)表于 08-31 14:27 ?508次閱讀
    2.0優(yōu)化<b class='flag-5'>PyTorch</b>推理與AWS引力<b class='flag-5'>子</b>處理器