文章目錄[隱藏]
Eli5是一個(ge) Python 庫,它讓我們(men) 可視化機器學習(xi) 模型所做的預測,以更好地了解我們(men) 網絡的性能。這可以幫助我們(men) 了解數據的哪些部分對預測有貢獻,我們(men) 可以利用這些知識來改進我們(men) 的模型。它也可以幫助我們(men) 推廣我們(men) 的模型。
Eli5主要提供機器學習(xi) 庫(Scikit-learn、XGBoost、CatBoost、LightGBM、lightning 等)的解釋功能,對深度學習(xi) 庫支持有限。
本文首先從(cong) torchtext 模塊中獲取了IMDB評論數據集,然後將使用LIME來解釋PyTorch文本分類網絡。
步驟1:讀取數據集
加載了 IMDB 數據集創建了數據加載器,數據加載器使用逐步過程返回矢量化數據。然後利用詞頻向量化方法來轉換文本數據為(wei) 數字。
import torch import torchtext import eli5 # 訓練和測試數據集都有 25k 文本評論。數據集的標簽是“pos”(正麵評論)和“neg”(負麵評論)。 train_dataset, test_dataset = torchtext.datasets.IMDB() from torchtext.data import get_tokenizer from torchtext.vocab import build_vocab_from_iterator # 然後使用 torchtext.data 模塊中可用的 get_tokenizer() 函數創建了分詞器 tokenizer = get_tokenizer("basic_english") categories = ["Negative", "Positive"]
build_vocab_from_iterator() 函數會(hui) 考慮整個(ge) 文本語料庫中的所有單詞,這會(hui) 創建一個(ge) 非常大的詞匯表。為(wei) 了稍微減少詞匯量,我們(men) 要求它考慮在文本語料庫中出現至少 2 次的單詞。
def build_vocab(datasets): for dataset in datasets: for _, text in dataset: ## Please make a note that in dataset first item is target class and second item is text of sample. yield tokenizer(text)vocab = build_vocab_from_iterator(build_vocab([train_dataset, test_dataset]), specials=["<UNK>"], min_freq=2) vocab.set_default_index(vocab["<UNK>"])
為(wei) 了向量化輸入文本數據,我們(men) 使用了 scikit-learn 提供的 CountVectorizer。我們(men) 已經使用在之前的單元格中創建的詞匯表和分詞器初始化了 CountVectorizer 實例。
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer from torch.utils.data import DataLoader from torchtext.data.functional import to_map_style_datasetvectorizer = CountVectorizer(vocabulary=vocab.get_itos(), tokenizer=tokenizer) def vectorize_batch(batch): Y, X = list(zip(*batch)) ## Please make a Note that labels are first. X = vectorizer.transform(X).todense() Y = [0 if i=='neg' else 1 for i in Y] return torch.tensor(X, dtype=torch.float32), torch.tensor(Y)train_dataset, test_dataset = torchtext.datasets.IMDB() train_dataset, test_dataset = to_map_style_dataset(train_dataset), to_map_style_dataset(test_dataset)train_loader = DataLoader(train_dataset, batch_size=256, shuffle=True, collate_fn=vectorize_batch) test_loader = DataLoader(test_dataset, batch_size=256, collate_fn=vectorize_batch)
步驟2:定義(yi) 文本分類模型
設計了一個(ge) 包含 3 層的簡單神經網絡,用於(yu) 對 IMDB 評論進行分類。三個(ge) 密集層有 64、32 和 2 個(ge) 輸出單元。前兩(liang) 層將 relu 激活函數應用於(yu) 輸出。
from torch import nn from torch.nn import functional as F class TextClassifier(nn.Module): def __init__(self): super(TextClassifier, self).__init__() self.seq = nn.Sequential( nn.Linear(len(vocab), 64), nn.ReLU(), nn.Linear(64, 32), nn.ReLU(), nn.Linear(32, 2), #nn.Linear(64, 4), ) def forward(self, X_batch): return self.seq(X_batch)
步驟3:訓練模型
epochs初始化為(wei) 5,將學習(xi) 率初始化為(wei) 0.0001。然後初始化了網絡、交叉熵損失函數和 Adam 優(you) 化器。
def TrainModel(model, loss_fn, optimizer, train_loader, val_loader, epochs=10): for i in range(1, epochs+1): losses = [] for X, Y in tqdm(train_loader): Y_preds = model(X) loss = loss_fn(Y_preds, Y) losses.append(loss.item()) optimizer.zero_grad() loss.backward() optimizer.step() gc.collect() print("Train Loss : {:.3f}".format(torch.tensor(losses).mean())) CalcValLossAndAccuracy(model, loss_fn, val_loader) from torch.optim import Adam epochs = 5 learning_rate = 1e-4 loss_fn = nn.CrossEntropyLoss() text_classifier = TextClassifier() optimizer = Adam(text_classifier.parameters(), lr=learning_rate)TrainModel(text_classifier, loss_fn, optimizer, train_loader, test_loader, epochs)
步驟4:評價(jia) 模型精度
可以從(cong) 結果中注意到,我們(men) 的模型具有約 89% 的準確率。如果我們(men) 嚐試不同的網絡架構,可以進一步提高準確性。
from sklearn.metrics import accuracy_score, classification_report, confusion_matrixprint("Test Accuracy : {}".format(accuracy_score(Y_actual, Y_preds))) print("nClassification Report : ") print(classification_report(Y_actual, Y_preds, target_names=["Negative", "Positive"])) print("nConfusion Matrix : ") print(confusion_matrix(Y_actual, Y_preds))
Test Accuracy : 0.8896Classification Report :
precision recall f1-score support Negative 0.87 0.92 0.89 12500
Positive 0.91 0.86 0.89 12500 accuracy 0.89 25000
macro avg 0.89 0.89 0.89 25000
weighted avg 0.89 0.89 0.89 25000
步驟5:ELI5解釋網絡
創建了一個(ge) TextExplainer 實例。它具有下麵提到的我們(men) 可以調整的參數。
- n_samples - 此參數接受整數,指定將從 fit() 調用期間給定的原始輸入樣本生成的樣本數,以訓練我們的本地機器學習分類器。默認值為 5000。
- clf - 這是一個分類器,將使用為 LIME 算法生成的樣本進行訓練。LIME 算法訓練本地 ML 算法來模仿我們的神經網絡的行為。默認情況下,使用使用 SGD (SGDClassifier) 訓練的彈性網絡正則化的邏輯回歸。
使用自定義(yi) 的模型代替已有的分類器:
def predict_proba(X_docs): X_vect = torch.tensor(vectorizer.transform(X_docs).todense(), dtype=torch.float32) preds = text_classifier(X_vect) preds = F.softmax(preds, dim=-1).detach().numpy() preds = np.array([pred / pred.sum() for pred in preds]) return predsexplainer.fit(X_test[0], predict_proba)
原始代碼鏈接:https://coderzcolumn.com/tutorials/artificial-intelligence/eli5-lime-explain-pytorch-text-classification-network-predictions
評論已經被關(guan) 閉。