06_1.Pytorch中如何表示字符串、word embedding、One - hot、Embedding(Word2vec、BERT、Glove)【学习总结】
1.6.1.如何表示字符串
1.6.1.1.word embedding
1.6.1.1.1.文本表示(Representation)
1.6.1.1.2.獨熱編碼 | one-hot representation
1.6.1.1.3.整數編碼
1.6.1.1.4.什么是詞嵌入 | word embedding ?
1.6.1.1.5. 2中主流的word embedding算法
1.6.1.1.6.百度百科和維基百科
1.6.1.1.7.維基百科版本
1.6.1.2.One - hot
1.6.1.2.1.文本數據向量化
1.6.1.2.2.ont-hot編碼
1.6.1.2.3.one-hot散列技巧
1.6.1.3.Embedding
1.6.1.3.1.Word2vec
1.6.1.3.1.1.什么是Word2vec
1.6.1.3.1.2.Word2vec的2中訓練模式
1.6.1.3.1.3.Word2vec的優缺點
1.6.1.3.1.4.百度百科
1.6.1.3.2.BERT
1.6.1.3.3.Glove
1.6.1.3.3.1.什么是GloVe?
1.6.1.3.3.2.GloVe是如何實現的?
1.6.1.3.3.4.Glove與LSA、word2vec的比較
1.6.1.3.3.5.公式推導
1.6.1.如何表示字符串
主要參考博文:
https://www.bilibili.com/read/cv4053575/
https://easyai.tech/ai-definition/word-embedding/
https://easyai.tech/ai-definition/word2vec/
https://easyai.tech/ai-definition/bert/
在深度學習中字符串不好表示,要通過以下的方式來表示。
1.6.1.1.word embedding
本文轉自:https://easyai.tech/ai-definition/word-embedding/
1.6.1.1.1.文本表示(Representation)
文本是一種非結構化的數據信息,是不可以直接被計算的。
文本表示的作用就是將這些非結構化的信息轉化為結構化的信息,這樣就可以針對文本信息做計算,來完成我們日常所見到的文本分類,情感分析等任務。
文本表示的方法有很多種,下面只介紹3類方式:
1.獨熱編碼 | one-hot representation
2.整數編碼
3.詞嵌入 | word embedding
1.6.1.1.2.獨熱編碼 | one-hot representation
假設我們要計算的文本中一共出現了4個詞:貓、狗、牛、羊。向量里每一個位置都代表一個詞。所以用one-hot來表示就是:
貓: [ 1, 0 ,0 ,0 ]
狗: [ 0, 1, 0, 0 ]
牛: [ 0, 0, 1, 0 ]
羊: [ 0, 0, 0, 1 ]
但是在實際情況中,文本中很可能出現成千上萬個不同的詞,這時候向量就會非常長。其中99%以上都是0。
one-hot的缺點如下:
1.無法表達詞語之間的關系。
2.這種過于稀疏的向量,導致計算和存儲的效率都不高。
1.6.1.1.3.整數編碼
這種方法也非常好理解,用一種數字來代表一個詞,上面的例子則是:
貓: 1
狗: 2
牛: 3
羊: 4
將句子里的每個詞拼起來就是可以表示一句話的向量。
整數編碼的缺點如下:
1.無法表達詞語之間的關系
2.對于模型解釋而言,整數編碼可能具有挑戰性。
1.6.1.1.4.什么是詞嵌入 | word embedding ?
word embedding 是文本表示的一類方法。跟one-hot編碼和整數編碼的目的一樣,不過他有更多的優點。
詞嵌入并不特指某個具體的算法,跟上面2種方式相比,這種方法有幾個明顯的優勢:
1.他可以將文本通過一個低維向量來表示,不像one-hot那么長。
2.語意相似的詞在向量空間上也會比較相近。
3.通用性很強,可以用在不同的任務中。
在回顧上面的例子:
1.6.1.1.5. 2中主流的word embedding算法
?Word2vec
這是一種基于統計方法來獲得詞向量的方法,他是 2013 年由谷歌的 Mikolov 提出了一套新的詞嵌入方法。
這種算法有2種訓練模式:
1.通過上下文來預測當前詞。
2.通過當前詞來預測上下文。
?GloVe
Glove是對Word2vec方法的擴展,它將全局統計和Word2vec的基于上下文的學習結合了起來。
想要了解GloVe的三步實現方法、訓練方法、和w2c的比較。
1.6.1.1.6.百度百科和維基百科
詞向量(Word embedding),又叫Word嵌入式自然語言處理(NLP)中的一組語言建模和特征學習技術的統稱,其中來自詞匯表的單詞或短語被映射到實數的向量。從概念上講,它涉及從每個單詞一維的空間到具有更低維度的連續向量空間的數學嵌入。
生成這種映射的方法包括神經網絡,單詞共生矩陣的降維,概率模型,可解釋的知識方法,和術語的顯示表示 單詞出現的背景。
當用做底層輸入表示時,單詞和短語嵌入已經被證明可以提高NLP任務的性能,例如語法分析和情感分析。
1.6.1.1.7.維基百科版本
Word embedding 是自然語言處理中的重要環節,它是一些語言處理模型的統稱,并不具體指某種算法或模型。Word embedding 的任務是把詞轉換成可以計算的向量 。從概念上講,它涉及從每個單詞一維的空間到具有更低維度的連續向量空間的數學嵌入。
生成這種映射的方法包括神經網絡,單詞共生矩陣的降維,概率模型,可解釋的知識庫方法,和術語的顯式表示單詞出現的上下文。
當用作底層輸入表示時,單詞和短語嵌入已經被證明可以提高NLP任務的性能,例如句法分析和情感分析。
1.6.1.2.One - hot
參考博文:https://www.bilibili.com/read/cv4053575/
1.6.1.2.1.文本數據向量化
文本數據的格式是一個序列數據,常見的有單詞和字符序列。如果需要應用到深度學習網絡模型中,就需要將將這些序列進行有效編碼。
這里所謂的編碼其實就將這些單詞或者字符進行向量化。
向量化:就是將文本信息轉化為數據張量信息。主要的方法如下:
?將文本分割為單詞,并將每個單詞轉換為一個向量。
?將文本分割為字符,并將每個字符轉換為一個向量。
?提取單詞或字符的 n-gram,并將每個 n-gram 轉換為一個向量。n-gram 是多個連續單詞或字符的集合(n-gram 之間可重疊)。
上面的整個過程就是將文本信息進行單元分割。這里有幾個概念:
標記(token): 將文本分解而成的單元(單詞、字符或 n-gram)
分詞(tokenization): 將文本分解成標記的過程
向量編碼: 將向量與標記相關聯的方法
?one-hot編碼(one-hot encoding)
?標記嵌入[token embedding] 詞嵌入(word embedding)
總結文本數據向量化的三個過程:
?原始文本(原始數據)
?將文本分解成標記(標記)
?將標記進行編碼(向量編碼)
如下圖所示:
n-gram是從一個句子中提取的N個(或更少)連續單詞(或字符)的集合。
例如:“The cat sat on the mat.”
二元語法(2-gram)集合:
三元語法(3-gram)集合:
{"The", "The cat", "cat", "cat sat", "The cat sat", "sat", "sat on", "on", "cat sat on", "on the", "the", "sat on the", "the mat", "mat", "on the mat"}以上的集合又稱為詞袋,處理的是標記組成的集合.一般它往往被用于淺層的語言處理模型,而不是深度學習模型.
在使用輕量級的淺層文本處理模型時(比如 logistic 回歸和隨機森林),n-gram 是一種功能強大、不可或缺的特征工程工具。
1.6.1.2.2.ont-hot編碼
one-hot編碼是將標記轉換為向量的最常用、最基本的方法。
它將每個單詞與一個唯一的整數索引相關聯,然后將這個整數索引 i 轉換為長度為 N 的二進制向量(N 是詞表大小),這個向量只有第 i 個元素是 1,其余元素都為 0。
單詞向量化
# -*- coding: UTF-8 -*-import numpy as np# 初始化數據,每個"樣本"一個條目 samples = ['The cat sat on the mat.', 'The dog ate my homework.']# 首先,構建數據中所有token的索引 token_index = {}for sample in samples:# 通過'split'方法對樣本進行標記。實際使用時還會從樣本中刪除標點符號和特殊字符for word in sample.split():# 可以參考如下去掉非字符的'''word = word.lower()# 去掉非字母字符if not word.isalpha():new_word = filter(str.isalpha(), word)word = ''.join(list(new_word))'''# 添加索引if word not in token_index:token_index[word] = len(token_index) + 1# 接下來,對樣本進行矢量化 # 對樣本進行分詞。只考慮每個樣本前max_length個單詞 max_length = 5# 用于存儲結果 results = np.zeros((len(samples), max_length, max(token_index.values()) + 1)) for i , samples in enumerate(samples):for j , word in list(enumerate(sample.split()))[:max_length]:index = token_index.get(word)results[i, j , index] = 1print(token_index) print(results)輸出結果:
{'The': 1, 'cat': 2, 'sat': 3, 'on': 4, 'the': 5, 'mat.': 6, 'dog': 7, 'ate': 8, 'my': 9, 'homework.': 10} [[[0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0.][0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0.][0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0.][0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0.][0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]][[0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0.][0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0.][0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0.][0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0.][0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]]]字符向量化
# -*- coding: UTF-8 -*- import numpy as np import stringsamples = ['The cat sat on the mat.', 'The dog ate my homeword.']characters = string.printable token_index = dict(zip(characters, range(1, len(characters) + 1)))max_length = 50 results = np.zeros((len(samples), max_length, max(token_index.values()) + 1)) for i ,samples in enumerate(samples):for j, characters in enumerate(samples[: max_length]):index = token_index.get(characters)results[i, j ,index] = 1print(token_index) print(results)輸出結果:
{'0': 1, '1': 2, '2': 3, '3': 4, '4': 5, '5': 6, '6': 7, '7': 8, '8': 9, '9': 10, 'a': 11, 'b': 12, 'c': 13, 'd': 14, 'e': 15, 'f': 16, 'g': 17, 'h': 18, 'i': 19, 'j': 20, 'k': 21, 'l': 22, 'm': 23, 'n': 24, 'o': 25, 'p': 26, 'q': 27, 'r': 28, 's': 29, 't': 30, 'u': 31, 'v': 32, 'w': 33, 'x': 34, 'y': 35, 'z': 36, 'A': 37, 'B': 38, 'C': 39, 'D': 40, 'E': 41, 'F': 42, 'G': 43, 'H': 44, 'I': 45, 'J': 46, 'K': 47, 'L': 48, 'M': 49, 'N': 50, 'O': 51, 'P': 52, 'Q': 53, 'R': 54, 'S': 55, 'T': 56, 'U': 57, 'V': 58, 'W': 59, 'X': 60, 'Y': 61, 'Z': 62, '!': 63, '"': 64, '#': 65, '$': 66, '%': 67, '&': 68, "'": 69, '(': 70, ')': 71, '*': 72, '+': 73, ',': 74, '-': 75, '.': 76, '/': 77, ':': 78, ';': 79, '<': 80, '=': 81, '>': 82, '?': 83, '@': 84, '[': 85, '\\': 86, ']': 87, '^': 88, '_': 89, '`': 90, '{': 91, '|': 92, '}': 93, '~': 94, ' ': 95, '\t': 96, '\n': 97, '\r': 98, '\x0b': 99, '\x0c': 100} [[[0. 0. 0. ... 0. 0. 0.][0. 0. 0. ... 0. 0. 0.][0. 0. 0. ... 0. 0. 0.]...[0. 0. 0. ... 0. 0. 0.][0. 0. 0. ... 0. 0. 0.][0. 0. 0. ... 0. 0. 0.]][[0. 0. 0. ... 0. 0. 0.][0. 0. 0. ... 0. 0. 0.][0. 0. 0. ... 0. 0. 0.]...[0. 0. 0. ... 0. 0. 0.][0. 0. 0. ... 0. 0. 0.][0. 0. 0. ... 0. 0. 0.]]]keras實現的one-hot 編碼
from keras.preprocessing.text import Tokenizersamples = ['The cat sat on the mat.', 'The dog ate my homeword.']# 創建一個tokenizer,配置為只考慮前1000個最常用的單詞 tokenizer = Tokenizer(num_words=20)# 構建單詞索引 tokenizer.fit_on_texts(samples)# 將字符串轉換為整數索引組成的列表 one_hot_results = tokenizer.texts_to_matrix(samples,mode='binary')# 找回單詞索引 word_index = tokenizer.word_index print('Found %s unique tokens.' % len(word_index)) print(one_hot_results)輸出結果:
Found 9 unique tokens. [[0. 1. 1. 1. 1. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.][0. 1. 0. 0. 0. 0. 1. 1. 1. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]1.6.1.2.3.one-hot散列技巧
如果詞表中唯一標記的數量太大而無法直接處理,就可以使用這種技巧。
這種方法沒有為每個單詞顯式分配一個索引并將這些索引保存在一個字典中,而是將單詞散列編碼為固定長度的向量,通常用一個非常簡單的散列函數來實現。
優點 它避免了維護一個顯式的單詞索引,從而節省內存并允許數據的在線編碼
缺點 就是可能會出現散列沖突(hash collision),即兩個不同的單詞可能具有相同的散列值。
1.6.1.3.Embedding
1.6.1.3.1.Word2vec
以下轉自:https://easyai.tech/ai-definition/word2vec/
Word2vec是Word Embedding方式之一,屬于NLP領域。他是將此轉化為”可計算”、”結構化”的向量的過程。
這種方式在2018年之前比較主流,但是隨著BERT、GPT2.0的出現,這種方式已經不算效果最好的方法了。
1.6.1.3.1.1.什么是Word2vec
?什么是Word Embedding?
在說明 Word2vec 之前,需要先解釋一下 Word Embedding。 它就是將”不可計算” , ”非結構化” 的詞轉化為”可計算”, ”結構化”的向量。
**這一步解決的是”將現實問題轉化為數學問題”,**是人工智能非常關鍵的一步。
將現實問題轉化為數學問題只是第一步,后面還需要求解這個數學問題。所以Word Embedding的模型本身并不重要,重要的是生成出來的結果----詞向量。因為在后續的任務中會直接用到這個詞向量。
?什么是Word2vec ?
Word2vec 是 Word Embedding 的方法之一。他是 2013 年由谷歌的 Mikolov 提出了一套新的詞嵌入方法。
Word2vec在整個NLP里面的位置可以用下圖表示:
在Word2vec 出現之前,已經有一些 Word Embedding 的方法,但是之前的方法并不成熟,也沒有大規模的得到應用。
1.6.1.3.1.2.Word2vec的2中訓練模式
CBOW(Continuous Bag-of-Words Model)和Skip-gram (Continuous Skip-gram Model),是Word2vec 的兩種訓練模式。下面簡單做一下解釋:
?CBOW
通過上下文來預測當前值。相當于一句話中扣掉一個詞,讓你猜這個詞是什么。
?Skip-gram
用當前詞來預測上下文。相當于給你一個詞,讓你猜前面和后面可能出現什么詞。
?優化方法
為了提高速度,Word2Vec經常采用2中加速方式:
1.Negative Sample(負采樣)
2.Hierarchical Softmax
1.6.1.3.1.3.Word2vec的優缺點
需要說明的是:Word2vec 是上一代的產物(18 年之前),18 年之后想要得到最好的效果,已經不使用 Word Embedding 的方法了,所以也不會用到 Word2vec。
優點:
1.由于 Word2vec 會考慮上下文,跟之前的 Embedding 方法相比,效果要更好(但不如 18 年之后的方法)
2.比之前的 Embedding方 法維度更少,所以速度更快
3.通用性很強,可以用在各種 NLP 任務中
缺點:
1.由于詞和向量是一對一的關系,所以多義詞的問題無法解決。
2.Word2vec是一種靜態的方法,雖然通用性強,但是無法針對特定任務做動態優化。
1.6.1.3.1.4.百度百科
Word2vec,是一群用來產生詞向量的相關模型。這些模型為淺而雙層的神經網絡,用來訓練以重新建構語言學之詞文本。網絡以詞表現,并且需猜測相鄰位置的輸入詞,在word2vec中詞袋模型假設下,詞的順序是不重要的。訓練完成之后,word2vec模型可用來映射每個詞到一個向量,可用來表示詞對詞之間的關系,該向量為神經網絡之隱藏層。
1.6.1.3.2.BERT
此部分來自:https://easyai.tech/ai-definition/bert/
BERT的全稱是Bidirectional Encoder Representation from Transformers,即雙向Transformer的Encoder,因為decoder是不能獲要預測的信息的。模型的主要創新點都在pre-train方法上,即用了Masked LM和Next Sentence Prediction兩種方法分別捕捉詞語和句子級別的representation。
從現在的大趨勢來看,使用某種模型預訓練一個語言模型看起來是一種比較靠譜的方法。從之前AI2的 ELMo,到 OpenAI的fine-tune transformer,再到Google的這個BERT,全都是對預訓練的語言模型的應用。BERT這個模型與其它兩個不同的是
1.它在訓練雙向語言模型時以減小的概率把少量的詞替成了Mask或者另一個隨機的詞。我個人感覺這個目的在于使模型被迫增加對上下文的記憶。至于這個概率,我猜是Jacob拍腦袋隨便設的。
2.增加了一個預測下一句的loss。這個看起來就比較新奇了。
BERT模型具有以下兩個特點:
1.是這個模型非常的深,12層,并不寬(wide),中間層只有1024,而之前的Transformer模型中間層有2048。這似乎又印證了計算機圖像處理的一個觀點——深而窄 比 淺而寬 的模型更好。
2.MLM(Masked Language Model),同時利用左側和右側的詞語,這個在ELMo上已經出現了,絕對不是原創。其次,對于Mask(遮擋)在語言模型上的應用,已經被Ziang Xie提出了(我很有幸的也參與到了這篇論文中):[1703.02573] Data Noising as Smoothing in Neural Network Language Models。這也是篇巨星云集的論文:Sida Wang,Jiwei Li(香儂科技的創始人兼CEO兼史上發文最多的NLP學者),Andrew Ng,Dan Jurafsky都是Coauthor。但很可惜的是他們沒有關注到這篇論文。用這篇論文的方法去做Masking,相信BRET的能力說不定還會有提升。
?擴展閱讀
入門類文章
深入淺出解析BERT原理及其表征的內容(2019-8)
NLP新秀 : BERT的優雅解讀(2019-2-18)
[NLP] Google BERT詳解]
[NLP自然語言處理]谷歌BERT模型深度解析
擴展視野類文章
BERT王者歸來!Facebook推出RoBERTa新模型,碾壓XLNet 制霸三大排行榜(2019-7)
Bert 改進: 如何融入知識(2019-7)
詳解BERT閱讀理解(2019-7)
XLNet:運行機制及和Bert的異同比較(2019-6)
站在BERT肩膀上的NLP新秀們(PART III)(2019-6)
站在BERT肩膀上的NLP新秀們(PART II)(2019-6)
站在BERT肩膀上的NLP新秀們(PART I)(2019-6)
BERT模型在NLP中目前取得如此好的效果,那下一步NLP該何去何從?(2019-6)
Bert時代的創新:Bert應用模式比較及其它(2019-5)
進一步改進GPT和BERT:使用Transformer的語言模型(2019-5)
76分鐘訓練BERT!谷歌大腦新型優化器LAMB加速大批量訓練(2019-4-3)
知乎-如何評價 BERT 模型?
從Word Embedding到Bert模型—自然語言處理中的預訓練技術發展史
BERT 論文
深度長文:NLP的巨人肩膀(上)
NLP 的巨人肩膀(下):從 CoVe 到 BERT
實踐類文章
美團BERT的探索和實踐(2019-11)
加速 BERT 模型有多少種方法?從架構優化、模型壓縮到模型蒸餾最新進展詳解!(2019-10)
BERT, RoBERTa, DistilBERT, XLNet的用法對比(2019-9)
一大批中文(BERT等)預訓練模型等你認領!(2019-6)
[GitHub] BERT模型從訓練到部署全流程(2019-6)
Bert時代的創新:Bert在NLP各領域的應用進展(2019-6)
BERT fintune 的藝術(2019-5)
中文語料的 Bert finetune(2019-5)
BERT源碼分析PART III(2019-5)
BERT源碼分析PART II(2019-5)
BERT源碼分析PART I(2019-5)
【干貨】BERT模型的標準調優和花式調優
BERT fine-tune 終極實踐教程
詳解谷歌最強NLP模型BERT(理論+實戰)
用BRET進行多標簽文本分類(附代碼)
1.6.1.3.3.Glove
轉自:http://www.fanyeong.com/2018/02/19/glove-in-detail/
1.6.1.3.3.1.什么是GloVe?
正如論文的標題而言,GloVe的全稱叫Global Vectors for Word Representation,它是一個基于全局詞頻統計(count-based & overall statistics)的詞表征(word representation)工具,它可以把一個單詞表達成一個由實數組成的向量,這些向量捕捉到了單詞之間一些語義特性,比如相似性(similarity)、類比性(analogy)等。我們通過對向量的運算,比如歐幾里得距離或者cosine相似度,可以計算出兩個單詞之間的語義相似性。
1.6.1.3.3.2.GloVe是如何實現的?
GloVe的實現分為以下三步:
1.6.1.3.3.3.GloVe是如何訓練的?
這個圖一共采用了三個指標:語義準確度,語法準確度以及總體準確度。那么我們不難發現Vector Dimension在300時能達到最佳,而context Windows size大致在6到10之間。
1.6.1.3.3.4.Glove與LSA、word2vec的比較
LSA(Latent Semantic Analysis)是一種比較早的count-based的詞向量表征工具,它也是基于co-occurance matrix的,只不過采用了基于奇異值分解(SVD)的矩陣分解技術對大矩陣進行降維,而我們知道SVD的復雜度是很高的,所以它的計算代價比較大。還有一點是它對所有單詞的統計權重都是一致的。而這些缺點在GloVe中被一一克服了。而word2vec最大的缺點則是沒有充分利用所有的語料,所以GloVe其實是把兩者的優點結合了起來。從這篇論文給出的實驗結果來看,GloVe的性能是遠超LSA和word2vec的,但網上也有人說GloVe和word2vec實際表現其實差不多。
1.6.1.3.3.5.公式推導
總結
以上是生活随笔為你收集整理的06_1.Pytorch中如何表示字符串、word embedding、One - hot、Embedding(Word2vec、BERT、Glove)【学习总结】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么人在战争中起决定作用?
- 下一篇: 07_创建tensor,从numpy创建