iT邦幫忙

2023 iThome 鐵人賽

DAY 19
0
AI & Data

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

【Day19】監督學習中的Transformer模型應用於IMDB情感分類

  • 分享至 

  • xImage
  •  

前面有提到監督學習(Supervised learning)我們這裡簡單做介紹。

這裡要先提到機器學習(Machine Learning),監督學習是裡其中一種,而機器學習是一門人工智慧(Artificial Intelligence,簡稱AI)的子領域,旨在開發能夠從數據中學習並改進性能的算法和模型

監督學習(Supervised Learning)

分類(Classification):這種機器學習方法用於將輸入數據分為不同的類別或標籤。它的目標是訓練一個模型,使其能夠將新的輸入數據映射到已知的類別中。

例如可以使用分類來檢測垃圾郵件,將郵件分為“垃圾郵件”和“非垃圾郵件”,或者用於圖像分類,將圖像分為“貓”和“狗”。

迴歸(Regression):這種機器學習方法用於預測連續數值輸出。它的目標是訓練一個模型,以預測目標變數的數值,而不是類別。

例如可以使用迴歸來預測房屋價格,根據不同特徵(如面積、位置等)預測價格,或者用於股票價格預測,預測未來股價的趨勢。

無監督學習(Unsupervised Learning)

聚類(Clustering):這種機器學習方法用於將數據分成不同的群組,每個群組內的數據相似。它的目標是發現數據中的潛在結構,而無需事先知道標籤。

例如可以使用聚類來將客戶分為不同的市場區段,以更好地了解他們的需求,或者用於圖像分割,將圖像分為不同的區域。

降維(Dimensionality Reduction):這種機器學習方法用於減少數據的維度,同時保留最重要的特徵。它的目標是簡化數據,減少冗餘信息,以便更容易進行分析或視覺化。

例如主成分分析(PCA)可以將高維數據轉換為低維表示,或者使用t-SNE進行數據嵌入,以在二維空間中可視化數據分佈。

半監督學習(Semi-Supervised Learning)

這是一種結合監督和無監督學習元素的方法,通常在只有少量標記數據的情況下使用,利用無監督學習的方法來提取有用的特徵或生成偽標籤,擴展監督模型的訓練數據。

強化學習(Reinforcement Learning)

這種機器學習方法用於代理根據環境的反饋採取行動,以最大化某種獎勵信號,強化學習的代表性應用包括機器人控制,遊戲玩法和自動駕駛,通過與環境的互動來學習最佳策略。

這裡我們只對其中這幾項做簡略說明

模型實作

我們這裡以IMDB

import torch
import torch.nn as nn
import torch.optim as optim
from torchtext import data
from torchtext import datasets
from torchtext.vocab import GloVe

1. 準備IMDB資料集

# 使用TorchText的datasets.IMDB來下載並載入IMDB資料集。
TEXT = data.Field(tokenize='spacy', lower=True) # 文字字段,用於處理文字數據
LABEL = data.LabelField(dtype=torch.float) # 標籤字段,用於處理標籤數據

train_data, test_data = datasets.IMDB.splits(TEXT, LABEL) # 分割訓練與測試資料集

2. 建立資料預處理和載入器

# 定義最大詞彙量大小,建立詞彙表,載入GloVe詞向量。
MAX_VOCAB_SIZE = 25000
TEXT.build_vocab(train_data, max_size=MAX_VOCAB_SIZE, vectors=GloVe(name='6B', dim=100))
LABEL.build_vocab(train_data)

BATCH_SIZE = 64
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

train_iterator, test_iterator = data.BucketIterator.splits(
     (train_data, test_data),
     batch_size=BATCH_SIZE,
     device=device
)

使用TorchText的datasets.IMDB下載並加載IMDB數據集,分為訓練數據和測試數據。
定義了TEXT和LABEL字段,TEXT用於處理文本數據,LABEL用於處理標籤數據。
創建了數據加載器(train_iterator和test_iterator)來加載和批處理數據。

