venerdì 3 maggio 2024

Regressione con tensorflow su dati di carbonati in suoli naturali

 Dopo aver trovato questo esempio sulla regressione con Tensorflow/Keras ho ritirato fuori un set di misure iperspettrali di laboratorio effettuato con FieldSpec in laboratorio per vedere se il metodo poteva essere utilizzato per la regressione della concentrazione di carbonati in campioni di terreno naturali

I campioni analizzati erano stati tutti setacciati a 0.075 mm ed erano stati passati in forno per eliminare l'umidita'. Di seguito gli spettri

Tutti i campioni sono stati analizzati in laboratorio per la determinazione chimica del contenuto in carbonato di calcio

Gli spettri sono stati letti dai file originali in .asd e convertiti in un csv mediante la libreria Python SpecDal 

L'ultima colonna e' il dato di laboratorio mentre le altre colonne corrispondono alla riflettanza alle differenti lunghezze d'onda e costituiscono le features


Ho provato a non effettuare la rimozione del continuum perche' le misure sono fatte in condizioni controllate su materiale preparato (con parita' di granulometria ed umidita')

Mediante lo script sottostante e' stata effettuata la regressione fino a 100 epochs (non si avevano vantaggi per numeri superiori). Il dataset originario di 40 misure e' stato diviso an 80% di addestramento (di cui 20% di validazione) e 20% di test



Dataset di validazione

Dataset di test

Durante il dottorato, su una serie differente ed usando la profondita' di picco normalizzata a 2345 nm, avevo avuto una regressione migliore utilizzando anche una matematica piu' semplice


L'aspetto interessante di questo approccio e' che non e' necessario conoscere a priori la lunghezza d'onda di assorbimento desiderato. L'algoritmo pur non conoscendolo esplicitamente lo invidua nelle features in modo autonomo


-*- coding: utf-8 -*-


import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

np.set_printoptions(precision=3, suppress=True)
import tensorflow as tf

from tensorflow import keras
from tensorflow.keras import layers

from google.colab import drive
drive.mount('/content/drive')

raw_dataset = pd.read_csv("/content/drive/MyDrive/calcite_vol_75.csv", sep=',')
dataset = raw_dataset.copy()

train_dataset = dataset.sample(frac=0.8, random_state=1)
test_dataset = dataset.drop(train_dataset.index)

print(train_dataset)

train_features = train_dataset.copy()
test_features = test_dataset.copy()

train_labels = train_features.pop('Calcite')
test_labels = test_features.pop('Calcite')

normalizer = tf.keras.layers.Normalization(axis=-1)
normalizer.adapt(np.array(train_features))

def build_and_compile_model(norm):
  model = keras.Sequential([
      norm,
      layers.Dense(64, activation='relu'),
      layers.Dense(64, activation='relu'),
      layers.Dense(1)
  ])

  model.compile(loss='mean_absolute_error',
                optimizer=tf.keras.optimizers.Adam(0.001))
  return model

def plot_loss(history):
  plt.plot(history.history['loss'], label='loss')
  plt.plot(history.history['val_loss'], label='val_loss')
  plt.ylim([0, 10])
  plt.xlabel('Epoch')
  plt.ylabel('Error')
  plt.legend()
  plt.grid(True)

dnn_model = build_and_compile_model(normalizer)
dnn_model.summary()

plot_loss(history)

test_predictions = dnn_model.predict(test_features).flatten()

a = plt.axes(aspect='equal')
plt.scatter(test_labels, test_predictions)
plt.xlabel('True Values')
plt.ylabel('Predictions')
lims = [0, 30]
plt.xlim(lims)
plt.ylim(lims)
_ = plt.plot(lims, lims)

error = test_predictions - test_labels
plt.hist(error, bins=25)
plt.xlabel('Prediction Error ')
_ = plt.ylabel('Count')




Nessun commento:

Posta un commento

Geologi

  E so anche espatriare senza praticamente toccare strada asfaltata