Visualizzazione post con etichetta Tensorflow Lite. Mostra tutti i post
Visualizzazione post con etichetta Tensorflow Lite. Mostra tutti i post

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

sabato 4 gennaio 2020

Analisi degli errori rete neurale foraminiferi

Aggiornamento

ho visto che il programma label_inmage.py prevede anche degli switch che settano i valori di input_mean e input_std (di default sono impostati a 127.5 entrambi i valori)

modificando questi parametri cambiano anche in maniera sensibili i risultati dello stesso file di modello tflite. Con una configurazione differente non ci sono classi particolarmente penalizzate


allo stesso modo anche make_image_classifier possono essere cambiate le epoch, il learning rate, batch size, momentum (gradient descent)

====================================================================

Questo al momento e' il miglior risultato della rete neurale sui foraminiferi

Si nota abbastanza chiaramente che la classe Globigerinita Glutinata ha un tasso di riconoscimento del tutto errato. Le altre classi hanno prestazioni migliori con risultati intorno al 60% di corrette identificazioni
Per cercare di isolare il problema ho isolato gli errori del set di test


Globigerina Bulloides

Gli score di corretti riconoscimenti sono compresi tra 0.83 e 0.33


GB 280

Globigerina Bulloides 280  scambiata per Globigerinoides Sacculifer  score 0.51

GB 315

Globigerina Bulloides 315  scambiata per  Globigerinoides Ruber   score 0.51

Globigerinita Glutinata 

Gli score di corretti riconoscimenti sono compresi tra 0.59 e 0.35

GG 1406

Globigerinita Glutinata 1406 identificata dalla rete neurale come Globigerina Bulloides con score 0.35. La seconda piu' probabile identificazione con score 0.33 era Gobigerinita Glutinata ovvero la classe corretta

GG 1449
Globigerinita Glutinata 1449 identificata dalla rete neurale come Globigerina Bulloides con score 0.67.

GG 265
Globigerinita Glutinata 265 identificata dalla rete neurale come Neogloboquadrina Pachyderma con score 0.60.

GG 564
Globigerinita Glutinata 564 identificata dalla rete neurale come Neogloboquadrina Pachyderma con score 0.76.

GG 68

Globigerinita Glutinata 68 identificata dalla rete neurale come Globigerinoides Sacculifer con score 0.55.


GG 765
Globigerinita Glutinata 765 identificata dalla rete neurale come Neogloboquadrina Pachyderma con score 0.65.

GG 822
Globigerinita Glutinata 882 identificata dalla rete neurale come Neogloboquadrina Pachyderma 

GG 955
Globigerinita Glutinata 955 identificata dalla rete neurale come Globigerinoides Ruber con score 0.7.

Globigerinoides Ruber


GR 1795


GR 1802

GR 1819
GR 355




lunedì 30 dicembre 2019

Retrain Model con dati di foraminiferi

Aggiornamento
Ho provato a fare girare il modello con dataset di train di 1000 e 1500 immagini

Dataset 1000 immagini per classe
57% di attribuzioni corrette


Dataset 1500 immagini per classe
56% di attribuzioni corrette



=======================================================================

Al posto di creare da zero un modello in Tensorflow per addestrare il riconoscimento di foraminiferi ho provato ad aggiungere le mie classi ad una rete gia' addestrata

Per fare cio' si deve aggiungere il supporto a Tensorflow HUB con

pip install "tensorflow~=2.0" 
pip install "tensorflow-hub[make_image_classifier]~=0.6"
Si lancia quindi il comando

make_image_classifier \
  --image_dir train \
  --tfhub_module https://tfhub.dev/google/tf2-preview/mobilenet_v2/feature_vector/4 \
  --saved_model_dir fora \
  --labels_output_file class_labels.txt \
  --tflite_output_file fora_mobile_model.tflite

Le immagini devono essere conformi al formato di mobilenet quindi devono avere una dimensione di 224x224 pixels

di default vengono selezionate 5 epoche ma si puo' cambiare il valore con lo switch --train_epochs

Ho iniziato con il dataset completo di 1500 immagini per 5 classi ma in modo non prevedibile il processo veniva killato senza preavviso. Si tratta di un problema di memoria cosi' sono sceso a 500 elementi per classe con una ram di 8Gb

