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]]