Ho provato ad usare Barrier, un software che permette di condividere tastiera e mouse tra piu' computer. Non si tratta di un clone di VNC perche' ogni computer deve avere il proprio monitor (non si puo' quindi fare amministrazione remota) e perche' le risorse non sono condivise (i programmi sono eseguiti sul calcolatore su cui vengono lanciati)
Si tratta quindi di un utilizzo un po' di nicchia ma che puo' essere comunque utile
Il programma esiste per Linux, Windows e Mac ed e' indifferente quale macchina fa da server (quella da cui vengono presi gli input di tastiera e mouse) e quali da client. L'unica cosa da impostare e' indicare l'IP della macchina server ed indicare l'hostname delle macchine client
Non sono riuscito a farlo funzionare su Gnome Shell di Debian in modalita' server ma la stessa macchina utilizzando I3 funziona bene
mercoledì 27 novembre 2019
martedì 26 novembre 2019
Classificazione binaria foraminferi con Tensorflow
Per continuare gli esperimenti questa una classificazione binaria con Tensorflow.
Le due categorie sono riprese dal precedente post (1500 elementi)
train
======================================================
import os
a_dir = os.path.join('./train/globigerinoides_ruber')
b_dir = os.path.join('./train/globigerina_bulloides')
print('globigerinoides_ruber images:', len(os.listdir(a_dir)))
print('globigerina_bulloides images:', len(os.listdir(b_dir)))
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
batch_size = 16
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPooling2D
from tensorflow.keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale=1/255)
train_generator = train_datagen.flow_from_directory(
'./train_binary',
target_size=(200, 200),
batch_size=batch_size,
shuffle=True,
class_mode='binary')
import tensorflow as tf
model = Sequential([
Conv2D(16, 3, padding='same', activation='relu', input_shape=(200, 200 ,3)),
MaxPooling2D(),
Conv2D(32, 3, padding='same', activation='relu'),
MaxPooling2D(),
Conv2D(64, 3, padding='same', activation='relu'),
MaxPooling2D(),
Flatten(),
Dense(512, activation='relu'),
Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
model.summary()
total_sample=train_generator.n
n_epochs = 15
history = model.fit_generator(
train_generator,
steps_per_epoch=int(total_sample/batch_size),
epochs=n_epochs,
verbose=1)
model.save('1500el_5classi_binary_model.h5')
======================================================
predict
======================================================
import tensorflow as tf
from tensorflow.keras import Model
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import sys
from numpy import asarray
import numpy as np
model = tf.compat.v2.keras.models.load_model('1500el_5classi_binary_model.h5')
image = Image.open(sys.argv[1])
image = image.resize((200,200))
pic = asarray(image)
pic = pic.astype('float32')
pic /= 255.0
pic=np.expand_dims(pic,axis=0)
prediction = model.predict(pic)
print(sys.argv[1])
float_formatter = "{:.2f}".format
np.set_printoptions(formatter={'float_kind':float_formatter})
print(prediction)
print()
======================================================
I risultati indicano 19 tentativi 13 corrette identificazioni (69%), 2 casi incerti (10.5%), 2 errori (10.5%)
Le due categorie sono riprese dal precedente post (1500 elementi)
Globigerinoides Ruber |
Globigerina Bulloides |
train
======================================================
import os
a_dir = os.path.join('./train/globigerinoides_ruber')
b_dir = os.path.join('./train/globigerina_bulloides')
print('globigerinoides_ruber images:', len(os.listdir(a_dir)))
print('globigerina_bulloides images:', len(os.listdir(b_dir)))
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
batch_size = 16
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Conv2D, Flatten, Dropout, MaxPooling2D
from tensorflow.keras.preprocessing.image import ImageDataGenerator
train_datagen = ImageDataGenerator(rescale=1/255)
train_generator = train_datagen.flow_from_directory(
'./train_binary',
target_size=(200, 200),
batch_size=batch_size,
shuffle=True,
class_mode='binary')
import tensorflow as tf
model = Sequential([
Conv2D(16, 3, padding='same', activation='relu', input_shape=(200, 200 ,3)),
MaxPooling2D(),
Conv2D(32, 3, padding='same', activation='relu'),
MaxPooling2D(),
Conv2D(64, 3, padding='same', activation='relu'),
MaxPooling2D(),
Flatten(),
Dense(512, activation='relu'),
Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
model.summary()
total_sample=train_generator.n
n_epochs = 15
history = model.fit_generator(
train_generator,
steps_per_epoch=int(total_sample/batch_size),
epochs=n_epochs,
verbose=1)
model.save('1500el_5classi_binary_model.h5')
predict
======================================================
import tensorflow as tf
from tensorflow.keras import Model
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import sys
from numpy import asarray
import numpy as np
model = tf.compat.v2.keras.models.load_model('1500el_5classi_binary_model.h5')
image = Image.open(sys.argv[1])
image = image.resize((200,200))
pic = asarray(image)
pic = pic.astype('float32')
pic /= 255.0
pic=np.expand_dims(pic,axis=0)
prediction = model.predict(pic)
print(sys.argv[1])
float_formatter = "{:.2f}".format
np.set_printoptions(formatter={'float_kind':float_formatter})
print(prediction)
print()
======================================================
I risultati indicano 19 tentativi 13 corrette identificazioni (69%), 2 casi incerti (10.5%), 2 errori (10.5%)
Globigerinoides Ruber | Globigerina Bulloides | |||
Predizione | ||||
Immagini reali | ||||
Globigerina Bulloides | 1 | 0% | 100% | |
2 | 100% | 0% | ||
3 | 0% | 100% | ||
4 | 0% | 100% | ||
5 | 0% | 100% | ||
6 | 58% | 42% | ||
7 | 47% | 53% | ||
8 | 0% | 100% | ||
9 | 0% | 100% | ||
Globigerinoides Ruber | 1 | 100% | 0% | |
2 | 0% | 100% | ||
3 | 63% | 37% | ||
4 | 100% | 0% | ||
5 | 100% | 0% | ||
6 | 94% | 6% | ||
7 | 0% | 100% | ||
8 | 0% | 100% | ||
9 | 100% | 0% | ||
10 | 100% | 0% |
venerdì 22 novembre 2019
Riconoscimento foraminiferi con rete neurale Tensorflow
Questa versione di codice prevede l'uso completo di Tensorflow Keras per creare delle classificazioni di immagini per il riconoscimento di foraminiferi(il codice e' stato adattato dal seguente link).
Spoiler: il modello ha effettuato il corretto riconoscimento di poco oltre il 54% dei tentativi...tirando a caso i successi stimati sarebbero del 20%
il dataaset non e' enorme ma si tratta di un esempio (immagini tratte da http://www.endlessforams.org/)
Sono state selezionate le specie con almeno 1500 immagini (ogni classe ha lo stesso numero di immagini in modo da non favorire nessuna classe nel training) e sono state selezionate le immagini a piu' alta qualita'
globigerinoides_ruber images: 1500
globigerina_bulloides images: 1500
globigerinita_glutinata images: 1500
globigerinoides_sacculifer images: 1500
neogloboquadrina_pachyderma images: 1500
le immagini dei foraminiferi sono classificate all'interno delle cartelle con il nome della rispettiva specie. Per questo esempio sono state selezionate 5 specie e quindi 5 classi
Si tratta quindi di algoritmi di image classification basati su class_mode=categorical
le immagini originali sono state tagliate dei 160 pixel alla base per togliere la banda bianca con le scritte
-------------------------------------------
for f in *.jpg
do
convert $f -gravity South -chop 0x160 a_$f
done
-------------------------------------------
===========================================================
i dati sono salvati in un file .h5
per la verifica del modello sono state selezionate 5 immagini per ogni classe che non erano comprese nel training con 15 epochs
questo e' lo script di predizione basato sulla libreria creata in precedenza (il nome del file immagine da esaminare viene passato sulla linea di comando)
============================================================
import tensorflow as tf
from tensorflow.keras import Model
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import sys
from numpy import asarray
import numpy as np
model = tf.compat.v2.keras.models.load_model('../1500el_5classi_model.h5')
image = Image.open(sys.argv[1])
image = image.resize((200,200))
pic = asarray(image)
pic = pic.astype('float32')
pic /= 255.0
pic=np.expand_dims(pic,axis=0)
prediction = model.predict(pic)
print(sys.argv[1])
float_formatter = "{:.2f}".format
np.set_printoptions(formatter={'float_kind':float_formatter})
print(prediction)
print()
============================================================
i risulati sono i seguenti
I risultati delle colonne seguenti sono in percentuali di affidabilita' (1=100%)
Aggiungedo un Dropout del 20% le cose migliorano ma non troppo
ho provato ad usare l'optimizer adam con 3 livelli di convoluzione ma i risultati sono stati peggiori
Spoiler: il modello ha effettuato il corretto riconoscimento di poco oltre il 54% dei tentativi...tirando a caso i successi stimati sarebbero del 20%
il dataaset non e' enorme ma si tratta di un esempio (immagini tratte da http://www.endlessforams.org/)
Sono state selezionate le specie con almeno 1500 immagini (ogni classe ha lo stesso numero di immagini in modo da non favorire nessuna classe nel training) e sono state selezionate le immagini a piu' alta qualita'
globigerinoides_ruber images: 1500
globigerina_bulloides images: 1500
globigerinita_glutinata images: 1500
globigerinoides_sacculifer images: 1500
neogloboquadrina_pachyderma images: 1500
Si tratta quindi di algoritmi di image classification basati su class_mode=categorical
le immagini originali sono state tagliate dei 160 pixel alla base per togliere la banda bianca con le scritte
-------------------------------------------
for f in *.jpg
do
convert $f -gravity South -chop 0x160 a_$f
done
-------------------------------------------
===========================================================
import os
a_dir = os.path.join('./train/globigerinoides_ruber')
b_dir = os.path.join('./train/globigerina_bulloides')
c_dir = os.path.join('./train/globigerinita_glutinata')
d_dir = os.path.join('./train/globigerinoides_sacculifer')
e_dir = os.path.join('./train/neogloboquadrina_pachyderma')
print('globigerinoides_ruber images:', len(os.listdir(a_dir)))
print('globigerina_bulloides images:', len(os.listdir(b_dir)))
print('globigerinita_glutinata images:', len(os.listdir(c_dir)))
print('globigerinoides_sacculifer images:', len(os.listdir(d_dir)))
print('neogloboquadrina_pachyderma images:', len(os.listdir(e_dir)))
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
batch_size = 16
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# riscala i valorei
train_datagen = ImageDataGenerator(rescale=1/255)
train_generator = train_datagen.flow_from_directory(
'./train',
target_size=(200, 200), # tutte le immagini vengono riscalate a 200x200. Gli originali sono circa 400x640
batch_size=batch_size,
classes = ['globigerinoides_ruber','globigerina_bulloides','globigerinita_glutinata','globigerinoides_sacculifer','neogloboquadrina_pachyderma'],
class_mode='categorical')
import tensorflow as tf
model = tf.keras.models.Sequential([
# The first convolution
tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(200, 200, 3)),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
# softmax deve essere impostato al numero di classi
tf.keras.layers.Dense(5, activation='softmax')
])
model.summary()
from tensorflow.keras.optimizers import RMSprop
model.compile(loss='categorical_crossentropy',
optimizer=RMSprop(lr=0.001),
metrics=['acc'])
total_sample=train_generator.n
n_epochs = 15
history = model.fit_generator(
train_generator,
steps_per_epoch=int(total_sample/batch_size),
epochs=n_epochs,
verbose=1)
model.save('1500el_5classi_model.h5')
===========================================================
a_dir = os.path.join('./train/globigerinoides_ruber')
b_dir = os.path.join('./train/globigerina_bulloides')
c_dir = os.path.join('./train/globigerinita_glutinata')
d_dir = os.path.join('./train/globigerinoides_sacculifer')
e_dir = os.path.join('./train/neogloboquadrina_pachyderma')
print('globigerinoides_ruber images:', len(os.listdir(a_dir)))
print('globigerina_bulloides images:', len(os.listdir(b_dir)))
print('globigerinita_glutinata images:', len(os.listdir(c_dir)))
print('globigerinoides_sacculifer images:', len(os.listdir(d_dir)))
print('neogloboquadrina_pachyderma images:', len(os.listdir(e_dir)))
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
batch_size = 16
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# riscala i valorei
train_datagen = ImageDataGenerator(rescale=1/255)
train_generator = train_datagen.flow_from_directory(
'./train',
target_size=(200, 200), # tutte le immagini vengono riscalate a 200x200. Gli originali sono circa 400x640
batch_size=batch_size,
classes = ['globigerinoides_ruber','globigerina_bulloides','globigerinita_glutinata','globigerinoides_sacculifer','neogloboquadrina_pachyderma'],
class_mode='categorical')
import tensorflow as tf
model = tf.keras.models.Sequential([
# The first convolution
tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(200, 200, 3)),
tf.keras.layers.MaxPooling2D(2, 2),
tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(64, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(128, activation='relu'),
# softmax deve essere impostato al numero di classi
tf.keras.layers.Dense(5, activation='softmax')
])
model.summary()
from tensorflow.keras.optimizers import RMSprop
model.compile(loss='categorical_crossentropy',
optimizer=RMSprop(lr=0.001),
metrics=['acc'])
total_sample=train_generator.n
n_epochs = 15
history = model.fit_generator(
train_generator,
steps_per_epoch=int(total_sample/batch_size),
epochs=n_epochs,
verbose=1)
model.save('1500el_5classi_model.h5')
i dati sono salvati in un file .h5
per la verifica del modello sono state selezionate 5 immagini per ogni classe che non erano comprese nel training con 15 epochs
questo e' lo script di predizione basato sulla libreria creata in precedenza (il nome del file immagine da esaminare viene passato sulla linea di comando)
============================================================
import tensorflow as tf
from tensorflow.keras import Model
from PIL import Image
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import sys
from numpy import asarray
import numpy as np
model = tf.compat.v2.keras.models.load_model('../1500el_5classi_model.h5')
image = Image.open(sys.argv[1])
image = image.resize((200,200))
pic = asarray(image)
pic = pic.astype('float32')
pic /= 255.0
pic=np.expand_dims(pic,axis=0)
prediction = model.predict(pic)
print(sys.argv[1])
float_formatter = "{:.2f}".format
np.set_printoptions(formatter={'float_kind':float_formatter})
print(prediction)
print()
============================================================
i risulati sono i seguenti
Corretti | Errati | |||
Globigerina Bulloides | 9 | 1 | ||
Globigerinita Glutinata | 1 | 9 | ||
Globigerinoides Ruber | 3 | 7 | ||
Globigerinoides Sacculifer | 9 | 0 | ||
Neogloboquadrina Pachyderma | 3 | 6 | ||
52% | 48% |
I risultati delle colonne seguenti sono in percentuali di affidabilita' (1=100%)
Globigerinoides Ruber | Globigerina Bulloides | Globigerinita Glutinata | Globigerinoides Sacculifer | Neogloboquadrina Pachyderma | |||
Predizione | |||||||
Immagini reali | |||||||
Globigerina Bulloides | 1 | 1.00 | |||||
2 | 1.00 | ||||||
3 | 1.00 | ||||||
4 | 1.00 | ||||||
5 | 1.00 | ||||||
6 | 0.17 | 0.93 | |||||
7 | 0.25 | 0.74 | 0.01 | ||||
8 | 1.00 | ||||||
9 | 1.00 | ||||||
10 | 1.00 | ||||||
Globigerinita Glutinata | 1 | 0.95 | 0.04 | ||||
2 | 0.32 | 0.03 | 0.65 | ||||
3 | 0.01 | 0.77 | 0.05 | 0.18 | |||
4 | 0.79 | 0.17 | 0.01 | 0.03 | |||
5 | 0.07 | 0.05 | 0.68 | 0.20 | |||
6 | 0.82 | 0.02 | 0.03 | 0.13 | |||
7 | 0.94 | 0.06 | |||||
8 | 0.00 | 0.61 | 0.04 | 0.35 | |||
9 | 0.21 | 0.11 | 0.1 | 0.58 | |||
10 | 0.12 | 0.14 | 0.01 | 0.73 | |||
Globigerinoides Ruber | 1 | 1.00 | |||||
2 | 0.02 | 0.98 | |||||
3 | 0.26 | 0.18 | 0.55 | ||||
4 | 1.00 | ||||||
5 | 0.98 | 0.01 | 0.01 | ||||
6 | 0.70 | 0.30 | |||||
7 | 0.02 | 0.98 | |||||
8 | 1.00 | ||||||
9 | 1.00 | ||||||
10 | 0.63 | 0.36 | |||||
Globigerinoides Sacculifer | 1 | 0.27 | 0.73 | ||||
2 | 0.01 | 0.99 | |||||
3 | 1.00 | ||||||
4 | 1.00 | ||||||
5 | 0.07 | 0.93 | |||||
6 | 1.00 | ||||||
7 | 1.00 | ||||||
8 | 1.00 | ||||||
9 | 1.00 | ||||||
Neogloboquadrina Pachyderma | 1 | 1.00 | |||||
2 | 1.00 | ||||||
3 | 0.89 | 0.01 | |||||
4 | 0.01 | 0.01 | 0.98 | ||||
5 | 1.00 | ||||||
6 | 1.00 | ||||||
7 | 0.95 | 0.01 | |||||
8 | 0.08 | 0.08 | 0.83 | ||||
9 | 0.02 | 0.97 |
Aggiungedo un Dropout del 20% le cose migliorano ma non troppo
Corretti | Errati | |||
Globigerina Bulloides | 10 | 0 | ||
Globigerinita Glutinata | 4 | 6 | ||
Globigerinoides Ruber | 5 | 5 | ||
Globigerinoides Sacculifer | 6 | 3 | ||
Neogloboquadrina Pachyderma | 1 | 9 | ||
54% | 48% |
ho provato ad usare l'optimizer adam con 3 livelli di convoluzione ma i risultati sono stati peggiori
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
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
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 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
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
venerdì 15 novembre 2019
Preparare i dati per Tensorflow
Questo spero si tratti l'inizio di alcuni post sulla possibilita' di usare Tensorflow per stimare la concentrazione di alcune specie chimiche partendo da spettri IR
Per questo scopo c'e' bisogno di un database in cui sono presenti spettri IR ed analisi composizionali del materiale. L'unico database pubblico che conosco e' usgs_splib07 da questo link
Per semplicita' sono stati selezionati gli spettri a 480 bande
I dati sono stati estratti dalla directory ASCIIData/ASCIIdata_splib07a/ChapterM_Minerals selezionando gli spettri denominati BECKb_AREF.
Un esempio di file e'
---------------------------------------
splib07a Record=120: Actinolite HS116.3B BECKb AREF
-1.2300000e+034
3.3700544e-002
3.5717472e-002
3.5481069e-002
3.5344660e-002
3.4786128e-002
3.3701397e-002
3.3403333e-002
3.3196956e-002
3.3779550e-002
3.2682978e-002
3.3049587e-002
3.4390874e-002
3.4718834e-002
3.6168687e-002
...............................................
---------------------------------------
Si iniziano quindi a preparare i dati per inserirli in un array compatibile con NumPy,formato idoneo al successivo utilizzo con Tensorflow
per prima cosa si toglie la prima riga di intestazione con sed
for f in *.txt ; do sed -i '1d' $f; done
viene quindi eseguito uno script python che legge i dati riga per riga e restituisce una stringa lineare con i dati separati da un punto e virgola
converti.py
=================================
with open("1.txt",'r') as f:
while True:
buf = f.readline()
if not buf:
break
print (buf.strip()),
print ';',
=================================
for f in *.txt ; do python converti.py > a$f; done
i nuovi file avranno il carattere a anteposto al precedente nome file
for f in ba*.txt; do (cat "${f}"; echo) >> completo.txt; done
from numpy import genfromtxt
data = genfromtxt('completo.txt', delimiter=',')
Da notare bene che tensorflow non funziona su macchine con processori non recenti perche' vengono usate delle istruzioni cpu recenti (AVX and AVX2 instruction sets)
Per installare Tensorflow su Debian con virtualenv si usa la sequenza (ripresa da questo sito)
python -c 'import tensorflow as tf; print(tf.__version__)'
Per questo scopo c'e' bisogno di un database in cui sono presenti spettri IR ed analisi composizionali del materiale. L'unico database pubblico che conosco e' usgs_splib07 da questo link
Per semplicita' sono stati selezionati gli spettri a 480 bande
SiO2 | Al2O3 | MgO | ||
1 | Actinolite HS116 | 57,8 | 0,22 | 22,4 |
2 | Actinolite HS22 | 54,5 | 1,64 | 21,69 |
3 | Actinolite HS315 | 57,7 | 1,38 | 24,58 |
4 | Albite NMNHC5390 | 68,18 | 20,07 | 0,02 |
5 | Almandine HS114 | 40,4 | 22,97 | 0,53 |
6 | Almandine WS475 | 37,98 | 22,14 | 7,35 |
7 | Almandine WS476 | 39,84 | 22,04 | 10,69 |
8 | Almandine WS478 | 39,09 | 22,05 | 5,74 |
9 | Almandine WS479 | 37,34 | 21,93 | 8,83 |
10 | Andradite NMNH113829 | 35,5 | 0,29 | 0,14 |
11 | Andradite WS474 | 35,85 | 0,085 | 0,67 |
12 | Annite WS661 | 33,48 | 14,51 | 0,006 |
13 | Antigorite NMNH96917a | 41,3 | 1,59 | 36,3 |
14 | Augite NMNH120049 | 48,93 | 8,44 | 14,37 |
15 | Biotite WS660 | 39,52 | 11,05 | 14,45 |
16 | Chlorite SMR-13 | 31 | 17,3 | 30,2 |
17 | Clinochlore GDS158 | 27,5 | 19,8 | 24,7 |
18 | Clinochlore GDS159 | 31,3 | 19,4 | 34,7 |
19 | Clinochlore NMNH83369 | 32 | 16 | 33,9 |
20 | Diopside NMNHR18685 | 54,77 | 0,49 | 18,26 |
21 | Elbaite NMNH94217 | 36,83 | 40,56 | 0,03 |
22 | Epidote GDS26 | 37,14 | 23,05 | 0,06 |
23 | Grossular NMNH155371 | 38,84 | 17,95 | 0,15 |
24 | Grossular WS484 | 39,71 | 22,58 | 0,019 |
25 | Halloysite CM13 | 46,3 | 35,2 | 0,31 |
26 | Hectorite SHCa-1 | 34,7 | 0,69 | 15,3 |
27 | Hydrogrossular NMNH120555 | 31,44 | 21,4 | 0,17 |
28 | Hypersthene NMNHC2368 | 51,32 | 4,89 | 26,09 |
29 | Illite GDS4 (Marblehead) | 51,62 | 23,96 | 3,83 |
30 | Illite IMt-1 | 52,1 | 21,9 | 2,39 |
31 | Kaolinite CM5 | 44,4 | 37,9 | 0,11 |
32 | Kaolinite CM7 | 44,6 | 36,4 | 0,14 |
33 | Kaolinite CM9 | 47,1 | 37,4 | 0,16 |
34 | Kaolinite KGa-1 (wxl) | 45 | 38 | 0,02 |
35 | Kaolinite KGa-2 (pxl) | 44,2 | 37,2 | 0,04 |
36 | Lizardite NMNHR4687 | 40,97 | 0 | 40,43 |
37 | Marialite NMNH126018-2 | 59,88 | 20,59 | 0 |
38 | Meionite WS701 | 49,6 | 25,45 | 0,06 |
39 | Mizzonite NMNH113775 | 49,6 | 25,43 | 0,03 |
40 | Montmorillonite CM20 | 52 | 18,36 | 3,32 |
41 | Montmorillonite CM26 | 63,4 | 18,2 | 2,26 |
42 | Montmorillonite CM27 | 57,6 | 20,9 | 2,66 |
43 | Montmorillonite+Illite CM37 | 46,5 | 22,7 | 2,74 |
44 | Montmorillonite+Illite CM42 | 54,8 | 21 | 3,4 |
45 | Montmorillonite SAz-1 | 60,4 | 17,6 | 6,46 |
46 | Montmorillonite SCa-2 | 52,4 | 15 | 6,68 |
47 | Montmorillonite STx-1 | 69,6 | 16,3 | 3,56 |
48 | Montmorillonite SWy-1 | 62,9 | 19,3 | 2,8 |
49 | Muscovite GDS108 | 44 | 35 | 0,57 |
50 | Nontronite NG-1 | 80 | 2 | 0,42 |
51 | Nontronite SWa-1 | 74,6 | 7,69 | 3,32 |
52 | Olivine GDS70 Fo89 | 41,09 | 0 | 49,29 |
53 | Olivine GDS71 Fo91 | 40,06 | 0 | 50,7 |
54 | Olivine KI3005 Fo11 | 30,11 | 0 | 4,42 |
55 | Olivine KI3054 Fo66 | 36,3 | 0 | 32,62 |
56 | Olivine KI3188 Fo51 | 34,34 | 0 | 23,8 |
57 | Olivine KI3189 Fo60 | 35,47 | 0 | 29,49 |
58 | Palygorskite CM46a | 56 | 10,6 | 8,56 |
59 | Pectolite NMNH94865 | 53,37 | 0,03 | 0,03 |
60 | Phlogopite GDS20 | 40,3 | 14,3 | 26,4 |
61 | Phlogopite WS496 | 43,015 | 11,6 | 29,62 |
62 | Quartz HS117 Aventurine | 100 | 0 | 0 |
63 | Rhodonite NMNHC6148 | 46,3 | 0,05 | 0,41 |
64 | Richterite NMNH150800 | 54,87 | 1,97 | 22,92 |
65 | Saponite SapCa-1 | 51,9 | 3,66 | 0,88 |
66 | Sepiolite SepNev-1.AcB | 50,9 | 0,45 | 22,3 |
67 | Talc HS21 | 60,47 | 0,12 | 30,29 |
68 | Talc WS659 | 58,38 | 0,18 | 31,9 |
69 | Thuringite SMR-15 | 24,7 | 21,1 | 16,8 |
70 | Tremolite NMNH117611 | 54,6 | 1,88 | 23,13 |
71 | Vermiculite VTx-1.a | 19,5 | 1,53 | 27,7 |
I dati sono stati estratti dalla directory ASCIIData/ASCIIdata_splib07a/ChapterM_Minerals selezionando gli spettri denominati BECKb_AREF.
Un esempio di file e'
---------------------------------------
splib07a Record=120: Actinolite HS116.3B BECKb AREF
-1.2300000e+034
3.3700544e-002
3.5717472e-002
3.5481069e-002
3.5344660e-002
3.4786128e-002
3.3701397e-002
3.3403333e-002
3.3196956e-002
3.3779550e-002
3.2682978e-002
3.3049587e-002
3.4390874e-002
3.4718834e-002
3.6168687e-002
...............................................
---------------------------------------
Si iniziano quindi a preparare i dati per inserirli in un array compatibile con NumPy,formato idoneo al successivo utilizzo con Tensorflow
per prima cosa si toglie la prima riga di intestazione con sed
for f in *.txt ; do sed -i '1d' $f; done
viene quindi eseguito uno script python che legge i dati riga per riga e restituisce una stringa lineare con i dati separati da un punto e virgola
converti.py
=================================
with open("1.txt",'r') as f:
while True:
buf = f.readline()
if not buf:
break
print (buf.strip()),
print ';',
=================================
for f in *.txt ; do python converti.py > a$f; done
for f in *.txt ; do python converti.py > a$f; done
si tolgono quindi gli spazi bianchi
for f in a*.txt ; do cat $f | tr - d "[:space:]" > b$f ; done
i nuovi file avranno il carattere b anteposto al precedente nome file
siamo quasi arrivati alla fine. Ogni file dello spettro e' costituito da un riga, si deve quindi creare un unico file in cui ogni riga rappresenta uno spettro
from numpy import genfromtxt
data = genfromtxt('completo.txt', delimiter=',')
Da notare bene che tensorflow non funziona su macchine con processori non recenti perche' vengono usate delle istruzioni cpu recenti (AVX and AVX2 instruction sets)
Per installare Tensorflow su Debian con virtualenv si usa la sequenza (ripresa da questo sito)
si installa python3
apt-get install python3-venv python3
mkdir spectra
cd spectra
python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install --upgrade tensorflow
per verificare l'installazione si usa
per terminare virtualenv si digita
deactivate
A questo punto ho diviso il file di 71 spettri in una serie di train di 60 spettri ed una serie di test di 11 spettri (x_train,x_test) . Per quanto riguarda le concentrazioni il file delle concentrazioni (y_train, y_test) i valori di concentrazioni sono stati divisi in 10 classi con la seguente regola
0-9.9% : classe 0
10-19.9% : classe 1
20-29.9% : classe 2
30-39.9% : classe 3
40-49.9% : classe 4
50-59.9% : classe 5
60-69.9% : classe 6
70-79.9% : classe 7
80-89.9% : classe 8
90-100% : classe 9
per prova ho usato le concentrazioni di SiO2 (uno dei parametri piu' difficili da determinare da uno spettro IR nel rilevamento iperspettrale)
Prima di procedere i valori No data contenuti negli spettri e indicati dal valore -1.2300000e+034 sono stati convertiti in 0
provando con un rete neurale con delle impostazioni non ottimizzate
==============================================================
import numpy as np
from numpy import genfromtxt
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
x_train = genfromtxt("x_train.txt",delimiter=';',usecols=np.arange(0,479))
x_test = genfromtxt("x_test.txt",delimiter=';',usecols=np.arange(0,479))
y_train = genfromtxt("y_train.txt",delimiter=';',usecols=np.arange(0,1))
y_test = genfromtxt("y_test.txt",delimiter=';',usecols=np.arange(0,1))
y_train = y_train.transpose()
#print (x_train)
y_train = y_train.astype(int)
y_test = y_test.astype(int)
#print (y_train)
print ("====================")
print ("X trains" + str(x_train.shape))
print ("Y trains" + str(y_train.shape))
print ("X test" + str(x_test.shape))
print ("Y test" + str(y_test.shape))
print ("====================")
model = tf.keras.Sequential()
model.add(layers.Dense(128,activation='relu'))
model.add(layers.Dropout(0.2))
model.add(layers.Dense(10,activation='softmax'))
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
model.fit(x_train,y_train,epochs=16)
model.evaluate(x_test,y_test,verbose=2)
==============================================================
Epoch 2/16
60/60 [==============================] - 0s 194us/sample - loss: 1.4062 - accuracy: 0.6500
Epoch 3/16
60/60 [==============================] - 0s 167us/sample - loss: 1.1572 - accuracy: 0.6500
Epoch 4/16
60/60 [==============================] - 0s 187us/sample - loss: 1.1490 - accuracy: 0.6333
Epoch 5/16
60/60 [==============================] - 0s 173us/sample - loss: 1.0612 - accuracy: 0.6333
Epoch 6/16
60/60 [==============================] - 0s 195us/sample - loss: 1.0615 - accuracy: 0.6500
Epoch 7/16
60/60 [==============================] - 0s 193us/sample - loss: 1.0023 - accuracy: 0.6333
Epoch 8/16
60/60 [==============================] - 0s 164us/sample - loss: 1.0067 - accuracy: 0.6667
Epoch 9/16
60/60 [==============================] - 0s 221us/sample - loss: 0.9609 - accuracy: 0.6667
Epoch 10/16
60/60 [==============================] - 0s 185us/sample - loss: 0.9922 - accuracy: 0.6333
Epoch 11/16
60/60 [==============================] - 0s 163us/sample - loss: 0.9188 - accuracy: 0.6333
Epoch 12/16
60/60 [==============================] - 0s 234us/sample - loss: 0.9704 - accuracy: 0.6333
Epoch 13/16
60/60 [==============================] - 0s 176us/sample - loss: 0.9234 - accuracy: 0.6833
Epoch 14/16
60/60 [==============================] - 0s 202us/sample - loss: 0.9051 - accuracy: 0.6833
Epoch 15/16
60/60 [==============================] - 0s 181us/sample - loss: 0.8635 - accuracy: 0.7167
Epoch 16/16
60/60 [==============================] - 0s 171us/sample - loss: 0.8449 - accuracy: 0.7000
11/1 - 0s - loss: 2.3372 - accuracy: 0.2727
0-9.9% : classe 0
10-19.9% : classe 1
20-29.9% : classe 2
30-39.9% : classe 3
40-49.9% : classe 4
50-59.9% : classe 5
60-69.9% : classe 6
70-79.9% : classe 7
80-89.9% : classe 8
90-100% : classe 9
per prova ho usato le concentrazioni di SiO2 (uno dei parametri piu' difficili da determinare da uno spettro IR nel rilevamento iperspettrale)
Prima di procedere i valori No data contenuti negli spettri e indicati dal valore -1.2300000e+034 sono stati convertiti in 0
provando con un rete neurale con delle impostazioni non ottimizzate
==============================================================
import numpy as np
from numpy import genfromtxt
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
x_train = genfromtxt("x_train.txt",delimiter=';',usecols=np.arange(0,479))
x_test = genfromtxt("x_test.txt",delimiter=';',usecols=np.arange(0,479))
y_train = genfromtxt("y_train.txt",delimiter=';',usecols=np.arange(0,1))
y_test = genfromtxt("y_test.txt",delimiter=';',usecols=np.arange(0,1))
y_train = y_train.transpose()
#print (x_train)
y_train = y_train.astype(int)
y_test = y_test.astype(int)
#print (y_train)
print ("====================")
print ("X trains" + str(x_train.shape))
print ("Y trains" + str(y_train.shape))
print ("X test" + str(x_test.shape))
print ("Y test" + str(y_test.shape))
print ("====================")
model = tf.keras.Sequential()
model.add(layers.Dense(128,activation='relu'))
model.add(layers.Dropout(0.2))
model.add(layers.Dense(10,activation='softmax'))
model.compile(optimizer='adam',loss='sparse_categorical_crossentropy',metrics=['accuracy'])
model.fit(x_train,y_train,epochs=16)
model.evaluate(x_test,y_test,verbose=2)
==============================================================
il risultato e' il seguente
====================
X trains(60, 479)
Y trains(60,)
X test(11, 479)
Y test(11,)
====================
2019-11-15 13:35:58.075622: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2019-11-15 13:35:58.099810: I tensorflow/core/platform/profile_utils/cpu_utils.cc:94] CPU Frequency: 2294770000 Hz
2019-11-15 13:35:58.100500: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x38bfc90 executing computations on platform Host. Devices:
2019-11-15 13:35:58.100551: I tensorflow/compiler/xla/service/service.cc:175] StreamExecutor device (0): Host, Default Version
Train on 60 samples
Epoch 1/16
60/60 [==============================] - 0s 8ms/sample - loss: 2.2551 - accuracy: 0.1000
Epoch 2/16
60/60 [==============================] - 0s 85us/sample - loss: 1.7444 - accuracy: 0.3833
Epoch 3/16
60/60 [==============================] - 0s 90us/sample - loss: 1.6373 - accuracy: 0.3333
Epoch 4/16
60/60 [==============================] - 0s 83us/sample - loss: 1.6465 - accuracy: 0.3167
Epoch 5/16
60/60 [==============================] - 0s 96us/sample - loss: 1.5436 - accuracy: 0.3833
Epoch 6/16
60/60 [==============================] - 0s 127us/sample - loss: 1.6167 - accuracy: 0.3667
Epoch 7/16
60/60 [==============================] - 0s 92us/sample - loss: 1.4574 - accuracy: 0.3833
Epoch 8/16
60/60 [==============================] - 0s 100us/sample - loss: 1.5219 - accuracy: 0.3500
Epoch 9/16
60/60 [==============================] - 0s 81us/sample - loss: 1.4713 - accuracy: 0.4000
Epoch 10/16
60/60 [==============================] - 0s 81us/sample - loss: 1.4284 - accuracy: 0.3500
Epoch 11/16
60/60 [==============================] - 0s 105us/sample - loss: 1.4529 - accuracy: 0.4167
Epoch 12/16
60/60 [==============================] - 0s 107us/sample - loss: 1.3913 - accuracy: 0.4167
Epoch 13/16
60/60 [==============================] - 0s 92us/sample - loss: 1.4574 - accuracy: 0.4000
Epoch 14/16
60/60 [==============================] - 0s 82us/sample - loss: 1.4370 - accuracy: 0.3500
Epoch 15/16
60/60 [==============================] - 0s 80us/sample - loss: 1.4666 - accuracy: 0.3667
Epoch 16/16
60/60 [==============================] - 0s 88us/sample - loss: 1.3726 - accuracy: 0.4500
11/1 - 0s - loss: 3.1148 - accuracy: 0.0000e+00
Impiegando i dati di concentrazione di Mg0 le cose migliorano
60/60 [==============================] - 1s 9ms/sample - loss: 1.8941 - accuracy: 0.3833Epoch 2/16
60/60 [==============================] - 0s 194us/sample - loss: 1.4062 - accuracy: 0.6500
Epoch 3/16
60/60 [==============================] - 0s 167us/sample - loss: 1.1572 - accuracy: 0.6500
Epoch 4/16
60/60 [==============================] - 0s 187us/sample - loss: 1.1490 - accuracy: 0.6333
Epoch 5/16
60/60 [==============================] - 0s 173us/sample - loss: 1.0612 - accuracy: 0.6333
Epoch 6/16
60/60 [==============================] - 0s 195us/sample - loss: 1.0615 - accuracy: 0.6500
Epoch 7/16
60/60 [==============================] - 0s 193us/sample - loss: 1.0023 - accuracy: 0.6333
Epoch 8/16
60/60 [==============================] - 0s 164us/sample - loss: 1.0067 - accuracy: 0.6667
Epoch 9/16
60/60 [==============================] - 0s 221us/sample - loss: 0.9609 - accuracy: 0.6667
Epoch 10/16
60/60 [==============================] - 0s 185us/sample - loss: 0.9922 - accuracy: 0.6333
Epoch 11/16
60/60 [==============================] - 0s 163us/sample - loss: 0.9188 - accuracy: 0.6333
Epoch 12/16
60/60 [==============================] - 0s 234us/sample - loss: 0.9704 - accuracy: 0.6333
Epoch 13/16
60/60 [==============================] - 0s 176us/sample - loss: 0.9234 - accuracy: 0.6833
Epoch 14/16
60/60 [==============================] - 0s 202us/sample - loss: 0.9051 - accuracy: 0.6833
Epoch 15/16
60/60 [==============================] - 0s 181us/sample - loss: 0.8635 - accuracy: 0.7167
Epoch 16/16
60/60 [==============================] - 0s 171us/sample - loss: 0.8449 - accuracy: 0.7000
11/1 - 0s - loss: 2.3372 - accuracy: 0.2727
Iscriviti a:
Post (Atom)
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...
-
In questo post viene indicato come creare uno scatterplot dinamico basato da dati ripresi da un file csv (nel dettaglio il file csv e' c...
-
Questo post e' a seguito di quanto gia' visto nella precedente prova Lo scopo e' sempre il solito: creare un sistema che permet...
-
La scheda ESP32-2432S028R monta un Esp Dev Module con uno schermo TFT a driver ILI9341 di 320x240 pixels 16 bit colore.Il sito di riferiment...