mercoledì 7 marzo 2018

Mandelbrot con TensorFlow

Questo esempio del calcolo dell'insieme di Mandelbrot e' compreso all'interno del tutorial di TensorFlow. Lo scopo di questo post e' di capire come e' stato inserito il calcolo ricorsivo nella logica di TensorFlow tutta indirizzata all'utilizzo di matrici

Una osservazione : stranamente il calcolo e' molto lento. Credo che il problema sia dovuto alla logica con cui e' fatto il calcolo..invece di uscire dal ciclo di calcolo per ogni punto una volta che si e' raggiunta la soglia di fuga, con questo programma il calcolo viene rieffettuato su tutta la matrice per 200 volte



La logica: invece di effettuare il calcolo usando una matrice e a celle singole
-----------------------------
import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
     
#MANDELBROT SET 520x600
# crea due array di 520x600 -1.3<X<1.3 -2<Y<1
# a passo 0.005
Y, X = np.mgrid[-1.3:1.3:0.005, -2:1:0.005]

#Crea una array di numeri complessi Z moltiplicando Y per sqrt(-1) (che in 
#in numpy e' j
Z = X+1j*Y

#trasforma l'array Z in un formato tensorflow
c = tf.constant(Z.astype("complex64"))

# popola la variabile zs con x
zs = tf.Variable(c)
# popola la variabile ns con tutti gli elementi a zero 
# e delle dimensioni di c, qui ci sara' il risultato del
# della divergenza
ns = tf.Variable(tf.zeros_like(c, "float32"))

#qui viene impiegata una sessione interattiva ma si puo' sostituire il comando con
# tf.Session()
# tanto non e' necessario il debug

sess = tf.InteractiveSession()
tf.initialize_all_variables().run()

# Compute the new values of z: z^2 + x
#zs_ e' una variabile transitoria su
#cui viene calcolata la ricorsione
zs_ = zs*zs + c

# se il modulo di zs e' minore di 4 
# salvalo nella matrice not_diverged
# nella matrice not_diverged viene salvato
# il valore boolean della condizione <4
# quindi nella matrice not_diverged ci sono 
# 0 ed 1
not_diverged = tf.abs(zs_) < 4

#tf.group raggruppa piu' operazioni
#copia la matrice transitoria zs_ su zs per continuare
# l'iterazione
# aggiunge poi alla matrice inizializzata  tutta a zeri (ns)
# il contenuto della matrice dei punti che non hanno fatto
#  modulo > 4. In questo modo viene creata una mappa
#di quanti cicli su ogni cella sono necessari
step = tf.group(
  zs.assign(zs_),
  ns.assign_add(tf.cast(not_diverged, "float32"))
  )

#200 cicli di iterazione della sessione
for i in range(200): step.run()

#mosta la matrice ns come immagine
plt.imshow(ns.eval())
plt.show()

Vacanze sul Sole

E dopo aver prenotato un posto sulla missione Insight per Marte adesso destinazione Sole con Parker Solar Probe .. devo informarmi un po' sulle date di partenza o se c'e' un taxi tra il Sole e Marte





domenica 4 marzo 2018

Supervised Classification USGS Spectral Library