Per effettuare l'inferenza (ovvero la previsione del modello su una immagine non contenuta nel training si usa lo script label_image.py

 https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/examples/python/label_image.py

python label_image.py -m fora_mobile_model.tflite -l class_labels.txt  -i test/a_globigerina_bulloides.1102.jpg 


I risultati sono leggermente peggiori del precedente post  : 22 corretti e 25 errati (46% corretti 54% errati) ma si nota in maniera netta come il riconoscimento di Globigerinita Glutinata sia totalmente sballato

martedì 19 novembre 2019

TensorFlow Lite Image Classification su Android

Per testare la image classification su TensorFlow Lite su Android si puo' scaricare il pacchetto

git clone https://github.com/tensorflow/examples



e si apre il progetto contenuto in
examples/lite/examples/image_classification/android/

La libreria di default riconosce un migliaio di oggetti

per modificare la libreria di default in modo da utlizzare i propri dati si aggiungono i file .tllite e le labels  in txt in /asssets del progetto. Con il comando "Find in Path...." si cercano le ricorrenze nel progetto di mobilenet_v1_1.0_224.tflite e labels.txt e si inseriscono i riferimenti ai file della propria libreria. Il file da modificare e' ClassifierFloatMobileNet.java e ClassifierQuantizedMobileNet.java 

Per riferimenti seguire il link

Riconoscimento foraminiferi con rete neurale Tensorflow Lite

Questo e' sempre stato uno dei miei sogni quando studiavo micropaleontologia....avere un sistema automatico (o semi automatico) che mi aiutasse nel riconoscimento di foraminiferi (planctonici del Miocene nel caso specifico)



Con Tensorflow Lite si puo' arrivare a qualcosa di simile
Prima di iniziare pero e' necessario avere una buona base di immagini....in cio' viene in aiuto il sito
http://www.endlessforams.org/ da cui e' possibile scaricare le fotografie di foraminiferi gia' classificati

Nello specifico, per il mio test, ho selezionato le prime 100 foto delle specie

Globigerina Falconensis
Globigerina Bulloides
Globigerinella Calida
Globigerinella Siphonifera
Globorotalia Crassiformis
Orbulina Universa

alcune sono state scelte volutamente con morfologia simile in modo da vedere il grado di risoluzione della macchina neurale. Queste 600 immagini sono in train dataset mentre sono state selezionate ulteriore 12 immagini (2 per specie) come test dataset; le immagini di test ovviamente non sono incluse nel set di apprendimento

Le immagini sono organizzate in una struttura di directory come in immagine seguente

In pratica il nome della directory e' la label utilizzata da Tensorflow per image recognition

E' giunto il momento di creare la libreria personalizzata di Tensorflow con il seguente script Python

Si apre il virtual environment con venv/bin/activate e si lancia

====================================================
from __future__ import absolute_import, division, print_function, unicode_literals

import numpy as np

import tensorflow as tf
assert tf.__version__.startswith('2')

from tensorflow_examples.lite.model_customization.core.data_util.image_dataloader import ImageClassifierDataLoader
from tensorflow_examples.lite.model_customization.core.task import image_classifier
from tensorflow_examples.lite.model_customization.core.task.model_spec import efficientnet_b0_spec
from tensorflow_examples.lite.model_customization.core.task.model_spec import ImageModelSpec

import matplotlib.pyplot as plt

image_path = "./foraminifera/"

data = ImageClassifierDataLoader.from_folder(image_path)
model = image_classifier.create(data)
loss, accuracy = model.evaluate()
model.export('fora_classifier.tflite', 'fora_labels.txt')
====================================================

