geografia experiments 2021 collections

master
agropunx 2 years ago
parent 0d12634f55
commit 5177a1d22b

@ -0,0 +1,6 @@
# A Chat Called Quest - ccq
metodi di Natural Language Processing per la comprensione, produzione e traduzione di lingua italiana e lingua italiana dei segni (LIS).
ancora è un work in progress, ma ci sono i primi esperimentini coi modelli transformers sotto forma di un odiabile jupiter-notebook ccq/ccq_explore.ipynb (nella cartella c'è l export del suddetto notebook processato in html)
rigiratore di sintassi tra lingue comuni e non

@ -0,0 +1,682 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "80e0cc42",
"metadata": {},
"source": [
"# 0 : Cosa c'è in questo notebook\n",
"Scaricamanto ed utilizzo modelli di Natural Language Processing da huggingface.com per fare un po di esperimenti ed esempi con dati testuali per il progetto __geografia__.\n",
"\n",
"In particolare si esplorano un po di metodi e strumenti per la comprensione e annotazione dei testi, sfruttando modelli già allenati su task che ci posssono interessare come ad esempio :\n",
"- __Mask-Filling__ (con huggingface transformer): predice un token mancante in una frase\n",
"- __Zero-Shot classification__ (con huggingface transformer): classifica una frase rispetto a delle classi variabili (utile per topic analysis, sentiment retrival e menate generiche)\n",
"- __Pos-Tagging__ (con la libreria spacy) : analisi grammaticale e sintattica del testo\n",
"\n",
"#### 0.1 Transformer Models da hugging face\n",
"I modelli pre-allenati sono stati sottoposti ad estensivi training con tantissimi dati, in genere macinati per giorni. i task non-supervisionati tipici utilizzati per l'allenamento sono in genere:\n",
"- next sentence prediction ( prendi un paragrafo, lo splitti sulla base del carattere '.' ed usi la prima frase come dato e la seconda come label da predirre)\n",
"- fill-mask: predirre la parola mancante di una frase ( nel training si prendono frasi complete e si maschera un termine a random per frase)\n",
"\n",
"Accanto a questi task usati per allenare la struttura della rete neurale (aka \"il grosso\" dei nodi profondi), i modelli di huggingface possono essere già \"fine-tunati\" rispetto ad ulteriori downstream task (tipo sentiment analysis o zero shot) e quindi utilizzabili direttamente. per alcune coppie di modelli-task invece è necessario un ulteriore sessione di fine-tuning con un dataset rilevante per il task d'interesse.\n",
"Qua c'è una lista delle tipologie di task piu comuni:\n",
"https://huggingface.co/tasks\n",
" \n",
"Infine un altra differenza sostanziale che ci interessa è se il modello sia:\n",
"- monolingua\n",
"- multilingua\n",
"\n",
"i modelli considerati per questo girovagare sono:\n",
"- il modello __dbmdz/bert-base-italian-cased__ è piu leggero e solo in italiano, ma di task ready-to-go disponibili c'è solo fill-mask e pos-tag\n",
"- il modello __facebook/bart-large-mnli__ è molto pesante, ma è multilingua ed ha implementato lo zero-shot-classification\n",
"- il modello __bert-base-cased__ solo inglese ma con praticamente tutti i downstream task già pronti all'utilizzo\n",
"\n",
"#### 0.2 Spacy Library\n",
"https://spacy.io/\n",
"libreria python piu semplice ed efficiente rispetto ai modelli transformer di hugging face, ma meno versatile per quantità di task possibili. ottima per pulire testi e tokenization (preprocessing), molto buono il pos-tagging\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "756d5d05",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/agropunx/anaconda3/envs/geografia/lib/python3.8/site-packages/tqdm/auto.py:22: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
" from .autonotebook import tqdm as notebook_tqdm\n",
"2022-07-06 20:22:23.485088: W tensorflow/stream_executor/platform/default/dso_loader.cc:64] Could not load dynamic library 'libcudart.so.11.0'; dlerror: libcudart.so.11.0: cannot open shared object file: No such file or directory\n",
"2022-07-06 20:22:23.485116: I tensorflow/stream_executor/cuda/cudart_stub.cc:29] Ignore above cudart dlerror if you do not have a GPU set up on your machine.\n"
]
}
],
"source": [
"from transformers import AutoModel, AutoTokenizer \n",
"from transformers import pipeline\n",
"multilingual_model_name = \"facebook/bart-large-mnli\" # 1.5 GB\n",
"italian_model_name = \"dbmdz/bert-base-italian-cased\" # 422 MB\n",
"alltask_model_name = \"bert-base-cased\" \n",
"\n",
"## Download model and configuration from huggingface.co and cache. \n",
"#muli_tokenizer = AutoTokenizer.from_pretrained(multilingual_model_name)\n",
"#muli_model = AutoModel.from_pretrained(multilingual_model_name)\n"
]
},
{
"cell_type": "markdown",
"id": "1f1657a9",
"metadata": {},
"source": [
"## 1 : Fill-Mask task example"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "2ace43c4",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Some weights of the model checkpoint at dbmdz/bert-base-italian-cased were not used when initializing BertForMaskedLM: ['cls.seq_relationship.weight', 'cls.seq_relationship.bias']\n",
"- This IS expected if you are initializing BertForMaskedLM from the checkpoint of a model trained on another task or with another architecture (e.g. initializing a BertForSequenceClassification model from a BertForPreTraining model).\n",
"- This IS NOT expected if you are initializing BertForMaskedLM from the checkpoint of a model that you expect to be exactly identical (initializing a BertForSequenceClassification model from a BertForSequenceClassification model).\n"
]
},
{
"data": {
"text/plain": [
"[{'score': 0.9144049286842346,\n",
" 'token': 482,\n",
" 'token_str': 'stato',\n",
" 'sequence': 'Umberto Eco è stato un grande scrittore'},\n",
" {'score': 0.025699790567159653,\n",
" 'token': 5801,\n",
" 'token_str': 'diventato',\n",
" 'sequence': 'Umberto Eco è diventato un grande scrittore'},\n",
" {'score': 0.022715440019965172,\n",
" 'token': 409,\n",
" 'token_str': 'anche',\n",
" 'sequence': 'Umberto Eco è anche un grande scrittore'},\n",
" {'score': 0.006274252198636532,\n",
" 'token': 1402,\n",
" 'token_str': 'oggi',\n",
" 'sequence': 'Umberto Eco è oggi un grande scrittore'},\n",
" {'score': 0.004773850552737713,\n",
" 'token': 14743,\n",
" 'token_str': 'divenuto',\n",
" 'sequence': 'Umberto Eco è divenuto un grande scrittore'}]"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"fill = pipeline('fill-mask',model=italian_model_name)\n",
"masked_sentence = 'Umberto Eco è [MASK] un grande scrittore'\n",
"fill(masked_sentence)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "df12c632",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[{'score': 0.1162119209766388,\n",
" 'token': 7607,\n",
" 'token_str': 'troviamo',\n",
" 'sequence': 'a che ora ci troviamo?'},\n",
" {'score': 0.06763438880443573,\n",
" 'token': 17567,\n",
" 'token_str': 'aspettiamo',\n",
" 'sequence': 'a che ora ci aspettiamo?'},\n",
" {'score': 0.06530702114105225,\n",
" 'token': 1303,\n",
" 'token_str': 'sarà',\n",
" 'sequence': 'a che ora ci sarà?'},\n",
" {'score': 0.05703262239694595,\n",
" 'token': 4238,\n",
" 'token_str': 'vediamo',\n",
" 'sequence': 'a che ora ci vediamo?'},\n",
" {'score': 0.05302278324961662,\n",
" 'token': 17387,\n",
" 'token_str': 'vedete',\n",
" 'sequence': 'a che ora ci vedete?'}]"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"masked_sentence = 'a che ora ci [MASK]?'\n",
"fill(masked_sentence)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "6d87ab9c",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[{'score': 0.36587169766426086,\n",
" 'token': 510,\n",
" 'token_str': 'cosa',\n",
" 'sequence': 'a che cosa ci troviamo?'},\n",
" {'score': 0.046960778534412384,\n",
" 'token': 739,\n",
" 'token_str': 'modo',\n",
" 'sequence': 'a che modo ci troviamo?'},\n",
" {'score': 0.04375715181231499,\n",
" 'token': 212,\n",
" 'token_str': 'non',\n",
" 'sequence': 'a che non ci troviamo?'},\n",
" {'score': 0.023330960422754288,\n",
" 'token': 1302,\n",
" 'token_str': 'livello',\n",
" 'sequence': 'a che livello ci troviamo?'},\n",
" {'score': 0.02314317226409912,\n",
" 'token': 1711,\n",
" 'token_str': 'condizioni',\n",
" 'sequence': 'a che condizioni ci troviamo?'}]"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"masked_sentence = 'a che [MASK] ci troviamo?'\n",
"fill(masked_sentence)"
]
},
{
"cell_type": "markdown",
"id": "ffa2e70f",
"metadata": {},
"source": [
"## 2 : Zero-Shot classification task example\n",
"\n",
"uso modello multilingua ( unico disponibile su huggingface in grado di performare l'inferenza zero-shot in italiano)\n",
" \n",
"link generico in italiano sullo __zero-shot__ learning e inference: https://zephyrnet.com/it/Zero-shot-learning-puoi-classificare-un-oggetto-senza-vederlo-prima/"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "ba49a3f4",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Some weights of the model checkpoint at dbmdz/bert-base-italian-cased were not used when initializing BertForSequenceClassification: ['cls.seq_relationship.bias', 'cls.predictions.transform.LayerNorm.weight', 'cls.predictions.decoder.weight', 'cls.predictions.transform.dense.bias', 'cls.seq_relationship.weight', 'cls.predictions.transform.LayerNorm.bias', 'cls.predictions.transform.dense.weight', 'cls.predictions.bias']\n",
"- This IS expected if you are initializing BertForSequenceClassification from the checkpoint of a model trained on another task or with another architecture (e.g. initializing a BertForSequenceClassification model from a BertForPreTraining model).\n",
"- This IS NOT expected if you are initializing BertForSequenceClassification from the checkpoint of a model that you expect to be exactly identical (initializing a BertForSequenceClassification model from a BertForSequenceClassification model).\n",
"Some weights of BertForSequenceClassification were not initialized from the model checkpoint at dbmdz/bert-base-italian-cased and are newly initialized: ['classifier.weight', 'classifier.bias']\n",
"You should probably TRAIN this model on a down-stream task to be able to use it for predictions and inference.\n",
"Failed to determine 'entailment' label id from the label2id mapping in the model config. Setting to -1. Define a descriptive label2id mapping in the model config to ensure correct outputs.\n"
]
}
],
"source": [
"zs = pipeline(\"zero-shot-classification\",model=italian_model_name)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f11053eb",
"metadata": {},
"outputs": [],
"source": [
"zs('che merda di giornata', candidate_labels=['positivo','negativo'],hypothesis_template='questa frase ha un tono {}',) #multiclass"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9c151ae8",
"metadata": {},
"outputs": [],
"source": [
"zs(sequences='dove vai stasera?',hypothesis_template='questa frase è una {}',candidate_labels=['affermazione','domanda'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "87c76244",
"metadata": {},
"outputs": [],
"source": [
"zs(sequences='where are you going?',hypothesis_template='this phrase is a {}',candidate_labels=['question','affirmation'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4a29d6a5",
"metadata": {},
"outputs": [],
"source": [
"zs(sequences='Voglio uscire con voi stasera, ma devo pulire casa prima',candidate_labels=['dubbio','invito','carro','positivo','negativo'], multiclass=True)"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "fcf8ff42",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'sequence': 'Sono felice di uscire con voi stasera',\n",
" 'labels': ['relax',\n",
" 'pace',\n",
" 'indifferenza',\n",
" 'interesse',\n",
" 'fastidio',\n",
" 'dubbio',\n",
" 'noia',\n",
" 'rabbia',\n",
" 'sconforto',\n",
" 'calma',\n",
" 'tristezza',\n",
" 'eccitazione',\n",
" 'gioia',\n",
" 'felicità'],\n",
" 'scores': [0.07741541415452957,\n",
" 0.07665539532899857,\n",
" 0.0763017013669014,\n",
" 0.07597608864307404,\n",
" 0.07575443387031555,\n",
" 0.07570748031139374,\n",
" 0.0756787359714508,\n",
" 0.07537700980901718,\n",
" 0.07522716373205185,\n",
" 0.07521089166402817,\n",
" 0.07490663230419159,\n",
" 0.07221430540084839,\n",
" 0.07031130790710449,\n",
" 0.02326352894306183]}"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#https://www.google.it/search?q=thayer+mood+plane+italia&biw=1528&bih=788&tbm=isch&source=iu&ictx=1&vet=1&fir=idr_CWra3dTA3M%252C3vr2PPAMir9TdM%252C_%253BEhLHcfw0fkhWHM%252CEh6xJHBGzk4cMM%252C_%253BaP-KPSMboAJg2M%252CnleMstLur1huUM%252C_%253BxHGASYvcnwBR5M%252CrZKJnx3na11TtM%252C_%253Bl2JjpwGxrk9aOM%252CEh6xJHBGzk4cMM%252C_%253BGC1du1ZkYglw-M%252Co4brRqZQk5p8CM%252C_%253BO8E8kjpRcFlMWM%252CnleMstLur1huUM%252C_%253BoYYMLq4zR-JFeM%252Co4brRqZQk5p8CM%252C_%253B1CIJmqw2RNg0VM%252C5o_XDTGFr1iuXM%252C_%253BaDO14J7XISRjIM%252CEh6xJHBGzk4cMM%252C_&usg=AI4_-kSIgRNOu3F0-x0YYMbNCEIyLXfEzg&sa=X&ved=2ahUKEwiyqNDN_cD3AhVc7rsIHWi3CFYQ9QF6BAghEAE#imgrc=EhLHcfw0fkhWHM\n",
"moods=['fastidio','rabbia','sconforto','tristezza','noia','pace','relax','calma','felicità','gioia','indifferenza','interesse','dubbio','eccitazione']\n",
"zs(sequences='Sono felice di uscire con voi stasera',candidate_labels=moods)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "8ec3e16f",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'sequence': 'ti ammazzo',\n",
" 'labels': ['noia',\n",
" 'eccitazione',\n",
" 'pace',\n",
" 'dubbio',\n",
" 'gioia',\n",
" 'rabbia',\n",
" 'indifferenza',\n",
" 'tristezza',\n",
" 'sconforto',\n",
" 'felicità',\n",
" 'fastidio',\n",
" 'calma',\n",
" 'relax',\n",
" 'interesse'],\n",
" 'scores': [0.07284864038228989,\n",
" 0.07268563657999039,\n",
" 0.07168520241975784,\n",
" 0.07163083553314209,\n",
" 0.07157977670431137,\n",
" 0.07146152853965759,\n",
" 0.07145626842975616,\n",
" 0.07143832743167877,\n",
" 0.07120247930288315,\n",
" 0.07110902667045593,\n",
" 0.07106047123670578,\n",
" 0.07105831056833267,\n",
" 0.07071790099143982,\n",
" 0.07006552070379257]}"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sentenza = 'ti ammazzo'\n",
"zs(sequences=sentenza,candidate_labels=moods)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "6a806191",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'sequence': 'non capisco perchè te la prendi con me, ti ho già regalato tutte le mi capre, non posso darti anche il bue',\n",
" 'labels': ['eccitazione',\n",
" 'indifferenza',\n",
" 'gioia',\n",
" 'relax',\n",
" 'felicità',\n",
" 'dubbio',\n",
" 'tristezza',\n",
" 'fastidio',\n",
" 'pace',\n",
" 'rabbia',\n",
" 'noia',\n",
" 'interesse',\n",
" 'sconforto',\n",
" 'calma'],\n",
" 'scores': [0.07354768365621567,\n",
" 0.07300304621458054,\n",
" 0.07294241338968277,\n",
" 0.07219138741493225,\n",
" 0.07172053307294846,\n",
" 0.07144749164581299,\n",
" 0.07143128663301468,\n",
" 0.07104679197072983,\n",
" 0.07093875855207443,\n",
" 0.07085791230201721,\n",
" 0.0706729143857956,\n",
" 0.07063259184360504,\n",
" 0.07041624188423157,\n",
" 0.06915094703435898]}"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"sentenza = 'non capisco perchè te la prendi con me, ti ho già regalato tutte le mi capre, non posso darti anche il bue'\n",
"zs(sequences=sentenza,candidate_labels=moods, multiclass=True)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "0d2d0f93",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'sequence': 'le tue orecchie sono bruttissime, non uscirò mai con te',\n",
" 'labels': ['logica', 'attualità', 'cotillons', 'estetica'],\n",
" 'scores': [0.2509896755218506,\n",
" 0.25027403235435486,\n",
" 0.24949680268764496,\n",
" 0.2492394745349884]}"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"zs(sequences='le tue orecchie sono bruttissime, non uscirò mai con te',candidate_labels=['estetica','logica','attualità','cotillons'], multiclass=True)"
]
},
{
"cell_type": "markdown",
"id": "64c9b9af",
"metadata": {},
"source": [
"## 3 : POS-TAG task example\n",
"\n",
"Positional tagging, task già noto alla maggior parte delle persone aventi la terza elementare come __analisi grammaticale__\n",
"Nell'analisi grammaticale italiana ogni parola può appartenere ad una delle nove categorie lessicali dell'italiano, cinque variabili: articolo, aggettivo, sostantivo o nome, pronome, verbo, e quattro invariabili: avverbio, preposizione, congiunzione, interiezione o esclamazione. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "118e6275",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 15,
"id": "9b74db59",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"testo originale ---> San Francisco prevede di bandire i robot di consegna porta a porta\n",
"\n",
"*** Pos-Tagging\n",
"WORD POS-TAG SYNTACTIC DEP\n",
"-------------------------------------\n",
"San PROPN nsubj\n",
"Francisco PROPN flat:name\n",
"prevede VERB ROOT\n",
"di ADP mark\n",
"bandire VERB xcomp\n",
"i DET det\n",
"robot NOUN obj\n",
"di ADP case\n",
"consegna NOUN nmod\n",
"porta VERB advcl\n",
"a ADP case\n",
"porta NOUN obl\n",
"\n",
"*** Analisi Entità specifiche nel testo:\n",
"ENTITY NAME LABEL\n",
"-------------------------------------\n",
"San Francisco LOC\n"
]
}
],
"source": [
"import spacy\n",
"from spacy.lang.it.examples import sentences \n",
"\n",
"try:\n",
" nlp = spacy.load(\"it_core_news_lg\")\n",
"except:\n",
" !python -m spacy download it_core_news_lg\n",
" nlp = spacy.load(\"it_core_news_lg\")\n",
"doc = nlp(sentences[2])\n",
"print('testo originale ---> ',doc.text)\n",
"print('\\n*** Pos-Tagging')\n",
"print('WORD', ' '*(10-len('word')), 'POS-TAG',' '*(10-len('POS-TAG')), 'SYNTACTIC DEP')\n",
"print('-------------------------------------')\n",
"for token in doc:\n",
" print(token.text,' '*(10-len(token.text)), token.pos_,' '*(10-len(token.pos_)), token.dep_ )\n",
"\n",
"print('\\n*** Analisi Entità specifiche nel testo:') \n",
"print('ENTITY NAME',' '*(20-len('ENTITY NAME')), 'LABEL')\n",
"print('-------------------------------------')\n",
"for ent in doc.ents:\n",
" print(ent.text ,' '*(20-len(ent.text)), ent.label_)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "92712a0d",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"testo originale ---> Londra è una grande città del Regno Unito.\n",
"\n",
"*** Pos-Tagging\n",
"WORD POS-TAG SYNTACTIC DEP\n",
"-------------------------------------\n",
"Londra PROPN nsubj\n",
"è AUX cop\n",
"una DET det\n",
"grande ADJ amod\n",
"città NOUN ROOT\n",
"del ADP case\n",
"Regno PROPN nmod\n",
"Unito PROPN flat:name\n",
". PUNCT punct\n",
"\n",
"*** Analisi Entità specifiche nel testo:\n",
"ENTITY NAME LABEL\n",
"-------------------------------------\n",
"Londra LOC\n",
"Regno Unito LOC\n"
]
}
],
"source": [
"doc = nlp(sentences[3])\n",
"print('testo originale ---> ',doc.text)\n",
"print('\\n*** Pos-Tagging')\n",
"print('WORD', ' '*(10-len('word')), 'POS-TAG',' '*(10-len('POS-TAG')), 'SYNTACTIC DEP')\n",
"print('-------------------------------------')\n",
"for token in doc:\n",
" print(token.text,' '*(10-len(token.text)), token.pos_,' '*(10-len(token.pos_)), token.dep_ )\n",
"\n",
"print('\\n*** Analisi Entità specifiche nel testo:') \n",
"print('ENTITY NAME',' '*(20-len('ENTITY NAME')), 'LABEL')\n",
"print('-------------------------------------')\n",
"for ent in doc.ents:\n",
" print(ent.text ,' '*(20-len(ent.text)), ent.label_)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "7ab8299b",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"testo originale ---> non capisco perchè te la prendi con Giacomo, ti ha già regalato tutte le sue capre, non può darti anche il bue\n",
"\n",
"*** Pos-Tagging\n",
"WORD POS-TAG SYNTACTIC DEP\n",
"-------------------------------------\n",
"non ADV advmod\n",
"capisco VERB ROOT\n",
"perchè SCONJ mark\n",
"te PRON expl\n",
"la PRON obj\n",
"prendi VERB ccomp\n",
"con ADP case\n",
"Giacomo PROPN obl\n",
", PUNCT punct\n",
"ti PRON iobj\n",
"ha AUX aux\n",
"già ADV advmod\n",
"regalato VERB conj\n",
"tutte DET det:predet\n",
"le DET det\n",
"sue DET det:poss\n",
"capre NOUN obj\n",
", PUNCT punct\n",
"non ADV advmod\n",
"può AUX aux\n",
"darti VERB conj\n",
"anche ADV advmod\n",
"il DET det\n",
"bue NOUN obj\n",
"\n",
"*** Analisi Entità specifiche nel testo:\n",
"ENTITY NAME LABEL\n",
"-------------------------------------\n",
"Giacomo PER\n"
]
}
],
"source": [
"doc = nlp(sentenza.replace('me','Giacomo').replace('mi','sue').replace('ho','ha').replace('posso','può'))\n",
"print('testo originale ---> ',doc.text)\n",
"print('\\n*** Pos-Tagging')\n",
"print('WORD', ' '*(10-len('word')), 'POS-TAG',' '*(10-len('POS-TAG')), 'SYNTACTIC DEP')\n",
"print('-------------------------------------')\n",
"for token in doc:\n",
" print(token.text,' '*(10-len(token.text)), token.pos_,' '*(10-len(token.pos_)), token.dep_ )\n",
"\n",
"print('\\n*** Analisi Entità specifiche nel testo:') \n",
"print('ENTITY NAME',' '*(20-len('ENTITY NAME')), 'LABEL')\n",
"print('-------------------------------------')\n",
"for ent in doc.ents:\n",
" print(ent.text ,' '*(20-len(ent.text)), ent.label_)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1f5fafff",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "geografia",
"language": "python",
"name": "geografia"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.13"
}
},
"nbformat": 4,
"nbformat_minor": 5
}

