Spaces:
Sleeping
Sleeping
| import torch | |
| import gradio as gr | |
| import tiktoken | |
| import pandas as pd | |
| import torch.nn as nn | |
| GPT_CONFIG_124M = { | |
| "vocab_size": 50257, | |
| "context_length": 1024, | |
| "emb_dim": 768, | |
| "n_heads": 12, | |
| "n_layers": 12, | |
| "drop_rate": 0.1, | |
| "qkv_bias": True | |
| } | |
| class multiheadv2(nn.Module): | |
| def __init__(self, d_in, d_out, context_length, dropout, attention_head, boolbias): | |
| super().__init__() | |
| self.head_dim = d_out // attention_head | |
| self.d_out = d_out | |
| self.attention_head = attention_head | |
| self.W_query = nn.Linear(d_in, d_out, bias=boolbias) | |
| self.W_key = nn.Linear(d_in, d_out, bias=boolbias) | |
| self.W_value = nn.Linear(d_in, d_out, bias=boolbias) | |
| self.out_proj = nn.Linear(d_out, d_out) | |
| self.dropout = nn.Dropout(dropout) | |
| self.register_buffer('mask', torch.triu(torch.ones(context_length, context_length), diagonal=1)) | |
| def forward(self, x): | |
| b, num_token, d_out = x.shape | |
| keys = self.W_key(x) | |
| queries = self.W_query(x) | |
| values = self.W_value(x) | |
| keys = keys.view(b, num_token, self.attention_head, self.head_dim).transpose(1, 2) | |
| queries = queries.view(b, num_token, self.attention_head, self.head_dim).transpose(1, 2) | |
| values = values.view(b, num_token, self.attention_head, self.head_dim).transpose(1, 2) | |
| attn_score = queries @ keys.transpose(2, 3) | |
| mask_bool = self.mask.bool()[:num_token, :num_token] | |
| attn_score.masked_fill_(mask_bool, -torch.inf) | |
| attn_weights = torch.softmax(attn_score / keys.shape[-1]**0.5, dim=-1) | |
| attn_weights = self.dropout(attn_weights) | |
| context_vec = (attn_weights @ values).transpose(1, 2).contiguous().view(b, num_token, self.d_out) | |
| context_vec = self.out_proj(context_vec) | |
| return context_vec | |
| class LayerNorm(nn.Module): | |
| def __init__(self, emb_dim): | |
| super().__init__() | |
| self.eps = 1e-5 | |
| self.scale_params = nn.Parameter(torch.ones(emb_dim)) | |
| self.shift_params = nn.Parameter(torch.zeros(emb_dim)) | |
| def forward(self, x): | |
| mean = x.mean(dim=-1, keepdim=True) | |
| var = x.var(dim=-1, keepdim=True, unbiased=False) | |
| norm = (x - mean) / torch.sqrt(var + self.eps) | |
| return norm * self.scale_params + self.shift_params | |
| class GELU(nn.Module): | |
| def forward(self, x): | |
| return 0.5 * x * (1 + torch.tanh(torch.sqrt(torch.tensor(2.0 / torch.pi)) * (x + 0.044715 * torch.pow(x, 3)))) | |
| class feedforward(nn.Module): | |
| def __init__(self, config): | |
| super().__init__() | |
| self.layers = nn.Sequential( | |
| nn.Linear(config['emb_dim'], config['emb_dim'] * 4), | |
| GELU(), | |
| nn.Linear(config['emb_dim'] * 4, config['emb_dim']), | |
| ) | |
| def forward(self, x): | |
| return self.layers(x) | |
| class TransformerBlock(nn.Module): | |
| def __init__(self, config): | |
| super().__init__() | |
| self.attn = multiheadv2(d_in=config['emb_dim'], d_out=config['emb_dim'], context_length=config['context_length'], dropout=config['drop_rate'], attention_head=config['n_heads'], boolbias=config['qkv_bias']) | |
| self.Layernorm1 = LayerNorm(config['emb_dim']) | |
| self.Layernorm2 = LayerNorm(config['emb_dim']) | |
| self.feedforw = feedforward(config) | |
| self.dropout = nn.Dropout(config['drop_rate']) | |
| def forward(self, x): | |
| skip = x | |
| x = self.Layernorm1(x) | |
| x = self.attn(x) | |
| x = self.dropout(x) | |
| x = x + skip | |
| skip = x | |
| x = self.Layernorm2(x) | |
| x = self.feedforw(x) | |
| x = self.dropout(x) | |
| x = x + skip | |
| return x | |
| class GPT_2(nn.Module): | |
| def __init__(self, cfg, num_classes): | |
| super().__init__() | |
| self.token_emb = nn.Embedding(cfg['vocab_size'], cfg["emb_dim"]) | |
| self.pos_emb = nn.Embedding(cfg['context_length'], cfg["emb_dim"]) | |
| self.drop_emb = nn.Dropout(cfg["drop_rate"]) | |
| self.trf_blocks = nn.Sequential(*[TransformerBlock(cfg) for _ in range(cfg["n_layers"])]) | |
| self.final_norm = LayerNorm(cfg["emb_dim"]) | |
| self.out_head = nn.Linear(cfg["emb_dim"], num_classes) | |
| def forward(self, inputidx): | |
| batch_size, seq = inputidx.shape | |
| tokens = self.token_emb(inputidx) | |
| pos_embeds = self.pos_emb(torch.arange(seq, device=inputidx.device)) | |
| x = tokens + pos_embeds | |
| x = self.drop_emb(x) | |
| x = self.trf_blocks(x) | |
| x = self.final_norm(x) | |
| logits = self.out_head(x[:, -1]) | |
| return logits | |
| tokenizer = tiktoken.get_encoding("gpt2") | |
| pad_token_id = tokenizer.eot_token | |
| df_temp = pd.read_csv("train.csv") | |
| label_mapping = dict(enumerate(df_temp["target"].astype("category").cat.categories)) | |
| num_classes = len(label_mapping) | |
| inv_label_mapping = {v: k for k, v in label_mapping.items()} | |
| device = torch.device("cuda" if torch.cuda.is_available() else "cpu") | |
| model = GPT_2(GPT_CONFIG_124M, num_classes) | |
| model.load_state_dict(torch.load("biofinetuned_partialEpoch1.pth", map_location=device)) | |
| model.to(device) | |
| model.eval() | |
| def classify_review(text, max_length=128): | |
| input_ids = tokenizer.encode(text)[:max_length] | |
| input_ids += [pad_token_id] * (max_length - len(input_ids)) | |
| input_tensor = torch.tensor(input_ids, device=device).unsqueeze(0) | |
| with torch.no_grad(): | |
| logits = model(input_tensor) | |
| predicted_label = torch.argmax(logits, dim=-1).item() | |
| return label_mapping[predicted_label] | |
| iface = gr.Interface( | |
| fn=classify_review, | |
| inputs=gr.Textbox(label="Enter a biomedical abstract section (e.g., Background, Objective, Methodology, etc.)"), | |
| outputs=gr.Textbox(label="Predicted Section Category"), | |
| title="MedGPT", | |
| description="A domain-specific classifier for biomedical abstract sections: Background, Objective, Methodology, Results, Conclusion." | |
| ) | |
| iface.launch() | |