引言
接上回,本文繼續說如何用TensorFlow將獨熱編碼應用到一個簡單的神經網絡中,以實現從一段隨機文本到另一段隨機文本的轉換。
步驟一:導入庫
import tensorflow as tf
import numpy as np
import random
import string
步驟二:生成隨機文本數據
用一個函數來生成隨機文本數據。
def generate_random_text(length):letters = string.ascii_lowercase + ' 'return ''.join(random.choice(letters) for i in range(length))random_text = generate_random_text(100)
print("Random Text:", random_text)
步驟三:獨熱編碼
接下來,我們將對生成的隨機文本進行獨熱編碼。為此,我們需要創建一個字符到整數的映射,并使用這個映射來構建獨熱編碼。
注:上一張我們說的是幾個分類(數字代表類別)轉為獨熱碼,那么如何將一串文本轉為獨熱碼呢?在這里我們的方法是將一串文本的每個字符都對應到一個數字(這個過程就我們叫做映射到數字,這個對應關系的表就成為詞匯表),之后從數字生成獨熱碼。把所有數字的獨熱碼放一起,就是這段文本的獨熱碼了。
chars = string.ascii_lowercase + ' '
char_to_int = {c: i for i, c in enumerate(chars)}
int_to_char = {i: c for c, i in char_to_int.items()}def one_hot_encode(text):encoded = [char_to_int[char] for char in text]return tf.one_hot(encoded, depth=len(chars))encoded_text = one_hot_encode(random_text)
步驟四:構建神經網絡模型
現在,讓我們定義一個簡單的密集神經網絡模型(后期講),它將接受獨熱編碼的文本并嘗試預測下一個字符的獨熱編碼。
model = tf.keras.Sequential([tf.keras.layers.Flatten(input_shape=(None, len(chars))),tf.keras.layers.Dense(128, activation='relu'),tf.keras.layers.Dense(len(chars), activation='softmax')
])
步驟五:訓練模型
因為作者個人感覺用隨機數據訓練沒什么意義,也擬合不出什么,所以省略了…
步驟六:模型預測與解碼
我們直接用沒訓練過的模型來預測輸入文本的輸出,并將其從獨熱編碼轉換回字符。
def decode_one_hot(output):return ''.join(int_to_char[np.argmax(out)] for out in output)# 假設我們已經訓練了模型
# predictions = model.predict(encoded_text)
# decoded_text = decode_one_hot(predictions)
# print("Decoded Text:", decoded_text)
一些話
雖然我們學了很多關于獨熱碼的知識,但是…對于我們的語言模型沒有什么卵用…我們用的是字符索引加嵌入層方法(后面細講)而不是獨熱碼,具體原因:
獨熱碼(One-Hot Encoding)
優勢:
- 簡單直觀:每個字符都由一個獨立的二進制位表示,這使得編碼非常明確和直接。
- 易于理解:模型的輸入維度與詞匯表大小直接相關,容易理解和解釋。
- 無參數共享:每個字符的表示獨立,不會受到其他字符的影響,這在某些情況下可能是有益的。
缺點:
- 維度災難:如果詞匯表很大,獨熱編碼會導致極其高維的特征空間,這會增加計算復雜性和存儲需求。
- 缺乏語義信息:獨熱編碼不包含任何關于字符之間關系的語義信息,即字符之間的相似性或關聯性完全被忽略。
- 不變性:對于字符的微小變化(如大小寫、拼寫錯誤等),獨熱編碼無法提供魯棒性。
字符索引 + 嵌入層(Character Index + Embedding Layer)
優勢:
- 維度降低:通過使用較低維度的密集向量來表示字符,嵌入層可以有效減少模型的輸入維度。
- 捕獲語義信息:嵌入層可以學習字符之間的語義關系,使得相似的字符在嵌入空間中擁有相似的表示。
- 參數共享:嵌入層中的參數是在所有字符之間共享的,這可以減少模型的總參數數量,提高泛化能力。
- 魯棒性:嵌入層可以對字符的小變化具有一定的魯棒性,例如拼寫錯誤或大小寫變化。
缺點:
- 需要大量數據:為了有效地學習嵌入,通常需要大量的訓練數據。
- 調參復雜:嵌入層的維度和其他超參數需要仔細調整,以找到最佳配置。
- 黑盒性質:嵌入層學到的表示可能不如獨熱編碼那樣直觀易懂。
有問題可以私信,看到會回復。