1. Bilddatenaugmentation
from keras.preprocessing.image import ImageDataGenerator
import matplotlib.pyplot as plt
import numpy as np
from keras.preprocessing import image
# Erstellen eines ImageDataGenerator für die Augmentation
datagen = ImageDataGenerator(
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest'
)
# Laden eines Beispielbildes
img = image.load_img('example.jpg') # Pfad zum Bild
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
# Generieren und Anzeigen der augmentierten Bilder
i = 0
for batch in datagen.flow(x, batch_size=1):
plt.figure(i)
imgplot = plt.imshow(image.array_to_img(batch[0]))
i += 1
if i % 4 == 0:
break
plt.show()
In diesem Beispiel verwenden wir den ImageDataGenerator von Keras, um verschiedene Transformationen auf ein Bild anzuwenden, wie Rotation, Verschiebung und Flip. Dies veranschaulicht die möglichen Augmentationen, die auf die Trainingsbilder angewendet werden können.
2. Vorgefertigte CNN-Modelle zur Bildklassifikation
Vorgefertigte Convolutional Neural Networks (CNNs) wie VGG16, ResNet50 und InceptionV3 können verwendet werden, um Bilder zu klassifizieren. Diese Modelle sind auf großen Datensätzen vortrainiert und können für spezifische Aufgaben weiterverwendet oder feingetunt werden.
Beispiel:
from keras.applications import VGG16
from keras.models import Sequential
from keras.layers import Dense, Flatten
# Laden des vortrainierten VGG16-Modells ohne die oberste Schicht
base_model = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
# Erstellen eines neuen Modells und Hinzufügen des vortrainierten Modells als Basismodell
model = Sequential()
model.add(base_model)
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dense(10, activation='softmax')) # Angenommen, wir haben 10 Klassen
# Kompilieren des Modells
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
# Ausgabe der Modellzusammenfassung
print(model.summary())
Ausgabe:
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
vgg16 (Functional) (None, 7, 7, 512) 14714688
_________________________________________________________________
flatten (Flatten) (None, 25088) 0
_________________________________________________________________
dense (Dense) (None, 256) 6422784
_________________________________________________________________
dense_1 (Dense) (None, 10) 2570
=================================================================
Total params: 21,138,042
Trainable params: 21,138,042
Non-trainable params: 0
_________________________________________________________________
In diesem Beispiel verwenden wir das vortrainierte VGG16-Modell und fügen eine Flatten-Schicht sowie zwei Dense-Schichten hinzu, um das Modell für eine Bildklassifikationsaufgabe mit 10 Klassen anzupassen.
3. Aufbau von Bildsegmentierungsmodellen
Die Bildsegmentierung ist eine anspruchsvolle Aufgabe der Bildverarbeitung, bei der jedes Pixel eines Bildes einer Klasse zugeordnet wird. U-Net ist eine beliebte Architektur für die Bildsegmentierung.
Beispiel:
from keras.models import Model
from keras.layers import Input, Conv2D, MaxPooling2D, UpSampling2D, concatenate
def unet_model(input_size=(256, 256, 1)):
inputs = Input(input_size)
# Downsampling
conv1 = Conv2D(64, 3, activation='relu', padding='same')(inputs)
conv1 = Conv2D(64, 3, activation='relu', padding='same')(conv1)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
conv2 = Conv2D(128, 3, activation='relu', padding='same')(pool1)
conv2 = Conv2D(128, 3, activation='relu', padding='same')(conv2)
pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
# Bottleneck
conv3 = Conv2D(256, 3, activation='relu', padding='same')(pool2)
conv3 = Conv2D(256, 3, activation='relu', padding='same')(conv3)
# Upsampling
up4 = UpSampling2D(size=(2, 2))(conv3)
up4 = concatenate([up4, conv2], axis=3)
conv4 = Conv2D(128, 3, activation='relu', padding='same')(up4)
conv4 = Conv2D(128, 3, activation='relu', padding='same')(conv4)
up5 = UpSampling2D(size=(2, 2))(conv4)
up5 = concatenate([up5, conv1], axis=3)
conv5 = Conv2D(64, 3, activation='relu', padding='same')(up5)
conv5 = Conv2D(64, 3, activation='relu', padding='same')(conv5)
outputs = Conv2D(1, 1, activation='sigmoid')(conv5)
model = Model(inputs=[inputs], outputs=[outputs])
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
return model
# Erstellen und Anzeigen des U-Net-Modells
model = unet_model()
print(model.summary())
Ausgabe:
Model: "model"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) [(None, 256, 256, 1)] 0
_________________________________________________________________
conv2d (Conv2D) (None, 256, 256, 64) 640
_________________________________________________________________
conv2d_1 (Conv2D) (None, 256, 256, 64) 36928
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 128, 128, 64) 0
_________________________________________________________________
conv2d_2 (Conv2D) (None, 128, 128, 128) 73856
_________________________________________________________________
conv2d_3 (Conv2D) (None, 128, 128, 128) 147584
_________________________________________________________________
max_pooling2d_1 (MaxPooling2D) (None, 64, 64, 128) 0
_________________________________________________________________
conv2d_4 (Conv2D) (None, 64, 64, 256) 295168
_________________________________________________________________
conv2d_5 (Conv2D) (None, 64, 64, 256) 590080
_________________________________________________________________
up_sampling2d (UpSampling2D) (None, 128, 128, 256) 0
_________________________________________________________________
concatenate (Concatenate) (None, 128, 128, 384) 0
_________________________________________________________________
conv2d_6 (Conv2D) (None, 128, 128, 128) 442496
_________________________________________________________________
conv2d_7 (Conv2D) (None, 128, 128, 128) 147584
_________________________________________________________________
up_sampling2d_1 (UpSampling2D) (None, 256, 256, 128) 0
_________________________________________________________________
concatenate_1 (Concatenate) (None, 256, 256, 192) 0
_________________________________________________________________
conv2d_8 (Conv2D) (None, 256, 256, 64) 110656
_________________________________________________________________
conv2d_9 (Conv2D) (None, 256, 256, 64) 36928
_________________________________________________________________
conv2d_10 (Conv2D) (None, 256, 256, 1) 65
=================================================================
Total params: 1,880,985
Trainable params: 1,880,985
Non-trainable params: 0
_________________________________________________________________
In diesem Beispiel erstellen wir ein U-Net-Modell für die Bildsegmentierung. Das Modell besteht aus abwärts und aufwärts gerichteten Pfaden mit mehreren Convolutional- und Max-Pooling-Schichten sowie Upsampling-Schichten.
Erklärung des Codes für den Aufbau von Bildsegmentierungsmodellen

