Views
No views yet
best_model.pt) for the paper: "Bridging the Sustainable Development Goals: A Multi-Label Text Classification Approach for Mapping and Visualizing Nexuses in Sustainability Research".studio-ousia/luke-large-lite for multi-label text classification of the 17 UN Sustainable Development Goals (SDGs). It has been trained on a uniquely diverse, multi-sectoral, and multilingual corpus designed to achieve high generalization performance across various domains (academic, policy, civil society, etc.).best_model.pt).1import torch
2from torch import nn
3from transformers import AutoTokenizer, AutoModel
4from huggingface_hub import hf_hub_download
5from pathlib import Path
6
7# --- 1. Define the Model Architecture ---
8# This class must match the architecture used during training.
9# You can copy this class from the original training script.
10class SDGClassifier(nn.Module):
11 def __init__(self, model_path, pooler_dropout, class_number):
12 super(SDGClassifier, self).__init__()
13 self.bert = AutoModel.from_pretrained(model_path)
14 self.dropout = nn.Dropout(pooler_dropout)
15 self.pooler = nn.Sequential(nn.Linear(in_features=self.bert.config.hidden_size, out_features=self.bert.config.hidden_size))
16 self.tanh = nn.Tanh()
17 self.cls = nn.Linear(in_features=self.bert.config.hidden_size, out_features=class_number)
18
19 def forward(self, input_ids, attention_mask, token_type_ids, position, labels):
20 # Note: 'position' and 'labels' are dummy inputs required by the forward signature,
21 # but are not used for inference if labels are not provided.
22 bert_output = self.bert(input_ids, attention_mask, token_type_ids=token_type_ids, output_attentions=True, output_hidden_states=True)
23 average_hidden_state = (bert_output.last_hidden_state * attention_mask.unsqueeze(-1)).sum(1) / attention_mask.sum(1, keepdim=True)
24 pooler_output = self.tanh(self.pooler(self.dropout(average_hidden_state)))
25 logits = self.cls(pooler_output)
26 return logits, average_hidden_state, bert_output.attentions
27
28# --- 2. Setup and Load Model ---
29device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
30
31# Model configuration
32BASE_MODEL = 'studio-ousia/luke-large-lite'
33NUM_CLASSES = 17
34DROPOUT_RATE = 0.26 # This is the optimized dropout rate from the paper's training
35
36# Instantiate the model
37model = SDGClassifier(model_path=BASE_MODEL, pooler_dropout=DROPOUT_RATE, class_number=NUM_CLASSES).to(device)
38model.eval() # Set to evaluation mode
39
40# Download the fine-tuned weights from this Hub
41model_weights_path = hf_hub_download(
42 repo_id="GE-Lab/SDGs-classifier",
43 filename="best_model.pt"
44)
45
46# Load the weights into the model
47model.load_state_dict(torch.load(model_weights_path, map_location=device))
48
49print("Model loaded successfully!")
50
51# --- 3. Prepare Input ---
52tokenizer = AutoTokenizer.from_pretrained(BASE_MODEL)
53text = "Our research focuses on renewable energy solutions to combat climate change and ensure a sustainable future for all."
54
55inputs = tokenizer.encode_plus(
56 text,
57 None,
58 add_special_tokens=True,
59 max_length=512,
60 padding='max_length',
61 return_token_type_ids=True,
62 truncation=True,
63 return_tensors='pt'
64).to(device)
65
66# The model's forward pass requires these additional dummy inputs
67inputs['position'] = torch.arange(0, inputs['input_ids'].shape[1]).unsqueeze(0).to(device)
68inputs['labels'] = torch.zeros(1, NUM_CLASSES).to(device) # Dummy labels for inference
69
70# --- 4. Get Predictions ---
71with torch.no_grad():
72 logits, _, _ = model(**inputs)
73 probabilities = torch.sigmoid(logits).cpu().numpy()[0]
74 predictions = (probabilities > 0.5).astype(int)
75
76# --- 5. Interpret the Results ---
77goal_contents = ['Goal 1: No Poverty','Goal 2: Zero Hunger','Goal 3: Good Health and Well-being','Goal 4: Quality Education','Goal 5: Gender Equality','Goal 6: Clean Water and Sanitation','Goal 7: Affordable and Clean Energy','Goal 8: Decent Work and Economic Growth','Goal 9: Industry, Innovation and Infrastructure','Goal 10: Reduced Inequalities','Goal 11: Sustainable Cities and Communities','Goal 12: Responsible Consumption and Production','Goal 13: Climate Action','Goal 14: Life Below Water','Goal 15: Life on Land','Goal 16: Peace, Justice and Strong Institutions','Goal 17: Partnerships for the Goals']
78
79print(f"\nText: '{text}'")
80print("\n--- Predicted SDGs (Threshold > 0.5) ---")
81predicted_goals = [goal_contents[i] for i, pred in enumerate(predictions) if pred == 1]
82if predicted_goals:
83 for goal in predicted_goals:
84 print(goal)
85else:
86 print("No SDGs detected with a probability > 0.5")
87
88print("\n--- All SDG Probabilities ---")
89for i, prob in enumerate(probabilities):
90 print(f"{goal_contents[i]:<55}: {prob:.2%}")
911@article{Miyashita2026,
2 title = {Bridging the Sustainable Development Goals: A Multi-Label Text Classification Approach for Mapping and Visualizing Nexuses in Sustainability Research},
3 author = {Miyashita, N. and Matsui, T. and Haga, C. and Masuhara, N. and Kawakubo, S.},
4 year = 2026,
5 publisher = {Zenodo},
6 doi = {10.5281/zenodo.18309569},
7 url = {https://doi.org/10.5281/zenodo.18309569},
8 note = {Preprint}
9}
10
11@article{Matsui2022,
12 title={A natural language processing model for supporting sustainable development goals: translating semantics, visualizing nexus, and connecting stakeholders},
13 author={Matsui, Takanori and Suzuki, Kanoko and Ando, Kyota and Kitai, Yuya and Haga, Chihiro and Masuhara, Naoki and Kawakubo, Shun},
14 journal={Sustainability Science},
15 volume={17},
16 number={3},
17 pages={969--985},
18 year={2022},
19 doi={10.1007/s11625-022-01093-3},
20 publisher={Springer}
21}
22