Dopo aver letto le note introduttive di TensorFlow (l'insieme di librerie di Machine Learning di Google) ed in particolar modo l'esempio sulla classificazione degli Iris sulla base di elementi morfologici mi e' venuta la domanda se il metodo era applicabile anche al telerilevamento iperspettrale, oggetto della mia tesi di dottorato.

Il problema a questo punto era prima di tutto trovare una base dati di training il piu' possibile popolata di elementi (in dottorato ho fatto collezione di spettri ma non organizzate in modo tale da essere utili allo scopo) e la scelta e' caduta su USGS Spectral Libray (gia' usata qui) in particolare per la sezione degli spettri del satellite Hyperion, oramai dismesso ma che e' stato anche lui oggetto di parte della tesi

Visto che a lavoro mi sto occupando in questi di minerali della famiglia dell'asbesto (http://debiaonoldcomputers.blogspot.it/2018/02/actinolite-e-tremolite-ad-impruneta.html) ho provato ad estrarre gli spettri di actinolite, tremolite e serpentino.
In totale il dataset, costituito dalle 3 classi, e' da 23 campioni da 234 bande (nel database gli spettri sono in numero maggiore ma sono stati scelti solo quelli che avevano un campionamento omogeneo)

Gli spettri sono stati tutti normalizzati prima di entrare nel file del dataset.
Si poteva a questo punto si fare l'analisi con le sole componenti principali (PCA analysis) per rendere il dataset piu' piccolo eliminando tutti i dati autocorrelati oppure dare in pasto all'algoritmo tutto lo spettro; ho provato con la seconda strada per vedere come si comportava il codice di calcolo

Nel dettaglio sono stati scelti

Actinolite
s07HYPRN_Actinolite_HS22.1B_ASDFRb_AREF
s07HYPRN_Actinolite_HS22.2B_ASDFRb_AREF
s07HYPRN_Actinolite_HS22.3B_ASDFRb_AREF
s07HYPRN_Actinolite_HS22.4B_ASDFRb_AREF
s07HYPRN_Actinolite_HS116.1B_ASDFRb_AREF
s07HYPRN_Actinolite_HS116.2B_ASDFRb_AREF
s07HYPRN_Actinolite_HS116.3B_ASDFRb_AREF
s07HYPRN_Actinolite_HS116.4B_ASDFRb_AREF
s07HYPRN_Actinolite_HS315.1B_ASDFRb_AREF
s07HYPRN_Actinolite_HS315.2B_ASDFRb_AREF

Tremolite

s07HYPRN_Tremolite_HS18.1B_ASDFRc_AREF
s07HYPRN_Tremolite_HS18.2B_ASDFRc_AREF
s07HYPRN_Tremolite_HS18.3_BECKc_AREF
s07HYPRN_Tremolite_HS18.3B_ASDFRc_AREF
s07HYPRN_Tremolite_HS18.3B_NIC4ccc_RREF
s07HYPRN_Tremolite_HS18.4B_ASDFRc_AREF
s07HYPRN_Tremolite_NMNH117611.HCl_BECKb_AREF
s07HYPRN_Tremolite_NMNH117611.HCL_NIC4bb_RREF

Serpentino
s07HYPRN_Serpentine_HS8.2B_ASDFRc_AREF
s07HYPRN_Serpentine_HS8.3B_ASDFRc_AREF
s07HYPRN_Serpentine_HS8.3B_BECKc_AREF
s07HYPRN_Serpentine_HS8.4B_ASDFRc_AREF
s07HYPRN_Serpentine_HS8.6_ASDFRc_AREF
s07HYPRN_Serpentine_HS318.1B_ASDFRc_AREF
s07HYPRN_Serpentine_HS318.2B_ASDFRc_AREF
s07HYPRN_Serpentine_HS318.3B_ASDFRc_AREF
s07HYPRN_Serpentine_HS318.4B_ASDFRc_AREF
s07HYPRN_Serpentine_HS318.4B_BECKc_AREF
s07HYPRN_Serpentine_HS318.6_ASDFRc_AREF



Ho provato ad usare TensorFlow per il calcolo ma mi e' decisamente ostico. Ho trovato che l'analisi del dataset Iris era stato trattato in questo post trattato con la libreria SkLearn,  con associate le librerie esterne Pandas e NumPy. I data sono tutti contenuti in un file, sia il training che il test dataset; il dataset sara' diviso in due dalla funzione train_test_split (in questo caso su 23 campioni viene scelto il 20% dei dati come parte di test del modello)

La prima riga del file all_data.txt e' costituito da un header con i nome delle 234 bande e un campo finale del nome (quindi la tabella e' di 235x24 celle)

-----------------------------------------
import pandas as pd
import numpy as np

dataset = pd.read_csv("all_data.txt")

X = dataset.iloc[:,:233].values
y = dataset['classe'].values

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20, random_state = 82)

from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

# Fitting Multiclass Logistic Classification to the Training set
from sklearn.linear_model import LogisticRegression

logisticregression = LogisticRegression()
logisticregression.fit(X_train, y_train)

LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
penalty='l2', random_state=None, solver='liblinear', tol=0.0001,
verbose=0, warm_start=False)

# Predicting the Test set results
y_pred = logisticregression.predict(X_test)
print(y_pred)

#lets see the actual and predicted value side by side
y_compare = np.vstack((y_test,y_pred)).T

#actual value on the left side and predicted value on the right hand side
#printing the top 5 values
y_compare[:5,:]

# Making the Confusion Matrix
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test, y_pred)
print(cm)

#finding accuracy from the confusion matrix.
a = cm.shape
corrPred = 0
falsePred = 0

