Leggendo di Enigma mi e' venuta la voglia di provar a scrivere una versione in Python..rendendomi conto che non e' proprio banale
La prima cosa che ho imparato a mie spese e' che si deve progettare tutto in modo simmetrico perche' la codifica e la successiva decodifica avvengono con le stesse impostazione
In un primo momento avevo usato un array per simulare un rotore ma lo avevo creato inserendo dei valori a caso. Invece per permettere che la decodifica segua lo stesso percorso (all'inverso della codifica) l'array non puo' essere creato a caso ma le posizioni devono essere reciproche...meglio con un esempio...se la posizione 5 dell'array contiene un valore 13 la posizione 13 deve contenere il vaore 5
================================================================================
import numpy as np
import readchar
# a b c d e f g h i j k l m n o p q r s t u v w x y z
# 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
plugboard = np.array([16,21,11,15,18,25, 9,22,14, 6,20, 2,13,12, 8, 3, 0,23, 4,24,10, 1, 7,17,19, 5])
rotore_1 = np.array([ 6,10,16,25,20,18, 0,23,17,11, 1, 9,15,19,24,12, 2, 8, 5,13, 4,22,21, 7,14, 3])
rotore_2 = np.array([25,24,23,22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0])
rotore_3 = np.array([17,22,25, 8,16,20,19,14, 3,23,12,24,10,18, 7,21, 4, 0,13, 6, 5,15, 1, 9,11, 2])
riflettore = np.array([24, 5,11,16,21, 1,25,23,10,22, 8, 2,13,12,18,20, 3,19,14,17,15, 4, 9, 7, 0, 6])
while True:
c = readchar.readkey()
print(c),
print(ord(c)-97),
pg = plugboard[ord(c)-97]
print("PG "+str(pg)),
r1 = rotore_1[pg]
print("/R1 "+str(r1)),
r2 = rotore_2[r1]
print("/R2 "+str(r2)),
r3 = rotore_3[r2]
print("/R3 "+str(r3)),
ri = riflettore[r3]
ri_2 = riflettore[ri]
print("/RI "+str(ri)),
print("/RI2 "+str(ri_2)),
r3 = rotore_3[ri_2]
print("/R3 "+str(r3)),
r2 = rotore_2[r3]
print("/R2 "+str(r2)),
r1 = rotore_1[r2]
================================================================================
Questa e' la base con tutti i passaggi nei rotori, nella plugboard e nel riflettore
Il problema e' che il dopo il primo passaggio il primo rotore esegue una rotazione per cambiare in automatico il percorso di criptazione ma al momento non sono riuscito ad utilizzare in modo semplice la rotazione dell'array
giovedì 20 febbraio 2020
venerdì 7 febbraio 2020
Dumpster Diving Samsung GT-S5280
E' abbastanza incredibile cosa si trovi nella raccolta differenziata delle batterie. Questa volta e' toccato ad un Samsung GT-S5280 (a cui per ironia della sorte avevano tolto proprio la batteria oltre alla Sim Card ed alla SD Card...falla a capire la logica delle persone)
Ovviamente e' partita la sfida a rimetterlo in vita.
All'accensione era presente un pattern lock....ho provato a fare un po' di tentativi di sblocco a caso ma senza successo. Non volevo resettarlo perche' ero curioso di vedere in che condizioni era il telefono (ovviamente non era mio interesse accedere ad account privati o foto...le avrei rimosse senza guardarle). Ho provato a cliccare su Forgot Pattern ma questa opzione mi ha portato alla richiesta di Pin ... vallo ad indovinare...1234...No....0000... Entrato, troppo facile.
Alla fine il precedente proprietario aveva fatto un Factory Reset (ma allora perche' mettere il Pattern Lock?) ma in ogni caso il telefon e' perfettamente funzionante e si e' aggiornato per diverse volte (Samsung ha ancora sui server gli aggiornamenti per un telefono del 2013!)
Ovviamente e' partita la sfida a rimetterlo in vita.
All'accensione era presente un pattern lock....ho provato a fare un po' di tentativi di sblocco a caso ma senza successo. Non volevo resettarlo perche' ero curioso di vedere in che condizioni era il telefono (ovviamente non era mio interesse accedere ad account privati o foto...le avrei rimosse senza guardarle). Ho provato a cliccare su Forgot Pattern ma questa opzione mi ha portato alla richiesta di Pin ... vallo ad indovinare...1234...No....0000... Entrato, troppo facile.
Alla fine il precedente proprietario aveva fatto un Factory Reset (ma allora perche' mettere il Pattern Lock?) ma in ogni caso il telefon e' perfettamente funzionante e si e' aggiornato per diverse volte (Samsung ha ancora sui server gli aggiornamenti per un telefono del 2013!)
giovedì 6 febbraio 2020
Conteggio automatico film radon con OpenCV
Per lavoro puo' essere che puo' essere che mi trovi a dover contare delle lastre dei rilevatori di radon e volevo provare a fare qualcosa di mio con OpenCV. Per prova ho preso delle immagini da Google Images e le ho trattate con OpenCV e gli Hough Circles
Immagine non elaborata
Immagine non elaborata con sovrapposizione del riconoscimento e del numero degli eventi
questo e' il file Python che e' preso dagli esempi di OpenCV con minime modifiche
=======================================================
import cv2
import numpy as np
# Read image as gray-scale
img = cv2.imread('cr39film.png', cv2.IMREAD_COLOR)
cv2.imshow('Originale',img)
# Convert to gray-scale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Blur the image to reduce noise
img_blur = cv2.medianBlur(gray, 5)
# Apply hough transform on the image
circles = cv2.HoughCircles(img_blur, cv2.HOUGH_GRADIENT, 1, img.shape[0]/32, param1=50, param2=5, minRadius=0, maxRadius=10)
conta = 0
# Draw detected circles
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0, :]:
# Draw outer circle
#cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)
# Draw inner circle
conta=conta+1
cv2.circle(img, (i[0], i[1]), 2, (0, 0, 255), 2)
print ("Numero identificazioni :"+str(conta))
cv2.imshow('tt',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
=======================================================
diciamo che nonostante il poco tempo dedicato al problema i risultati non sono niente male
Immagine non elaborata
Immagine non elaborata con sovrapposizione del riconoscimento e del numero degli eventi
![]() |
| Elabotazione Conteggio 126 eventi |
=======================================================
import cv2
import numpy as np
# Read image as gray-scale
img = cv2.imread('cr39film.png', cv2.IMREAD_COLOR)
cv2.imshow('Originale',img)
# Convert to gray-scale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Blur the image to reduce noise
img_blur = cv2.medianBlur(gray, 5)
# Apply hough transform on the image
circles = cv2.HoughCircles(img_blur, cv2.HOUGH_GRADIENT, 1, img.shape[0]/32, param1=50, param2=5, minRadius=0, maxRadius=10)
conta = 0
# Draw detected circles
if circles is not None:
circles = np.uint16(np.around(circles))
for i in circles[0, :]:
# Draw outer circle
#cv2.circle(img, (i[0], i[1]), i[2], (0, 255, 0), 2)
# Draw inner circle
conta=conta+1
cv2.circle(img, (i[0], i[1]), 2, (0, 0, 255), 2)
print ("Numero identificazioni :"+str(conta))
cv2.imshow('tt',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
=======================================================
![]() |
| Elaborazione Conteggio 175 eventi |
martedì 4 febbraio 2020
Number Station F03a
Ero sempre stato curioso delle Number Station e volevo provare ad ascoltarle ma ho scoperto che sono praticamente tutte in VLF con frequenze dell'ordine delle migliaia di KHz cioe' ben fuori dal sintonizzatore del mio dongle Usb SDR-RTL
Con questo servizio online si puo' esplorare senza troppi problemi queste frequenze
Il problema a questo punto e' che le trasmissioni di solito sono molto brevi. In questo ci viene in aiuto il sito priyom.org.
Sono riuscito a registrare la trasmissione dell'emittente FO3a alle 10:45 del 4 febbraio 2020 (sembra appartenere alla Polonia) ma ovviamente il tutto e' abbastanza inutile (non si tratta peraltro di una trasmissione con voce sintetica ma una vera e propria trasmissione dati da decodificare per la presenza di una modulazione)
Con questo servizio online si puo' esplorare senza troppi problemi queste frequenze
Il problema a questo punto e' che le trasmissioni di solito sono molto brevi. In questo ci viene in aiuto il sito priyom.org.
Sono riuscito a registrare la trasmissione dell'emittente FO3a alle 10:45 del 4 febbraio 2020 (sembra appartenere alla Polonia) ma ovviamente il tutto e' abbastanza inutile (non si tratta peraltro di una trasmissione con voce sintetica ma una vera e propria trasmissione dati da decodificare per la presenza di una modulazione)
lunedì 3 febbraio 2020
ADS-B con Dump1090
ADS-B e' un sistema per il controllo del traffico aereo su frequenza di 1.09 GHz che si puo' ricevere tranquillamente con un sistema RTL-SDR da pochi euro senza particolari antenne
Lo ho provato con il software dump1090 su Debian (ho dovuto compilare da sorgenti perche' non ho trovato il pacchetto apt su testing)
Una volta avviato il programma con
./dump1090 --interactive si puo' avere la lista dei dati ricevuti
Al momento la funzione --net non funziona perche' GMaps non e' piu pubblico
Usando FlightRadar24 e' stato possibile verificare che ricevevo anche distanti 100 Km (la stazione ricevente e' posizionata a Firenze)
Abilitando lo switch --raw si osservano i pacchetti esadecimali
Per il dettaglio della decodifica si rimanda a questo sito
-----------------------------------------------------------------------------------
*8d4caa77589704822c7d7a8719c8;
*8d4caa779910a2bcb0082dae0e6c;
*a00012b0b8adc570a8000482522a;
*a800118eba0a432ee01402fc49f1;
*5d4ca815fff886;
*5d3c6742ce5fc7;
*a000133bc4662330a800003a2dd4;
*a8000516a74a392f212c26c0885a;
*8d3c6742991418328004214c8854;
*02e192b030f0ca;
*a00012b0000000000000001d8a97;
*5d4caa77e1bd4d;
*02e197178f112b;
*02e197178f112b;
*02e197178f112b;
*8d4ca815f8230006004878f3f968;
*5d4b9067729b5b;
*02e197178f112b;
*8d3c674258b9715920c213e6d5d7;
*a00012b0b8adc570a8000482522a;
*a000133cc4662330a80000bddf33;
*02e1933c39b1b2;
*8d4caa77589700fd788cb9f6c050;
*8d4ca815e1051600000000a2765f;
*8d4ca815ea447865351c08d85a00;
*a0001717c6500031300000993d6b;
*80e1933c609bc1adaa921b079299;
*02e1933c39b1b2;
Lo ho provato con il software dump1090 su Debian (ho dovuto compilare da sorgenti perche' non ho trovato il pacchetto apt su testing)
Una volta avviato il programma con
./dump1090 --interactive si puo' avere la lista dei dati ricevuti
Al momento la funzione --net non funziona perche' GMaps non e' piu pubblico
Usando FlightRadar24 e' stato possibile verificare che ricevevo anche distanti 100 Km (la stazione ricevente e' posizionata a Firenze)
Abilitando lo switch --raw si osservano i pacchetti esadecimali
Per il dettaglio della decodifica si rimanda a questo sito
-----------------------------------------------------------------------------------
*8d4caa77589704822c7d7a8719c8;
*8d4caa779910a2bcb0082dae0e6c;
*a00012b0b8adc570a8000482522a;
*a800118eba0a432ee01402fc49f1;
*5d4ca815fff886;
*5d3c6742ce5fc7;
*a000133bc4662330a800003a2dd4;
*a8000516a74a392f212c26c0885a;
*8d3c6742991418328004214c8854;
*02e192b030f0ca;
*a00012b0000000000000001d8a97;
*5d4caa77e1bd4d;
*02e197178f112b;
*02e197178f112b;
*02e197178f112b;
*8d4ca815f8230006004878f3f968;
*5d4b9067729b5b;
*02e197178f112b;
*8d3c674258b9715920c213e6d5d7;
*a00012b0b8adc570a8000482522a;
*a000133cc4662330a80000bddf33;
*02e1933c39b1b2;
*8d4caa77589700fd788cb9f6c050;
*8d4ca815e1051600000000a2765f;
*8d4ca815ea447865351c08d85a00;
*a0001717c6500031300000993d6b;
*80e1933c609bc1adaa921b079299;
*02e1933c39b1b2;
venerdì 31 gennaio 2020
Tensorflow Lite su Arduino Ble 33
A questo link e' comparso un interessante esempio su come utilizzare i sensori (accelerometro e giroscopio) di una Arduino BLE per addestrare una rete neurale con Tensorflow Lite e poi utilizzare la stessa libreria per classificare le gesture sempre tramite Arduino
Per prova ho inserito la Arduino sotto ad un guanto (per tenerla bloccata) e poi registrando un centinaio di rotazione del polso verso l'interno e verso l'esterno
L'ultima modifica che ho apportato e' di modificare a 50 il numero di campioni per gesture
Una volta salvata due file csv (uno per movimento) ho utilizzato questo Colab per creare il file model. h
Come si deve dai grafici l'errore del modello in train/validation e' estremamente ridotto
Il risultato del Notebook sono un file di modello di Tensorflow Lite ed un file model.h che deve essere copiato nello sketch ImuClassifier per fare il deploy del modello
Devo ammettere che il sistema funziona ma e' lontano dall'essere perfetto. Devo ancora capire se e' un problema di posizionamento del sensore durante le varie proprie (che per ovvi motivi non e' sempre identico) od un addestramento errato
Per prova ho inserito la Arduino sotto ad un guanto (per tenerla bloccata) e poi registrando un centinaio di rotazione del polso verso l'interno e verso l'esterno
L'ultima modifica che ho apportato e' di modificare a 50 il numero di campioni per gesture
Una volta salvata due file csv (uno per movimento) ho utilizzato questo Colab per creare il file model. h
![]() |
| Grafico accelerazione di riferimento |
![]() |
| Grafico giroscopi di riferimento |
![]() |
| Training and validation loss |
![]() |
| Stesso grafico precedente eliminando i primi 100 dati |
![]() |
| Risultati validazione |
Il risultato del Notebook sono un file di modello di Tensorflow Lite ed un file model.h che deve essere copiato nello sketch ImuClassifier per fare il deploy del modello
Devo ammettere che il sistema funziona ma e' lontano dall'essere perfetto. Devo ancora capire se e' un problema di posizionamento del sensore durante le varie proprie (che per ovvi motivi non e' sempre identico) od un addestramento errato
SSTV da ISS 30/01/2020 17:33 GTM Firenze
Dopo aver avuto un contatto radio con la ISS via voce nel transito del 30 gennaio 2020 alle 17:33 GMT sono riuscito a registrare una trasmissione della ARISS SSTV
La ricezione e' avvenuta da Firenze con un normalissimo scanner radio palmare Icom IC-R5 ed antenna standard registrando l'audio direttamente dal cellulare
Per la cronaca avevo acceso anche un Baofeng UV-5R ma con questo dispositivo il segnala era praticamente sommerso dal rumore nonostante le due radio fossero a meno di 3 metri di distanza.
La decodifica e' stata effettuata con la applicazione Android Robot360
L'immagine e' stata poi postata al sito https://www.spaceflightsoftware.com/ARISS_SSTV/
Alla fine ho anche mandato ad Ariss SSTV Archive la mia immagine ed e' stato impressionante vedere il numero di radioamatori che hanno condiviso nello stesso momento le immagini a giro per il mondo
La ricezione e' avvenuta da Firenze con un normalissimo scanner radio palmare Icom IC-R5 ed antenna standard registrando l'audio direttamente dal cellulare
Per la cronaca avevo acceso anche un Baofeng UV-5R ma con questo dispositivo il segnala era praticamente sommerso dal rumore nonostante le due radio fossero a meno di 3 metri di distanza.
La decodifica e' stata effettuata con la applicazione Android Robot360
L'immagine e' stata poi postata al sito https://www.spaceflightsoftware.com/ARISS_SSTV/
Alla fine ho anche mandato ad Ariss SSTV Archive la mia immagine ed e' stato impressionante vedere il numero di radioamatori che hanno condiviso nello stesso momento le immagini a giro per il mondo
mercoledì 29 gennaio 2020
NOAA 18
Una volta capito come funziona ci si prende gusto. A questo giro ho provato a ricevere i dati dal satellite NOOA18, un satellite meteo in orbita polare
Il passaggio sull'Europa e' avvenuto alle 21:15 (GMT+1) del 28 gennaio (fonte https://www.heavens-above.com/)
La caratteristica di questo satellite e' che trasmette sui 137.912 MHz con una ampiezza di banda di 38 KHz. In WebSDR per allargare l'ampiezza di banda si deve selezionare FM e poi con il mouse selezionare ciascun estremo della banda e trascinarlo fino a quando non viene coperta tutta l'estenzione del segnale. Il segnale e' caratterizzato da una serie di righe parallele nella modalita' waterfall
Vista la frequenza di esercizio non potevo usare il WebSdr utilizzato per la ISS e mi sono spostato su questo link http://erc-websdr.esa.int/
Il passaggio sull'Europa e' avvenuto alle 21:15 (GMT+1) del 28 gennaio (fonte https://www.heavens-above.com/)
La caratteristica di questo satellite e' che trasmette sui 137.912 MHz con una ampiezza di banda di 38 KHz. In WebSDR per allargare l'ampiezza di banda si deve selezionare FM e poi con il mouse selezionare ciascun estremo della banda e trascinarlo fino a quando non viene coperta tutta l'estenzione del segnale. Il segnale e' caratterizzato da una serie di righe parallele nella modalita' waterfall
![]() |
| Waterfall |
![]() |
| Spettro |
Vista la frequenza di esercizio non potevo usare il WebSdr utilizzato per la ISS e mi sono spostato su questo link http://erc-websdr.esa.int/
Di fatto il problema principale con NOOA e' possedere una antenna a polarizzazione circolare destra
Il file .wav deve essere processato attraverso il software WxtoImg ma e' posssibile utilizzare anche https://noaa-apt.mbernardi.com.ar/
Se si usa WxtoImg si deve prima prendere il file .wav in uscita da WebSDR e processarlo con Audacity per ricampionarlo da 8000 Hz s 11025 Hz. Si salva il file ma cio' comporta che il nuovo file abbia un timestamp diverso dal file iniziale. Per correggere questo problema si utilizza il comando
touch -a -m -t 202001282130.00 t1.wav
dove il timestamp e' formato YYYYMMDDHHMM.SS
Il software si chiama in questo modo perche' il protocollo di trasmissione e' denominato WeFax ed e' in pratica molto simile al buon vecchio sistema Fax che si usava in ufficio
Il servizio APT e' invece una trasmissione di due immagini relative a due bande (in questo caso nel termico) di 2080 x 909 pixels
Elaborazioni con WxToImg
![]() |
| Temperatura Mare |
![]() |
| MCIR |
![]() |
| Tenpeartura |
se si usa noaa-apt i passi di cambio ora e resampling sono eseguiti in automatico e questo e' il risultato. Di fatto con questo software non possono essere eseguite elaborazioni. Le due bande vengono visualizzate a fianco con inclusa la banda di sincronia del segnale
Per confronto questa e' la stessa immagine acquisita da https://www.osservatoriometeoesismicoperugia.it/satellitipolari/index.html
La differenza principale e' che qui le nuvole sono bianche mentre in wxtoimg risultano grigie
La differenza principale e' che qui le nuvole sono bianche mentre in wxtoimg risultano grigie
martedì 28 gennaio 2020
ISS Ham Radio Luca Parmitano 27/01/2020 17:38 GMT
Erano anni che provavo ad ascoltare il canale amatoriale della Stazione Spaziale ISS sulla frequenza 145.800 MHz con radio sempre migliori (ma sempre a basso costo da scanner palmari a RTL-SDR)
Ma di fatto bisogna avere fortuna perche' i transiti della ISS sono di pochi minuti e di solito gli astronauti sono impegnati in altre cose (si tratta di una Ham Radio, non si tratta della radio effettiva di lavoro con il controllo missione)
Finalmente ci sono riuscito anche se non usando la mia apparecchiatura.
Visto che il transito sull'Europa era previsto quando non ero in casa mi sono collegato con il sito http://farnham-sdr.com/ dove si puo' usare una radio RTL-SDR a piacimento (l'antenna si trova nella parte meridionale dell'Inghilterra)
Tramite https://www.heavens-above.com/ era calcolato un transito alle 16:38 GMT (in Italia 17:38) e puntualmente come la ISS e' emersa dall'orizzonte ho visto il segnale sul waterfall
La cosa che mi ha fatto ancora piu' piacere e' stato trovare Luca Parmitano in trasmissione (avevo provato ad ascoltare anche nella precedente missione 36 senza nessun successo)
La cosa impressionante e' lo spostamente doppler del segnale. La frequenza di riferimento e' di 145.800 MHz ma quando emerge dall'orizzonte la frequenza e' oltre 145.803 MHz
per poi spostarsi rapidamente verso sinistra nello spettro, Nel momento di passaggio allo zenit lo spostamento Doppler e' cosi' rapido che la linea di riferimento sullo spettro e' chiaramente inclinata (la ISS e' dannatamente veloce!). Quando e' scomparsa all'orizzonte opposto la frequenza era vicino a 145.796 MHz
Ma di fatto bisogna avere fortuna perche' i transiti della ISS sono di pochi minuti e di solito gli astronauti sono impegnati in altre cose (si tratta di una Ham Radio, non si tratta della radio effettiva di lavoro con il controllo missione)
Finalmente ci sono riuscito anche se non usando la mia apparecchiatura.
Visto che il transito sull'Europa era previsto quando non ero in casa mi sono collegato con il sito http://farnham-sdr.com/ dove si puo' usare una radio RTL-SDR a piacimento (l'antenna si trova nella parte meridionale dell'Inghilterra)
Tramite https://www.heavens-above.com/ era calcolato un transito alle 16:38 GMT (in Italia 17:38) e puntualmente come la ISS e' emersa dall'orizzonte ho visto il segnale sul waterfall
La cosa che mi ha fatto ancora piu' piacere e' stato trovare Luca Parmitano in trasmissione (avevo provato ad ascoltare anche nella precedente missione 36 senza nessun successo)
La cosa impressionante e' lo spostamente doppler del segnale. La frequenza di riferimento e' di 145.800 MHz ma quando emerge dall'orizzonte la frequenza e' oltre 145.803 MHz
per poi spostarsi rapidamente verso sinistra nello spettro, Nel momento di passaggio allo zenit lo spostamento Doppler e' cosi' rapido che la linea di riferimento sullo spettro e' chiaramente inclinata (la ISS e' dannatamente veloce!). Quando e' scomparsa all'orizzonte opposto la frequenza era vicino a 145.796 MHz
lunedì 27 gennaio 2020
Mobike e BLE
Mentre stavo giocherellando con lo scanner Bluetooth LE mi e' apparso in lista un dispositivo Mobike ed ho visto che era stata appena parcheggiata una bicicletta a noleggio fuori dall'ufficio. Avevo sempre pensato che le Mobike fossero basate tutte su comunicazioni dati su rete cellulare ma a quanto sembra non e' proprio cosi..di fatto vengono esposte due servizi di uno scrivibile via BLE
c'e ovviamente chi ha fatto un'analisi decisamente piu' apprfondita
https://gsec.hitb.org/ materials/sg2018/D2%20-% 20Hacking%20BLE%20Bicycle% 20Locks%20for%20Fun%20and%20( a%20Small)%20Profit%20-% 20Vincent%20Tan.pdf
e c'e' anche chi ha smontato un lucchetto Mobike trovandoci dentro un modulo telefonico, un GPS ed un processore STM32
https://projectgus.com/2017/04/sharing-bikes-in-shanghai/
In ogni caso la gran parte del lavoro di scambio dati per lo sblocco e' svolto dal telefono del cliente
Sarei curioso di sapere come e' stato risolto da Mobike il problema di alimentare un sistema cosi' energivoro (GPS+Cellulare possono drenare in modo molto veloce le batterie)
c'e ovviamente chi ha fatto un'analisi decisamente piu' apprfondita
https://gsec.hitb.org/
e c'e' anche chi ha smontato un lucchetto Mobike trovandoci dentro un modulo telefonico, un GPS ed un processore STM32
https://projectgus.com/2017/04/sharing-bikes-in-shanghai/
In ogni caso la gran parte del lavoro di scambio dati per lo sblocco e' svolto dal telefono del cliente
Sarei curioso di sapere come e' stato risolto da Mobike il problema di alimentare un sistema cosi' energivoro (GPS+Cellulare possono drenare in modo molto veloce le batterie)
BLE Write Characteristic da Android
Dopo il precedente tentativo di leggere una caratteristica BLE da Python adesso un tentativo di scrivere una caratteristica (lo so e' una brutta traduzione) da Android su un dispositivo BLE
Lo sketch Arduino e' stato modificato per esporre una caratteristica 2A30 in modalita' lettura/scrittura, settare il valore a 3, leggere il valore e se e' differente da 3 spengere il Led di Arduino
=================================================================
#include <ArduinoBLE.h>
BLEService numero("180F");
BLEUnsignedCharCharacteristic casuale("2A19",BLERead | BLENotify);
BLEUnsignedCharCharacteristic scrittura("2A30",BLERead | BLEWrite);
long previousMillis = 0;
byte test =3 ;
void setup() {
Serial.begin(9600);
while (!Serial);
pinMode(LED_BUILTIN, OUTPUT);
if (!BLE.begin()) {
while (1);
}
BLE.setLocalName("Random");
BLE.setAdvertisedService(numero);
numero.addCharacteristic(casuale);
numero.addCharacteristic(scrittura);
BLE.addService(numero);
casuale.writeValue(0); // set initial value for this characteristic
scrittura.writeValue(2);
BLE.advertise();
}
void loop() {
int i = 0;
BLEDevice central = BLE.central();
if (central) {
while (central.connected()) {
long currentMillis = millis();
if (currentMillis - previousMillis >= 20) {
previousMillis = currentMillis;
scrittura.readValue(test);
if(test ==3)
{
Serial.println(test);
digitalWrite(LED_BUILTIN, HIGH);
}
else
{
Serial.println(test);
digitalWrite(LED_BUILTIN, LOW);
}
}
}
digitalWrite(LED_BUILTIN, LOW);
}
}
=================================================================
Per Android ho usato la libreria a questo indirizzo . Ne esistono di piu' complete ma
in questo caso avevo bisogno di semplicita'
=================================================================
Lo sketch Arduino e' stato modificato per esporre una caratteristica 2A30 in modalita' lettura/scrittura, settare il valore a 3, leggere il valore e se e' differente da 3 spengere il Led di Arduino
=================================================================
#include <ArduinoBLE.h>
BLEService numero("180F");
BLEUnsignedCharCharacteristic casuale("2A19",BLERead | BLENotify);
BLEUnsignedCharCharacteristic scrittura("2A30",BLERead | BLEWrite);
long previousMillis = 0;
byte test =3 ;
void setup() {
Serial.begin(9600);
while (!Serial);
pinMode(LED_BUILTIN, OUTPUT);
if (!BLE.begin()) {
while (1);
}
BLE.setLocalName("Random");
BLE.setAdvertisedService(numero);
numero.addCharacteristic(casuale);
numero.addCharacteristic(scrittura);
BLE.addService(numero);
casuale.writeValue(0); // set initial value for this characteristic
scrittura.writeValue(2);
BLE.advertise();
}
void loop() {
int i = 0;
BLEDevice central = BLE.central();
if (central) {
while (central.connected()) {
long currentMillis = millis();
if (currentMillis - previousMillis >= 20) {
previousMillis = currentMillis;
scrittura.readValue(test);
if(test ==3)
{
Serial.println(test);
digitalWrite(LED_BUILTIN, HIGH);
}
else
{
Serial.println(test);
digitalWrite(LED_BUILTIN, LOW);
}
}
}
digitalWrite(LED_BUILTIN, LOW);
}
}
=================================================================
Per Android ho usato la libreria a questo indirizzo . Ne esistono di piu' complete ma
in questo caso avevo bisogno di semplicita'
=================================================================
package com.ble.ellamma.ble; import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log; import com.ble.ellamma.bleand.Ble;
import java.util.UUID;
public class MainActivity extends AppCompatActivity { private static final String MAC_ADDRESS = "ED:CB:86:2A:68:C1"; private static final UUID BLE_NOTIFY_CHARACTER = UUID.fromString("00002a19-0000-1000-8000-00805f9b34fb"); //.00002a19-0000-1000-8000-00805f9b34fb--18 private static final UUID BLE_SERVICE = UUID.fromString("0000180f-0000-1000-8000-00805f9b34fb"); private static final UUID CLIENT_CCD = UUID.fromString("00002a30-0000-1000-8000-00805f9b34fb"); ArrayList<String> getDevicess; List<BluetoothDevice> getConnectedDevicess; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); getDevicess = new ArrayList<>();
getConnectedDevicess = new ArrayList<>(); Ble ble = new Ble(this,getApplicationContext(),".Myreceiver"); ble.enableBle();
//ble.scanLeDevice(true,1000);
//ble.getDevices(); ble.connectBLE(MAC_ADDRESS);
byte dati[] = "A".getBytes();
ble.writeCharacteristics(dati,BLE_SERVIVE,CLIENT_CCD,true);
ble.disConnectBLE(); } public void onReceive(Context context, Intent intent) { //String data = intent.getStringExtra("data");
//Log.w("Luca", "Request Recieved On MyReciever ::" + data); } }
venerdì 24 gennaio 2020
Lenovo Ultrabay HD e LVM
Dato che avevo uno slot libero sul mio Lenovo T430 mi sono comprato una estensione SATA per lo slot Ultrabay. Ho riutilizzato un disco SSD che ho preso da un'altra macchina ma al momento di montarlo sulla Debian Box non riuscivo a vederlo
Guardando con GParted il disco era formattato LVM. A questo punto ho scaricato il pacchetto LVM
apt-get install lvm2
con vgscan ho scansionato i dischi ed ho attivato il volume con
vgachange -ay centos
con lvs si possono vedere le partizioni sul disco. A questo punto si puo' montare il filesystem
mount /dev/centos/home /media/ -o ro,user
a questo punto per fare le cose per bene sarebbe da inserire in fstab. Per avere lo UUID si puo' digitare blkid
Guardando con GParted il disco era formattato LVM. A questo punto ho scaricato il pacchetto LVM
apt-get install lvm2
con vgscan ho scansionato i dischi ed ho attivato il volume con
vgachange -ay centos
con lvs si possono vedere le partizioni sul disco. A questo punto si puo' montare il filesystem
mount /dev/centos/home /media/ -o ro,user
a questo punto per fare le cose per bene sarebbe da inserire in fstab. Per avere lo UUID si puo' digitare blkid
giovedì 23 gennaio 2020
Cython
Era un po' di tempo che volevo provare Cython, la versione compilata di Python, ma non avevo mai avuto la necessita'. Con il trasferimento dati via BLE del precedente post pensavo che il collo di bottiglia fosse legato a Python e non al transfer rate di BLE ed ho cosi' convertito lo script in Python tramite Cython. In pratica il primo passo e' la conversione in C mentre il secondo passo e' una classica compilazione con GCC per avere un eseguibile
cython --embed -o ble_test.c ../ble_test.py
gcc -Os -I /usr/include/python2.7/ -o ble_test ble_test.c -lpython2.7 -lpthread -lm -util -ldl
...e no, il problema non era Python
cython --embed -o ble_test.c ../ble_test.py
gcc -Os -I /usr/include/python2.7/ -o ble_test ble_test.c -lpython2.7 -lpthread -lm -util -ldl
...e no, il problema non era Python
BLE Arduino Nano 33
Un eesmpio di scambio dati via Bluetooth LE tra una scheda Arduino Nano 33 BLE ed un PC
La Arduino Nano BLE 33 e' una scheda interessante perche' oltre al Bluetooth LE sono disponibili una IMU (LMS9DS1), un microfono digitale (MP34DT05), un sensore di colore e prossimita' (APDS9960), un sensore di pressione atmosferica (LPS22HB), un sensore di umidita' relativa e temperatura (HTS221)
Lo sketch su Arduino apre un servizio su BLE con numero 180F ed una caratteristica 2A19 in cui vengono salvati i dati di un contatore progressivo da 0 a 255 (questo per fare in modo che sul lato PC si sia in grado di vedere se si perdono pacchetti)
Lato Arduino
================================================
#include <ArduinoBLE.h>
BLEService numero("180F");
BLEUnsignedCharCharacteristic casuale("2A19",BLERead | BLENotify);
long previousMillis = 0;
void setup() {
Serial.begin(9600);
while (!Serial);
pinMode(LED_BUILTIN, OUTPUT);
if (!BLE.begin()) {
while (1);
}
BLE.setLocalName("Random");
BLE.setAdvertisedService(numero);
numero.addCharacteristic(casuale);
BLE.addService(numero);
casuale.writeValue(0); // set initial value for this characteristic
BLE.advertise();
}
void loop() {
int i = 0;
BLEDevice central = BLE.central();
if (central) {
digitalWrite(LED_BUILTIN, HIGH);
while (central.connected()) {
long currentMillis = millis();
if (currentMillis - previousMillis >= 20) {
i++;
casuale.writeValue(i%255);
previousMillis = currentMillis;
}
}
digitalWrite(LED_BUILTIN, LOW);
}
}
================================================
Per verificare che i dati vengano inviati correttamente si puo' usare gattool
================================================
gatttool -b ED:CB:86:2A:68:C1 -I
[ED:CB:86:2A:68:C1][LE]> connect
Attempting to connect to ED:CB:86:2A:68:C1
Connection successful
[ED:CB:86:2A:68:C1][LE]> char-read-uuid 2A19
handle: 0x000b value: 41
================================================
A questo punto con la libreria Bluepy si possono leggere i dati inviati dalla Arduino
================================================
from bluepy import btle
from bluepy.btle import UUID, Peripheral
addr = "ED:CB:86:2A:68:C1"
conn = Peripheral(addr, "public")
print ("-Servizi")
services = conn.getServices()
for service in services:
print(service.uuid)
print("-Caratteristica")
charac_dic = service.getCharacteristics()
for charac in charac_dic:
print(charac.uuid)
if charac.uuid == "2a19":
print ("Trovata")
Data_char = charac
print(Data_char)
Data_handle = Data_char.getHandle()
print Data_handle
while True:
print (ord(charac.read()))
La Arduino Nano BLE 33 e' una scheda interessante perche' oltre al Bluetooth LE sono disponibili una IMU (LMS9DS1), un microfono digitale (MP34DT05), un sensore di colore e prossimita' (APDS9960), un sensore di pressione atmosferica (LPS22HB), un sensore di umidita' relativa e temperatura (HTS221)
Lo sketch su Arduino apre un servizio su BLE con numero 180F ed una caratteristica 2A19 in cui vengono salvati i dati di un contatore progressivo da 0 a 255 (questo per fare in modo che sul lato PC si sia in grado di vedere se si perdono pacchetti)
Lato Arduino
================================================
#include <ArduinoBLE.h>
BLEService numero("180F");
BLEUnsignedCharCharacteristic casuale("2A19",BLERead | BLENotify);
long previousMillis = 0;
void setup() {
Serial.begin(9600);
while (!Serial);
pinMode(LED_BUILTIN, OUTPUT);
if (!BLE.begin()) {
while (1);
}
BLE.setLocalName("Random");
BLE.setAdvertisedService(numero);
numero.addCharacteristic(casuale);
BLE.addService(numero);
casuale.writeValue(0); // set initial value for this characteristic
BLE.advertise();
}
void loop() {
int i = 0;
BLEDevice central = BLE.central();
if (central) {
digitalWrite(LED_BUILTIN, HIGH);
while (central.connected()) {
long currentMillis = millis();
if (currentMillis - previousMillis >= 20) {
i++;
casuale.writeValue(i%255);
previousMillis = currentMillis;
}
}
digitalWrite(LED_BUILTIN, LOW);
}
}
================================================
Per verificare che i dati vengano inviati correttamente si puo' usare gattool
================================================
gatttool -b ED:CB:86:2A:68:C1 -I
[ED:CB:86:2A:68:C1][LE]> connect
Attempting to connect to ED:CB:86:2A:68:C1
Connection successful
[ED:CB:86:2A:68:C1][LE]> char-read-uuid 2A19
handle: 0x000b value: 41
================================================
A questo punto con la libreria Bluepy si possono leggere i dati inviati dalla Arduino
================================================
from bluepy import btle
from bluepy.btle import UUID, Peripheral
addr = "ED:CB:86:2A:68:C1"
conn = Peripheral(addr, "public")
print ("-Servizi")
services = conn.getServices()
for service in services:
print(service.uuid)
print("-Caratteristica")
charac_dic = service.getCharacteristics()
for charac in charac_dic:
print(charac.uuid)
if charac.uuid == "2a19":
print ("Trovata")
Data_char = charac
print(Data_char)
Data_handle = Data_char.getHandle()
print Data_handle
while True:
print (ord(charac.read()))
================================================
la trasmissione dati in questo modo e' piuttosto lenta..circa un dato ogni decimo di secondo.
Usando la tecnica di subscribe and notify la Arduino invia i dati al PC senza la necessita' per quest'ultimo di richiederli. Con questa tecnica non si perde nessun pacchetto
================================================
from bluepy import btle
from bluepy.btle import UUID, Peripheral
import struct
def listAll(p):
for svc in p.getServices():
print(svc.uuid.getCommonName())
for ch in svc.getCharacteristics():
print(" " + str(ch.valHandle) + ": " + ch.uuid.getCommonName())
class MyDelegate(btle.DefaultDelegate):
def __init__(self):
btle.DefaultDelegate.__init__(self)
def handleNotification(self, cHandle, data):
print(ord(data))
addr = "ED:CB:86:2A:68:C1"
p = btle.Peripheral(addr,"public")
services=p.getServices()
for service in services:
print(service.uuid)
p.setDelegate( MyDelegate() )
listAll(p)
svc = p.getServiceByUUID("0000180f-0000-1000-8000-00805f9b34fb")
ch = svc.getCharacteristics()[0]
p.writeCharacteristic(ch.valHandle+1, b'\x01\x00', withResponse=True)
while True:
if p.waitForNotifications(1.0):
continue
print "Waiting..."
from bluepy.btle import UUID, Peripheral
import struct
def listAll(p):
for svc in p.getServices():
print(svc.uuid.getCommonName())
for ch in svc.getCharacteristics():
print(" " + str(ch.valHandle) + ": " + ch.uuid.getCommonName())
class MyDelegate(btle.DefaultDelegate):
def __init__(self):
btle.DefaultDelegate.__init__(self)
def handleNotification(self, cHandle, data):
print(ord(data))
addr = "ED:CB:86:2A:68:C1"
p = btle.Peripheral(addr,"public")
services=p.getServices()
for service in services:
print(service.uuid)
p.setDelegate( MyDelegate() )
listAll(p)
svc = p.getServiceByUUID("0000180f-0000-1000-8000-00805f9b34fb")
ch = svc.getCharacteristics()[0]
p.writeCharacteristic(ch.valHandle+1, b'\x01\x00', withResponse=True)
while True:
if p.waitForNotifications(1.0):
continue
print "Waiting..."
martedì 21 gennaio 2020
Debian Bullseye e Xrandr
Mettendo a posto una Debian Testing BullsEye su un Lenovo Thinkpad serie T volevo usare il trucco di newrez per aumentare la risoluzione dello schermo ma nonostante tutto xrandr sembrava non funzionare
Ho scoperto dopo un po' che era in uso Wayland e cio' impediva l'uso di xrandr. A questo punto e' stato necessario editare il file /etc/gdm3/daemon.conf e decommentare WaylandEnable=false
Al successivo riavvio e' stato possibile far funzionare newrew semplicemente modificando LVDS1 a LDVS-1 e VGA1 a VGA-1
Ho scoperto dopo un po' che era in uso Wayland e cio' impediva l'uso di xrandr. A questo punto e' stato necessario editare il file /etc/gdm3/daemon.conf e decommentare WaylandEnable=false
Al successivo riavvio e' stato possibile far funzionare newrew semplicemente modificando LVDS1 a LDVS-1 e VGA1 a VGA-1
sabato 18 gennaio 2020
Copiare docker container su diverse macchine
Per spostare un container tra due macchine si procede prima creando un file .tar con docker save
docker save -o /home/luca/container.tar DOCKER_ID
per avere un tgz si puo' usare
docker save DOCKER_ID | gzip -c > container.tar.gz
una volta copiato il file sulla seconda macchina il container puo' essere installato con
docker load -i container.tar
facendo cosi' si avranno Repository e Tag impostati a <none>. Per completare il lavoro si usa
docker image tag DOCKER_ID nome_repository nome_tag
con DOCKER_ID recuperato tramite il comando docker image ls e impostando il nome_repository con la sintassi per esempio tensorflow/tensorflow mentre il nome_tag puo' essere per esempio latest
docker save -o /home/luca/container.tar DOCKER_ID
per avere un tgz si puo' usare
docker save DOCKER_ID | gzip -c > container.tar.gz
una volta copiato il file sulla seconda macchina il container puo' essere installato con
docker load -i container.tar
facendo cosi' si avranno Repository e Tag impostati a <none>. Per completare il lavoro si usa
docker image tag DOCKER_ID nome_repository nome_tag
con DOCKER_ID recuperato tramite il comando docker image ls e impostando il nome_repository con la sintassi per esempio tensorflow/tensorflow mentre il nome_tag puo' essere per esempio latest
giovedì 16 gennaio 2020
Single Step LSTM Time Series Tensorflow
Le serie tempo sono successioni di uno (univariata) o piu' parametri (multivariata) acquisiti da strumenti a cadenza regolari di tempo (il tempo definisce l'indice della serie)
A differenza di una serie normale di dati qui l'ordine assume una importanza perche' ciascun dato e' collegato a quello immediatamente successivo e antecedente in una successione che i matematici direbbero continua
Un metodo per poter prevedere il prossimo dato nella successione usando le reti neurali e' quello di usare l'approccio LSTM (Long Short Term Memory) riconducibili alle reti RNN
Il fato che il titolo indichi Single Step vuol dire che l'algoritmo e' in grado di individuare solo il valore della variabile al tempo T+1 e non e' possibile avere piu' dati previsti
Un sistema comodo per esplorare l'algoritmo e' quello di usare il codice a questo GitHub
Nel file di configurazione training_config.json si possono impostare le caratteristiche della rete neurale come i dati di train e test, il dropout ma soprattutto si imposa la window_size ovvero la grandezza della finestra che viene usata dall'algoritmo per calcolare il valore al tempo T+1
Per effettuare ho preso i dati della stazione meteo di Antella (localita' vicino a Firenze) nel periodo dicembre 2002 aprile 2010 con misure giornaliere della temperatura massima
i dati sono stati processati mediante il codice linkato in precedenza
Il risultato della validazione dei dati risulta sostanzialemente corretta
Nel grafico sottostante (ripreso da qui) si osservano tutti i limiti del metodo nel caso di estrapolazione di piu' di un valore sul tren futuro. Usando una finestra mobile e' stato simulata la previsione di trend nel futuro su varie porzioni dei dati e si vede abbastanza chiaramente che la predizione, essendo legata alla finestra dei dati immediatamente precedenti, puo; indurre anche errori grossolani
asdasd
A differenza di una serie normale di dati qui l'ordine assume una importanza perche' ciascun dato e' collegato a quello immediatamente successivo e antecedente in una successione che i matematici direbbero continua
Un metodo per poter prevedere il prossimo dato nella successione usando le reti neurali e' quello di usare l'approccio LSTM (Long Short Term Memory) riconducibili alle reti RNN
Il fato che il titolo indichi Single Step vuol dire che l'algoritmo e' in grado di individuare solo il valore della variabile al tempo T+1 e non e' possibile avere piu' dati previsti
Un sistema comodo per esplorare l'algoritmo e' quello di usare il codice a questo GitHub
Nel file di configurazione training_config.json si possono impostare le caratteristiche della rete neurale come i dati di train e test, il dropout ma soprattutto si imposa la window_size ovvero la grandezza della finestra che viene usata dall'algoritmo per calcolare il valore al tempo T+1
Per effettuare ho preso i dati della stazione meteo di Antella (localita' vicino a Firenze) nel periodo dicembre 2002 aprile 2010 con misure giornaliere della temperatura massima
i dati sono stati processati mediante il codice linkato in precedenza
Il risultato della validazione dei dati risulta sostanzialemente corretta
Nel grafico sottostante (ripreso da qui) si osservano tutti i limiti del metodo nel caso di estrapolazione di piu' di un valore sul tren futuro. Usando una finestra mobile e' stato simulata la previsione di trend nel futuro su varie porzioni dei dati e si vede abbastanza chiaramente che la predizione, essendo legata alla finestra dei dati immediatamente precedenti, puo; indurre anche errori grossolani
asdasd
mercoledì 15 gennaio 2020
Jupyter notebook inside docker
Per poter utilizzare un Notebook Jupyter contenuto all'interno di un container docker si avvia prima il container con una sintassi del tipo
docker run -it --rm -p8888:8888 -v /home/luca/Downloads/time-series-forecasting-rnn-tensorflow-master:/tmp2 -w /tmp2 intelaipg/intel-optimized-tensorflow:2.0.0-mkl-py3
montando la directory esterna al docker dove sono contenuti i notebook
a questo punto dall'interno del container si lancia
jupyter notebook --ip 0.0.0.0 --no-browser --allow-root
docker run -it --rm -p8888:8888 -v /home/luca/Downloads/time-series-forecasting-rnn-tensorflow-master:/tmp2 -w /tmp2 intelaipg/intel-optimized-tensorflow:2.0.0-mkl-py3
a questo punto dall'interno del container si lancia
jupyter notebook --ip 0.0.0.0 --no-browser --allow-root
Docker tensorflow ottimizzato per Intel
Usando la versione standard di Tensorflow distribuita da Google si nota il messaggio "Your CPU supports instructions that this Tensorflow binary was not compiled to use: AVX2 FMA"
Questo perche' la versione distribuita e' compilata per funzionare su un ampio spettro di calcolatori
La soluzione per avere una versione ottimizzata per tutte le istruzioni della CPU e' quella di compilare da sorgenti Tensorflow oppure di utilizzare dei container docker che gia' hanno il codice compilato ottimizzato. In questo senso vengono utili i container prodotti da Intel con il supporto MKL (Math Kernel for Deep Neural Network)
Vi sono versioni con Python 2.7
docker run -it -p 8888:8888 intelaipg/intel-optimized-tensorflow
e Python 3.6
Per modificare in modo permanente il container con le librerie di normale uso si lancia
docker run -it intelaipg/intel-optimized-tensorflow:2.0.0-mkl-py3 /bin/bash
docker commit Docker_ID intelaipg/intel-optimized-tensorflow:2.0.0-mkl-py3
Questo perche' la versione distribuita e' compilata per funzionare su un ampio spettro di calcolatori
La soluzione per avere una versione ottimizzata per tutte le istruzioni della CPU e' quella di compilare da sorgenti Tensorflow oppure di utilizzare dei container docker che gia' hanno il codice compilato ottimizzato. In questo senso vengono utili i container prodotti da Intel con il supporto MKL (Math Kernel for Deep Neural Network)
Vi sono versioni con Python 2.7
docker run -it -p 8888:8888 intelaipg/intel-optimized-tensorflow
e Python 3.6
docker run -it -p 8888:8888 intelaipg/intel-optimized-tensorflow:2.0.0-mkl-py3
Per modificare in modo permanente il container con le librerie di normale uso si lancia
e con pip si installano normalmente le librerie Python (per esempio Pandas, Matplotlib...)
al termine si fa exit e con
docker ps -a
si copia l'ID del container modificato. A questo punto con commit si modifica in modo definitivo il container
lunedì 13 gennaio 2020
Videoscrittura o computer
Frugando tra dei libri destinati al cestino ho trovato questo libro del 1984 "Scrivere con il computer" in cui l'autore ci guida alla domanda se sia meglio un sistema di video scrittura, come la serie Olivetti ETV, oppure un PC con Wordstar
Fa strano pensarlo ai giorni nostri ma ricordo che ai tempi del liceo (tipo 1987-1988) il professore di filosofia aveva acquistato un sistema di video scrittura mentre il professore di italiano usava un Olivetti M15
Fa strano pensarlo ai giorni nostri ma ricordo che ai tempi del liceo (tipo 1987-1988) il professore di filosofia aveva acquistato un sistema di video scrittura mentre il professore di italiano usava un Olivetti M15
giovedì 9 gennaio 2020
Foraminiferi Tensorflow : train vs retrain model con Tensorflow
Continua la mia battaglia personale con le reti neurali per il riconoscimento di foraminiferi.
Attualmente le strade percorse sono state due: la prima prevede di scrivere ed addestrare da zero una rete neurale CNN mentre la seconda prevede il retraining di reti gia' addestrate (nello specifico mobilenet v2 ed inception v3)
Quali sono i risultati migliori??
In entrambi i casi le corrette previsioni del modello si e' aggirato intorno al 60 % (quindi poco performante ma l'oggetto di studio e' di per se difficile anche per un umano)
La reale differenze e' che il modello con retrain ha la tendenza di indovinare o sbagliare completamente le previsioni mentre con la rete addestrata da zero la distribuzione di successi /insuccessi e' molto piu' distribuita
Attualmente le strade percorse sono state due: la prima prevede di scrivere ed addestrare da zero una rete neurale CNN mentre la seconda prevede il retraining di reti gia' addestrate (nello specifico mobilenet v2 ed inception v3)
Quali sono i risultati migliori??
In entrambi i casi le corrette previsioni del modello si e' aggirato intorno al 60 % (quindi poco performante ma l'oggetto di studio e' di per se difficile anche per un umano)
![]() |
| Retrain Inception v3 |
![]() |
| CNN Trained |
Predizione classificazione immagini con Tensorflow da modelli .h5
In un esempio precedente avevo usato il modello .tflite per fare predizione di classificazione immagine.
Il modello e' stato creato da un train di Inception
============================================================
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
import sys
import tensorflow as tf
import tensorflow_hub as hub
from keras.models import load_model
model = tf.keras.models.load_model('incept.h5', custom_objects={'KerasLayer':hub.KerasLayer})
#print(model.get_config())
from keras.preprocessing import image
img = image.load_img(sys.argv[1])# , target_size=(299,299,3))
img = image.img_to_array(img)
img = img.reshape((1,) + img.shape)
img = img/255
build_input_shape = img.reshape(-1,299,299,3)
#print (build_input_shape)
img_class=model.predict_classes(img)
print (sys.argv[1])
print(img_class)
Il modello e' stato creato da un train di Inception
============================================================
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
import sys
import tensorflow as tf
import tensorflow_hub as hub
from keras.models import load_model
model = tf.keras.models.load_model('incept.h5', custom_objects={'KerasLayer':hub.KerasLayer})
#print(model.get_config())
from keras.preprocessing import image
img = image.load_img(sys.argv[1])# , target_size=(299,299,3))
img = image.img_to_array(img)
img = img.reshape((1,) + img.shape)
img = img/255
build_input_shape = img.reshape(-1,299,299,3)
#print (build_input_shape)
img_class=model.predict_classes(img)
print (sys.argv[1])
print(img_class)
mercoledì 8 gennaio 2020
Conversione da formato .pd (saved_model) a tflite
Un file in formato .pb racchiude al suo interno un modello completo di grafo con calcoli e pesi e puo' essere utilizzato direttamente per il serving
Tflite e' invece il formato di TensorFlow Lite ed e' caratterizzato da ridotte dimesioni mediante model quantization e model pruning
Per passare da .pb a .tflite (il contrario non si puo' fare) si possono usare i programmi toco e tflite_converter (il file risultante e' equivalente)
toco --saved_model_dir ./fora --output_file test.tflite
Nella conversione, a seconda del livello di ottimizzazione, il modello tflite puo' performare in modo uguale od inferiore al modello completo
Tflite e' invece il formato di TensorFlow Lite ed e' caratterizzato da ridotte dimesioni mediante model quantization e model pruning
Per passare da .pb a .tflite (il contrario non si puo' fare) si possono usare i programmi toco e tflite_converter (il file risultante e' equivalente)
toco --saved_model_dir ./fora --output_file test.tflite
tflite_convert -output_file = model.tflite --saved_model_dir = my_dir
Nella conversione, a seconda del livello di ottimizzazione, il modello tflite puo' performare in modo uguale od inferiore al modello completo
Esempio Retraining an image classifier
Ho trovato un esempio completo per il retraining di un classificatore di immagini a questo link
https://colab.research.google.com/github/tensorflow/hub/blob/master/examples/colab/tf2_image_retraining.ipynb
Si tratta di un Jupyter Notebook in cui si puo' attivare data augmentation e fine tuning e si puo' scegliere tra MobileNet v2 e Inception v3. I dati presentano gia' uno split con il 20% destinato alla validazione e shuffle del training, shuffle sul training, dropout
Girando su Colab si ha a disposizione una istanza con 12 Gb di Ram ed una GPU da 16 Gb di ram.
Il modello viene salvato nel formato .pb ma puo' essere convertito in formato .tflite con una verifica di quanto si perda in prestazioni utilizzando il formato di TensorFlow Lite
per attivare ogni singola cella di codice si usa CTRL+Enter
il file puo' essere visualizzato, una volta scaricato dal proprio GDrive, con il comando
saved_model_cli show --dir fora2/ --all
https://colab.research.google.com/github/tensorflow/hub/blob/master/examples/colab/tf2_image_retraining.ipynb
Si tratta di un Jupyter Notebook in cui si puo' attivare data augmentation e fine tuning e si puo' scegliere tra MobileNet v2 e Inception v3. I dati presentano gia' uno split con il 20% destinato alla validazione e shuffle del training, shuffle sul training, dropout
Girando su Colab si ha a disposizione una istanza con 12 Gb di Ram ed una GPU da 16 Gb di ram.
Il modello viene salvato nel formato .pb ma puo' essere convertito in formato .tflite con una verifica di quanto si perda in prestazioni utilizzando il formato di TensorFlow Lite
per attivare ogni singola cella di codice si usa CTRL+Enter
il file puo' essere visualizzato, una volta scaricato dal proprio GDrive, con il comando
saved_model_cli show --dir fora2/ --all
----------------------------------------------------------------------------
MetaGraphDef with tag-set: 'serve' contains the following SignatureDefs:
signature_def['__saved_model_init_op']:
The given SavedModel SignatureDef contains the following input(s):
The given SavedModel SignatureDef contains the following output(s):
outputs['__saved_model_init_op'] tensor_info:
dtype: DT_INVALID
shape: unknown_rank
name: NoOp
Method name is:
signature_def['serving_default']:
The given SavedModel SignatureDef contains the following input(s):
inputs['input_1'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 224, 224, 3)
name: serving_default_input_1:0
The given SavedModel SignatureDef contains the following output(s):
outputs['output_1'] tensor_info:
dtype: DT_FLOAT
shape: (-1, 5)
name: StatefulPartitionedCall:0
Method name is: tensorflow/serving/predict
martedì 7 gennaio 2020
Iscriviti a:
Post (Atom)
LLama3 Anita
A seguito di questo post ho provato a vedere ho provato a vedere cosa accadeva ad utilizzare un modello specifico per la lingua italiana in...
-
Aggiornamento questo e' la risposta degli sviluppatori First of all, almost all operating systems on both mobile and laptop/desktop n...
-
La scheda ESP32-2432S028R monta un Esp Dev Module con uno schermo TFT a driver ILI9341 di 320x240 pixels 16 bit colore.Il sito di riferiment...
-
Questo post e' a seguito di quanto gia' visto nella precedente prova Lo scopo e' sempre il solito: creare un sistema che permet...










































