Einführung in Bilddaten
- 10 Minuten
In der Computervision lösen wir normalerweise eines der folgenden Probleme:
- Die Bildklassifizierung ist die einfachste Aufgabe, wenn wir ein Bild in eine von vielen vordefinierten Kategorien klassifizieren müssen, z. B. eine Katze von einem Hund auf einem Foto unterscheiden oder eine handschriftliche Ziffer erkennen müssen.
- Die Objekterkennung ist eine etwas schwierigere Aufgabe, bei der bekannte Objekte auf dem Bild gefunden und lokalisiert werden müssen, d. h. das Begrenzungsfeld für jedes erkannte Objekt zurückgeben.
- Die Segmentierung ist mit der Objekterkennung vergleichbar, aber anstelle des Begrenzungsrahmens müssen wir eine genaue Pixelkarte zurückgeben, die jedes der erkannten Objekte darstellt.
Bild von CS231n Stanford Course
Bilder als Tensoren
Computer Vision funktioniert mit Bildern. Wie Sie wahrscheinlich wissen, bestehen Bilder aus Pixeln, sodass sie als rechteckige Sammlung (Array) von Pixeln betrachtet werden können.
Im ersten Teil dieses Moduls befassen wir uns mit der handschriftlichen Ziffernerkennung. Wir verwenden das MNIST-Dataset, das aus Graustufenbildern handschriftlicher Ziffern besteht, 28 x 28 Pixel. Jedes Bild kann als Array mit 28 x 28 dargestellt werden, und Elemente dieses Arrays würden die Intensität des entsprechenden Pixels angeben – entweder im Maßstab des Bereichs 0 bis 1 (in diesem Fall gleitkommazahlen werden verwendet) oder 0 bis 255 (ganze Zahlen). Eine beliebte Python-Bibliothek, genannt numpy, wird häufig für Aufgaben der Computer Vision verwendet, da man damit effektiv mit mehrdimensionalen Arrays arbeiten kann.
Um mit Farbbildern umzugehen, benötigen wir eine Möglichkeit, Farben darzustellen. In den meisten Fällen stellen wir jedes Pixel um 3 Intensitätswerte dar, die den Komponenten Rot (R), Grün (G) und Blau (B) entsprechen. Diese Farbcodierung wird als RGB bezeichnet, und daher wird das Farbbild der Größe W×H als Array von Größe H×W×3 dargestellt (manchmal kann die Reihenfolge der Komponenten unterschiedlich sein, aber die Idee ist identisch). In der Arraydarstellung kommt die Höhe (Anzahl der Zeilen) vor der Breite (Anzahl der Spalten), was das Gegenteil der allgemeinen Bildkonvention von W×H ist.
Mehrdimensionale Arrays werden auch als Tensoren bezeichnet. Die Verwendung von Tensoren zur Darstellung von Bildern hat ebenfalls einen Vorteil, da wir eine zusätzliche Dimension verwenden können, um eine Abfolge von Bildern zu speichern. Um beispielsweise ein Videofragment darzustellen, das aus 200 Frames mit einer Dimension von 800x600 (Breite × Höhe) besteht, können wir den Tensor der Größe 200x600x800x3 verwenden. Denken Sie daran, dass Tensorabmessungen H×W (Zeilen-Hauptreihenfolge) verwenden, nicht die W×H-Konvention, die häufig in Bild-Editoren zu sehen ist. Die Reihenfolge hier ist Frames × Höhe (600) × Breite (800) × Kanäle. Diese Reihenfolge ist als channels_last bekannt und ist die Standardeinstellung in TensorFlow. Einige andere Frameworks platzieren Kanäle vor Höhe und Breite (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__)
Wir werden das Keras-Framework für unsere Experimente verwenden. In diesem Modul verwenden wir import keras (den eigenständigen Keras 3-Importstil), der TensorFlow 2.16 oder höher erfordert (oder eine eigenständige Installation über pip install keras>=3.0). Wenn Sie eine ältere TensorFlow 2.x-Version verwenden, ersetzen Sie diese durch import kerasfrom 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)
Visualisieren des Zifferndatensatzes
Nachdem wir das Dataset heruntergeladen haben, können wir einige der Ziffern visualisieren:
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
Datasetstruktur
Es gibt insgesamt 60.000 Schulungsbilder und 10.000 Testbilder, und jedes Bild hat eine Größe von 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'>
Wie Sie sehen können, ist numpy der Datentyp Array. Jede Pixelintensität wird durch einen ganzzahligen Wert zwischen 0 und 255 dargestellt:
print('Min intensity value: ', x_train.min())
print('Max intensity value: ', x_train.max())
# Output:
# Min intensity value: 0
# Max intensity value: 255
Der Grund, warum es zwischen 0 und 255 liegt, liegt daran, dass jedes Pixel durch eine 8-Bit-Ganzzahl dargestellt wird. In vielen Fällen, insbesondere bei der Arbeit mit neuralen Netzwerken, ist es praktischer, alle Werte auf den Bereich zu skalieren [0, 1] durch Dividieren um 255. Dieser Prozess wird als Normalisierung bezeichnet:
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]
Jetzt haben wir die Daten, und wir sind bereit, mit dem Training unseres ersten neuralen Netzwerks zu beginnen!