for row in range(a[0]):
for c in range(a[1]):
if row == c:
corrPred +=cm[row,c]
else:
falsePred += cm[row,c]
print('Correct predictions: ', corrPred)
print('False predictions', falsePred)
print ('Accuracy of the multiclass logistic classification is: ', corrPred/(cm.sum()))
------------------------------

Il risultato finale e' seguente

[[2 0 0]
 [0 2 0]
 [0 0 1]]
('Correct predictions: ', 5)
('False predictions', 0)

('Accuracy of the multiclass logistic classification is: ', 1)


Per prova ho deliberatamente messo nel test dataset uno spettro con una classificazione sbagliata. Il risultato e' che l'algoritmo mi ha riportato un errore di classificazione...quindi direi che funziona

Il dataset e' sicuramente modesto e si possono fare miglioramenti ma direi che lo scopo e' stato raggiunto. La cosa interessante sarebbe ripetere questa esperienza con TensorFlow









venerdì 2 marzo 2018

Evadere da un proxy server (definitivo)

Tempo fa (un bel po') avevo provato ad aprire una sessione SSH attraverso il proxy aziendale fallendo miseramente



Adesso mi sono rimesso a studiare il problema con un po' piu' di attenzione.
Con poca fatica ho scoperto che il prxy aziendale e' uno Squid che di default tiene aperte queste porte


L'intuizione di usare la porta 443 per configurare un server SSH esterno come ponte era giusta ma mancavano un po' di dettagli. 
Prima di tutto ho scoperto che un server SSH su Linux puo' essere messo in ascolto su piu' porte..basta aggiungere nella configurazione del demone SSHD /etc/ssh/sshd_config una porta aggiuntiva alla 22 (altrimenti tutti gli altri servizi gia' attivi li perdevo) ovvero la 443

Port 22
Port 443

si ricarica la configurazione ed il server SSH risponde alle due porte (ovviamente il web server non ha la necessita' di https)

la macchina di ufficio e' un Windows e di solito uso Putty. Si deve configurare oltre alla connessione anche il proxy spuntando HTTP ed inserendo IP e porta del proxy



e come direbbe Joe Dalton ... LIBERO!!


Pulizie di (quasi) primavera

Regola numero 1: non tenere bottiglie aperte sulla scrivania del lavoro specialmente quando hai il portatile

Regola numero 2 : non mangiare alla scrivania di lavoro, specialmente cose che si sbriciolano


Regola numero 3 : ricordati di fare pulizia periodica della tastiera

Forse devo fare pulizia

Piu' nel dettaglio
Regola numero 4 : NON PERDERE I TASTI !! (li devi rimontare)

mercoledì 28 febbraio 2018

Reverse SSH con Lan Turtle

Un paio un po' di premesse

1) l'hardware non e' male .... il problema e' dal punto di vista software fa veramente schifo. E' molto meglio andare in shell e configurarsi tutto a mano

2) Nonostante abbia pagato la spedizione mi sono trovato la sorpresa della dogana. Non era meglio indicarlo prima ?'

3) l'hardware ripeto non e' male....ma sono cose che si possono fare con qualsiasi Raspberry o simili. L'unico vantaggio reale e' che il dispositivo e' molto anonimo...certo che si prevedeva l'alimentazione POE (e non come unica fonte dal lato USB) non era necessario attaccare un trasformatore od un powerbank che in un rack di rete attirano decisamente l'attenzione. Se si usa una porta USB dello switch si deve installare un dongle Data Blocker per evitare che si apra la porta sul 172.xxx.xxx.xxx

4) E' possibile configurare la Lan Turtle solo se si connettono insieme la USB e il cavo Ethernet. Solo con la USB connessa non si riesce ad entrare in SSH nonostante il dispositivo sia acceso

5) Visto le lamentele di molti utenti NON ho fatto l'update del firmware alla v.4




