File size: 6,077 Bytes
35b68c1 6a7e30d 35b68c1 7827446 35b68c1 7827446 35b68c1 8406021 35b68c1 588b770 35b68c1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 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 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# pip section :)
#!pip install -q transformers datasets gradio
# imports section
import torch
import torch.nn as nn
from transformers import RobertaTokenizer, RobertaModel
from datasets import load_dataset
import gradio as gr
import numpy as np
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
print("Using:", device)
# setup dataset
from datasets import load_dataset
dataset = load_dataset("stanfordnlp/imdb")
# setup tokenizer and dataset
tokenizer = RobertaTokenizer.from_pretrained("roberta-base")
dataset = load_dataset("imdb")
def tokenize(batch):
return tokenizer(batch["text"], padding="max_length", truncation=True, max_length=128)
encoded_dataset = dataset.map(tokenize, batched=True)
encoded_dataset.set_format(type="torch", columns=["input_ids", "attention_mask", "label"])
# Roberta + BiLSTM + Attention setup
class RobertaBiLSTMAttention(nn.Module):
def __init__(self, hidden_dim=128, num_labels=2):
super().__init__()
self.roberta = RobertaModel.from_pretrained("roberta-base")
self.lstm = nn.LSTM(768, hidden_dim, batch_first=True, bidirectional=True)
self.attn = nn.Linear(hidden_dim * 2, 1)
self.dropout = nn.Dropout(0.3)
self.fc = nn.Linear(hidden_dim * 2, num_labels)
def forward(self, input_ids, attention_mask):
with torch.no_grad():
roberta_out = self.roberta(input_ids=input_ids, attention_mask=attention_mask).last_hidden_state
lstm_out, _ = self.lstm(roberta_out)
weights = torch.softmax(self.attn(lstm_out), dim=1)
context = torch.sum(weights * lstm_out, dim=1)
output = self.fc(self.dropout(context))
return output
# setup train set and batch size
from torch.utils.data import DataLoader
train_loader = DataLoader(encoded_dataset["train"].select(range(20000)), batch_size=16, shuffle=True)
test_loader = DataLoader(encoded_dataset["test"].select(range(2000)), batch_size=16)
###
model = RobertaBiLSTMAttention().to(device)
# load model (weight) from my HF model repo
from huggingface_hub import hf_hub_download
import torch
model_path = hf_hub_download(
repo_id="hrnrxb/roberta-bilstm-attention-sentiment",
filename="pytorch_model.bin"
)
model.load_state_dict(torch.load(model_path, map_location=device))
model.eval()
# # training process
# from tqdm import tqdm
# model = RobertaBiLSTMAttention().to(device)
# criterion = nn.CrossEntropyLoss()
# optimizer = torch.optim.Adam(model.parameters(), lr=2e-5)
# for epoch in range(10):
# model.train()
# total_loss = 0
# progress_bar = tqdm(train_loader, desc=f"Epoch {epoch+1}")
# for batch in progress_bar:
# input_ids = batch["input_ids"].to(device)
# attention_mask = batch["attention_mask"].to(device)
# labels = batch["label"].to(device)
# optimizer.zero_grad()
# outputs = model(input_ids, attention_mask)
# loss = criterion(outputs, labels)
# loss.backward()
# optimizer.step()
# total_loss += loss.item()
# avg_loss = total_loss / (progress_bar.n if progress_bar.n else 1)
# progress_bar.set_postfix(loss=f"{avg_loss:.4f}")
# inner evaluation
model.eval()
samples = [
# 1: sarcasm
"Wow, what a masterpiece. I especially loved the part where nothing happened for two hours.", # ๐ด Negative
# 2: emotionally mixed
"The movie was boring at times, but the ending completely blew my mind.", # ๐ข Positive (ูุณุจุชุงู ู
ุซุจุช)
# 3: taโarofy tone (fake praise)
"It was... fine, I guess. Not bad. Not good. Just there.", # ๐ด Negative (neutral leaning negative)
# 4: visually good but poor content
"Beautiful cinematography canโt save a script written by a potato.", # ๐ด Negative
# 5: praise with weird slang
"Yo that movie was sick af! ๐ฅ๐ฅ", # ๐ข Positive ("sick" = slang for amazing)
# 6: backhanded compliment
"I didnโt expect much, and yet it still managed to disappoint me.", # ๐ด Negative
# 7: full sarcasm
"10/10 would recommend... if you enjoy falling asleep halfway through.", # ๐ด Negative
# 8: fake excitement
"Absolutely incredible! I only checked my phone 12 times.", # ๐ด Negative
# 9: nostalgic + honest
"Reminded me of my childhood, cheesy but heartwarming.", # ๐ข Positive
# 10: hype tone
"Bro that film went HARD. Straight banger!", # ๐ข Positive (slang-heavy positive)
]
for s in samples:
tokens = tokenizer(s, return_tensors="pt", truncation=True, padding="max_length", max_length=128).to(device)
with torch.no_grad():
logits = model(tokens["input_ids"], tokens["attention_mask"])
pred = torch.argmax(logits, dim=1).item()
print(f"{s} โค {'๐ข Positive' if pred == 1 else '๐ด Negative'} ")
# UI w/ gradio
import gradio as gr
header = gr.HTML("""
<div style="text-align:center; margin-bottom:10px;">
<a href="https://github.com/hrnrxb/Advanced-Sentiment-Classifier" target="_blank" style="font-weight:bold; font-size:18px; text-decoration:none; color:#4A90E2;">
๐ View on GitHub
</a> |
<a href="https://hrnrxb.github.io" target="_blank" style="font-weight:bold; font-size:18px; text-decoration:none; color:#4A90E2;">
๐ My Website
</a>
</div>
""")
def predict(text):
model.eval()
tokens = tokenizer(text, return_tensors="pt", truncation=True, padding="max_length", max_length=128).to(device)
with torch.no_grad():
logits = model(tokens["input_ids"], tokens["attention_mask"])
prob = torch.softmax(logits, dim=1)
pred = torch.argmax(prob, dim=1).item()
conf = prob[0][pred].item()
label = "๐ข Positive" if pred == 1 else "๐ด Negative"
return f"{label} ({conf*100:.1f}%)"
gr.Interface(fn=predict, inputs=gr.Textbox(label="Enter a review"), outputs="text", description="โญ๏ธ [GitHub Repo](https://github.com/hrnrxb/Advanced-Sentiment-Classifier) | ๐ [My Website (https://hrnrxb.github.io)](https://hrnrxb.github.io)").launch()
|