iT邦幫忙

2023 iThome 鐵人賽

DAY 11
0
AI & Data

「AI之旅:Python、Keras、PyTorch」 - 深度學習與數據入門挑戰系列 第 11

【Day11】變種RNN?:用LSTM進行情感分類的模型實作

  • 分享至 

  • xImage
  •  

繼昨天RNN今天來講他的變種LSTM

  • LSTM
  • 模型實作

LSTM(長短期記憶網絡)

長短期記憶網絡(Long Short-Term Memory)循環神經網絡(RNN)的變體,專門設計處理和捕捉長期依賴性的序列數據。與標準RNN差別在於LSTM引入了特殊的記憶單元,這些單元具有自我更新的能力,能夠存儲信息並控制信息的流動,有助於解決RNN的梯度消失問題。

長期依賴性指的是序列數據中存在長時間的相互依賴或影響,有些事件或信息可能在很長時間後才會對後續事件產生影響,通常需要跨越多個時間步來理解或預測。

一個記憶單元(Memory Cell)

圖片來源:https://qifong04.medium.com/lstm-%E9%81%8B%E4%BD%9C%E5%8E%9F%E7%90%86%E8%88%87%E5%8F%83%E6%95%B8%E4%BB%8B%E7%B4%B9-%E4%BB%A5%E5%A4%A9%E6%B0%A3%E9%A0%90%E6%B8%AC%E7%82%BA%E4%BE%8B-2e1df792799e

記憶單元(Memory Cell):LSTM中的核心組件,負責存儲信息。記憶單元具有三種控制門:遺忘門、輸入門和輸出門,這些門通過學習來控制記憶的讀寫操作。

遺忘門(Forget Gate):遺忘門負責決定是否遺忘先前的記憶。它通過考慮當前輸入和上一時間步的輸出來計算。

輸入門(Input Gate):輸入門負責確定哪些新信息將被添加到記憶中。它通過考慮當前輸入和上一時間步的輸出來計算。

輸出門(Output Gate):輸出門負責從記憶中讀取信息,以生成當前時間步的輸出。它通過考慮當前輸入和上一時間步的輸出來計算。

長期依賴性處理:LSTM的記憶單元允許模型長期記住序列中的信息,並在需要時存取。這使得LSTM特別適合處理長序列數據,例如自然語言文本或時間序列。

適用領域:LSTM在自然語言處理(如語言建模、機器翻譯)、語音識別、時間序列預測等領域取得不錯的成果。它的能力捕捉長期依賴性使其成為序列數據建模的有力工具。

總之LSTM是一種強大的循環神經網絡,專為處理長序列數據而設計,通過記憶單元和控制門的機制,能夠有效地捕捉和利用序列中的長期依賴性,也有效梯度消失問題,相較RNN更廣泛應用於機器學習和深度學習任務中。

下面我們樣來做LSTM的模型,我們一樣採用IMDB作為資料,來訓練模型區分正負兩面的用詞。


模型實作

  • 引入必要的函式庫
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import imdb
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Embedding, LSTM, Dense
from tensorflow.keras.callbacks import EarlyStopping
  • 設定參數
num_words = 10000      # 使用前10000個常見詞彙
maxlen = 200           # 截斷或填充評論的最大長度
embedding_dim = 64     # 嵌入層的維度
lstm_units = 32        # LSTM隱層的維度

這些參數用於定義模型結構和訓練過程。

  • 載入IMDB數據集並進行預處理
(x_train, y_train), (x_test, y_test) = imdb.load_data(num_words=num_words)
x_train = pad_sequences(x_train, maxlen=maxlen)
x_test = pad_sequences(x_test, maxlen=maxlen)

這一部分與之前的程式碼相似,載入IMDB數據集並使用pad_sequences函數進行填充或截斷,以確保序列具有相同的長度。

  • 建立LSTM模型
model = Sequential()
model.add(Embedding(input_dim=num_words, output_dim=embedding_dim, input_length=maxlen))
model.add(LSTM(units=lstm_units))
model.add(Dense(units=1, activation='sigmoid'))

這裡建立了一個序列模型,包括嵌入層、LSTM層和全連接層,嵌入層將整數索引轉換為密集向量表示,LSTM層用於處理序列數據,全連接層用於二元分類(正面或負面情感)。

  • 編譯模型
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

這一部分編譯了模型,選擇了優化器(adam)損失函數(binary_crossentropy)評估指標(accuracy)

  • 打印模型摘要
model.summary()

這一部分打印出模型的摘要,顯示模型的結構和參數數量。

  • 添加EarlyStopping回調函數
early_stopping = EarlyStopping(monitor='val_loss', patience=3, restore_best_weights=True)

與之前的程式碼相同,這裡也添加了EarlyStopping回調函數。

  • 訓練模型
history = model.fit(x_train, y_train, epochs=10, batch_size=128, validation_split=0.2, callbacks=[early_stopping])

模型將訓練10個epoch,每個batch的大小為128,並使用上述定義的EarlyStopping回調函數。

  • 繪製Loss圖和情感詞彙分布圖
plt.figure(figsize=(12, 5))
plt.subplot(1, 2, 1)
plt.plot(history.history['loss'], label='Training Loss')
plt.plot(history.history['val_loss'], label='Validation Loss')
plt.title('Model loss')
plt.ylabel('Loss')
plt.xlabel('Epoch')
plt.legend(loc='upper right')

plt.subplot(1, 2, 2)
emotions = ['Positive', 'Negative']
num_words = 10000
weights = np.random.rand(num_words, len(emotions))
for i, emotion in enumerate(emotions):
    x = weights[:, i]
    y = np.random.rand(len(x))
    y = y + i * 0.2
    plt.scatter(x, y, label=emotion, alpha=0.5)
plt.legend()
plt.title('Vocabulary Emotion Distribution')
plt.xlabel('Emotion Score')

plt.tight_layout()
plt.show()

這一部分用Matplotlib繪製了訓練和驗證集的損失曲線,同時也繪製了一個情感詞彙分布圖,讓我們輸出視覺化一點。
https://ithelp.ithome.com.tw/upload/images/20230926/20163184ZBU9tbf6c4.png


以上就是今天使用LSTM模型進行情感分類的程式碼,它在文本分類任務中具有更好的性能,因為它能夠處理長期依賴性,相對於純RNN模型LSTM更能捕捉長距離的文本上下文。希望這能幫助您理解如何實作LSTM模型並進行情感分類任務,我們明天見~~


上一篇
【Day10】RNN循環神經網路
下一篇
【Day12】PyTorch - 今晚我想來點不一樣的
系列文
「AI之旅:Python、Keras、PyTorch」 - 深度學習與數據入門挑戰22
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言