CoolFace
Apppublic

CatZM/value-detection

sourceHugging Faceupdated 2y agoView on Hugging Face
0likes
app.py386 linesDownload Raw Back to root
1import torch2import torch.nn as nn3import torch.nn.functional as F4import torch.optim as optim5import numpy as np6import matplotlib.pyplot as plt7import torchtext8import pandas as pd9import spacy10import argparse11import os12import csv13import re14from copy import copy, deepcopy15from transformers import AutoTokenizer, AutoModel, AutoConfig16from transformers import TrainingArguments, Trainer17from transformers import set_seed, AdamW18from torchtext import data19from torch.utils.data import Dataset, DataLoader20from tqdm.notebook import tqdm21from transformers import get_linear_schedule_with_warmup22import locale23import random24import gradio as gr25import time26 27 28def getpreferredencoding(do_setlocale=True):29    return "UTF-8"30 31 32locale.getpreferredencoding = getpreferredencoding33# print(locale.getpreferredencoding())34 35bert_tokenizer = AutoTokenizer.from_pretrained("distilbert-base-uncased")36 37final_value_list = ['ACHIEVEMENT', 'BENEVOLENCE', 'CONFORMITY', 'HEDONISM',38                    'POWER', 'SELF-DIRECTION', 'TRADITION', 'SECURITY', 'STIMULATION', 'UNIVERSALISM']39value_index = {40    'SECURITY': 0,41    'BENEVOLENCE': 1,42    'ACHIEVEMENT': 2,43    'SELF-DIRECTION': 3,44    'POWER': 4,45    'UNIVERSALISM': 5,46    'STIMULATION': 6,47    'CONFORMITY': 7,48    'TRADITION': 8,49    'HEDONISM': 950}51 52thresholds = {'SECURITY': 0.5, 'BENEVOLENCE': 0.66, 'ACHIEVEMENT': 0.94, 'SELF-DIRECTION': 0.52, 'POWER': 0.72, 'UNIVERSALISM': 0.64, 'STIMULATION': 0.54, 'CONFORMITY': 0.55, 'TRADITION': 0.81, 'HEDONISM': 0.52}53 54softmax = nn.Softmax(dim=1)55########################################## Global Variable ##############################################56# Get GPT2 model tokenizer57gpt2_tokenizer = AutoTokenizer.from_pretrained("gpt2")58# GPT2 uses the last token for prediction so we need to pad to the left.59gpt2_tokenizer.padding_side = "left"60# Define PAD Token = EOS Token = 5025661gpt2_tokenizer.pad_token = gpt2_tokenizer.eos_token62#########################################################################################################63 64gpt2_model = AutoModel.from_pretrained('gpt2')65# resize model embedding to match new tokenizer66gpt2_model.resize_token_embeddings(len(gpt2_tokenizer))67# fix model padding token id68gpt2_model.config.pad_token_id = gpt2_model.config.eos_token_id69 70for param in gpt2_model.parameters():71    param.requires_grad = False72 73 74def is_english_statement(input):75    english_letters_or_symbols = re.compile(r'^[A-Za-z0-9 .,!?:;\-_=+@#$%^&*()"\']*$')76    return bool(english_letters_or_symbols.match(input))77 78 79def obtain_output(input, models):80    if is_english_statement(input) == False:81        # print("Invalid input. The input is not English.")82        return83    if len(input) == 0:84        # print("Invalid input.")85        return86    sigmoid = nn.Sigmoid()87    output_list = {}88    encoded_input = gpt2_tokenizer(input, return_tensors='pt').input_ids89    if len(encoded_input[0]) < 4:90        num = 4 - len(encoded_input[0])91        token_to_add = torch.full((1, num), gpt2_model.config.eos_token_id)92        encoded_input = torch.cat((token_to_add, encoded_input), dim=1)93 94    for i in range(len(final_value_list)):95        value = final_value_list[i]96        model = models[i]97        output = model(encoded_input).squeeze(1)98        prob = sigmoid(output)[0].item()99        # print(f"{value}: {prob: .2f}")100        if (prob > thresholds[value]):101            output_list[value] = prob102 103    # if len(output_list) == 0:104    #     print("No value detected from the statement.")105 106    output_list = sorted(output_list, key=output_list.get, reverse=True)107    return output_list[:3]108 109 110def load_model_state(model_path):111    state = torch.load(model_path)112    transformer_model = getNewGPT2Model()113    classifier_model = CNN(768, 384, [2, 4])114    model = GPT2_CNN(transformer_model, classifier_model)115    model.load_state_dict(state)116    return model117 118 119def getNewGPT2Model():120    # Get GPT2 model tokenizer121    gpt2_tokenizer = AutoTokenizer.from_pretrained("gpt2")122    # GPT2 uses the last token for prediction so we need to pad to the left.123    gpt2_tokenizer.padding_side = "left"124    # Define PAD Token = EOS Token = 50256125    gpt2_tokenizer.pad_token = gpt2_tokenizer.eos_token126 127    gpt2_model = AutoModel.from_pretrained('gpt2')128    # resize model embedding to match new tokenizer129    gpt2_model.resize_token_embeddings(len(gpt2_tokenizer))130    # fix model padding token id131    gpt2_model.config.pad_token_id = gpt2_model.config.eos_token_id132 133    for param in gpt2_model.parameters():134        param.requires_grad = False135 136    return gpt2_model137 138 139class GPT2_CNN(nn.Module):140    def __init__(self, GPT2_model, CNN_model):141        super(GPT2_CNN, self).__init__()142 143        self.transformer = GPT2_model144        self.classifier = CNN_model145 146    def forward(self, x, lengths=None):147 148        # x=[sentence length, batch size] -> [sentence length, batch size, embedding_dim]149        output = self.transformer(x).last_hidden_state150        output = output.permute(1, 0, 2)151        output = self.classifier(output)152        return output153 154 155class CNN(nn.Module):156    def __init__(self, embedding_dim, n_filters, filter_sizes):157        super(CNN, self).__init__()158 159        self.conv1 = nn.Conv2d(1, n_filters, kernel_size=(160            embedding_dim, filter_sizes[0]))161        self.conv2 = nn.Conv2d(1, n_filters, kernel_size=(162            embedding_dim, filter_sizes[1]))163        self.fc = nn.Linear(embedding_dim, 1)164 165    def forward(self, x, lengths=None):166 167        # x = self.embedding(x) # x=[sentence length, batch size] -> [sentence length, batch size, embedding_dim]168        x = x.unsqueeze(0)  # x=[1, sentence length, batch size, embedding_dim]169        # x=[batch_size, 1, embedding_dim, sentence length]170        x = x.permute(2, 0, 3, 1)171        C1 = F.relu(self.conv1(x))  # C1=[batch_size, n_filters, 1, num_words]172        C2 = F.relu(self.conv2(x))  # C2=[batch_size, n_filters, 1, num_words]173        C1 = C1.squeeze(2)174        C2 = C2.squeeze(2)  # C1, C2=[batch_size, n_filters, num_words]175        pool1 = nn.MaxPool1d(C1.size()[2])176        pool2 = nn.MaxPool1d(C2.size()[2])177        C1 = pool1(C1).squeeze(2)178        C2 = pool2(C2).squeeze(2)  # C1, C2=[batch_size, n_filters]179        C3 = torch.cat((C1, C2), 1)  # C3 = [batch_size, n_filters+n_filters]180        C3 = self.fc(C3)  # C3 = [batch_size]181        return C3182 183 184device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')185# print(device)186best_model_for_achievement = load_model_state(187    "./train_result/ACHIEVEMENT_backtranslation")188best_model_for_benevolence = load_model_state(189    "./train_result/BENEVOLENCE_backtranslation")190best_model_for_conformity = load_model_state(191    "./train_result/CONFORMITY_backtranslation")192best_model_for_hedonism = load_model_state(193    "./train_result/HEDONISM_backtranslation")194best_model_for_power = load_model_state(195    "./train_result/POWER_backtranslation")196best_model_for_self_d = load_model_state(197    "./train_result/SELF-DIRECTION_backtranslation")198best_model_for_tradition = load_model_state(199    "./train_result/TRADITION_backtranslation")200best_model_for_security = load_model_state(201    "./train_result/SECURITY_backtranslation")202best_model_for_stimulation = load_model_state(203    "./train_result/STIMULATION_backtranslation")204best_model_for_universalism = load_model_state(205    "./train_result/UNIVERSALISM_backtranslation")206final_models = [best_model_for_achievement, best_model_for_benevolence, best_model_for_conformity, best_model_for_hedonism, best_model_for_power, best_model_for_self_d, best_model_for_tradition, best_model_for_security, best_model_for_stimulation, best_model_for_universalism]207 208 209definitions = {210    'ACHIEVEMENT': "personal success through demonstrating competence according to social standards",211    'BENEVOLENCE': "preservation and enhancement of the people with whom one is in frequent personal contact",212    'CONFORMITY': "restraint of actions, inclinations, and impulses likely to upset or harm others and violate social expectations or norms",213    'HEDONISM': "pleasure and sensuous gratification for oneself",214    'POWER': "social status and prestige, control or dominance over people and resources",215    'SECURITY': "safety, harmony, and stability of society, of relationships, and of self",216    'SELF-DIRECTION': "independent thought and action choosing, creating, exploring",217    'STIMULATION': "excitement, novelty, and challenge in life",218    'TRADITION': "respect, commitment, and acceptance of the customs and ideas that traditional culture or religion provides",219    'UNIVERSALISM': "understanding, appreciation, tolerance and protection for the welfare of all people and for nature",220}221 222begin = '''223# Value Detector Slim\n224Thank you for trying out Value Detector Slim.\n225This is a simplified interface to detect human value(s) in an English sentence.226You can enter your statement in the input box and click "Submit". \n227Based on your response, our product will output the human value (s) detected in your statement and their definition. \n228If you would like to learn more about human values and our product, you can check them in 'About Project' page.\n229'''230 231 232def detect_value(input):233    response = ''234    if len(input) == 0:235        raise gr.Error(236            "Please enter a valid statement with at least one word.")237    elif not is_english_statement(input):238        raise gr.Error("Please enter the statement in English.")239    else:240        output = obtain_output(input, final_models)241        if len(output) == 0:242            response = 'None'243        else:244            for value in output:245                response += f"{value.title()}, which represents {definitions[value]}.\n\n"246    return response247 248 249with gr.Blocks() as demo:250    gr.Markdown(begin)251    with gr.Row():252        with gr.Column():253            input = gr.Textbox(label="Your Statement")254            with gr.Row():255                clear_button = gr.Button(value="Clear")256                submit_button = gr.Button(value="Submit")257        with gr.Column():258            output = gr.Textbox(label="Detected Value(s)")259 260        submit_button.click(detect_value, inputs=input, outputs=output)261        clear_button.click(lambda x: gr.update(value=''),262                           inputs=input, outputs=input)263 264 265demo.launch()266 267# input = "Start"268# obtain_output(input, final_models)269 270# begin = "Hi, thank you for trying Value Detector (beta). \n" + "This is a chatbot-alike interface to detect human value(s) in an English sentence." + "To simulate a conversation, the chatbot will ask you a question. " + \271#     "Based on your response, our product will output the human value (s) detected in your statement. \n" + \272#     "If you would like to learn more about human values and our product, you can check them in 'About Project' page. \n" + \273#         "Please click 'New Question' to prompt a new question. "274 275 276# achievement = "Personal success through demonstrating competence according to social standards."277# benevolence = "Preservation and enhancement of the people with whom one is in frequent personal contact."278# conformity = "Restraint of actions, inclinations, and impulses likely to upset or harm others and violate social expectations or norms."279# hedonism = "Pleasure and sensuous gratification for oneself."280# power = "Social status and prestige, control or dominance over people and resources."281# security = "Safety, harmony, and stability of society, of relationships, and of self."282# self_direction = "Independent thought and action choosing, creating, exploring."283# stimulation = "Excitement, novelty, and challenge in life."284# tradition = "Respect, commitment, and acceptance of the customs and ideas that traditional culture or religion provides."285# universalism = "Understanding, appreciation, tolerance and protection for the welfare of all people and for nature."286 287# # output = "The statement holds the following values:" + list of value + definition288 289 290# questions = [291#     "What are your aspirations in life?",292#     "Tell about a short-term goal you have.",293#     "What do you like most about yourself?",294#     "What kind of a person do you want to be?",295#     "What are your strengths?",296#     "What are you grateful for?",297#     "What is your biggest fear?",298#     "How do you think others see you?",299#     "Tell about a time you were happy.",300#     "Who do you admire and why?"301# ]302 303 304# def respond(chat_history, message, sstate):305#     output_message = obtain_output(message, final_models)306#     output_message = output_message.title()307#     if message.lower() == 'quit' or message.lower() == 'exit':308#         sstate = 5309#     else:310#         if sstate == -1:311#             if message.lower() == 'start':312#                 sstate = 0313#         elif sstate == 0:314#             if output_message == 'Null':315#                 sstate = 1316#             elif output_message == 'None':317#                 sstate = 2318#             else:319#                 sstate = 3320#         elif sstate == 1:321#             if output_message == 'Null':322#                 sstate = 1323#             elif output_message == 'None':324#                 sstate = 2325#             else:326#                 sstate = 3327#         elif sstate == 2:328#             if message.lower() == 'yes':329#                 sstate = 0330#             elif message.lower() == 'no':331#                 sstate = 5332#             else:333#                 sstate = 4334#         elif sstate == 3:335#             if message.lower() == 'yes':336#                 sstate = 0337#             elif message.lower() == 'no':338#                 sstate = 5339#             else:340#                 sstate = 4341#         elif sstate == 4:342#             if message.lower() == 'yes':343#                 sstate = 0344#             elif message.lower() == 'no':345#                 sstate = 5346#             else:347#                 sstate = 4348#         elif sstate == 5:349#             if message.lower() == 'reset':350#                 sstate = -1351 352#     if sstate == -1:353#         response = 'Please Enter start'354#     elif sstate == 0:355#         response = random.choice(questions)356#     elif sstate == 1:357#         response = 'Please enter in English'358#     elif sstate == 2:359#         response = 'No value detected from the statement. Would you like to a new question?'360#     elif sstate == 3:361#         response = 'Values: ' + output_message + '. Would you like to a new question?'362#     elif sstate == 4:363#         response = 'Please enter yes/no'364#     elif sstate == 5:365#         response = 'END'366 367#     return chat_history + [[message, response]], sstate368 369 370# with gr.Blocks() as demo:371#     sstate = gr.State(value=-1)372#     gr.Markdown(373#         """374#     # Value Detector (beta)375#     This is a chatbot-alike interface to detect human value(s) in an English human-spoken sentence.376 377#     To view the full list of human values please refer to "About Project".378#     """)379#     chatbot = gr.Chatbot()380#     msg = gr.Textbox()381#     clear = gr.Button("Clear Conversation")382#     msg.submit(respond, [chatbot, msg, sstate], [chatbot, sstate])383#     clear.click(lambda: None, None, chatbot, queue=False)384 385# demo.launch(share=True)386