mercoledì 3 aprile 2024

Tensorflow e firme spettrali

Questa e' sola una prova di fattibilita', non ha interesse di uso pratico

Era un po' di tempo che volevo provare ad usare una rete neurale per classificare le firme spettrali da telerilevamento

Per semplicita' ho preso una immagine Sentinel 2 e selezionato 90 Pin sulla mappa (3 categorie: sedimenti fluviali, suolo nudo, vegetazione) per estrarre le firme tramite Optical/Spectrum View


 

C'e' da osservare che SNAP  estrae solo le bande Sentinel 2 a risoluzione a 10 m. Il file csv e' del tipo  (ho provato a fare il resampling per estrarre tutta la firma spettrale mostrata in grafico ma senza successo)

490,560,665,842,Classe
0.0737,0.0992,0.1278,0.2956,1
0.064,0.0882,0.1038,0.2976,1
0.0682,0.0964,0.1086,0.2792,1
0.0674,0.0956,0.1142,0.2832,1
0.0772,0.1046,0.1386,0.2642,1 

 

A questo punto ho modificato questo esempio di tensorflow basato sul dataset Iris sostituendo le feature della morfologia dei fiori con la risposta spettrale


import pandas as pd
import numpy as np
import tensorflow as tf
import seaborn as sns
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense,Dropout
from sklearn.preprocessing import LabelEncoder , StandardScaler
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score, confusion_matrix

df = pd.read_csv('spettri.csv')
print(df.head())

le = LabelEncoder()
df['classe'] = le.fit_transform(df['classe'])

X = df.drop(columns=['classe'])
y = df['classe']
print(y.head())
print(y.value_counts())

X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.25,shuffle=True,random_state=7)

sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)

print(y_train)
y_train = tf.keras.utils.to_categorical(y_train,num_classes=3)

def get_models():
model = Sequential([
Dense(units=32,input_shape=(4,),activation='relu'),
Dense(units=32,activation='relu'),
Dropout(0.5),
Dense(units=3,activation='softmax')
])
return model

model = get_models()
model.compile(optimizer='Adam',loss='categorical_crossentropy',metrics=['accuracy'])
model.summary()

model.fit(X_train,y_train,epochs=100, verbose=2)

prediction = model.predict(X_test)
prediction = np.argmax(prediction,axis=-1)
acury = accuracy_score(y_test,prediction)
print(acury)
cm = confusion_matrix(y_test,prediction)
print(cm)


In fase di test il perggior riconoscimento e' dell' 86%

Questa e' la matrice di confusione del risultato peggiore
 

[[7 1 0]
 [0 5 2]
 [0 0 8]]



Nessun commento:

Posta un commento

Ricampionare un segnale con SciPy

Un sistema rapido per ricampionare dati con spaziatura non omogenea  usando una curva di interpolazione   Dati originali   import matplotlib...