In diesem Abschnitt des Codes erstellen wir einen "Bottleneck"-Bereich und führen dann das "Upsampling" durch. Dieser Code gehört zum U-Net-Modell, das für die Bildsegmentierung verwendet wird. Das U-Net-Modell besteht aus einem Encoder-Teil (Downsampling) und einem Decoder-Teil (Upsampling), um die Bildauflösung wiederherzustellen und gleichzeitig die Merkmale zu segmentieren.
Bottleneck
Der Bottleneck-Teil des U-Net-Modells ist der tiefste Punkt des Netzwerks, an dem die Merkmale am stärksten verdichtet sind. In diesem Abschnitt werden mehrere Convolutional-Schichten angewendet, um komplexe Merkmale zu extrahieren.
# Bottleneck
conv3 = Conv2D(256, 3, activation='relu', padding='same')(pool2)
conv3 = Conv2D(256, 3, activation='relu', padding='same')(conv3)
Erklärung:
Conv2D(256, 3, activation='relu', padding='same')
: Diese Zeile definiert eine Convolutional-Schicht mit 256 Filtern, einer Kernelgröße von 3x3 und einer ReLU-Aktivierungsfunktion. Daspadding='same'
stellt sicher, dass die räumliche Größe der Eingabe beibehalten wird.(pool2)
: Diese Schicht wird auf die Ausgabe der vorhergehenden Max-Pooling-Schichtpool2
angewendet.- Die zweite Convolutional-Schicht wird auf die Ausgabe der ersten Convolutional-Schicht angewendet, wodurch die Merkmale weiter verdichtet werden.
Upsampling
Im Upsampling-Teil werden die verdichteten Merkmale wieder auf die ursprüngliche Bildauflösung hochskaliert. Dies geschieht schrittweise, indem die Auflösung durch UpSampling2D
vergrößert und die resultierenden Merkmale mit den entsprechenden Merkmalen aus dem Encoder-Teil kombiniert werden (Skip Connections).
# Upsampling
up4 = UpSampling2D(size=(2, 2))(conv3)
up4 = concatenate([up4, conv2], axis=3)
Erklärung:
UpSampling2D(size=(2, 2))
: Diese Schicht vergrößert die räumliche Auflösung der Eingabe um das Doppelte in beiden Dimensionen (Höhe und Breite).(conv3)
: Das Upsampling wird auf die Ausgabe des Bottleneck-Teilsconv3
angewendet.concatenate([up4, conv2], axis=3)
: Diese Zeile führt eine "Skip Connection" durch, indem die hochgesampelten Merkmaleup4
mit den Merkmalen aus der entsprechenden Ebene des Encoder-Teilsconv2
entlang der Kanaldimension (axis=3) kombiniert werden. Dies hilft, Details, die während des Downsamplings verloren gegangen sein könnten, wiederherzustellen.
Diese detaillierten Erklärungen und Beispiele sollten Ihnen helfen, verschiedene Techniken der Bildverarbeitung mit Keras zu verstehen und in Ihren eigenen Projekten anzuwenden.