Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

TensorFlow.js Layer-API für Keras-Benutzer

Die Layer-API von TensorFlow.js ist Keras nachempfunden. Wir bemühen uns, die Layer-API angesichts der Unterschiede zwischen JavaScript und Python so ähnlich wie Keras zu gestalten. Dies erleichtert Benutzern mit Erfahrung in der Entwicklung von Keras-Modellen in Python die Migration zu TensorFlow.js-Ebenen in JavaScript. Der folgende Keras-Code wird beispielsweise in JavaScript übersetzt:

 # Python:
import keras
import numpy as np

# Build and compile model.
model = keras.Sequential()
model.add(keras.layers.Dense(units=1, input_shape=[1]))
model.compile(optimizer='sgd', loss='mean_squared_error')

# Generate some synthetic data for training.
xs = np.array([[1], [2], [3], [4]])
ys = np.array([[1], [3], [5], [7]])

# Train model with fit().
model.fit(xs, ys, epochs=1000)

# Run inference with predict().
print(model.predict(np.array([[5]])))
 
 // JavaScript:
import * as tf from '@tensorlowjs/tfjs';

// Build and compile model.
const model = tf.sequential();
model.add(tf.layers.dense({units: 1, inputShape: [1]}));
model.compile({optimizer: 'sgd', loss: 'meanSquaredError'});

// Generate some synthetic data for training.
const xs = tf.tensor2d([[1], [2], [3], [4]], [4, 1]);
const ys = tf.tensor2d([[1], [3], [5], [7]], [4, 1]);

// Train model with fit().
await model.fit(xs, ys, {epochs: 1000});

// Run inference with predict().
model.predict(tf.tensor2d([[5]], [1, 1])).print();
 

Es gibt jedoch einige Unterschiede, die wir in diesem Dokument hervorheben und erläutern möchten. Sobald Sie diese Unterschiede und die Gründe dafür verstanden haben, sollte Ihre Migration von Python zu JavaScript (oder die Migration in umgekehrter Richtung) eine relativ reibungslose Erfahrung sein.

Konstruktoren verwenden JavaScript-Objekte als Konfigurationen

Vergleichen Sie die folgenden Python- und JavaScript-Zeilen aus dem obigen Beispiel: Beide erstellen eine dichte Ebene.

 # Python:
keras.layers.Dense(units=1, inputShape=[1])
 
 // JavaScript:
tf.layers.dense({units: 1, inputShape: [1]});
 

JavaScript-Funktionen entsprechen nicht den Schlüsselwortargumenten in Python-Funktionen. Wir möchten vermeiden, Konstruktoroptionen als Positionsargumente in JavaScript zu implementieren, was für Konstruktoren mit einer großen Anzahl von Schlüsselwortargumenten (z. B. LSTM ) besonders umständlich zu merken und zu verwenden wäre. Aus diesem Grund verwenden wir JavaScript-Konfigurationsobjekte. Solche Objekte bieten das gleiche Maß an Positionsinvarianz und Flexibilität wie Python-Schlüsselwortargumente.

Einige Methoden der Model-Klasse, z. B. Model.compile() , verwenden auch ein JavaScript-Konfigurationsobjekt als Eingabe. Model.fit() Sie jedoch, dass Model.fit() , Model.evaluate() und Model.predict() geringfügig voneinander abweichen. Da diese Methoden obligatorische x (Merkmale) und y (Beschriftungen oder Ziele) Daten als Eingaben verwenden; x und y sind Positionsargumente, die vom folgenden Konfigurationsobjekt getrennt sind, das die Rolle der Schlüsselwortargumente spielt. Beispielsweise:

 // JavaScript:
await model.fit(xs, ys, {epochs: 1000});
 

Model.fit () ist asynchron

Model.fit() ist die primäre Methode, mit der Benutzer Modellschulungen in TensorFlow.js durchführen. Diese Methode kann oft lange dauern und Sekunden oder Minuten dauern. Daher verwenden wir die async Funktion der JavaScript-Sprache, damit diese Funktion so verwendet werden kann, dass der Haupt-UI-Thread beim Ausführen im Browser nicht blockiert wird. Dies ähnelt anderen potenziell lang laufenden Funktionen in JavaScript, z. B. dem async Abruf . Beachten Sie, dass async ein Konstrukt ist, das in Python nicht vorhanden ist. Während die fit() -Methode in Keras ein History-Objekt zurückgibt, gibt das Gegenstück zur fit() -Methode in JavaScript ein Promise of History zurück, das abgewartet (wie im obigen Beispiel) oder mit der then () -Methode verwendet werden kann.