Dopo le premesse si inizia: Lan Turtle e' un dispositivo che puo' essere utile per amministrare le proprie reti oppure per violare reti altrui...in ogni caso si deve accesso fisico alla rete. E' costituito da una porta USB (che viene configurata come una scheda di rete virtuale) che si usa per la configurazione del dispositivo all'indirizzo 172.16.84.1 (con DHCP Server) ed una porta Ethernet (con un DHCP client). Quando si inserisce in un computer la scheda e' completamente trasparente e non si ha la necessita' di installare driver...tutto il traffico in entrata ed in uscita dal computer viene instradato in modo trasparente tra le due interfacce
La documentazione ufficiale si trova qui https://www.hak5.org/gear/lan-turtle/docs
Una volta entrati come root con la password di default sh3llz (e' richiesto il cambio al primo accesso) si entra in un menu di amministrazione (richiamabile da shell con il comando turtle) ma si fa prima a non usarlo perche' e' molto buggato (almeno per la parte autossh)

Prima di procedere alla configurazione di autossh si deve creare la chiave SSH e si deve effettuare lo scambio con il server esterno da cui controllare Lan Turtle. Per verificare che cio' sia avvenuto in modo corretto se ci ci connette in SSH da shell non dovra' essere richiesta la password (in questa fase ho riscontrato un problema ma i codici di errori erano sparsi per tutto lo schermo...meglio usare le vecchie maniere) 
Questa e' l'interfaccia di amministrazione di AutoSSH ... come si vede accanto all'IP del server remoto c'e' un carattere apice...non l'ho messo io...lo mette in automatico Lan Turtle ed il bello e' che lo scrive anche nel file /etc/init.d/autossh rendendolo lo script non eseguibile

Una volta fatta la configurazione si dovrebbe avviare AutoSSH ogni reboot....ma non funziona.
il file /etc/config/autossh configurato a mano e che funziona e' il seguente
-----------------------------------
config autossh
option gatetime '0'
option monitorport '20000'
option poll '600'

option ssh '-i /root/.ssh/id_rsa -N -T -R 2222:localhost:22 luca@xxx.xxx.xxx.xxx'
-----------------------------------

La soluzione per avviare AutoSSH al boot e' quella di configurare il file /etc/rc.local
/etc/init.d/autossh enable

Comunque puo' essere interessante fare un giro a questo link per vedere quanti problemi software ha questo dispositivo. In caso di problemi il reset del firmware e' possibile ma non immediato

USGS Spectral Library Convex Hull con Octave

Questo post e' l'inizio di un lavoro sulle reti neurali applicate a dati iperspettrali (il tema della mia tesi di dottorato)

Per usare una rete neurale e' necessario avere una ottima base dati di training ed ho scelto l'archivio USGS Spectral Library scaricabile liberamente e con dati in formato testuale



Il primo lavoro da fare e' quello di normalizzare gli spettri. Quando ero all'Universita' avevo accesso ad una licenza di Matlab ma adesso devo impiegare Octave, la versione Open Source di Matlab.
Questo metodo e' descritto nell'articolo

Two GUIs-based analysis tool for spectroradiometer data pre-processing

----------------------------------------------------------------------------------
close all
clear all

filename = 's07HYPRN_Actinolite_HS22.2B_ASDFRb_AREF.txt';
fid = fopen (filename, "r");
conta = 0;
nr = 2;
dati = [];

#aggiunge uno zero in testa 
#serve per rendere il calcolo di Convex Hull
#piu' affidabile
dati = [dati;0];

#legge tutte le righe del file saltando
#la prima ed inserendo il tutto in array
while (!feof(fid))
  text_line = fgetl(fid);
  #salta la prima riga descrittiva
  if (conta > 0)
    transi = str2num(text_line);
    # salta in valori NULL
    if (transi > 0)
      dati = [dati;transi];
      nr = nr +1;
      endif
  endif
  conta = conta + 1;
endwhile
fclose (fid);

#aggiunge uno zero in coda
#serve per rendere il calcolo di Convex Hull
#piu' affidabile
dati = [dati;0];


x = 1:1:nr;
reshape(x,1,nr);

#calcola la convex hull dello spettro
cx = convhull(x,dati);

#rende continua la convex hull 
#la convex hull viene calcolata di default
#come una spezzata di segmenti
xq = 1:1:nr;
vq1 = interp1(x(cx),dati(cx),xq);

#divide ogni valore di riflettanza per il corrispondente
#valore della convex hull per ottenere valori normalizzati
dati2 = reshape(dati,1,nr);
normalizzato = dati2./vq1;

#plotta i dati 
plot(x(cx),dati(cx),'r-',x,vq1,'b*',x,normalizzato,"g*");

#salvi i dati normalizzati in un file csv
normalizzato = normalizzato(2:nr-1);

#il nome del file normalizzato ha un prefisso "norm_"
filename = ["norm_" filename];
dlmwrite(filename,normalizzato);

Debugger integrato ESP32S3

Aggiornamento In realta' il Jtag USB funziona anche sui moduli cinesi Il problema risiede  nell'ID USB della porta Jtag. Nel modulo...