a questo punto si e' pronti per testare la libreria con il seguente script
====================================================
"""label_image for tflite."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import argparse
import numpy as np

from PIL import Image

#import tensorflow as tf # TF2
import tflite_runtime.interpreter as tflite



def load_labels(filename):
  with open(filename, 'r') as f:
    return [line.strip() for line in f.readlines()]


if __name__ == '__main__':
  parser = argparse.ArgumentParser()
  parser.add_argument(
      '-i',
      '--image',
      default='./test_image/orbulina_test.jpg',
      help='image to be classified')
  parser.add_argument(
      '-m',
      '--model_file',
      default='fora_classifier.tflite',
      help='.tflite model to be executed')
  parser.add_argument(
      '-l',
      '--label_file',
      default='fora_labels.txt',
      help='name of file containing labels')
  parser.add_argument(
      '--input_mean',
      default=127.5, type=float,
      help='input_mean')
  parser.add_argument(
      '--input_std',
      default=127.5, type=float,
      help='input standard deviation')
  args = parser.parse_args()

  #interpreter = tf.lite.Interpreter(model_path=args.model_file)

  interpreter = tflite.Interpreter(model_path=args.model_file)

  interpreter.allocate_tensors()

  input_details = interpreter.get_input_details()
  output_details = interpreter.get_output_details()

  # check the type of the input tensor
  floating_model = input_details[0]['dtype'] == np.float32

  # NxHxWxC, H:1, W:2
  height = input_details[0]['shape'][1]
  width = input_details[0]['shape'][2]
  img = Image.open(args.image).resize((width, height))

  # add N dim
  input_data = np.expand_dims(img, axis=0)

  if floating_model:
    input_data = (np.float32(input_data) - args.input_mean) / args.input_std

  interpreter.set_tensor(input_details[0]['index'], input_data)

  interpreter.invoke()

  output_data = interpreter.get_tensor(output_details[0]['index'])
  results = np.squeeze(output_data)

  top_k = results.argsort()[-5:][::-1]
  labels = load_labels(args.label_file)
  for i in top_k:
    if floating_model:
      print('{:08.6f}: {}'.format(float(results[i]), labels[i]))
    else:
      print('{:08.6f}: {}'.format(float(results[i] / 255.0), labels[i]))
====================================================

lo script si lancia con la sintassi

(venv) luca@debian:~/tensor/tf_spectra/fora$ python classify_image_2.py -i ./test_image/crassaformis_test.jpg

in pratica con lo switch -i si indica il file immagine di test di cui si vuole riconoscere l'immagine

un risultato di esempio e'

(venv) luca@debian:~/tensor/tf_spectra/fora$ python classify_image_2.py -i ./test_image/crassaformis_test.jpg
INFO: Initialized TensorFlow Lite runtime.
0.823927: globorotalia_crassaformis
0.098882: globigerina_bulloides
0.031008: globigerinella_calida
0.023761: globiferina_falconensis
0.015816: orbulina_universa

in pratica l'immagine di test di una Globorotalia Crassaformis e' stato riconosciuta al 83% di confidenza con la giusta classificazione
Mettendo in tabella i risultati


In verde la corretta attribuzione, in arancione attribuzione errata da parte della rete neurale

commentando i risultati si osserva che su 12 test 8 hanno portato ad un corretto riconoscimento, con punteggi molto alti in caso di foraminiferi molto caratteristici come le Orbuline, in un caso e' stato individuato in modo corretto il genere ma non la specie, mentre nei due rimanenti casi di errata classificazione l'errore e' molto marcato

1. Hsiang AY, Brombacher A, Rillo MC, Mleneck-Vautravers MJ, Conn S, Lordsmith S, Jentzen A, Henehan MJ, Metcalfe B, Fenton I, Wade BS, Fox L, Meilland J, Davis CV, Baranowski U, Groeneveld J, Edgar KM, Movellan A, Aze T, Dowsett H, Miller G, Rios N, Hull PM. (2019) Endless Forams: >34,000 modern planktonic foraminiferal images for taxonomic training and automated species recognition using convolutional neural networks. Paleoceanography & Paleoclimatology, 34. https://doi.org/10.1029/2019PA003612
2. Elder L.E., Hsiang A.Y., Nelson K., Strotz L.C., Kahanamoku S.S., Hull P.M. Sixty-one thousand recent planktonic foraminifera from the Atlantic Ocean. Scientific Data 5: 180109. https://doi.org/10.1038/sdata.2018.109
3. Rillo M.C., Whittaker J., Ezard T.H.G., Purvis A., Henderson A.S., Stukins S., Miller C.G. 2016. The unknown planktonic foraminiferal pioneer Henry Buckley and his collection at The Natural History Museum, London. Journal of Micropalaeontology. https://doi.org/10.1144/jmpaleo2016-020

Tour de France Firenze Gran Depart

  Poagcar Wout Van Aert Vingegaard       Van Der Poel