Introduzione ai dati delle immagini
- 10 minuti
In visione artificiale, in genere risolviamo uno dei problemi seguenti:
- Classificazione immagini è l'attività più semplice, quando è necessario classificare un'immagine in una delle molte categorie predefinite, ad esempio distinguere un gatto da un cane su una fotografia o riconoscere una cifra scritta a mano.
- Rilevamento oggetti è un'attività un po' più difficile, in cui è necessario trovare oggetti noti nell'immagine e localizzarli, ovvero restituire il rettangolo di selezione per ognuno degli oggetti riconosciuti.
- La segmentazione è simile al rilevamento degli oggetti, ma invece di fornire un riquadro di delimitazione, dobbiamo restituire una mappa pixel per pixel che delinei ciascuno degli oggetti riconosciuti.
Immagine dal corso CS231n di Stanford
Immagini come tensori
Visione artificiale funziona con immagini. Come probabilmente sapete, le immagini sono costituite da pixel, in modo che possano essere considerate come una raccolta rettangolare (matrice) di pixel.
Nella prima parte di questo modulo verrà illustrato il riconoscimento delle cifre scritte a mano. Utilizzeremo il set di dati MNIST, composto da immagini in scala di grigi di cifre scritte a mano, di 28x28 pixel. Ogni immagine può essere rappresentata come matrice 28x28 e gli elementi di questa matrice denotano l'intensità del pixel corrispondente, sia nella scala dell'intervallo da 0 a 1 (nel qual caso vengono usati numeri a virgola mobile) o da 0 a 255 (numeri interi). Una popolare libreria Python chiamata numpy viene spesso usata con le attività di visione artificiale, perché consente di operare con matrici multidimensionali in modo efficace.
Per gestire le immagini a colori, è necessario un modo per rappresentare i colori. Nella maggior parte dei casi, rappresentiamo ogni pixel per 3 valori di intensità, corrispondenti ai componenti Red (R), Green (G) e Blue (B). Questa codifica dei colori è denominata RGB e quindi l'immagine a colori delle dimensioni W×H verrà rappresentata come una matrice di dimensioni H×W×3 (a volte l'ordine dei componenti potrebbe essere diverso, ma l'idea è la stessa). Nella rappresentazione di matrice, l'altezza (numero di righe) precede la larghezza (numero di colonne), che è l'opposto della convenzione di immagine comune di W×H.
Le matrici multidimensionali sono dette anche tensori. L'uso di tensori per rappresentare le immagini offre anche un vantaggio, perché è possibile usare una dimensione aggiuntiva per archiviare una sequenza di immagini. Ad esempio, per rappresentare un frammento video costituito da 200 fotogrammi con dimensione 800x600 (larghezza × altezza), è possibile usare il tensore di dimensioni 200x600x800x3. Tenere presente che le dimensioni del tensore usano l'ordine H×W (row-major), non la convenzione W×H comunemente vista negli editor di immagini. L'ordine è: fotogrammi × altezza (600) × larghezza (800) × canali. Questo ordinamento è noto come channels_last e è l'impostazione predefinita in TensorFlow; altri framework posizionano i canali prima dell'altezza e della larghezza (channels_first).
import tensorflow as tf
import keras
import matplotlib.pyplot as plt
import numpy as np
# Prints the installed TensorFlow version
print(tf.__version__)
Useremo il framework Keras per gli esperimenti. In questo modulo viene usato import keras (lo stile di importazione autonomo Keras 3), che richiede TensorFlow 2.16 o versione successiva (o un'installazione autonoma tramite pip install keras>=3.0). Se si usa una versione precedente di TensorFlow 2.x, sostituire import keras con from tensorflow import keras.
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
# Output: (60000, 28, 28) (60000,)
print(x_train.shape, y_train.shape)
# Output: (10000, 28, 28) (10000,)
print(x_test.shape, y_test.shape)
Visualizzare il dataset delle cifre
Ora che è stato scaricato il set di dati, è possibile visualizzare alcune delle cifre:
fig, ax = plt.subplots(1, 7)
for i in range(7):
ax[i].imshow(x_train[i])
ax[i].set_title(y_train[i])
ax[i].axis('off')
# Displays a row of seven handwritten digit images with their labels
Struttura del set di dati
Abbiamo un totale di 60.000 immagini di training e 10.000 immagini di test e ogni immagine ha una dimensione di 28×28 pixel:
print('Training samples:', len(x_train))
print('Test samples:', len(x_test))
print('Tensor size:', x_train[0].shape)
print('First 10 digits are:', y_train[:10])
print('Type of data is ', type(x_train))
# Output:
# Training samples: 60000
# Test samples: 10000
# Tensor size: (28, 28)
# First 10 digits are: [5 0 4 1 9 2 1 3 1 4]
# Type of data is <class 'numpy.ndarray'>
Come si può notare, il tipo di dati è numpy matrice. Ogni intensità di pixel è rappresentata da un valore intero compreso tra 0 e 255:
print('Min intensity value: ', x_train.min())
print('Max intensity value: ', x_train.max())
# Output:
# Min intensity value: 0
# Max intensity value: 255
Il motivo per cui è compreso tra 0 e 255 è perché ogni pixel è rappresentato da un numero intero a 8 bit. In molti casi, soprattutto quando si lavora con reti neurali, è più conveniente ridimensionare tutti i valori nell'intervallo [0, 1] dividendo per 255. Questo processo è denominato normalizzazione:
x_train = x_train.astype(np.float32) / 255.0
x_test = x_test.astype(np.float32) / 255.0
# Pixel values are now floating point numbers in the range [0, 1]
Ora abbiamo i dati e siamo pronti per iniziare il training della prima rete neurale.
Verificare le conoscenze
Commenti e suggerimenti
Questa pagina è stata utile?
No
Serve aiuto con questo argomento?
Provare a usare Ask Learn per chiarire o guidare l'utente in questo argomento?