Kein NumPy für TensorFlow.js

Python Keras-Benutzer verwenden häufig NumPy , um grundlegende numerische Operationen und Array-Operationen auszuführen, z. B. das Generieren von 2D-Tensoren im obigen Beispiel.

 # Python:
xs = np.array([[1], [2], [3], [4]])
 

In TensorFlow.js werden diese grundlegenden numerischen Operationen mit dem Paket selbst ausgeführt. Beispielsweise:

 // JavaScript:
const xs = tf.tensor2d([[1], [2], [3], [4]], [4, 1]);
 

Der tf.* -Namensraum bietet auch eine Reihe anderer Funktionen für Array- und lineare Algebraoperationen wie die Matrixmultiplikation. Weitere Informationen finden Sie in der TensorFlow.js Core-Dokumentation .

Verwenden Sie Factory-Methoden, keine Konstruktoren

Diese Zeile in Python (aus dem obigen Beispiel) ist ein Konstruktoraufruf:

 # Python:
model = keras.Sequential()
 

Bei einer strengen Übersetzung in JavaScript würde der entsprechende Konstruktoraufruf wie folgt aussehen:

 // JavaScript:
const model = new tf.Sequential();  // !!! DON'T DO THIS !!!
 

Wir haben uns jedoch entschieden, die "neuen" Konstruktoren nicht zu verwenden, da 1) das "neue" Schlüsselwort den Code aufgebläht machen würde und 2) der "neue" Konstruktor als "schlechter Teil" von JavaScript angesehen wird: eine potenzielle Gefahr, wie wird in JavaScript argumentiert : die guten Teile . Um Modelle und Ebenen in TensorFlow.js zu erstellen, rufen Sie Factory-Methoden auf, die niedrigereCamelCase-Namen haben, zum Beispiel:

 // JavaScript:
const model = tf.sequential();

const layer = tf.layers.batchNormalization({axis: 1});
 

Optionszeichenfolgenwerte sind lowerCamelCase, nicht snake_case

In JavaScript ist es üblicher, Kamel-Groß- / Kleinschreibung für Symbolnamen zu verwenden (siehe z. B. Google JavaScript Style Guide ), als in Python, wo Schlangen-Groß- / Kleinschreibung üblich ist (z. B. in Keras). Aus diesem Grund haben wir uns entschieden, lowerCamelCase für Zeichenfolgenwerte für Optionen zu verwenden, einschließlich der folgenden:

  • DataFormat, z. B. channelsFirst anstelle von channels_first
  • Initialisierer, z. B. glorotNormal anstelle von glorot_normal
  • Verlust und Metriken, zB meanSquaredError statt mean_squared_error , categoricalCrossentropy statt categorical_crossentropy .

Zum Beispiel wie im obigen Beispiel:

 // JavaScript:
model.compile({optimizer: 'sgd', loss: 'meanSquaredError'});
 

Seien Sie in Bezug auf die Modellserialisierung und -deserialisierung versichert. Der interne Mechanismus von TensorFlow.js stellt sicher, dass Schlangenfälle in JSON-Objekten korrekt behandelt werden, z. B. beim Laden vorab trainierter Modelle aus Python Keras.

Führen Sie Layer-Objekte mit apply () aus, nicht indem Sie sie als Funktionen aufrufen

In Keras ist für ein Layer-Objekt die Methode __call__ definiert. Daher kann der Benutzer die Logik der Schicht aufrufen, indem er das Objekt als Funktion aufruft, z.

 # Python:
my_input = keras.Input(shape=[2, 4])
flatten = keras.layers.Flatten()

print(flatten(my_input).shape)
 

Dieser Python-Syntaxzucker ist als apply () -Methode in TensorFlow.js implementiert:

 // JavaScript:
const myInput = tf.input({shape: [2, 4]});
const flatten = tf.layers.flatten();

console.log(flatten.apply(myInput).shape);
 

Layer.apply () unterstützt die zwingende (eifrige) Bewertung konkreter Tensoren

Derzeit kann der Call - Methode in Keras, nur arbeiten (Python) TensorFlow der tf.Tensor Objekte (TensorFlow Backend vorausgesetzt), die symbolisch sind und nicht halten tatsächlichen numerischen Werte. Dies wird im Beispiel im vorherigen Abschnitt gezeigt. In TensorFlow.js kann die Methode apply () von Ebenen jedoch sowohl im symbolischen als auch im imperativen Modus ausgeführt werden. Wenn apply() mit einem SymbolicTensor aufgerufen wird (eine enge Analogie zu tf.Tensor), ist der Rückgabewert ein SymbolicTensor. Dies geschieht normalerweise während des Modellbaus. Wenn jedoch apply() mit einem tatsächlichen konkreten Tensorwert aufgerufen wird, wird ein konkreter Tensor zurückgegeben. Beispielsweise:

 // JavaScript:
const flatten = tf.layers.flatten();

flatten.apply(tf.ones([2, 3, 4])).print();
 

Diese Funktion erinnert an die Eager Execution von (Python) TensorFlow. Es bietet eine größere Interaktivität und Debugbarkeit während der Modellentwicklung und öffnet Türen zum Aufbau dynamischer neuronaler Netze.

Optimierer sind im Zug. , keine Optimierer.

In Keras befinden sich die Konstruktoren für Optimizer-Objekte unter dem Namespace keras.optimizers.* . In TensorFlow.js-Layern befinden sich die Factory-Methoden für Optimierer unter dem Namespace tf.train.* . Beispielsweise:

 # Python:
my_sgd = keras.optimizers.sgd(lr=0.2)
 
 // JavaScript:
const mySGD = tf.train.sgd({lr: 0.2});
 

loadLayersModel () wird von einer URL geladen, nicht von einer HDF5-Datei

In Keras, Modelle werden in der Regel gespeichert als HDF5 (.h5) Datei, die später die Verwendung geladen werden kann keras.models.load_model() Methode. Die Methode nimmt einen Pfad zur .h5-Datei. Das Gegenstück zu load_model() in TensorFlow.js ist tf.loadLayersModel() . Da HDF5 kein tf.loadLayersModel() Dateiformat ist, verwendet tf.loadLayersModel() ein TensorFlow.js-spezifisches Format. tf.loadLayersModel() eine Datei model.json als Eingabeargument. Die model.json kann mit dem pip-Paket tensorflowjs aus einer Keras HDF5-Datei konvertiert werden.

 // JavaScript:
const model = await tf.loadLayersModel('https://foo.bar/model.json');
 

Beachten Sie auch, dass tf.loadLayersModel() ein Promise von tf.Model .

Im Allgemeinen erfolgt das Speichern und Laden von tf.Model in TensorFlow.js mit den Methoden tf.Model.save bzw. tf.loadLayersModel . Wir haben diese APIs so konzipiert, dass sie der API save and load_model von Keras ähneln . Die Browser-Umgebung unterscheidet sich jedoch erheblich von der Backend-Umgebung, in der grundlegende Deep-Learning-Frameworks wie Keras ausgeführt werden, insbesondere in Bezug auf die Routen zum Speichern und Übertragen von Daten. Daher gibt es einige interessante Unterschiede zwischen den Save / Load-APIs in TensorFlow.js und in Keras. Weitere Informationen finden Sie in unserem Tutorial zum Speichern und Laden von tf.Model .

Verwenden Sie fitDataset() , um Modelle mit tf.data.Dataset Objekten zu trainieren

In Python TensorFlows tf.keras kann ein Modell mithilfe eines Dataset- Objekts trainiert werden. Die fit() -Methode des Modells akzeptiert ein solches Objekt direkt. Ein TensorFlow.js-Modell kann auch mit dem JavaScript-Äquivalent der Dataset-Objekte trainiert werden (siehe Dokumentation der tf.data-API in TensorFlow.js ). Im Gegensatz zu Python erfolgt das datasetbasierte Training jedoch über eine spezielle Methode, nämlich fitDataset . Die Methode fit () ist nur für das tensorbasierte Modelltraining vorgesehen.

Speicherverwaltung von Ebenen- und Modellobjekten

TensorFlow.js wird in WebGL im Browser ausgeführt, wobei die Gewichte von Ebenen- und Modellobjekten durch WebGL-Texturen unterstützt werden. WebGL bietet jedoch keine integrierte Unterstützung für die Speicherbereinigung. Ebenen- und Modellobjekte verwalten den Tensorspeicher für den Benutzer intern während seiner Inferenz- und Trainingsaufrufe. Sie ermöglichen es dem Benutzer jedoch auch, sie zu entsorgen, um den von ihnen belegten WebGL-Speicher freizugeben. Dies ist in Fällen nützlich, in denen viele Modellinstanzen innerhalb einer einzelnen Seitenladung erstellt und freigegeben werden. Verwenden Sie die Methode dispose() um ein Ebenen- oder Modellobjekt zu dispose() .