Il progetto sulla carta sembra semplice: inquadri una serie di monete, e un algoritmo calcola la somma del denaro.
Ora complichiamo il tutto. In base alle nostre ridotte conoscenze:
- dobbiamo creare un modello, ed effettuare il training.
- occorre raccogliere quante più immagini possibili di monete, in diverso stato, da diverse angolazioni.
- il nostro è un problema di data classification.
Dimentico qualcosa? O meglio, sto considerando tutto? Certo che no! Ma è questo il bello. Pensi di dover scalare una montagna alta 500m, e quando giri l’angolo scopri che non avevi considerato la k tra 0 e m…

Possiamo procedere in due modi:
Alla cieca, pensando di essere i primi a tentare una simile impresa. Se così non fosse, andremo prima o poi incontro ai codici scritti da un altro pazzo come noi.
Oppure, iniziamo subito a vedere se qualche pazzo è disposto a condividere con noi i suoi progressi.

Seconda opzione all the life
Aspetta un attimo. Non è tanto un “vediamo se qualcun altro ha già fatto questo, e copiamolo spudoratamente” ma più un “ok, non sappiamo da dove partire. Vediamo se c’è qualcuno che ci può indicare la strada di partenza… per non perdere troppo tempo“.
Un tizio ha avuto la nostra stessa idea. Lui però pensava di creare un’app per android. Non perdo tempo a cerecare di capire se ha ottenuto qualche risultato decente, perché nel post su stackoverflow sembrava parrecchio confuso.
E’ vero, anche noi non sappiamo minimamente dove andare; ma siamo determinati. Molto. Lui non mi sembrava così determinato. Magari mi sbaglio… ma chissene. Procediamo
Da dove partiamo?

Questa immagine è stata prodotta da un’analisi di YOLO Object Detection standard, non ottimizzata per le monete.
Non è che AI sia proprio brava a identificare le monete… per carità, ti faccio i complimenti perché nemmeno io avrei capito che il pezzo di legno sotto fosse un tavolo, però… bere il latte con 20 centesimi è un po difficile
Andiamo con le maniere forti: “how train model scratch tensorflow“
Anzi, sarebbe meglio usare direttamente YOLO. mmmm facciamo più ricerche.
Perfetto ci siamo
Ho trovato questo articolo su medium, in cui l’autore spiega come ha creato un modello per identificare un pallone da calcio. Ci basiamo sul suo procedimento per creare il nostro modello.
Download dataset
Questo eroe ha creato il dataset che tanto ci interessa. Scarichiamo e procediamo oltre. Ok, è un po’ scarno ma proviamo a farcelo bastare.
Training process
Ricordi che stiamo procedendo senza sapere nulla? Perfetto.

Tienilo a mente. Infatti questo è il momento in cui non so cosa scrivere perché vorrei evitare di sparare un mucchio di muschiate. Quindi seguo l’istinto e vediamo dove arrivo. Se riesco a concludere qualcosa, magari provo a spiegarmi.
Andiamo! E invece…
E’ mattino. Sono le 7:41. Nuova giornata, nuova avventura, nuovi ostacoli, nuovi obiettivi.
Cosa sappiamo

Sarebbe il momento di prendere una bella lavagna bianca, un pennarello lavabile, e iniziare a stilare una lista di tutte le informazioni in nostro possesso così da focalizzare l’attenzione su singoli task.
In alternativa, usiamo il log da 0 a 0,001.
Dunque. Ehm Ehm. Schiariamoci la voce.
Attraverso un’analisi “YOLO” vogliamo che il computer rilevi e calcoli la somma del denaro presente in un’immagine (foto o video). Ci stiamo concentrando sulla prima parte: la rilevazione.
Il nostro punto di partenza è un sistema che non riconosce alcuna moneta, quindi vogliamo creare un classificatore che identifichi le varie “taglie” di euro. Questo significa che è necessario realizzare un modello e “allenarlo” (fase di traning).
Abbiamo già il nostro dataset, che tuttavia è lungi dal poter essere usato: mancano i “label”, cioè contiene delle foto che il computer non è capace di gestire. Dobbiamo spiegargli che la foto 1, ad esempio, è una moneta da 50 centesimi, mentre la 2 è una moneta da 2 euro.
Si tratta del così detto supervised learning ovvero “apprendimento supervisionato”.
Non solo, oltre a creare i “labels” dobbiamo specificare all’interno di un file *.xml in che posizione della foto si trova l’elemento che la nosta AI dovrà riconoscere. La creazione del file e l’attribuzione del label è svolta automaticamente da un programma ma ahimé siamo noi che dobbiamo, manualmente, identificare l’elemento che sarà usato nella fase di training.
Non finisce qui. Il traning è un’operazione lunga e complessa che svolge autonomamente la GPU e la CPU. Tuttavia è come il “Bimby”, cucina lui, ma devi mettere dentro i gisuti ingredienti o esce fuori una “pappa” muschiosa.
Nel nostro caso, non essendoci una ricetta (ovvero una guida che spieghi come e quali file usare, che abbiamo intenzione di creare), stiamo ancora cercando i giusti ingredienti.
Ripartiamo | Log 4: gli ingredienti per il training
Nuova fonte, tante risorse.
Torno indietro, sto facendo un back and forward tra cartelle e pagine web per capire, per imparare. In darkflow-master c’è una cartella “train” contenente due sotto-cartelle: “annotations” e “images”. Nella prima sono presenti i file in formato “*.xml” che fannno riferimento alle foto della seconda, e indicano in quale posizione si trovino gli elementi da analizzare.
Da quanto stiamo capendo, la notazione “*.xml” è compatibile solo con il traning sul PASCAL VOC Dataset. Ora. Cosa singnifica?
Ho diversi elementi che non riesco a collegare tra loro. La notazione “*.xml” è compatibile solo con il VOC dataset(?), ma io ho il mio dataset quindi perché mi serve il VOC? E se volessi non usarlo come potrei fare altrimenti? In che ordine devo mettere i labels? E come fa il sistema a capire che si riferiscono proprio a quelle foto?
Mi servono risposte.
Ho scaricato il VOC Dataset.
Ora credo di aver capito. Nella pagina di GitHub di darkflow, nella sezione training usa l’esempio del VOC. Facciamo chiarezza, il VOC Dataset… è un Dataset. Ora mi prendi per scemo, ma non avevo ancora realizzato. Io dicevo Dataset, e capivo “modello già allenato”, quindi pronto a riconoscere cose. Questo perché nella cartella cfg di darkflow, in cui sono presenti le strutture dei modelli e nella cartella bin, in cui sono presenti i modelli allenati, compaiono file con la dicitura “VOC” e questo mi ha fatto confondere.
Sembra che l’esempio si riferisca ad un re–train di modelli già esistenti, con l’aggiunta di nuovi elementi. Se così fosse dovrei trovare nel file label.txt due nomi che fanno riferimento agli oggetti che vogliamo identificare nelle foto fornite come esempio, presenti nella cartella test/training/images.
Quindi, “bike” e “horse” ? Apriamo il file labels.txt
Peccato. Sembrava un lampo di genio.

