def get_model(args): sd = None model_args = args if args.load is not None and args.load != '': # sd = torch.load(args.load, map_location=lambda storage, location: 'cpu') device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') sd = torch.load(args.load, map_location=device) if 'args' in sd: model_args = sd['args'] if 'sd' in sd: sd = sd['sd'] ntokens = model_args.data_size concat_pools = model_args.concat_max, model_args.concat_min, model_args.concat_mean if args.model == 'transformer': model = SentimentClassifier(model_args.model, ntokens, None, None, None, model_args.classifier_hidden_layers, model_args.classifier_dropout, None, concat_pools, False, model_args) else: model = SentimentClassifier( model_args.model, ntokens, model_args.emsize, model_args.nhid, model_args.nlayers, model_args.classifier_hidden_layers, model_args.classifier_dropout, model_args.all_layers, concat_pools, False, model_args) args.heads_per_class = model_args.heads_per_class args.use_softmax = model_args.use_softmax try: args.classes = list(model_args.classes) except: args.classes = [args.label_key] try: args.dual_thresh = model_args.dual_thresh and not model_args.joint_binary_train except: args.dual_thresh = False if args.cuda: model.cuda() if args.fp16: model.half() if sd is not None: try: model.load_state_dict(sd) except: # if state dict has weight normalized parameters apply and remove weight norm to model while loading sd if hasattr(model.lm_encoder, 'rnn'): apply_weight_norm(model.lm_encoder.rnn) else: apply_weight_norm(model.lm_encoder) model.lm_encoder.load_state_dict(sd) remove_weight_norm(model) if args.neurons > 0: print('WARNING. Setting neurons %s' % str(args.neurons)) model.set_neurons(args.neurons) return model
train_loader = DataLoader(dataset_train, batch_size=args["batch_size"], num_workers=5, shuffle=True, drop_last=True) val_loader = DataLoader(dataset_validation, batch_size=args["batch_size"], num_workers=5, shuffle=True, drop_last=True) starting_epoch = 0 if checkpoint: print("Loading state dict") model.load_state_dict(checkpoint["model_state_dict"]) optimizer.load_state_dict(checkpoint["optimizer_state_dict"]) print("Starting training from evaluation accuracy: %s" % checkpoint["evaluation_accuracy"]) starting_epoch = checkpoint["epoch"] + 1 scheduler = CosineAnnealingWarmRestarts( optimizer, T_0=args["SGDR_T0"], T_mult=args["SGDR_T_MULT"], eta_min=args["SGDR_ETA_MIN"], last_epoch=checkpoint["epoch"] if checkpoint else -1) if checkpoint: scheduler.load_state_dict(checkpoint["scheduler_state_dict"])
import pandas as pd from model import SentimentClassifier from dataset import SSTDataset #Create validation set val_set = SSTDataset(filename='data/dev.tsv', maxlen=30) #Create validation dataloader val_loader = DataLoader(val_set, batch_size=64, num_workers=5) #Create the network net = SentimentClassifier() #CPU or GPU device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") #Put the network to the GPU if available net = net.to(device) #Load the state dictionary of the network net.load_state_dict(torch.load('./models/model', map_location=device)) #Takes as the input the logits of the positive class and computes the binary cross-entropy criterion = nn.BCEWithLogitsLoss() def get_accuracy_from_logits(logits, labels): #Get a tensor of shape [B, 1, 1] with probabilities that the sentiment is positive probs = torch.sigmoid(logits.unsqueeze(-1)) #Convert probabilities to predictions, 1 being positive and 0 being negative soft_probs = (probs > 0.5).long() #Check which predictions are the same as the ground truth and calculate the accuracy acc = (soft_probs.squeeze() == labels).float().mean() #Return the accuracy return acc
neg_pred, neut_pred, pos_pred = predict(raw_tweet) response = {} response["response"] = { 'sentiment': { "positive": str(pos_pred), "neutral": str(neut_pred), "negative": str(neg_pred), }, "tweet": str(raw_tweet), "time_taken": str(time.time() - start_time), } return flask.jsonify(response) @app.route('/') def index(): return app.send_static_file('index.html') if __name__ == "__main__": MODEL = SentimentClassifier(len(CLASS_NAMES)) TOKENIZER = BertTokenizer.from_pretrained(PRE_TRAINED_MODEL_NAME) MODEL = nn.DataParallel(MODEL) MODEL.load_state_dict( torch.load(MODEL_PATH, map_location=torch.device(DEVICE))) MODEL.to(DEVICE) MODEL.eval() app.run(host='0.0.0.0')
train_data, val_data, test_data = data_config.apply(args) ntokens = args.data_size model = SentimentClassifier(args.model, ntokens, args.emsize, args.nhid, args.nlayers, 0.0, args.all_layers) if args.cuda: model.cuda() if args.fp16: model.half() with open(args.load_model, 'rb') as f: sd = torch.load(f) try: model.load_state_dict(sd) except: apply_weight_norm(model.encoder.rnn) model.load_state_dict(sd) remove_weight_norm(model) if args.neurons > 0: model.set_neurons(args.neurons) # uses similar function as transform from transfer.py def classify(model, text): model.eval() labels = np.array([]) first_label = True
class ModelHandler(BaseHandler): """ A custom model handler implementation. """ def __init__(self): self.model = None self._context = None self.initialized = False self.explain = False self.target = 0 def initialize(self, ctx): """ Initialize model. This will be called during model loading time :param context: Initial context contains model server system properties. :return: """ self.properties = ctx.system_properties self.initialized = True # load the model, refer 'c ustom handler class' above for details self.device = torch.device("cuda:" + str(self.properties.get("gpu_id")) if torch. cuda.is_available() else "cpu") model_dir = self.properties.get("model_dir") # Read model serialize/pt file model_pt_path = os.path.join(model_dir, "model.bin") # # Read model definition file # model_def_path = os.path.join(model_dir, "model.py") # if not os.path.isfile(model_def_path): # raise RuntimeError("Missing the model definition file") PRE_TRAINED_MODEL_NAME = 'dccuchile/bert-base-spanish-wwm-cased' from model import SentimentClassifier self.model = SentimentClassifier(2) self.model.to(self.device) self.tokenizer = BertTokenizer.from_pretrained(PRE_TRAINED_MODEL_NAME) self.model.load_state_dict( torch.load(model_pt_path, map_location=torch.device(self.device))) self.model = self.model.eval() self.initialized = True logger.debug( 'Transformer model from path {0} loaded successfully'.format( model_dir)) def preprocess(self, data): """ Transform raw input into model input data. :param batch: list of raw requests, should match batch size :return: list of preprocessed model input data """ # # Take the input data and make it inference ready # text = data[0].get("data") # if text is None: try: reclamo = data[0].get("body").get("data") except: reclamo = data[0].get("body") # logger.debug(data) # logger.debug(str(data)) MAX_LEN = 450 inputs = self.tokenizer.encode_plus( reclamo, add_special_tokens=True, max_length=MAX_LEN, return_token_type_ids=False, padding='max_length', truncation=True, return_attention_mask=True, return_tensors='pt', ) return { 'review_text': reclamo, 'input_ids': inputs['input_ids'].flatten(), 'attention_mask': inputs['attention_mask'].flatten() } def inference(self, model_input): """ Internal inference methods :param model_input: transformed model input data :return: list of inference output in NDArray """ # Do some inference call to engine here and return output input_ids = model_input["input_ids"].to(self.device) attention_mask = model_input["attention_mask"].to(self.device) model_output, pooled_output = self.model( input_ids=input_ids.unsqueeze(0), attention_mask=attention_mask.unsqueeze(0)) _, preds = torch.max(model_output, dim=1) probs = F.softmax(model_output, dim=1) predicted_idx = str(preds.item()) out_dic = { 'idx': [predicted_idx], 'probs': probs.detach().numpy().tolist(), 'pooled': pooled_output.detach().numpy().tolist() } out_js = json.dumps(out_dic) return [out_js] def postprocess(self, inference_output): """ Return inference result. :param inference_output: list of inference output :return: list of predict results """ # Take output from network and post-process to desired format postprocess_output = inference_output return postprocess_output
def run(): df = pd.read_csv("inputs/reviews.csv") df["sentiment"] = df.score.apply(rating_to_sentiment) df_train, df_rem = train_test_split(df, test_size=0.1, random_state=config.RANDOM_SEED) df_val, df_test = train_test_split(df_rem, test_size=0.5, random_state=config.RANDOM_SEED) train_data_loader = create_data_loader(df_train, config.TOKENIZER, config.MAX_LEN, config.BATCH_SIZE) val_data_loader = create_data_loader(df_val, config.TOKENIZER, config.MAX_LEN, config.BATCH_SIZE) test_data_loader = create_data_loader(df_test, config.TOKENIZER, config.MAX_LEN, config.BATCH_SIZE) # data = next(iter(val_data_loader)) # input_ids = data["input_ids"].to(config.DEVICE) # attention_mask = data["attention_mask"].to(config.DEVICE) # bert_model = BertModel.from_pretrained(config.BERT_NAME) model = SentimentClassifier(num_classes=len(class_labels)) if config.LOAD_MODEL == True: model.load_state_dict(torch.load("best_model_state.bin")) model = model.to(config.DEVICE) optimizer = AdamW(model.parameters(), lr=2e-5, correct_bias=False) total_steps = len(train_data_loader) * config.EPOCHS scheduler = get_linear_schedule_with_warmup(optimizer, num_warmup_steps=0, num_training_steps=total_steps) loss_fn = nn.CrossEntropyLoss().to(config.DEVICE) history = defaultdict(list) best_accuracy = 0 for epoch in range(config.EPOCHS): print(f"Epoch {epoch + 1}/{config.EPOCHS}") print("-" * 10) train_acc, train_loss = train_fn( model, train_data_loader, loss_fn, optimizer, config.DEVICE, scheduler, len(df_train), ) print(f"Train loss {train_loss} accuracy {train_acc}") val_acc, val_loss = eval_fn(model, val_data_loader, loss_fn, config.DEVICE, len(df_val)) print(f"Val loss {val_loss} accuracy {val_acc}") print() history["train_acc"].append(train_acc) history["train_loss"].append(train_loss) history["val_acc"].append(val_acc) history["val_loss"].append(val_loss) if val_acc > best_accuracy: torch.save(model.state_dict(), "best_model_state.bin") best_accuracy = val_acc
def predict(): sentence = request.args.get("sentence") start_time = time.time() positive_prediction = sentence_prediction(sentence, model=MODEL) negative_prediction = 1 - positive_prediction response = {} response["response"] = { "positive": str(positive_prediction), "negative": str(negative_prediction), "neutral": str(neutral_prediction), "sentence": str(sentence), "time_taken": str(time.time() - start_time), } return flask.jsonify(response) if __name__ == "__main__": RANDOM_SEED = 42 np.random.seed(RANDOM_SEED) torch.manual_seed(RANDOM_SEED) device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") print(device) MODEL = SentimentClassifier(3) MODEL.load_state_dict(torch.load(config.MODEL_PATH, map_location='cpu')) MODEL.to(DEVICE) MODEL.eval() app.run() # oaded_state = torch.load(model_path+seq_to_seq_test_model_fname,map_location='cuda:0'