Keras-Tutorial: Was ist Keras? So installieren Sie es in Python [Beispiel]
Was ist Keras?
Keras ist eine Open Source-Bibliothek für neuronale Netzwerke, geschrieben in Python das auf Theano oder Tensorflow läuft. Es ist modular, schnell und benutzerfreundlich konzipiert. Es wurde von François Chollet, einem Google-Ingenieur, entwickelt. Keras übernimmt keine Berechnungen auf niedriger Ebene. Stattdessen verwendet es dafür eine andere Bibliothek, das sogenannte „Backend“.
Keras ist ein High-Level-API-Wrapper für die Low-Level-API, der auf TensorFlow, CNTK oder Theano ausgeführt werden kann. Die Keras High-Level-API verwaltet die Art und Weise, wie wir Modelle erstellen, Ebenen definieren oder mehrere Input-Output-Modelle einrichten. Auf dieser Ebene kompiliert Keras auch unser Modell mit Verlust- und Optimierungsfunktionen sowie den Trainingsprozess mit der Anpassungsfunktion. Keras in Python verarbeitet keine Low-Level-APIs wie das Erstellen von Berechnungsdiagrammen, Tensoren oder anderen Variablen, da dies bereits von der „Backend“-Engine übernommen wurde.
Was ist ein Backend?
Backend ist ein Begriff in Keras, der alle Berechnungen auf niedriger Ebene wie Tensorprodukte, Faltungen und viele andere Dinge mit Hilfe anderer Bibliotheken wie Tensorflow oder Theano durchführt. Die „Backend-Engine“ übernimmt also die Berechnung und Entwicklung der Modelle. Tensorflow ist die standardmäßige „Backend-Engine“, wir können sie jedoch in der Konfiguration ändern.
Theano, Tensorflow und CNTK-Backend
Theano ist ein Open-Source-Projekt, das von der MILA-Gruppe an der Universität von Montreal, Quebec, Kanada, entwickelt wurde. Es war das erste weit verbreitete Framework. Es ist ein Python Bibliothek, die bei mehrdimensionalen Arrays für mathematische Operationen mit Numpy oder Scipy hilft. Theano kann GPUs für schnellere Berechnungen verwenden und automatisch symbolische Graphen zum Berechnen von Gradienten erstellen. Auf seiner Website behauptet Theano, dass es numerisch instabile Ausdrücke erkennen und mit stabileren Algorithmen berechnen kann, was für unsere instabilen Ausdrücke sehr nützlich ist.
Andererseits ist Tensorflow der aufstrebende Stern im Deep-Learning-Framework. Es wurde vom Brain-Team von Google entwickelt und ist das beliebteste Deep-Learning-Tool. Mit vielen Funktionen tragen Forscher dazu bei, dieses Framework für Deep-Learning-Zwecke zu entwickeln.
Eine weitere Backend-Engine für Keras ist The Microsoft Cognitive Toolkit oder CNTK. Es handelt sich um ein Open-Source-Deep-Learning-Framework, das von entwickelt wurde Microsoft Team. Es kann auf mehreren GPUs oder mehreren Maschinen ausgeführt werden, um Deep-Learning-Modelle in großem Umfang zu trainieren. In einigen Fällen wurde berichtet, dass CNTK schneller ist als andere Frameworks wie Tensorflow oder Theano. Als Nächstes vergleichen wir in diesem Keras CNN-Tutorial die Backends von Theano, TensorFlow und CNTK.
Vergleich der Backends
Wir müssen einen Benchmark durchführen, um den Vergleich zwischen diesen beiden Backends zu ermitteln. Wie Sie darin sehen können Jeong-Yoon Lees Maßstab, wird die Leistung von 3 verschiedenen Backends auf unterschiedlicher Hardware verglichen. Das Ergebnis ist Berichten zufolge, dass Theano langsamer ist als das andere Backend 50 mal langsamer, aber die Genauigkeit liegt nahe beieinander.
Ein anderer Benchmark-Test wird durchgeführt von Jasmeet Bhatia. Er berichtete, dass Theano für einige Tests langsamer als Tensorflow sei. Die Gesamtgenauigkeit ist jedoch für jedes getestete Netzwerk nahezu gleich.
Zwischen Theano, Tensorflow und CTK ist es also offensichtlich, dass TensorFlow besser als Theano ist. Mit TensorFlow ist die Rechenzeit viel kürzer und CNN ist besser als die anderen.
Als nächstes in diesem Keras Python Tutorial lernen wir den Unterschied zwischen Keras und TensorFlow kennen (Keras vs. Tensorflow).
Keras vs. Tensorflow
Parameter | Keras | Tensorflow |
---|---|---|
Typ | High-Level-API-Wrapper | Low-Level-API |
Komplexität | Einfach zu bedienen, wenn Sie Python Sprache | Sie müssen die Syntax für die Verwendung einiger Tensorflow-Funktionen erlernen |
Sinn | Schnelle Bereitstellung für die Modellerstellung mit Standardebenen | Ermöglicht die Erstellung eines beliebigen Rechendiagramms oder von Modellebenen |
Werkzeuge | Verwendet ein anderes API-Debug-Tool wie TFDBG | Sie können Tensorboard-Visualisierungstools verwenden |
Community | Große aktive Gemeinschaften | Große aktive Communities und weithin gemeinsam genutzte Ressourcen |
Vorteile von Keras
Schnelle Bereitstellung und leicht verständlich
Keras ist sehr schnell, um ein Netzwerkmodell zu erstellen. Wenn Sie ein einfaches Netzwerkmodell mit wenigen Zeilen erstellen möchten, Python Keras kann Ihnen dabei helfen. Sehen Sie sich das folgende Keras-Beispiel an:
from keras.models import Sequential from keras.layers import Dense, Activation model = Sequential() model.add(Dense(64, activation='relu', input_dim=50)) #input shape of 50 model.add(Dense(28, activation='relu')) #input shape of 50 model.add(Dense(10, activation='softmax'))
Aufgrund der benutzerfreundlichen API können wir den Prozess leicht verstehen. Schreiben Sie den Code mit einer einfachen Funktion, ohne dass mehrere Parameter festgelegt werden müssen.
Große Community-Unterstützung
Es gibt viele KI-Communitys, die Keras für ihr Deep-Learning-Framework verwenden. Viele von ihnen veröffentlichen ihre Codes sowie Tutorials für die breite Öffentlichkeit.
Haben Sie mehrere Backends
Sie können Tensorflow, CNTK und Theano als Backend mit Keras wählen. Je nach Bedarf können Sie für verschiedene Projekte ein anderes Backend wählen. Jedes Backend hat seinen eigenen einzigartigen Vorteil.
Plattformübergreifende und einfache Modellbereitstellung
Mit einer Vielzahl unterstützter Geräte und Plattformen können Sie Keras auf jedem beliebigen Gerät bereitstellen
- iOS mit CoreML
- Android mit Tensorflow Android,
- Webbrowser mit .js-Unterstützung
- Cloud-Engine
- Raspberry Pi
Unterstützung mehrerer GPUs
Sie können Keras auf einer einzelnen GPU trainieren oder mehrere GPUs gleichzeitig verwenden. Da Keras über eine integrierte Unterstützung für Datenparallelität verfügt, kann es große Datenmengen verarbeiten und die für das Training erforderliche Zeit verkürzen.
Nachteile von Keras
Die Low-Level-API kann nicht verarbeitet werden
Keras verarbeitet nur High-Level-APIs, die auf anderen Frameworks oder Backend-Engines wie Tensorflow, Theano oder CNTK ausgeführt werden. Daher ist es nicht sehr nützlich, wenn Sie für Ihre Forschungszwecke eine eigene abstrakte Ebene erstellen möchten, da Keras bereits über vorkonfigurierte Ebenen verfügt.
Keras installieren
In diesem Abschnitt werden wir verschiedene Methoden zur Installation von Keras untersuchen
Direktinstallation oder virtuelle Umgebung
Welches ist besser? Direkte Installation auf dem aktuellen Python oder Verwendung einer virtuellen Umgebung? Ich empfehle die Verwendung einer virtuellen Umgebung, wenn Sie viele Projekte haben. Möchten Sie wissen, warum? Dies liegt daran, dass verschiedene Projekte möglicherweise eine unterschiedliche Version einer Keras-Bibliothek verwenden.
Ich habe zum Beispiel ein Projekt, das Python 3.5 mit OpenCV 3.3 mit älterem Keras-Theano-Backend, aber im anderen Projekt muss ich Keras mit der neuesten Version und einem Tensorflow als Backend verwenden mit Python 3.6.6 Unterstützung
Wir wollen nicht, dass die Keras-Bibliothek miteinander in Konflikt gerät, oder? Wir verwenden also eine virtuelle Umgebung, um das Projekt mit einem bestimmten Bibliothekstyp zu lokalisieren, oder wir können eine andere Plattform wie einen Cloud-Service verwenden, um unsere Berechnungen für uns durchzuführen Amazon Internetservice.
Keras installieren auf Amazon Webdienst (AWS)
Amazon Web Service ist eine Plattform, die Cloud-Computing-Dienste und -Produkte für Forscher oder andere Zwecke anbietet. AWS vermietet seine Hardware, Netzwerke, Datenbanken usw., damit wir sie direkt aus dem Internet nutzen können. Einer der beliebtesten AWS-Dienste für Deep-Learning-Zwecke ist der Amazon Machine Image Deep Learning Service oder DL
Ausführliche Anweisungen zur Verwendung von AWS finden Sie hier Lernprogramm
Hinweis zum AMI: Ihnen steht folgendes AMI zur Verfügung
AWS Deep Learning AMI ist eine virtuelle Umgebung im AWS EC2 Service, die Forschern oder Praktikern bei der Arbeit mit Deep Learning hilft. DLAMI bietet von kleinen CPU-Engines bis hin zu leistungsstarken Multi-GPU-Engines mit vorkonfiguriertem CUDA, cuDNN und einer Vielzahl von Deep-Learning-Frameworks.
Wenn Sie es sofort verwenden möchten, sollten Sie sich für Deep Learning AMI entscheiden, da beliebte Deep-Learning-Frameworks vorinstalliert sind.
Wenn Sie jedoch ein benutzerdefiniertes Deep-Learning-Framework für die Forschung ausprobieren möchten, sollten Sie das Deep Learning Base AMI installieren, da es grundlegende Bibliotheken wie CUDA, cuDNN, GPU-Treiber und andere benötigte Bibliotheken für die Ausführung mit Ihrer Deep-Learning-Umgebung enthält.
So installieren Sie Keras auf Amazon SageMaker
Amazon SageMaker ist eine Deep-Learning-Plattform, die Sie beim Training und Einsatz von Deep-Learning-Netzwerken mit dem besten Algorithmus unterstützt.
Als Anfänger ist dies bei weitem die einfachste Methode, Keras zu verwenden. Nachfolgend finden Sie einen Prozess zur Installation von Keras Amazon SageMaker:
Schritt 1) Öffnen Amazon SageMaker
Öffnen Sie im ersten Schritt die Amazon Sagemaker Konsole und klicken Sie auf Notebook-Instanz erstellen.
Schritt 2) Geben Sie die Details ein
- Geben Sie den Namen Ihres Notizbuchs ein.
- Erstellen Sie eine IAM-Rolle. Es wird eine AMI-Rolle erstellt Amazon IAM-Rolle im Format von AmazonSageMaker-Ausführungsrolle-JJJJMMTT|HHmmSS.
- Wählen Sie abschließend „Notebook-Instanz erstellen“. Nach ein paar Augenblicken, Amazon Sagemaker startet eine Notebook-Instanz.
Note: Wenn Sie auf Ressourcen aus Ihrem VPC zugreifen möchten, aktivieren Sie den direkten Internetzugang. Andernfalls hat diese Notebook-Instanz keinen Internetzugang und es ist nicht möglich, Modelle zu trainieren oder zu hosten.
Schritt 3) Starten Sie die Instanz
Klicken Sie auf Öffnen, um die Instanz zu starten
Schritt 4) Beginnen Sie mit dem Codieren
In Jupyter, Klicken Sie auf Neu > conda_tensorflow_p36 und Sie können mit dem Codieren beginnen
Installieren Sie Keras unter Linux
Um Keras mit Tensorflow als Backend-Engine zu aktivieren, müssen wir zuerst Tensorflow installieren. Führen Sie diesen Befehl aus, um Tensorflow mit CPU (keine GPU) zu installieren.
pip install --upgrade tensorflow
Wenn Sie die GPU-Unterstützung für Tensorflow aktivieren möchten, können Sie diesen Befehl verwenden
pip install --upgrade tensorflow-gpu
Lass uns einchecken Python um zu sehen, ob unsere Installation erfolgreich war, indem Sie eingeben
user@user:~$ python Python 3.6.4 (default, Mar 20 2018, 11:10:20) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import tensorflow >>>
Wenn keine Fehlermeldung angezeigt wird, ist der Installationsvorgang erfolgreich
Installieren Sie Keras
Nachdem wir Tensorflow installiert haben, beginnen wir mit der Installation von Keras. Geben Sie diesen Befehl im Terminal ein
pip install keras
Es beginnt mit der Installation von Keras und allen seinen Abhängigkeiten. Sie sollten etwa Folgendes sehen:
Jetzt haben wir Keras in unserem System installiert!
Überprüfen
Bevor wir Keras verwenden, sollten wir prüfen, ob unsere Keras Tensorflow als Backend verwenden, indem wir die Konfigurationsdatei öffnen:
gedit ~/.keras/keras.json
Sie sollten so etwas sehen
{ "floatx": "float32", "epsilon": 1e-07, "backend": "tensorflow", "image_data_format": "channels_last" }
Wie Sie sehen können, verwendet das „Backend“ Tensorflow. Das bedeutet, dass Keras wie erwartet Tensorflow als Backend verwendet
und führen Sie es nun durch Eingabe auf dem Terminal aus
user@user:~$ python3 Python 3.6.4 (default, Mar 20 2018, 11:10:20) [GCC 5.4.0 20160609] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import keras Using TensorFlow backend. >>>
So installieren Sie Keras auf Windows
Bevor wir installieren Tensorflow und Keras, wir sollten installieren Python, pip und virtualenv. Wenn Sie diese Bibliotheken bereits installiert haben, sollten Sie mit dem nächsten Schritt fortfahren, andernfalls gehen Sie wie folgt vor:
Installieren Python 3 durch Herunterladen von diesem Link
Installieren Sie pip, indem Sie es ausführen fehlen uns die Worte.
Installieren Sie virtualenv mit diesem Befehl
pip3 install –U pip virtualenv
Installieren Microsoft visuell C++ 2015 Weiterverteilbares Update 3
- Gehen Sie zur Visual Studio-Download-Site https://www.microsoft.com/en-us/download/details.aspx?id=53587
- Wählen Sie Redistributables und Build Tools aus
- Laden Sie die Microsoft visuell C++ 2015 Weiterverteilbares Update 3
Führen Sie dann dieses Skript aus
pip3 install virtualenv
Richten Sie eine virtuelle Umgebung ein
Dies wird verwendet, um das Arbeitssystem vom Hauptsystem zu isolieren.
virtualenv –-system-site-packages –p python3 ./venv
Aktivieren Sie die Umgebung
.\venv\Scripts\activate
Nach der Vorbereitung der Umgebung bleibt die Installation von Tensorflow und Keras dieselbe wie bei Linux. Als nächstes lernen wir in diesem Deep Learning mit Keras-Tutorial die Keras-Grundlagen für Deep Learning kennen.
Keras-Grundlagen für Deep Learning
Die Hauptstruktur in Keras ist das Modell, das den vollständigen Graphen eines Netzwerks definiert. Sie können einem vorhandenen Modell weitere Ebenen hinzufügen, um ein benutzerdefiniertes Modell zu erstellen, das Sie für Ihr Projekt benötigen.
Hier erfahren Sie, wie Sie ein sequentielles Modell und einige häufig verwendete Ebenen beim Deep Learning erstellen
1. Sequentielles Modell
from keras.models import Sequential from keras.layers import Dense, Activation,Conv2D,MaxPooling2D,Flatten,Dropout model = Sequential()
2. Faltungsschicht
Dies ist ein Keras Python Beispiel einer Faltungsschicht als Eingabeschicht mit der Eingabeform 320 x 320 x 3, mit 48 Filtern der Größe 3 x 3 und Verwendung von ReLU als Aktivierungsfunktion.
input_shape=(320,320,3) #this is the input shape of an image 320x320x3 model.add(Conv2D(48, (3, 3), activation='relu', input_shape= input_shape))
ein anderer Typ ist
model.add(Conv2D(48, (3, 3), activation='relu'))
3. maxPooling Ebene
Um die Eingabedarstellung herunterzurechnen, verwenden Sie MaxPool2d und geben Sie die Kernelgröße an
model.add(MaxPooling2D(pool_size=(2, 2)))
4. Dichte Schicht
Hinzufügen einer vollständig verbundenen Ebene mit lediglich Angabe der Ausgabegröße
model.add(Dense(256, activation='relu'))
5. Dropout-Ebene
Dropout-Schicht mit 50 % Wahrscheinlichkeit hinzufügen
model.add(Dropout(0.5))
Kompilieren, trainieren und auswerten
Nachdem wir unser Modell definiert haben, beginnen wir mit dem Training. Es ist erforderlich, das Netzwerk zunächst mit der Verlustfunktion und der Optimierungsfunktion zu kompilieren. Dadurch kann das Netzwerk Gewichte ändern und der Verlust wird minimiert.
model.compile(loss='mean_squared_error', optimizer='adam')
Um nun mit dem Training zu beginnen, verwenden Sie fit, um die Trainings- und Validierungsdaten in das Modell einzuspeisen. Dadurch können Sie das Netzwerk stapelweise trainieren und die Epochen festlegen.
model.fit(X_train, X_train, batch_size=32, epochs=10, validation_data=(x_val, y_val))
Unser letzter Schritt besteht darin, das Modell mit den Testdaten auszuwerten.
score = model.evaluate(x_test, y_test, batch_size=32)
Versuchen wir es mit einer einfachen linearen Regression
import keras from keras.models import Sequential from keras.layers import Dense, Activation import numpy as np import matplotlib.pyplot as plt x = data = np.linspace(1,2,200) y = x*4 + np.random.randn(*x.shape) * 0.3 model = Sequential() model.add(Dense(1, input_dim=1, activation='linear')) model.compile(optimizer='sgd', loss='mse', metrics=['mse']) weights = model.layers[0].get_weights() w_init = weights[0][0][0] b_init = weights[1][0] print('Linear regression model is initialized with weights w: %.2f, b: %.2f' % (w_init, b_init)) model.fit(x,y, batch_size=1, epochs=30, shuffle=False) weights = model.layers[0].get_weights() w_final = weights[0][0][0] b_final = weights[1][0] print('Linear regression model is trained to have weight w: %.2f, b: %.2f' % (w_final, b_final)) predict = model.predict(data) plt.plot(data, predict, 'b', data , y, 'k.') plt.show()
Nach dem Training der Daten sollte die Ausgabe so aussehen
mit dem Ausgangsgewicht
Linear regression model is initialized with weights w: 0.37, b: 0.00
und Endgewicht
Linear regression model is trained to have weight w: 3.70, b: 0.61
Feinabstimmung vorab trainierter Modelle in Keras und deren Verwendung
Warum wir Fine-Tuning-Modelle verwenden und wann wir sie verwenden
Bei der Feinabstimmung geht es darum, ein vorab trainiertes Modell so zu optimieren, dass sich die Parameter an das neue Modell anpassen. Wenn wir ein neues Modell von Grund auf trainieren möchten, benötigen wir eine große Datenmenge, damit das Netzwerk alle Parameter finden kann. In diesem Fall verwenden wir jedoch ein vorab trainiertes Modell, sodass die Parameter bereits gelernt sind und eine Gewichtung haben.
Wenn wir beispielsweise unser eigenes Keras-Modell trainieren möchten, um ein Klassifizierungsproblem zu lösen, aber nur über eine kleine Datenmenge verfügen, können wir dies mithilfe von a lösen Lernen übertragen + Feinabstimmungsmethode.
Mit einem vorab trainierten Netzwerk und Gewichten müssen wir nicht das gesamte Netzwerk trainieren. Wir müssen nur die letzte Ebene trainieren, die zur Lösung unserer Aufgabe verwendet wird, was wir als Feinabstimmungsmethode bezeichnen.
Vorbereitung des Netzwerkmodells
Für das vorab trainierte Modell können wir eine Vielzahl von Modellen laden, die Keras bereits in seiner Bibliothek hat, wie zum Beispiel:
- VGG16
- EinführungV3
- ResNet
- MobileNet
- Xception
- InceptionResNetV2
Aber in diesem Prozess werden wir das VGG16-Netzwerkmodell und das ImageNet als Gewicht für das Modell verwenden. Wir werden ein Netzwerk verfeinern, um 8 verschiedene Arten von Klassen mithilfe von Bildern von zu klassifizieren Kaggle Natural Images-Datensatz
VGG16-Modellarchitektur
Hochladen unserer Daten in den AWS S3 Bucket
Für unseren Trainingsprozess verwenden wir ein Bild natürlicher Bilder aus 8 verschiedenen Klassen wie Flugzeuge, Auto, Katze, Hund, Blume, Obst, Motorrad und Person. Zuerst müssen wir unsere Daten hochladen Amazon S3-Eimer.
Amazon S3-Eimer
Schritt 1) Nachdem Sie sich bei Ihrem S3-Konto angemeldet haben, erstellen wir durch Takten einen Bucket Neues Bucket
Schritt 2) Wählen Sie nun einen Bucket-Namen und Ihre Region entsprechend Ihrem Konto. Stellen Sie sicher, dass der Bucket-Name verfügbar ist. Klicken Sie danach Erstellen.
Schritt 3) Wie Sie sehen, ist Ihr Bucket einsatzbereit. Aber wie Sie sehen, ist der Zugriff nicht öffentlich, es ist gut für Sie, wenn Sie ihn für sich privat halten möchten. Sie können diesen Bucket in den Bucket-Eigenschaften für den öffentlichen Zugriff ändern
Schritt 4) Jetzt beginnen Sie mit dem Hochladen Ihrer Trainingsdaten in Ihren Bucket. Hier werde ich die Datei tar.gz hochladen, die aus Bildern für den Schulungs- und Testprozess besteht.
Schritt 5) Klicken Sie nun auf Ihre Datei und kopieren Sie die Link damit wir es herunterladen können.
Datenaufbereitung
Wir müssen unsere Trainingsdaten mithilfe der Keras ImageData generierenGenerator.
Zuerst müssen Sie mit wget den Link zu Ihrer Datei aus S3 Bucket herunterladen.
!wget https://s3.us-east-2.amazonaws.com/naturalimages02/images.tar.gz !tar -xzf images.tar.gz
Nachdem Sie die Daten heruntergeladen haben, beginnen wir mit dem Trainingsprozess.
from keras.preprocessing.image import ImageDataGenerator import numpy as np import matplotlib.pyplot as plt train_path = 'images/train/' test_path = 'images/test/' batch_size = 16 image_size = 224 num_class = 8 train_datagen = ImageDataGenerator(validation_split=0.3, shear_range=0.2, zoom_range=0.2, horizontal_flip=True) train_generator = train_datagen.flow_from_directory( directory=train_path, target_size=(image_size,image_size), batch_size=batch_size, class_mode='categorical', color_mode='rgb', shuffle=True)
Die ImageDataGenerator erstellt X_training-Daten aus einem Verzeichnis. Das Unterverzeichnis in diesem Verzeichnis wird als Klasse für jedes Objekt verwendet. Das Bild wird mit dem RGB-Farbmodus, mit dem kategorialen Klassenmodus für die Y_training-Daten und einer Stapelgröße von 16 geladen. Zum Schluss werden die Daten gemischt.
Sehen wir uns unsere Bilder zufällig an, indem wir sie mit matplotlib plotten
x_batch, y_batch = train_generator.next() fig=plt.figure() columns = 4 rows = 4 for i in range(1, columns*rows): num = np.random.randint(batch_size) image = x_batch[num].astype(np.int) fig.add_subplot(rows, columns, i) plt.imshow(image) plt.show()
Danach erstellen wir unser Netzwerkmodell aus VGG16 mit vorab trainiertem ImageNet-Gewicht. Wir werden diese Schichten einfrieren, sodass sie nicht trainierbar sind, um die Rechenzeit zu verkürzen.
Erstellen unseres Modells aus VGG16
import keras from keras.models import Model, load_model from keras.layers import Activation, Dropout, Flatten, Dense from keras.preprocessing.image import ImageDataGenerator from keras.applications.vgg16 import VGG16 #Load the VGG model base_model = VGG16(weights='imagenet', include_top=False, input_shape=(image_size, image_size, 3)) print(base_model.summary()) # Freeze the layers for layer in base_model.layers: layer.trainable = False # # Create the model model = keras.models.Sequential() # # Add the vgg convolutional base model model.add(base_model) # # Add new layers model.add(Flatten()) model.add(Dense(1024, activation='relu')) model.add(Dense(1024, activation='relu')) model.add(Dense(num_class, activation='softmax')) # # Show a summary of the model. Check the number of trainable parameters print(model.summary())
Wie Sie unten sehen können, ist die Zusammenfassung unseres Netzwerkmodells. Aus einer Eingabe von VGG16-Schichten fügen wir dann zwei vollständig verbundene Schichten hinzu, die 2 Features extrahieren, und eine Ausgabeschicht, die die 1024 Klassen mit der Softmax-Aktivierung berechnet.
Layer (type) Output Shape Param # ================================================================= vgg16 (Model) (None, 7, 7, 512) 14714688 _________________________________________________________________ flatten_1 (Flatten) (None, 25088) 0 _________________________________________________________________ dense_1 (Dense) (None, 1024) 25691136 _________________________________________________________________ dense_2 (Dense) (None, 1024) 1049600 _________________________________________________________________ dense_3 (Dense) (None, 8) 8200 ================================================================= Total params: 41,463,624 Trainable params: 26,748,936 Non-trainable params: 14,714,688
Ausbildung
# # Compile the model from keras.optimizers import SGD model.compile(loss='categorical_crossentropy', optimizer=SGD(lr=1e-3), metrics=['accuracy']) # # Start the training process # model.fit(x_train, y_train, validation_split=0.30, batch_size=32, epochs=50, verbose=2) # # #save the model # model.save('catdog.h5') history = model.fit_generator( train_generator, steps_per_epoch=train_generator.n/batch_size, epochs=10) model.save('fine_tune.h5') # summarize history for accuracy import matplotlib.pyplot as plt plt.plot(history.history['loss']) plt.title('loss') plt.ylabel('loss') plt.xlabel('epoch') plt.legend(['loss'], loc='upper left') plt.show()
Ergebnisse
Epoch 1/10 432/431 [==============================] - 53s 123ms/step - loss: 0.5524 - acc: 0.9474 Epoch 2/10 432/431 [==============================] - 52s 119ms/step - loss: 0.1571 - acc: 0.9831 Epoch 3/10 432/431 [==============================] - 51s 119ms/step - loss: 0.1087 - acc: 0.9871 Epoch 4/10 432/431 [==============================] - 51s 119ms/step - loss: 0.0624 - acc: 0.9926 Epoch 5/10 432/431 [==============================] - 51s 119ms/step - loss: 0.0591 - acc: 0.9938 Epoch 6/10 432/431 [==============================] - 51s 119ms/step - loss: 0.0498 - acc: 0.9936 Epoch 7/10 432/431 [==============================] - 51s 119ms/step - loss: 0.0403 - acc: 0.9958 Epoch 8/10 432/431 [==============================] - 51s 119ms/step - loss: 0.0248 - acc: 0.9959 Epoch 9/10 432/431 [==============================] - 51s 119ms/step - loss: 0.0466 - acc: 0.9942 Epoch 10/10 432/431 [==============================] - 52s 120ms/step - loss: 0.0338 - acc: 0.9947
Wie Sie sehen, sind unsere Verluste deutlich gesunken und die Genauigkeit liegt bei fast 100 %. Um unser Modell zu testen, haben wir zufällig Bilder aus dem Internet ausgewählt und sie mit einer anderen Klasse zum Testen in den Testordner gelegt
Testen unseres Modells
model = load_model('fine_tune.h5') test_datagen = ImageDataGenerator() train_generator = train_datagen.flow_from_directory( directory=train_path, target_size=(image_size,image_size), batch_size=batch_size, class_mode='categorical', color_mode='rgb', shuffle=True) test_generator = test_datagen.flow_from_directory( directory=test_path, target_size=(image_size, image_size), color_mode='rgb', shuffle=False, class_mode='categorical', batch_size=1) filenames = test_generator.filenames nb_samples = len(filenames) fig=plt.figure() columns = 4 rows = 4 for i in range(1, columns*rows -1): x_batch, y_batch = test_generator.next() name = model.predict(x_batch) name = np.argmax(name, axis=-1) true_name = y_batch true_name = np.argmax(true_name, axis=-1) label_map = (test_generator.class_indices) label_map = dict((v,k) for k,v in label_map.items()) #flip k,v predictions = [label_map[k] for k in name] true_value = [label_map[k] for k in true_name] image = x_batch[0].astype(np.int) fig.add_subplot(rows, columns, i) plt.title(str(predictions[0]) + ':' + str(true_value[0])) plt.imshow(image) plt.show()
Und unser Test ist wie unten angegeben! Aus einem Test mit 1 Bildern wurde nur 14 Bild falsch vorhergesagt!
Neuronales Netzwerk zur Gesichtserkennung mit Keras
Warum wir Anerkennung brauchen
Wir brauchen die Erkennung, damit wir das Gesicht einer Person, den Objekttyp, das geschätzte Alter einer Person anhand ihres Gesichts leichter erkennen oder identifizieren oder sogar den Gesichtsausdruck dieser Person kennen können.
Vielleicht stellen Sie fest, dass jedes Mal, wenn Sie versuchen, das Gesicht Ihres Freundes auf einem Foto zu markieren, die Funktion in Facebook dies für Sie erledigt hat, nämlich das Gesicht Ihres Freundes zu markieren, ohne dass Sie es zuerst markieren müssen. Dabei handelt es sich um die Gesichtserkennung von Facebook, die uns das Markieren von Freunden erleichtert.
Wie funktioniert es also? Jedes Mal, wenn wir das Gesicht unseres Freundes markieren, lernt die KI von Facebook dies und versucht, es vorherzusagen, bis das richtige Ergebnis erzielt wird. Das gleiche System werden wir verwenden, um unsere eigene Gesichtserkennung zu erstellen. Beginnen wir mit der Entwicklung unserer eigenen Gesichtserkennung mithilfe von Deep Learning
Netzwerkmodell
Wir werden ein VGG16-Netzwerkmodell verwenden, jedoch mit VGGFace-Gewicht.
VGG16-Modellarchitektur
Was ist VGGFace? Es handelt sich um eine Keras-Implementierung der Deep Face Recognition, die von Parkhi, Omkar M. et al. eingeführt wurde. „Deep Face Recognition.“ BMVC (2015). Das Framework verwendet VGG16 als Netzwerkarchitektur.
Sie können das VGGFace herunterladen unter github
from keras.applications.vgg16 import VGG16 from keras_vggface.vggface import VGGFace face_model = VGGFace(model='vgg16', weights='vggface', input_shape=(224,224,3)) face_model.summary()
Wie Sie der Netzwerkzusammenfassung entnehmen können
_________________________________________________________________ Layer (type) Output Shape Param # ================================================================= input_1 (InputLayer) (None, 224, 224, 3) 0 _________________________________________________________________ conv1_1 (Conv2D) (None, 224, 224, 64) 1792 _________________________________________________________________ conv1_2 (Conv2D) (None, 224, 224, 64) 36928 _________________________________________________________________ pool1 (MaxPooling2D) (None, 112, 112, 64) 0 _________________________________________________________________ conv2_1 (Conv2D) (None, 112, 112, 128) 73856 _________________________________________________________________ conv2_2 (Conv2D) (None, 112, 112, 128) 147584 _________________________________________________________________ pool2 (MaxPooling2D) (None, 56, 56, 128) 0 _________________________________________________________________ conv3_1 (Conv2D) (None, 56, 56, 256) 295168 _________________________________________________________________ conv3_2 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ conv3_3 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ pool3 (MaxPooling2D) (None, 28, 28, 256) 0 _________________________________________________________________ conv4_1 (Conv2D) (None, 28, 28, 512) 1180160 _________________________________________________________________ conv4_2 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ conv4_3 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ pool4 (MaxPooling2D) (None, 14, 14, 512) 0 _________________________________________________________________ conv5_1 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ conv5_2 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ conv5_3 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ pool5 (MaxPooling2D) (None, 7, 7, 512) 0 _________________________________________________________________ flatten (Flatten) (None, 25088) 0 _________________________________________________________________ fc6 (Dense) (None, 4096) 102764544 _________________________________________________________________ fc6/relu (Activation) (None, 4096) 0 _________________________________________________________________ fc7 (Dense) (None, 4096) 16781312 _________________________________________________________________ fc7/relu (Activation) (None, 4096) 0 _________________________________________________________________ fc8 (Dense) (None, 2622) 10742334 _________________________________________________________________ fc8/softmax (Activation) (None, 2622) 0 ================================================================= Total params: 145,002,878 Trainable params: 145,002,878 Non-trainable params: 0 _________________________________________________________________ Traceback (most recent call last):
Wir werden eins machen Lernen übertragen + Feinabstimmung, um das Training bei kleinen Datensätzen zu beschleunigen. Zuerst werden wir die Basisschichten einfrieren, sodass die Schichten nicht trainierbar sind.
for layer in face_model.layers: layer.trainable = False
Dann fügen wir unsere eigene Ebene hinzu, um unsere Testgesichter zu erkennen. Wir werden zwei vollständig verbundene Schichten und eine Ausgabeschicht mit 2 zu erkennenden Personen hinzufügen.
from keras.models import Model, Sequential from keras.layers import Input, Convolution2D, ZeroPadding2D, MaxPooling2D, Flatten, Dense, Dropout, Activation person_count = 5 last_layer = face_model.get_layer('pool5').output x = Flatten(name='flatten')(last_layer) x = Dense(1024, activation='relu', name='fc6')(x) x = Dense(1024, activation='relu', name='fc7')(x) out = Dense(person_count, activation='softmax', name='fc8')(x) custom_face = Model(face_model.input, out)
Sehen wir uns unsere Netzwerkzusammenfassung an
Layer (type) Output Shape Param # ================================================================= input_1 (InputLayer) (None, 224, 224, 3) 0 _________________________________________________________________ conv1_1 (Conv2D) (None, 224, 224, 64) 1792 _________________________________________________________________ conv1_2 (Conv2D) (None, 224, 224, 64) 36928 _________________________________________________________________ pool1 (MaxPooling2D) (None, 112, 112, 64) 0 _________________________________________________________________ conv2_1 (Conv2D) (None, 112, 112, 128) 73856 _________________________________________________________________ conv2_2 (Conv2D) (None, 112, 112, 128) 147584 _________________________________________________________________ pool2 (MaxPooling2D) (None, 56, 56, 128) 0 _________________________________________________________________ conv3_1 (Conv2D) (None, 56, 56, 256) 295168 _________________________________________________________________ conv3_2 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ conv3_3 (Conv2D) (None, 56, 56, 256) 590080 _________________________________________________________________ pool3 (MaxPooling2D) (None, 28, 28, 256) 0 _________________________________________________________________ conv4_1 (Conv2D) (None, 28, 28, 512) 1180160 _________________________________________________________________ conv4_2 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ conv4_3 (Conv2D) (None, 28, 28, 512) 2359808 _________________________________________________________________ pool4 (MaxPooling2D) (None, 14, 14, 512) 0 _________________________________________________________________ conv5_1 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ conv5_2 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ conv5_3 (Conv2D) (None, 14, 14, 512) 2359808 _________________________________________________________________ pool5 (MaxPooling2D) (None, 7, 7, 512) 0 _________________________________________________________________ flatten (Flatten) (None, 25088) 0 _________________________________________________________________ fc6 (Dense) (None, 1024) 25691136 _________________________________________________________________ fc7 (Dense) (None, 1024) 1049600 _________________________________________________________________ fc8 (Dense) (None, 5) 5125 ================================================================= Total params: 41,460,549 Trainable params: 26,745,861 Non-trainable params: 14,714,688
Wie Sie oben sehen können, wird die Pool5-Ebene nach der Ebene zu einem einzelnen Merkmalsvektor abgeflacht, der von der dichten Ebene für die endgültige Erkennung verwendet wird.
Unsere Gesichter vorbereiten
Jetzt bereiten wir unsere Gesichter vor. Ich habe ein Verzeichnis mit fünf berühmten Personen erstellt
- Jack Ma
- Jason Statham
- Johnny Depp
- Robert Downey Jr
- Rowan Atkinson
Jeder Ordner enthält 10 Bilder für jeden Schulungs- und Bewertungsprozess. Es handelt sich um eine sehr kleine Datenmenge, aber das ist die Herausforderung, oder?
Zur Vorbereitung der Daten nutzen wir das Keras-Tool. Diese Funktion durchläuft den Datensatzordner und bereitet ihn dann vor, damit er im Training verwendet werden kann.
from keras.preprocessing.image import ImageDataGenerator batch_size = 5 train_path = 'data/' eval_path = 'eval/' train_datagen = ImageDataGenerator(rescale=1./255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True) valid_datagen = ImageDataGenerator(rescale=1./255, shear_range=0.2, zoom_range=0.2, horizontal_flip=True) train_generator = train_datagen.flow_from_directory( train_path, target_size=(image_size,image_size), batch_size=batch_size, class_mode='sparse', color_mode='rgb') valid_generator = valid_datagen.flow_from_directory( directory=eval_path, target_size=(224, 224), color_mode='rgb', batch_size=batch_size, class_mode='sparse', shuffle=True, )
Training unseres Modells
Beginnen wir unseren Trainingsprozess mit der Zusammenstellung unseres Netzwerks mit Verlustfunktion und Optimierer. Hier verwenden wir sparse_categorical_crossentropy als unsere Verlustfunktion mit Hilfe von SGD als unserem Lernoptimierer.
from keras.optimizers import SGD custom_face.compile(loss='sparse_categorical_crossentropy', optimizer=SGD(lr=1e-4, momentum=0.9), metrics=['accuracy']) history = custom_face.fit_generator( train_generator, validation_data=valid_generator, steps_per_epoch=49/batch_size, validation_steps=valid_generator.n, epochs=50) custom_face.evaluate_generator(generator=valid_generator) custom_face.save('vgg_face.h5') Epoch 25/50 10/9 [==============================] - 60s 6s/step - loss: 1.4882 - acc: 0.8998 - val_loss: 1.5659 - val_acc: 0.5851 Epoch 26/50 10/9 [==============================] - 59s 6s/step - loss: 1.4882 - acc: 0.8998 - val_loss: 1.5638 - val_acc: 0.5809 Epoch 27/50 10/9 [==============================] - 60s 6s/step - loss: 1.4779 - acc: 0.8597 - val_loss: 1.5613 - val_acc: 0.5477 Epoch 28/50 10/9 [==============================] - 60s 6s/step - loss: 1.4755 - acc: 0.9199 - val_loss: 1.5576 - val_acc: 0.5809 Epoch 29/50 10/9 [==============================] - 60s 6s/step - loss: 1.4794 - acc: 0.9153 - val_loss: 1.5531 - val_acc: 0.5892 Epoch 30/50 10/9 [==============================] - 60s 6s/step - loss: 1.4714 - acc: 0.8953 - val_loss: 1.5510 - val_acc: 0.6017 Epoch 31/50 10/9 [==============================] - 60s 6s/step - loss: 1.4552 - acc: 0.9199 - val_loss: 1.5509 - val_acc: 0.5809 Epoch 32/50 10/9 [==============================] - 60s 6s/step - loss: 1.4504 - acc: 0.9199 - val_loss: 1.5492 - val_acc: 0.5975 Epoch 33/50 10/9 [==============================] - 60s 6s/step - loss: 1.4497 - acc: 0.8998 - val_loss: 1.5490 - val_acc: 0.5851 Epoch 34/50 10/9 [==============================] - 60s 6s/step - loss: 1.4453 - acc: 0.9399 - val_loss: 1.5529 - val_acc: 0.5643 Epoch 35/50 10/9 [==============================] - 60s 6s/step - loss: 1.4399 - acc: 0.9599 - val_loss: 1.5451 - val_acc: 0.5768 Epoch 36/50 10/9 [==============================] - 60s 6s/step - loss: 1.4373 - acc: 0.8998 - val_loss: 1.5424 - val_acc: 0.5768 Epoch 37/50 10/9 [==============================] - 60s 6s/step - loss: 1.4231 - acc: 0.9199 - val_loss: 1.5389 - val_acc: 0.6183 Epoch 38/50 10/9 [==============================] - 59s 6s/step - loss: 1.4247 - acc: 0.9199 - val_loss: 1.5372 - val_acc: 0.5934 Epoch 39/50 10/9 [==============================] - 60s 6s/step - loss: 1.4153 - acc: 0.9399 - val_loss: 1.5406 - val_acc: 0.5560 Epoch 40/50 10/9 [==============================] - 60s 6s/step - loss: 1.4074 - acc: 0.9800 - val_loss: 1.5327 - val_acc: 0.6224 Epoch 41/50 10/9 [==============================] - 60s 6s/step - loss: 1.4023 - acc: 0.9800 - val_loss: 1.5305 - val_acc: 0.6100 Epoch 42/50 10/9 [==============================] - 59s 6s/step - loss: 1.3938 - acc: 0.9800 - val_loss: 1.5269 - val_acc: 0.5975 Epoch 43/50 10/9 [==============================] - 60s 6s/step - loss: 1.3897 - acc: 0.9599 - val_loss: 1.5234 - val_acc: 0.6432 Epoch 44/50 10/9 [==============================] - 60s 6s/step - loss: 1.3828 - acc: 0.9800 - val_loss: 1.5210 - val_acc: 0.6556 Epoch 45/50 10/9 [==============================] - 59s 6s/step - loss: 1.3848 - acc: 0.9599 - val_loss: 1.5234 - val_acc: 0.5975 Epoch 46/50 10/9 [==============================] - 60s 6s/step - loss: 1.3716 - acc: 0.9800 - val_loss: 1.5216 - val_acc: 0.6432 Epoch 47/50 10/9 [==============================] - 60s 6s/step - loss: 1.3721 - acc: 0.9800 - val_loss: 1.5195 - val_acc: 0.6266 Epoch 48/50 10/9 [==============================] - 60s 6s/step - loss: 1.3622 - acc: 0.9599 - val_loss: 1.5108 - val_acc: 0.6141 Epoch 49/50 10/9 [==============================] - 60s 6s/step - loss: 1.3452 - acc: 0.9399 - val_loss: 1.5140 - val_acc: 0.6432 Epoch 50/50 10/9 [==============================] - 60s 6s/step - loss: 1.3387 - acc: 0.9599 - val_loss: 1.5100 - val_acc: 0.6266
Wie Sie sehen, beträgt unsere Validierungsgenauigkeit bis zu 64 %, was für eine kleine Menge an Trainingsdaten ein gutes Ergebnis ist. Wir können dies verbessern, indem wir mehr Ebenen oder Trainingsbilder hinzufügen, damit unser Modell mehr über die Gesichter erfahren und eine höhere Genauigkeit erreichen kann.
Testen wir unser Modell mit einem Testbild
from keras.models import load_model from keras.preprocessing.image import load_img, save_img, img_to_array from keras_vggface.utils import preprocess_input test_img = image.load_img('test.jpg', target_size=(224, 224)) img_test = image.img_to_array(test_img) img_test = np.expand_dims(img_test, axis=0) img_test = utils.preprocess_input(img_test) predictions = model.predict(img_test) predicted_class=np.argmax(predictions,axis=1) labels = (train_generator.class_indices) labels = dict((v,k) for k,v in labels.items()) predictions = [labels[k] for k in predicted_class] print(predictions) ['RobertDJr']
Wenn wir das Bild von Robert Downey Jr. als unser Testbild verwenden, zeigt sich, dass das vorhergesagte Gesicht wahr ist!
Vorhersage mit Live-Cam!
Wie wäre es, wenn wir unsere Fähigkeit testen würden, es mit einem Input von einer Webcam umzusetzen? Mithilfe von OpenCV und der Haar Face-Kaskade können wir unser Gesicht finden und mit Hilfe unseres Netzwerkmodells die Person erkennen.
Der erste Schritt besteht darin, die Gesichter von Ihnen und Ihren Freunden vorzubereiten. Je mehr Daten wir haben, desto besser ist das Ergebnis!
Bereiten Sie Ihr Netzwerk wie im vorherigen Schritt vor und trainieren Sie es. Fügen Sie nach Abschluss des Trainings diese Zeile hinzu, um das Eingabebild von der Kamera zu erhalten
#Load trained model from keras.models import load_model from keras_vggface import utils import cv2 image_size = 224 device_id = 0 #camera_device id model = load_model('my faces.h5') #make labels according to your dataset folder labels = dict(fisrtname=0,secondname=1) #and so on print(labels) cascade_classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') camera = cv2.VideoCapture(device_id) while camera.isOpened(): ok, cam_frame = camera.read() if not ok: break gray_img=cv2.cvtColor(cam_frame, cv2.COLOR_BGR2GRAY) faces= cascade_classifier.detectMultiScale(gray_img, minNeighbors=5) for (x,y,w,h) in faces: cv2.rectangle(cam_frame,(x,y),(x+w,y+h),(255,255,0),2) roi_color = cam_frame [y:y+h, x:x+w] roi color = cv2.cvtColor(roi_color, cv2.COLOR_BGR2RGB) roi_color = cv2.resize(roi_color, (image_size, image_size)) image = roi_color.astype(np.float32, copy=False) image = np.expand_dims(image, axis=0) image = preprocess_input(image, version=1) # or version=2 preds = model.predict(image) predicted_class=np.argmax(preds,axis=1) labels = dict((v,k) for k,v in labels.items()) name = [labels[k] for k in predicted_class] cv2.putText(cam_frame,str(name), (x + 10, y + 10), cv2.FONT_HERSHEY_SIMPLEX, 1, (255,0,255), 2) cv2.imshow('video image', cam_frame) key = cv2.waitKey(30) if key == 27: # press 'ESC' to quit break camera.release() cv2.destroyAllWindows()
Welches ist besser? Keras oder Tensorflow
Keras bietet Einfachheit beim Schreiben des Skripts. Wir können mit Keras direkt mit dem Schreiben beginnen und es verstehen, da es nicht allzu schwer zu verstehen ist. Es ist benutzerfreundlicher und einfacher zu implementieren, da zum Ausführen des Modells nicht viele Variablen erstellt werden müssen. Wir müssen also nicht jedes Detail im Backend-Prozess verstehen.
Auf der anderen Seite bietet Tensorflow Low-Level-Operationen, die Flexibilität und erweiterte Operationen bieten, wenn Sie ein beliebiges Rechendiagramm oder -modell erstellen möchten. Tensorflow kann den Prozess auch mithilfe von visualisieren TensorBoard und ein spezielles Debugger-Tool.
Wenn Sie also mit Deep Learning ohne allzu große Komplexität beginnen möchten, verwenden Sie Keras. Denn Keras ist einfacher zu verwenden und benutzerfreundlicher und lässt sich leichter implementieren als Tensorflow. Wenn Sie jedoch Ihren eigenen Algorithmus für ein Deep-Learning-Projekt oder eine Forschung schreiben möchten, sollten Sie stattdessen Tensorflow verwenden.
Zusammenfassung
Fassen wir also alles zusammen, was wir in diesem Tutorial besprochen und getan haben.
- Keras in einer High-Level-API, die mithilfe der Backend-Engine zur Vereinfachung von Deep-Learning-Netzwerken verwendet wird.
- Keras ist mit Python-Unterstützung einfach zu verwenden und zu verstehen, sodass es sich natürlicher anfühlt als je zuvor. Es ist gut für Anfänger, die etwas über Deep Learning lernen möchten, und für Forscher, die eine einfach zu verwendende API wünschen.
- Der Installationsprozess ist einfach und Sie können eine virtuelle Umgebung oder eine externe Plattform wie z. B. verwenden AWS.
- Keras verfügt außerdem über verschiedene Arten von Netzwerkmodellen, sodass wir das verfügbare Modell einfacher für das Vortraining und die Feinabstimmung unseres eigenen Netzwerkmodells verwenden können.
- Außerdem gibt es zahlreiche Tutorials und Artikel über die Verwendung von Keras-Codes aus Communitys weltweit für Deep-Learning-Zwecke.