Binary file not shown.

@ -0,0 +1,24 @@
# colemano
_un modulo scritto coi piedi_
Video/Image Recognition applicato all'interpretazione della lingua dei segni
Sono utilizzate delle reti neurali (link-wiki-NN) per il riconoscimento (preparazione ed allenamento in train/ASL).
Le reti utilizzate sfruttano il transfer-learning (link-wiki-transfer-learning)
per adesso è considerata solo la ASL (American Sign Language) perchè i dataset ed un bel po di script erano già pronti.
L'idea è di traslare il tutto anche con la LIS.
le due principali funzionalità sono:
- data un immagine o video predirre con i modelli allenati il segno e la parola associata.
- data una parola fornire un esempio grafico/fotografico/video del segno associato
## usage
per lanciare la demo con flask lancia il seguente script:
`python flask/app.py`
cerca di avere uno sfondo uniforme durante la ripresa.
apri il browser e vai su http://127.0.0.1:5000/

@ -0,0 +1,50 @@
#!/home//agropunx/anaconda3/envs/geografia/bin/python
#Import necessary librarie
from flask import Flask, render_template, request, Response, redirect,session
from flask_bootstrap import Bootstrap
import cv2, sys, os
di=os.path.dirname(os.path.abspath(__file__))
#sys.path.append('/'.join(di.split('/')[:-1]))
cur_dir = os.getcwd().split('/')[-1]
if cur_dir=='geografia':
sys.path.append('/'.join(di.split('/')[:-2]))
from colemano.src import colemano as clm
from colemano.src.config import *
else:
sys.path.append('/'.join(di.split('/')[:-1]))
from src import colemano as clm
from src.config import *
#Initialize the Flask app
app = Flask(__name__)
coso = clm.ColeMano()
@app.route('/',methods=['GET','POST'])
def index():
if ' ON ' in request.args:
coso.ison = True
elif 'OFF&RESET' in request.args:
coso.ison = False
coso.firstFrame = None
return render_template('index.html')
@app.route('/colemano_routine',methods=['GET','POST'])
def colemano_routine():
return Response(coso.flask_routine(), mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
try:
app.run(debug=True)
except:
cv2.destroyAllWindows()
finally:
cv2.destroyAllWindows()

@ -0,0 +1,46 @@
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"
integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<title>Live Streaming Demonstration</title>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-lg-8 offset-lg-2">
<h3 class="mt-5">Colemano Live Demo : riconoscimento American Sign Language</h3>
<img src="{{ url_for('colemano_routine') }}" width="100%">
</div>
</div>
<div class="row">
<div class="col-sm-8 offset-sm-2">
<h5 class='mt-1'>lascia lo sfondo nel riquadro blu piu neutro ed omogeneo possibile</h5>
</div>
</div>
<div class="row">
<div class="col-sm-8 offset-sm-2">
<h5 class='mt-1'>cerca di non apparire con i tuoi arti e corpicino la dentro quando fai partire il riconoscimento con i tasti qua sotto</h5>
</div>
</div>
<div class="row">
<div class="col-lg-8 offset-lg-2">
<h3 class="mt-3">Prediction On/Off</h3>
<form>
<input type="submit" name=" ON " value="ON">
<input type="submit" name="OFF&RESET" value="OFF">
</form>
</div>
</div>
</div>
</body>
</html>

@ -0,0 +1,233 @@
#!/usr/bin/python3
import traceback
import datetime, imutils, cv2, argparse,os,sys
from tensorflow.keras.models import load_model
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import numpy as np
cur_dir = os.getcwd().split('/')[-1]
if cur_dir=='colemano':
from src.config import *
elif cur_dir =='src':
from config import *
elif cur_dir=='geografia':
from colemano.src.config import *
elif cur_dir=='demo_flask':
sys.path.append('./..')
from src.config import *
class ColeMano():
def __init__(self, gestures_path=GESTURES_PATH,model_path=MODEL_PATH, predict_path=PREDICT_PATH):
self.model = load_model(model_path)
self.gestures_path = gestures_path
self.prepare_predict_path(predict_path)
self.init_gestures()
self.live=False
self.ison=False
def prepare_predict_path(self,predict_path):
self.predict_path = predict_path + '/0'
os.makedirs(self.predict_path,exist_ok=True)
for f in os.listdir(self.predict_path):
os.remove(f"{self.predict_path}/{f}")
def init_gestures(self):
self.datagen_root = ImageDataGenerator(
samplewise_center=True,
samplewise_std_normalization=True,
brightness_range=[0.8, 1.0],
zoom_range=[1.0, 1.2]
)
self.gestures = self.datagen_root.flow_from_directory(
self.gestures_path ,
target_size=TARGET_SIZE,
color_mode="rgb",
shuffle=False,
class_mode='categorical',
batch_size=1).class_indices
self.gestures = {v:k for k,v in self.gestures.items()}
def video_init(self, recorded_video=None):
if recorded_video:
self.video = cv2.VideoCapture(recorded_video)
self.live =False
else:
self.video = cv2.VideoCapture(-1)
self.live = True
print(f'video opened : {self.video.isOpened()}')
self.video.set(cv2.CAP_PROP_FRAME_WIDTH, 480)
self.video.set(cv2.CAP_PROP_FRAME_HEIGHT, 420)
def show_example(self,what):
if isinstance(what,int):
what=self.gestures[what]
def get_gray(self, frame):
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
return cv2.GaussianBlur(gray, (21, 21), 0)
def get_frame(self, bg_frame=None,x_origin=-1, y_origin=-1, width=-1, height=-1):
if not bg_frame:
success, bg_frame = self.video.read()
else:
success=True
if not success:
bg_frame = np.zeros((480,420,3))
if x_origin+y_origin+width+height>=4:
cv2.rectangle(bg_frame, (x_origin, y_origin), (x_origin + width, y_origin + height), (255, 0, 0), 2)
frame = bg_frame[x_origin:x_origin+width,y_origin:y_origin+height,:]
else:
frame=bg_frame
return bg_frame, frame
def thresholdContours(self,gray):
# compute the absolute difference between the current frame and first frame
frameDelta = cv2.absdiff(self.firstFrame, gray)
thresh = cv2.threshold(frameDelta, 25, 255, cv2.THRESH_BINARY)[1]
# dilate the thresholded image to fill in holes, then find contours on thresholded image
thresh = cv2.dilate(thresh, None, iterations=2)
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
return imutils.grab_contours(cnts)
def contoursLooper(self,frame, cnts,min_area=7000,show_contour_box=True):
# loop over the contours
current_area_sum=0
for ic,c in enumerate(cnts):
# if the contour is too small, ignore it
last_area = cv2.contourArea(c)
if last_area < min_area:
continue
current_area_sum += last_area
# compute the bounding box for the contour, draw it on the frame and update the text
if show_contour_box:
(x, y, w, h) = cv2.boundingRect(c)
cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2)
return current_area_sum
def predict_routine(self,gesture,ix=0,num_predict_samples=1):
if ix==num_predict_samples-1:
probs = self.model.predict(self.datagen_root.flow(self.frames,batch_size=1))
probs = np.mean(probs,axis=0) # or median
pred = np.argmax(probs)
gesture = self.gestures[pred]
elif ix==num_predict_samples:
ix=0
return gesture,ix
def routine_check(self,frame,ix,last_area_sum,current_area_sum, same_gesture_ratio=.3):
if last_area_sum==0:
last_area_sum=current_area_sum
key = cv2.waitKey(1) & 0xFF
if key == ord(QUIT_BUTTON):
ix=-1
elif (key == ord(PHOTO_BUTTON)) or ((current_area_sum!=0) and (abs((last_area_sum - current_area_sum) / last_area_sum) < same_gesture_ratio)):
self.frames[ix,...] = frame
ix+=1
return ix
def clean_cv2(self):
self.video.release()
cv2.destroyAllWindows()
def flask_routine(self, min_area=7000,same_gesture_ratio=0.3, num_predict_samples=3, show_contour_box=True):
if not self.live:
self.video_init()
self.firstFrame = None
last_area_sum=0
ix=0
gesture='no sign'
empty_frames = np.zeros((num_predict_samples,TARGET_SIZE[0],TARGET_SIZE[1],3))
self.frames = empty_frames.copy()
while True:
try:
bg_frame, frame = self.get_frame(None,X_ORIGIN,Y_ORIGIN,WIDTH,HEIGHT)
gray = self.get_gray(frame)
success=True
except Exception as e:
print(traceback.format_exc())
print("\n\n scostumat', non mi aspettavo proprio un errore come di cui sopra da te \n\n")
bg_frame = np.zeros((480,420,3))
bg_frame, frame = self.get_frame(bg_frame,X_ORIGIN,Y_ORIGIN,WIDTH,HEIGHT)
success=False
if self.ison and success:
gray = self.get_gray(frame)
# if the first frame is None, initialize it
if self.firstFrame is None:
self.firstFrame = gray
continue
cnts = self.thresholdContours(gray)
current_area_sum = self.contoursLooper(frame,cnts, min_area, show_contour_box)
ix=self.routine_check(frame,ix,last_area_sum,current_area_sum,same_gesture_ratio)
if ix<0:
break
gesture,ix = self.predict_routine(gesture, ix=ix, num_predict_samples=num_predict_samples)
last_area_sum=current_area_sum
cv2.putText(frame, "---> {} <---".format(gesture), (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
"""
else:
cv2.putText(bg_frame, "lascia lo sfondo nel riquadro piu neutro ed omogeneo possibile",(10,10),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,255),2)
cv2.putText(bg_frame, "cerca di non apparire con il tuo corpicino la dentro",(10,20),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,255),2)
cv2.putText(bg_frame, "infine premi start per iniziare il riconoscimento",(10,30),cv2.FONT_HERSHEY_SIMPLEX,0.5,(0,0,255),2)
"""
ret, buffer = cv2.imencode('.jpg', bg_frame)
frame = buffer.tobytes()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n') # concat frame one by one and show result
#yield bg_frame
print("\n\n chiudo tutte cose lisio \n\n")
self.clean_cv2()
def routine(self, min_area=7000,same_gesture_ratio=0.3, num_predict_samples=3, show_contour_box=True):
if not self.live:
self.video_init()
self.firstFrame = None
last_area_sum=0
ix=0
gesture='nada'
self.frames = np.zeros((num_predict_samples,TARGET_SIZE[0],TARGET_SIZE[1],3))
try:
while True:
bg_frame, frame = self.get_frame(None,X_ORIGIN,Y_ORIGIN,WIDTH,HEIGHT)
gray = self.get_gray(frame)
# if the first frame is None, initialize it
if self.firstFrame is None:
self.firstFrame = gray
continue
cnts = self.thresholdContours(gray)
current_area_sum = self.contoursLooper(frame,cnts, min_area, show_contour_box)
ix=self.routine_check(frame,ix,last_area_sum,current_area_sum,same_gesture_ratio)
if ix<0:
break
gesture,ix = self.predict_routine(gesture, ix=ix, num_predict_samples=num_predict_samples)
last_area_sum=current_area_sum
cv2.putText(frame, "---> {} <---".format(gesture), (10, 20), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
cv2.imshow("Colemano Reco",bg_frame)
print("\n\n chiudo tutte cose lisio \n\n")
self.clean_cv2()
except Exception as e:
print(traceback.format_exc())
print("\n\n scostumat', non mi aspettavo proprio un errore come di cui sopra da te \n\n")
finally:
self.clean_cv2()

@ -0,0 +1,24 @@
import os
cur_dir = os.getcwd().split('/')[-1]
WORK_DIR = 'colemano'
if cur_dir==WORK_DIR:
WORK_DIR='.'
elif (cur_dir=='demo_flask') | (cur_dir=='src'):
WORK_DIR='..'
elif cur_dir=='geografia':
WORK_DIR='colemano'
QUIT_BUTTON = 'q'
PHOTO_BUTTON = 'p'
MODEL_PATH = f'{WORK_DIR}/train/ASL/static/models/asl_static_D.h5'
GESTURES_PATH = f'{WORK_DIR}/src/ASL_gestures'
PREDICT_PATH = f'{WORK_DIR}/tmp_camera'
TARGET_SIZE=(200,200)
X_ORIGIN = 100
Y_ORIGIN = 100
WIDTH = 200
HEIGHT = 200

@ -0,0 +1,91 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# acchiappa il dataset WLASL\n",
"\n",
"__data source__:\n",
"\n",
"https://github.com/dxli94/WLASL"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"__scarica e prepara il dataset__ (comandi bash)"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"colemano$ git clone https://github.com/dxli94/WLASL.git ASL_train/WLASL\n",
"\n",
"# installa youtube-dl\n",
"colemano$ sudo curl -L https://yt-dl.org/downloads/latest/youtube-dl -o /usr/local/bin/youtube-dl\n",
"colemano$ sudo chmod a+rx /usr/local/bin/youtube-dl\n",
"\n",
"# Download video raw, ci mette un botto tipo 1 giorno\n",
"colemano$ cd ASL_train/WLASL/start_kit\n",
"ASL_train/WLASL/start_kit$ python3 video_downloader.py\n",
"\n",
"# Estrai i samples dai video\n",
"ASL_train/WLASL/start_kit$ python3 preprocess.py\n",
"\n",
"# un po di url sono stati spostati dalla pubblicazione, quindi lancia pure per richiederli agli autori,\n",
"# altrimenti sticaz, io l'ho fatto appena rimetto a posto metto tutti i dataset in condivisione.\n",
"# (di 20000 video circa un 1/3 son sparuti)\n",
"ASL_train/WLASL/start_kit$ python find_missing.py\n",
"# volendo si possono richiedere i videii mancanti in missing.txt agli autori"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"__transfer learning e training__ (sempre bash)"
]
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"ASL_train/WLASL/start_kit$ mv videos ../data/WLASL2000/\n",
"\n",
"# per fare transfer-learning automagico scarica weights.zip e archieved.zip, unzippali e mettili in WLASL/code/I3D.\n",
"# kinetics weights---> https://drive.google.com/uc?id=1JgTRHGBRCHyHRT_rAF0fOjnfiFefXkEd&export=download\n",
"# archieve---> https://drive.google.com/uc?id=1jALimVOB69ifYkeT0Pe297S1z4U3jC48&export=download\n",
"# poi,\n",
"\n",
"ASL_train/WLASL/start_kit$ cd ../code/I3D/\n",
"\n",
"# lancia il training, serve la gpu per adesso (12-01-2022)..\n",
"ASL_train/WLASL/code/I3D/$ train_i3d.py"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 4
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1,11 @@
tqdm
pandas
numpy
seaborn
matplotlib
cv2
sklearn
keras
tensorflow
torch
torchvision

File diff suppressed because one or more lines are too long

@ -0,0 +1,17 @@
name: geografia_research
dependencies:
- pip
- python=3.8
- numpy
- matplotlib
- ipykernel
- pytorch
- transformers
- torchvision
- cudatoolkit=10.2
- pip:
- imutils==0.5.4
- spacy==3.3.0
- opencv-python==4.2.0.32
- tensorflow==2.8.0

@ -0,0 +1,28 @@
#!/usr/bin/env bash
set -euo pipefail
# to install anaconda
# https://docs.anaconda.com/anaconda/install/linux/
source /home/agropunx/anaconda3/etc/profile.d/conda.sh
conda create -y --name geografia_research python=3.8 pip
conda activate geografia
# conda env
conda install -c anaconda ipykernel
python -m ipykernel install --user --name=geografia_research #-f ./geografia_research.yml
# general
pip install flask flask_bootstrap numpy pandas scipy
pip install protobuf==3.20
# colemano
pip install imutils==0.5.4
pip install tensorflow==2.8.0
pip install opencv-python==4.2.0.32
# ccq
pip install transformers==4.14.1
conda install pytorch torchvision torchaudio cudatoolkit=10.2 -c pytorch # cudatoolkit not present in pip
pip install spacy==3.3.0
Loading…
Cancel
Save