3. 建構Transformer模型

# 建立一個名為Transformer的PyTorch模型,包括詞嵌入、Transformer層和全連接層。
class Transformer(nn.Module):
     def __init__(self, vocab_size, d_model, nhead, num_encoder_layers, num_decoder_layers):
         super(Transformer, self).__init__()
         self.embedding = nn.Embedding(vocab_size, d_model) # 字嵌入層
         self.transformer = nn.Transformer(d_model, nhead, num_encoder_layers, num_decoder_layers) # Transformer層
         self.fc = nn.Linear(d_model, 1) # 全連接層

     def forward(self, src, tgt):
         src_embed = self.embedding(src)
         tgt_embed = self.embedding(tgt)
         output = self.transformer(src_embed, tgt_embed) # Transformer前向傳播
         output = self.fc(output[-1, :, :]) # 取最後一個時間步的輸出
         return output

INPUT_DIM = len(TEXT.vocab)
D_MODEL = 256
NHEAD = 8
NUM_ENCODER_LAYERS = 3
NUM_DECODER_LAYERS = 3

model = Transformer(INPUT_DIM, D_MODEL, NHEAD, NUM_ENCODER_LAYERS, NUM_DECODER_LAYERS).to(device) # 建立Transformer模型並移至GPU(如果可用)

創建一個名為Transformer的PyTorch模型,包括詞嵌入層、Transformer層和全連接層。
詞嵌入層用於將文本數據轉換為詞嵌入向量。
Transformer層實現了Transformer模型的核心結構,包括多個注意力層和位置編碼。
全連接層用於將Transformer的輸出映射到情感分類的輸出。

4. 定義損失函數和最佳化器

# 定義損失函數為BCEWithLogitsLoss(二元交叉熵損失),最佳化器為Adam。
criterion = nn.BCEWithLogitsLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

定義了二元交叉熵損失(nn.BCEWithLogitsLoss)作為損失函數。
使用Adam最佳化器(optim.Adam)來更新模型的參數。

5. 訓練模型

# 寫一個訓練函數,用於迭代訓練模型。
def train(model, iterator, optimizer, criterion):
     model.train() # 設定模型為訓練模式
     epoch_loss = 0
     for batch in iterator:
         optimizer.zero_grad() # 梯度清零
         src = batch.text
         trg = batch.label.unsqueeze(1)
         output = model(src, trg) # 模型前向傳播
         loss = criterion(output, trg) # 計算損失
         loss.backward() # 反向傳播
         optimizer.step() # 更新權重
         epoch_loss += loss.item()
     return epoch_loss / len(iterator)

N_EPOCHS = 10
for epoch in range(N_EPOCHS):
     train_loss = train(model, train_iterator, optimizer, criterion)
     print(f'Epoch: {epoch+1:02}, Train Loss: {train_loss:.3f}')

定義了一個訓練函數train,用於訓練模型。
進行多個epoch的訓練,每個epoch都計算訓練損失並打印。

6. 評估模型效能

# 編寫一個評估函數,用於評估模型在測試資料上的表現。
def evaluate(model, iterator, criterion):
     model.eval() # 設定模型為評估模式
     epoch_loss = 0
     with torch.no_grad():
         for batch in iterator:
             src = batch.text
             trg = batch.label.unsqueeze(1)
             output = model(src, trg) # 模型前向傳播
             loss = criterion(output, trg) # 計算損失
             epoch_loss += loss.item()
     return epoch_loss / len(iterator)

test_loss = evaluate(model, test_iterator, criterion)
print(f'Test Loss: {test_loss:.3f}')

定義了一個評估函數evaluate,用於評估模型在測試數據上的性能。
計算測試損失並顯示出來。

這裡我們先以IMDB做一個模型,今天就到這邊。


上一篇
【Day18】Transformer:革命性的序列建模模型
下一篇
【Day20】爬取IMDB電影評論
系列文
「AI之旅:Python、Keras、PyTorch」 - 深度學習與數據入門挑戰22
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言