Spaces:
Sleeping
Sleeping
| import torch | |
| import torch.nn as nn | |
| import torch.nn.functional as F | |
| from transformers import AutoTokenizer, AutoModel | |
| import numpy as np | |
| from sklearn.preprocessing import StandardScaler | |
| from joblib import load | |
| import random | |
| def set_seed(seed=42): | |
| random.seed(seed) | |
| np.random.seed(seed) | |
| torch.manual_seed(seed) | |
| if torch.cuda.is_available(): | |
| torch.cuda.manual_seed_all(seed) | |
| # set_seed(42) | |
| class BertEmbedder: | |
| def __init__(self, model_name = "./embedding-model/matscibert", device="cuda"): | |
| self.tokenizer = AutoTokenizer.from_pretrained(model_name) | |
| self.model = AutoModel.from_pretrained(model_name).to(device) | |
| self.device = device | |
| self.model.eval() | |
| def encode(self, text): | |
| inputs = self.tokenizer( | |
| text, | |
| padding=True, | |
| truncation=True, | |
| max_length=512, | |
| return_tensors="pt" | |
| ).to(self.device) | |
| outputs = self.model(**inputs) | |
| last_hidden = outputs.last_hidden_state | |
| mask = inputs.attention_mask.unsqueeze(-1) | |
| embedding = (last_hidden * mask).sum(1) / mask.sum(1) | |
| return embedding.cpu().numpy().squeeze().tolist() | |
| class FeatureExtractor(nn.Module): | |
| def __init__(self): | |
| super().__init__() | |
| self.net = nn.Sequential( | |
| nn.Linear(779, 1024), | |
| nn.ReLU(), | |
| nn.Linear(1024, 512), | |
| nn.ReLU(), | |
| nn.Linear(512, 256), | |
| nn.Linear(256, 32), | |
| ) | |
| def forward(self, x): | |
| return self.net(x).squeeze(-1) | |
| class MCDropoutModel(nn.Module): | |
| def __init__(self, input_dim=32, dropout_rate=0.1): | |
| super().__init__() | |
| # self.fc1 = nn.Linear(input_dim, 64) | |
| self.fc2 = nn.Linear(32, 128) | |
| self.fc3 = nn.Linear(128, 32) | |
| self.fc4 = nn.Linear(32, 1) | |
| self.dropout = nn.Dropout(dropout_rate) | |
| def forward(self, x): | |
| # x = F.leaky_relu(self.fc1(x), negative_slope=0.05) | |
| x = F.leaky_relu(self.dropout(self.fc2(x)), negative_slope=0.05) | |
| x = F.leaky_relu(self.dropout(self.fc3(x)), negative_slope=0.05) | |
| x = self.fc4(x) | |
| return x.squeeze(-1) | |
| def mc_dropout_predict(model, X, n_samples = 50): | |
| set_seed(42) | |
| device = next(model.parameters()).device | |
| X_tensor = torch.FloatTensor(X).to(device) | |
| model.eval() | |
| for m in model.modules(): | |
| if isinstance(m, nn.Dropout): | |
| m.train() | |
| predictions = [] | |
| with torch.no_grad(): | |
| for _ in range(n_samples): | |
| pred = model(X_tensor) | |
| predictions.append(pred.cpu().numpy()) | |
| predictions = np.array(predictions) | |
| return predictions.mean(axis=0), predictions.std(axis=0) | |
| def predict(Al_content=None, | |
| Nb_content=None, | |
| Ta_content=None, | |
| Ti_content=None, | |
| Zr_content=None, | |
| Mo_content=None, | |
| V_content=None, | |
| Cr_content=None, | |
| W_content=None, | |
| Hf_content=None, | |
| Ni_content=None, | |
| process_text = None, | |
| scaler_model = "./ANN-modeling/mc_dropout_scaler.pkl", | |
| model_path = './ANN-modeling/mc_dropout_best_vam_only.pth', | |
| embedding_model = "./embedding-model/matscibert", | |
| extract_model = "./DANN-modeling/feature_extractor.pth", | |
| device = 'cuda'): | |
| comp_list = [ | |
| Al_content or 0.0, | |
| Nb_content or 0.0, | |
| Ta_content or 0.0, | |
| Ti_content or 0.0, | |
| Zr_content or 0.0, | |
| Mo_content or 0.0, | |
| V_content or 0.0, | |
| Cr_content or 0.0, | |
| W_content or 0.0, | |
| Hf_content or 0.0, | |
| Ni_content or 0.0, | |
| ] | |
| comp_list = [float(x) for x in comp_list] | |
| if process_text is not None: | |
| # print("Embedding process text...") | |
| embedder = BertEmbedder(embedding_model) | |
| emb = embedder.encode(process_text) | |
| proc_emb = np.array(emb) | |
| # print("Extracting features...") | |
| extractor = FeatureExtractor().to(device) | |
| extractor.load_state_dict(torch.load(extract_model, map_location=device)) | |
| # combinate process and composition | |
| # X = np.hstack([comp_list, proc_emb]) | |
| comp_array = np.atleast_2d(comp_list) # Shape: (n_samples, 11) | |
| proc_emb_array = np.tile(proc_emb, (comp_array.shape[0], 1)) # Repeat proc_emb for each sample | |
| X = np.hstack([comp_array, proc_emb_array]) | |
| lantent_features = extractor(torch.FloatTensor(X).to(device)).cpu().detach().numpy() | |
| # print("Predicting...") | |
| model = MCDropoutModel().to(device) | |
| model.load_state_dict(torch.load(model_path, map_location=device)) | |
| # scaler = StandardScaler() | |
| scaler = load(scaler_model) | |
| lantent_features_scaled = scaler.transform(lantent_features) | |
| pred, std = mc_dropout_predict(model, lantent_features_scaled) | |
| return np.round(pred, 2), np.round(std, 2) | |
| if __name__ == "__main__": | |
| # set_seed(42) | |
| process_text = "prepared by laser powder bed fusion technique using a feedstock of pre-alloyed powders with optimized process parameters: laser power 230 W, scanning speed 900 mm/s, hatch spacing 62 μm, and layer thickness 30 μm." | |
| ys, std = predict(Al_content=25, | |
| Nb_content=25, | |
| Ta_content=None, | |
| Ti_content=25, | |
| Zr_content=None, | |
| Mo_content=None, | |
| V_content=25, | |
| Cr_content=None, | |
| W_content=None, | |
| Hf_content=None, | |
| Ni_content=None, | |
| process_text = process_text, | |
| scaler_model = "./ANN-modeling/mc_dropout_scaler.pkl", | |
| model_path = './ANN-modeling/mc_dropout_best_vam_only.pth', | |
| embedding_model = "./embedding-model/matscibert", | |
| extract_model = "./DANN-modeling/feature_extractor.pth", | |
| device = 'cuda') | |
| print(ys, std) |