Quindi? Quindi continuiamo.
Proviamo ad eseguire il training sul VOC dataset e vediamo cosa succede, quali file produce e come si comportano questi file. Se ho ragione, il risultato dovrebbe essere un file weights (il nostro modello allenato) compatibile con il cfg in input (la struttura del nostor modello).
Un apppunto: label.txt è usato solo quando viene riconosciuto un file .cfg estraneo al dataset COCO o VOC, in questo caso invece sono caricati i rispettivi labels.
A questo punto, dobbiamo solo capire come modificare il file cfg.
Apro yolo_voc.cfg, noto che nella sezione [region], classes=20. E’ il nostro file perché, dopo aver controllolato sul sito ufifciale, le classi del dataset Pascla VOC sono effettivamente 20.
Creo un nuovo file voc.cfg, identico al preecedente.
Eseguo comando:
python flow –model cfg/voc.cfg –train –dataset –annotation test/train/annotations –dataset test/train/JPEGImages –gpu 0.7
ERROR - Invalid argument: --dataset
Try running flow --help

Zio impanato. Modifico ed eseguo il comando:
python flow –model cfg/voc.cfg –train –annotation test/train/annotations –dataset test/train/JPEGImages –gpu 0.7
AssertionError: labels.txt and cfg/voc.cfg indicate inconsistent class numbers

Zio impanato. Cosa avevo detto?
Un apppunto: label.txt è usato solo quando viene riconosciuto un file .cfg estraneo al dataset COCO o VOC, in questo caso invece sono caricati i rispettivi labels.
Andrea Provino
Sa, modifichiamo labels.txt. Errore. Modifichiamo di nuovo togliendo la prima label “background”. Train partito, forse.
Zio impanato.
Error: Annotation directory not found test/train/annotations .
Ma che muschiata ho scritto?
Zio impanato al prosciutto. Ho cannato il percorso, di nuovo.
Invio comando:
python flow –model cfg/voc.cfg –train –annotation test/annotations –dataset test/JPEGImages –gpu 0.7
Ci siamo. Sta caricando gli xml. Label confermate. Training iniziato. Training fallito.

Zio impanato.
ERROR : Allocator (GPU_0_bfc) ran out of memory trying to allocate
ERROR: ResorucesExhaustError
python flow –batch 8 –model cfg/voc.cfg –train –annotation test/annotations –dataset test/JPEGImages –gpu 0.7
Ci siamo
Abbiamo un loss altissimo 110-107, dovrebbe arrivare intorno a 2-0… ne abbiamo di strada da fare. Ho dovuto abbassare il batch size. Ora inizio train con gpu 70%: 9:15.
Primo Checkpoint step 250 loss 106-104
Checkpoint 3750 loss 24, ave loss 26 (9:52)
Ho fermato manualmente il training a 7500 iterazioni, perché stava consumando troppa memoria. (15GB)
Abbiamo eseguito il comando:
python flow --model cfg/voc.cfg --load -1 --savepb
E sono stati creati i file voc.pb e voc.meta che corrispondono al weights e al cfg.
Niente da fare. Ho provato ad usare questi due file ma il risultato è nullo. Diverse sono le cose che potrebbero non funzionare:
- la fase di training eseguita in modo errato;
- considerazioni di fondo scorrette sulla natura dei file da usare
- processo di post-training sbagliato
Insomma, servono ulteriori indagini.
E’ arrivato il momento di chiudere questo LOG. Purtroppo con nessuna conclusione di fatto. Abbiamo imparato molto, ma non siamo riusciti nel nostro intento. Dopo aver cercato, pare siano necessari molte più ore di training. Conviene cambiare approccio.
Alla prossima!
Un caldo abbraccio, Andrea
No Comment