Machine Learning mit Python und TensorFlow - Praktischer Leitfaden
Machine Learning mit
ai-mlMachine Learning mit Python und TensorFlow - Praktischer Leitfaden
Machine Learning (ML) revolutioniert die Art und Weise, wie wir Software entwickeln. Anstatt explizite Regeln zu programmieren, trainieren wir Modelle, um Muster in Daten zu erkennen. TensorFlow, entwickelt von Google, ist eines der leistungsstärksten Frameworks zum Erstellen und Bereitstellen von ML-Modellen. In diesem Leitfaden führen wir Sie von den theoretischen Grundlagen über die TensorFlow-Architektur bis hin zu praktischen Implementierungen und produktionsreifen Deployment-Strategien.
Grundlagen des Machine Learning#
Bevor wir in TensorFlow eintauchen, ist es wichtig, die drei Hauptparadigmen des maschinellen Lernens zu verstehen.
Überwachtes Lernen (Supervised Learning)#
Beim überwachten Lernen wird ein Modell mit Paaren von (Eingabedaten, erwartete Ausgabe) trainiert. Anhand dieser Beispiele lernt es eine Funktion, die Eingaben auf Ausgaben abbildet.
Typische Anwendungen:
- Klassifikation - Bilderkennung, Sentimentanalyse, Spam-Erkennung
- Regression - Preisvorhersage, Wetterprognose, Lieferzeitschätzung
# Einfaches Beispiel: Binäre Klassifikation
import tensorflow as tf
from tensorflow import keras
# Trainingsdaten: Merkmale und Labels
X_train = [[0.1, 0.2], [0.4, 0.6], [0.8, 0.9], [0.3, 0.1]]
y_train = [0, 0, 1, 0] # 0 = Klasse A, 1 = Klasse B
model = keras.Sequential([
keras.layers.Dense(16, activation='relu', input_shape=(2,)),
keras.layers.Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(X_train, y_train, epochs=50, verbose=0)
Unüberwachtes Lernen (Unsupervised Learning)#
Das Modell analysiert Daten ohne Labels und sucht nach verborgenen Mustern und Strukturen.
Typische Anwendungen:
- Clustering - Kundensegmentierung, Bildsegmentierung
- Dimensionsreduktion - Visualisierung hochdimensionaler Daten (PCA, t-SNE)
- Anomalieerkennung - Betrugserkennung, Systemüberwachung
# Autoencoder zur Anomalieerkennung
encoder = keras.Sequential([
keras.layers.Dense(64, activation='relu', input_shape=(100,)),
keras.layers.Dense(32, activation='relu'),
keras.layers.Dense(16, activation='relu') # Engpass (Bottleneck)
])
decoder = keras.Sequential([
keras.layers.Dense(32, activation='relu', input_shape=(16,)),
keras.layers.Dense(64, activation='relu'),
keras.layers.Dense(100, activation='sigmoid')
])
autoencoder_input = keras.layers.Input(shape=(100,))
encoded = encoder(autoencoder_input)
decoded = decoder(encoded)
autoencoder = keras.Model(autoencoder_input, decoded)
autoencoder.compile(optimizer='adam', loss='mse')
Bestärkendes Lernen (Reinforcement Learning)#
Ein Agent lernt, Entscheidungen in einer Umgebung zu treffen, indem er Belohnungen für gute Aktionen und Strafen für schlechte erhält. Dieses Paradigma steckt hinter dem Erfolg von AlphaGo, Robotik und autonomen Fahrzeugen.
Schlüsselkonzepte:
- Agent - die entscheidende Instanz
- Umgebung (Environment) - die Welt, in der der Agent agiert
- Strategie (Policy) - die Entscheidungsstrategie des Agenten
- Belohnung (Reward) - Rückmeldungssignal aus der Umgebung
TensorFlow- und Keras-Architektur#
TensorFlow ist ein umfassendes Ökosystem für maschinelles Lernen. Keras, die High-Level-API von TensorFlow, vereinfacht den Modellaufbau erheblich.
Tensoren - Die grundlegende Datenstruktur#
Ein Tensor ist ein mehrdimensionales numerisches Array. Der Name TensorFlow leitet sich vom Fluss der Tensoren durch einen Berechnungsgraphen ab.
import tensorflow as tf
# Skalar (0-dimensionaler Tensor)
scalar = tf.constant(42)
print(scalar.shape) # ()
# Vektor (1-dimensionaler Tensor)
vector = tf.constant([1.0, 2.0, 3.0])
print(vector.shape) # (3,)
# Matrix (2-dimensionaler Tensor)
matrix = tf.constant([[1, 2], [3, 4], [5, 6]])
print(matrix.shape) # (3, 2)
# 3-dimensionaler Tensor (z.B. Batch von RGB-Bildern)
images = tf.random.normal([32, 224, 224, 3])
print(images.shape) # (32, 224, 224, 3)
# Tensor-Operationen
a = tf.constant([[1, 2], [3, 4]])
b = tf.constant([[5, 6], [7, 8]])
print(tf.add(a, b)) # Elementweise Addition
print(tf.matmul(a, b)) # Matrixmultiplikation
print(tf.reduce_mean(a)) # Mittelwert
Schichten (Layers)#
Schichten sind die grundlegenden Bausteine von Modellen. Jede Schicht führt eine Transformation der Eingabedaten durch.
# Die wichtigsten Schichten in Keras
# Dense - vollständig verbundene Schicht
dense = keras.layers.Dense(128, activation='relu')
# Conv2D - 2D-Faltungsschicht
conv = keras.layers.Conv2D(64, kernel_size=(3, 3), activation='relu', padding='same')
# LSTM - Long Short-Term Memory
lstm = keras.layers.LSTM(256, return_sequences=True)
# Dropout - Regularisierung (verhindert Overfitting)
dropout = keras.layers.Dropout(0.3)
# BatchNormalization - Batch-Normalisierung
bn = keras.layers.BatchNormalization()
# Embedding - bildet Indizes auf dichte Vektoren ab
embedding = keras.layers.Embedding(input_dim=10000, output_dim=128)
Modelle - Sequential vs. Functional API#
Keras bietet zwei Hauptansätze zum Erstellen von Modellen.
# 1. Sequential API - einfacher Schichtenstapel
model_sequential = keras.Sequential([
keras.layers.Dense(256, activation='relu', input_shape=(784,)),
keras.layers.Dropout(0.3),
keras.layers.Dense(128, activation='relu'),
keras.layers.Dropout(0.2),
keras.layers.Dense(10, activation='softmax')
])
# 2. Functional API - flexible Graphen (mehrere Ein-/Ausgänge, Skip-Connections)
inputs = keras.layers.Input(shape=(784,))
x = keras.layers.Dense(256, activation='relu')(inputs)
x = keras.layers.Dropout(0.3)(x)
# Skip-Connection (Residual)
skip = keras.layers.Dense(128)(inputs)
x = keras.layers.Dense(128, activation='relu')(x)
x = keras.layers.Add()([x, skip])
x = keras.layers.Dropout(0.2)(x)
outputs = keras.layers.Dense(10, activation='softmax')(x)
model_functional = keras.Model(inputs=inputs, outputs=outputs)
Die Trainingsschleife (Training Loop)#
Der Trainingsprozess eines Modells besteht aus mehreren Phasen: Kompilierung, Training und Auswertung.
# Modellkompilierung
model.compile(
optimizer=keras.optimizers.Adam(learning_rate=0.001),
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
# Callbacks - Überwachung und Steuerung des Trainings
callbacks = [
keras.callbacks.EarlyStopping(
monitor='val_loss',
patience=5,
restore_best_weights=True
),
keras.callbacks.ReduceLROnPlateau(
monitor='val_loss',
factor=0.5,
patience=3
),
keras.callbacks.ModelCheckpoint(
filepath='best_model.keras',
monitor='val_accuracy',
save_best_only=True
),
keras.callbacks.TensorBoard(log_dir='./logs')
]
# Training
history = model.fit(
X_train, y_train,
epochs=100,
batch_size=32,
validation_split=0.2,
callbacks=callbacks
)
# Auswertung auf Testdaten
test_loss, test_acc = model.evaluate(X_test, y_test)
print(f"Test-Genauigkeit: {test_acc:.4f}")
Gängige Architekturen neuronaler Netze#
CNN - Convolutional Neural Networks#
Faltungsnetze dominieren die Bildverarbeitung. Faltungsfilter lernen automatisch, visuelle Merkmale auf verschiedenen Abstraktionsebenen zu erkennen.
def build_cnn_classifier(input_shape=(224, 224, 3), num_classes=10):
"""Aufbau eines CNN-Bildklassifikators."""
model = keras.Sequential([
# Faltungsblock 1
keras.layers.Conv2D(32, (3, 3), activation='relu',
padding='same', input_shape=input_shape),
keras.layers.Conv2D(32, (3, 3), activation='relu', padding='same'),
keras.layers.MaxPooling2D((2, 2)),
keras.layers.BatchNormalization(),
# Faltungsblock 2
keras.layers.Conv2D(64, (3, 3), activation='relu', padding='same'),
keras.layers.Conv2D(64, (3, 3), activation='relu', padding='same'),
keras.layers.MaxPooling2D((2, 2)),
keras.layers.BatchNormalization(),
# Faltungsblock 3
keras.layers.Conv2D(128, (3, 3), activation='relu', padding='same'),
keras.layers.Conv2D(128, (3, 3), activation='relu', padding='same'),
keras.layers.MaxPooling2D((2, 2)),
keras.layers.BatchNormalization(),
keras.layers.Dropout(0.3),
# Klassifikator-Kopf
keras.layers.GlobalAveragePooling2D(),
keras.layers.Dense(256, activation='relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(num_classes, activation='softmax')
])
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
return model
# Verwendung
cnn_model = build_cnn_classifier(num_classes=10)
cnn_model.summary()
Wichtige CNN-Schichten:
- Conv2D - erkennt lokale Merkmale (Kanten, Texturen, Formen)
- MaxPooling2D - reduziert räumliche Dimensionen, vergrößert das rezeptive Feld
- GlobalAveragePooling2D - aggregiert Feature-Maps zu einem Vektor
- BatchNormalization - stabilisiert das Training, schnellere Konvergenz
RNN - Recurrent Neural Networks#
Rekurrente Netze verarbeiten sequenzielle Daten wie Text, Zeitreihen und Audio. LSTM- und GRU-Architekturen lösen das Problem des verschwindenden Gradienten.
def build_text_classifier(vocab_size=20000, max_length=200, num_classes=5):
"""Textklassifikator mit bidirektionalem LSTM."""
model = keras.Sequential([
keras.layers.Embedding(vocab_size, 128, input_length=max_length),
keras.layers.Bidirectional(
keras.layers.LSTM(64, return_sequences=True)
),
keras.layers.Bidirectional(keras.layers.LSTM(32)),
keras.layers.Dense(64, activation='relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(num_classes, activation='softmax')
])
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
return model
# Textgenerierung mit RNN
def build_text_generator(vocab_size, seq_length):
"""Zeichenbasiertes Textgenerierungsmodell."""
model = keras.Sequential([
keras.layers.Embedding(vocab_size, 256, input_length=seq_length),
keras.layers.LSTM(512, return_sequences=True),
keras.layers.LSTM(512),
keras.layers.Dense(256, activation='relu'),
keras.layers.Dense(vocab_size, activation='softmax')
])
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy')
return model
Transformer - Eine Revolution in NLP und darüber hinaus#
Die Transformer-Architektur, basierend auf dem Self-Attention-Mechanismus, hat NLP revolutioniert und wird zunehmend auch in der Computer Vision eingesetzt.
class TransformerBlock(keras.layers.Layer):
"""Transformer-Block mit Multi-Head Attention."""
def __init__(self, embed_dim, num_heads, ff_dim, dropout_rate=0.1):
super().__init__()
self.attention = keras.layers.MultiHeadAttention(
num_heads=num_heads,
key_dim=embed_dim // num_heads
)
self.ffn = keras.Sequential([
keras.layers.Dense(ff_dim, activation='gelu'),
keras.layers.Dense(embed_dim)
])
self.layernorm1 = keras.layers.LayerNormalization(epsilon=1e-6)
self.layernorm2 = keras.layers.LayerNormalization(epsilon=1e-6)
self.dropout1 = keras.layers.Dropout(dropout_rate)
self.dropout2 = keras.layers.Dropout(dropout_rate)
def call(self, inputs, training=False):
# Multi-Head Self-Attention + Residual
attn_output = self.attention(inputs, inputs)
attn_output = self.dropout1(attn_output, training=training)
out1 = self.layernorm1(inputs + attn_output)
# Feed-Forward-Netzwerk + Residual
ffn_output = self.ffn(out1)
ffn_output = self.dropout2(ffn_output, training=training)
return self.layernorm2(out1 + ffn_output)
def build_transformer_classifier(
vocab_size=20000, max_length=200, embed_dim=128,
num_heads=4, ff_dim=256, num_blocks=2, num_classes=5
):
"""Transformer-basierter Textklassifikator."""
inputs = keras.layers.Input(shape=(max_length,))
x = keras.layers.Embedding(vocab_size, embed_dim)(inputs)
# Positional Encoding (einfach - gelernt)
positions = keras.layers.Embedding(max_length, embed_dim)(
tf.range(max_length)
)
x = x + positions
for _ in range(num_blocks):
x = TransformerBlock(embed_dim, num_heads, ff_dim)(x)
x = keras.layers.GlobalAveragePooling1D()(x)
x = keras.layers.Dense(64, activation='relu')(x)
x = keras.layers.Dropout(0.3)(x)
outputs = keras.layers.Dense(num_classes, activation='softmax')(x)
model = keras.Model(inputs=inputs, outputs=outputs)
model.compile(
optimizer=keras.optimizers.Adam(learning_rate=1e-4),
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
return model
Transfer Learning - Die Kraft vortrainierter Modelle#
Transfer Learning ermöglicht es, Wissen aus Modellen zu nutzen, die auf riesigen Datensätzen trainiert wurden. Statt von Grund auf zu trainieren, passen wir ein vortrainiertes Modell an unsere spezifische Aufgabe an.
def build_transfer_learning_model(num_classes, fine_tune_at=100):
"""
Bildklassifikator mit Transfer Learning (EfficientNetV2).
Nur die oberen Schichten werden trainiert, die Basis bleibt eingefroren.
"""
# Vortrainiertes Modell als Feature-Extraktor
base_model = keras.applications.EfficientNetV2B0(
weights='imagenet',
include_top=False,
input_shape=(224, 224, 3)
)
# Basisschichten einfrieren
base_model.trainable = False
# Modellaufbau
model = keras.Sequential([
base_model,
keras.layers.GlobalAveragePooling2D(),
keras.layers.Dense(256, activation='relu'),
keras.layers.Dropout(0.3),
keras.layers.Dense(num_classes, activation='softmax')
])
model.compile(
optimizer=keras.optimizers.Adam(learning_rate=1e-3),
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
return model, base_model
def fine_tune_model(model, base_model, fine_tune_at=100):
"""
Phase 2: Fine-Tuning - obere Schichten des Basismodells auftauen.
Niedrigere Lernrate verwenden, um vortrainierte Gewichte nicht zu zerstören.
"""
base_model.trainable = True
for layer in base_model.layers[:fine_tune_at]:
layer.trainable = False
model.compile(
optimizer=keras.optimizers.Adam(learning_rate=1e-5),
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
return model
# Verwendung
model, base_model = build_transfer_learning_model(num_classes=5)
# Phase 1: Klassifikator trainieren (eingefrorene Basis)
model.fit(train_ds, epochs=10, validation_data=val_ds)
# Phase 2: Fine-Tuning (aufgetaute obere Schichten)
model = fine_tune_model(model, base_model, fine_tune_at=100)
model.fit(train_ds, epochs=10, validation_data=val_ds)
Beliebte vortrainierte Modelle in TensorFlow:
- EfficientNetV2 - bestes Verhältnis von Genauigkeit und Effizienz für Bilder
- ResNet50/101 - klassische Architektur mit Residual Connections
- MobileNetV3 - optimiert für mobile Geräte
- BERT/DistilBERT - vortrainierte Sprachmodelle (über TF Hub oder Hugging Face)
Praxisbeispiel: Bildklassifikation#
Erstellen wir eine vollständige Pipeline zur Bildklassifikation mit Datenaugmentierung und Transfer Learning.
import tensorflow as tf
from tensorflow import keras
import matplotlib.pyplot as plt
# 1. Daten laden und vorbereiten
BATCH_SIZE = 32
IMG_SIZE = (224, 224)
train_ds = keras.utils.image_dataset_from_directory(
'dataset/train',
image_size=IMG_SIZE,
batch_size=BATCH_SIZE,
label_mode='int',
shuffle=True,
seed=42
)
val_ds = keras.utils.image_dataset_from_directory(
'dataset/validation',
image_size=IMG_SIZE,
batch_size=BATCH_SIZE,
label_mode='int'
)
class_names = train_ds.class_names
num_classes = len(class_names)
# 2. Datenaugmentierung
data_augmentation = keras.Sequential([
keras.layers.RandomFlip('horizontal'),
keras.layers.RandomRotation(0.2),
keras.layers.RandomZoom(0.2),
keras.layers.RandomContrast(0.2),
keras.layers.RandomTranslation(0.1, 0.1)
])
# 3. Datenpipeline-Optimierung
AUTOTUNE = tf.data.AUTOTUNE
train_ds = train_ds.cache().shuffle(1000).prefetch(buffer_size=AUTOTUNE)
val_ds = val_ds.cache().prefetch(buffer_size=AUTOTUNE)
# 4. Modellaufbau mit Transfer Learning
base_model = keras.applications.EfficientNetV2B0(
weights='imagenet', include_top=False, input_shape=(*IMG_SIZE, 3)
)
base_model.trainable = False
inputs = keras.layers.Input(shape=(*IMG_SIZE, 3))
x = data_augmentation(inputs)
x = keras.applications.efficientnet_v2.preprocess_input(x)
x = base_model(x, training=False)
x = keras.layers.GlobalAveragePooling2D()(x)
x = keras.layers.Dense(256, activation='relu')(x)
x = keras.layers.Dropout(0.3)(x)
outputs = keras.layers.Dense(num_classes, activation='softmax')(x)
model = keras.Model(inputs, outputs)
# 5. Training
model.compile(
optimizer=keras.optimizers.Adam(1e-3),
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
history = model.fit(
train_ds, epochs=20, validation_data=val_ds,
callbacks=[
keras.callbacks.EarlyStopping(patience=5, restore_best_weights=True),
keras.callbacks.ReduceLROnPlateau(patience=3, factor=0.5)
]
)
# 6. Ergebnisse visualisieren
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))
ax1.plot(history.history['accuracy'], label='Training')
ax1.plot(history.history['val_accuracy'], label='Validierung')
ax1.set_title('Genauigkeit')
ax1.legend()
ax2.plot(history.history['loss'], label='Training')
ax2.plot(history.history['val_loss'], label='Validierung')
ax2.set_title('Verlust')
ax2.legend()
plt.savefig('training_history.png', dpi=150)
plt.show()
Praxisbeispiel: Sentimentanalyse (NLP)#
import tensorflow as tf
from tensorflow import keras
import tensorflow_datasets as tfds
# 1. IMDB-Reviews-Datensatz laden
(train_data, test_data), info = tfds.load(
'imdb_reviews',
split=['train', 'test'],
as_supervised=True,
with_info=True
)
# 2. Tokenisierung und Datenvorbereitung
VOCAB_SIZE = 20000
MAX_LENGTH = 300
# TextVectorization - integrierte Tokenisierungsschicht
text_vectorizer = keras.layers.TextVectorization(
max_tokens=VOCAB_SIZE,
output_mode='int',
output_sequence_length=MAX_LENGTH
)
# An Trainingsdaten anpassen
train_texts = train_data.map(lambda text, label: text)
text_vectorizer.adapt(train_texts)
# 3. Datensätze vorbereiten
def preprocess(text, label):
text = text_vectorizer(tf.expand_dims(text, -1))
text = tf.squeeze(text, axis=0)
return text, label
BATCH_SIZE = 64
AUTOTUNE = tf.data.AUTOTUNE
train_ds = (train_data
.map(preprocess, num_parallel_calls=AUTOTUNE)
.shuffle(10000)
.batch(BATCH_SIZE)
.prefetch(AUTOTUNE))
test_ds = (test_data
.map(preprocess, num_parallel_calls=AUTOTUNE)
.batch(BATCH_SIZE)
.prefetch(AUTOTUNE))
# 4. Modell: 1D CNN + Bidirektionales LSTM
model = keras.Sequential([
keras.layers.Embedding(VOCAB_SIZE, 128, input_length=MAX_LENGTH),
keras.layers.Conv1D(128, 5, activation='relu', padding='same'),
keras.layers.MaxPooling1D(2),
keras.layers.Bidirectional(keras.layers.LSTM(64)),
keras.layers.Dense(64, activation='relu'),
keras.layers.Dropout(0.5),
keras.layers.Dense(1, activation='sigmoid')
])
model.compile(
optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy']
)
# 5. Training
history = model.fit(
train_ds, epochs=10, validation_data=test_ds,
callbacks=[keras.callbacks.EarlyStopping(patience=3)]
)
# 6. Vorhersage
def predict_sentiment(texts):
"""Sentiment-Vorhersage für eine Liste von Texten."""
vectorized = text_vectorizer(tf.constant(texts))
predictions = model.predict(vectorized)
for text, pred in zip(texts, predictions):
sentiment = "Positiv" if pred[0] > 0.5 else "Negativ"
print(f"{sentiment} ({pred[0]:.2%}): {text[:80]}...")
predict_sentiment([
"This movie was absolutely fantastic! Great acting and storyline.",
"Terrible film. Waste of time. The plot made no sense at all."
])
TensorFlow.js - Machine Learning im Browser#
TensorFlow.js ermöglicht es, ML-Modelle direkt im Browser oder in Node.js auszuführen und erlaubt Client-seitige Inferenz ohne Serverkommunikation.
// Installation: npm install @tensorflow/tfjs
import * as tf from '@tensorflow/tfjs';
// Laden eines vortrainierten Bildklassifikationsmodells
async function classifyImage(imageElement) {
// MobileNet-Modell laden
const model = await tf.loadGraphModel(
'https://tfhub.dev/google/tfjs-model/imagenet/mobilenet_v3_small_100_224/classification/5/default/1',
{ fromTFHub: true }
);
// Bild in einen Tensor umwandeln
const tensor = tf.browser.fromPixels(imageElement)
.resizeBilinear([224, 224])
.expandDims(0)
.div(255.0);
// Inferenz
const predictions = model.predict(tensor);
const topK = tf.topk(predictions, 5);
const indices = await topK.indices.data();
const values = await topK.values.data();
// Speicher freigeben
tensor.dispose();
predictions.dispose();
return indices.map((idx, i) => ({
classIndex: idx,
confidence: values[i]
}));
}
// Konvertierung eines Keras-Modells zu TensorFlow.js
// In Python:
// import tensorflowjs as tfjs
// tfjs.converters.save_keras_model(model, 'tfjs_model/')
Vorteile von TensorFlow.js:
- Datenschutz - Daten verlassen nie das Gerät des Nutzers
- Geringe Latenz - kein Round-Trip zum Server
- Offline - das Modell funktioniert ohne Internet
- Skalierung - Inferenz auf Nutzergeräten statt auf teuren GPU-Servern
Deployment von Modellen in der Produktion#
TensorFlow Serving#
TensorFlow Serving ist ein leistungsstarkes System zum Bereitstellen von Modellen in der Produktion.
# Modell im SavedModel-Format speichern
model.save('saved_model/image_classifier/1')
# Verzeichnisstruktur:
# saved_model/
# image_classifier/
# 1/ <- Modellversion
# saved_model.pb
# variables/
# docker-compose.yml - TensorFlow Serving
version: "3.8"
services:
tf-serving:
image: tensorflow/serving:latest
ports:
- "8501:8501" # REST-API
- "8500:8500" # gRPC
volumes:
- ./saved_model:/models
environment:
MODEL_NAME: image_classifier
deploy:
resources:
reservations:
devices:
- driver: nvidia
count: 1
capabilities: [gpu]
# REST-API aufrufen
import requests
import numpy as np
import json
def predict_via_serving(image_array):
"""Vorhersageanfrage an TensorFlow Serving senden."""
url = "http://localhost:8501/v1/models/image_classifier:predict"
payload = {
"instances": image_array.tolist()
}
response = requests.post(url, json=payload)
predictions = response.json()['predictions']
return np.array(predictions)
# Batch-Vorhersage
images = np.random.rand(8, 224, 224, 3).astype(np.float32)
results = predict_via_serving(images)
print(f"Vorhersagen-Shape: {results.shape}")
Export nach ONNX#
ONNX (Open Neural Network Exchange) ist ein offenes Format, das die Ausführung von Modellen in verschiedenen Laufzeitumgebungen ermöglicht.
# TensorFlow -> ONNX-Konvertierung
# pip install tf2onnx
import tf2onnx
import onnxruntime as ort
# Konvertierung
spec = (tf.TensorSpec((None, 224, 224, 3), tf.float32, name="input"),)
model_proto, _ = tf2onnx.convert.from_keras(
model, input_signature=spec, output_path="model.onnx"
)
# Inferenz mit ONNX Runtime (schneller als TF auf der CPU)
session = ort.InferenceSession("model.onnx")
input_name = session.get_inputs()[0].name
output_name = session.get_outputs()[0].name
result = session.run(
[output_name],
{input_name: np.random.rand(1, 224, 224, 3).astype(np.float32)}
)
print(f"ONNX-Vorhersage: {result[0]}")
TensorFlow Lite - Modelle auf mobilen Geräten#
# Konvertierung zu TFLite mit Quantisierung
converter = tf.lite.TFLiteConverter.from_saved_model('saved_model/image_classifier/1')
# Post-Training-Quantisierung (reduziert die Modellgröße um das 4-fache)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
# Optional: Vollständige Int8-Quantisierung (erfordert Kalibrierung)
def representative_dataset():
for i in range(100):
yield [np.random.rand(1, 224, 224, 3).astype(np.float32)]
converter.representative_dataset = representative_dataset
converter.target_spec.supported_types = [tf.float16]
tflite_model = converter.convert()
with open('model.tflite', 'wb') as f:
f.write(tflite_model)
print(f"TFLite-Modellgröße: {len(tflite_model) / 1024 / 1024:.2f} MB")
TensorFlow vs. PyTorch - Vergleich#
Die Wahl des Frameworks hängt vom Projektkontext ab. Hier sind die wichtigsten Unterschiede:
| Aspekt | TensorFlow | PyTorch | |--------|-----------|---------| | Ausführungsmodus | Eager + Graph (tf.function) | Eager standardmäßig, TorchScript für Graph | | High-Level-API | Keras (integriert) | torch.nn (integriert), Lightning | | Deployment | TF Serving, TFLite, TF.js | TorchServe, ONNX, ExecuTorch | | Mobil/Edge | TFLite (ausgereift) | ExecuTorch (neuer) | | Browser | TensorFlow.js (ausgereift) | ONNX.js / Transformers.js | | Ökosystem | TFX, TF Hub, TF Data | Hugging Face, PyTorch Ecosystem | | Beliebtheit in der Forschung | Rückläufig | Dominant | | Beliebtheit in der Produktion | Weiterhin stark | Wachsend | | Debugging | Schwieriger (Graph-Modus) | Einfacher (pythonisch) | | Dokumentation | Umfangreich, aber verstreut | Konsistent, gut organisiert |
Wann TensorFlow wählen:
- Multi-Plattform-Deployment (Web, Mobil, Embedded)
- Vorhandene TFX-Infrastruktur in der Organisation
- Bedarf an TensorFlow.js für Browser-Inferenz
- Produktionsprojekte, die TF Serving erfordern
Wann PyTorch wählen:
- Wissenschaftliche Forschung und Prototyping
- Arbeit mit Hugging-Face-Modellen
- Bevorzugung einer pythonischen API und einfachem Debugging
- Projekte, die neueste Architekturen aus Forschungsarbeiten erfordern
Best Practices in ML-Projekten#
1. Experiment-Management#
import mlflow
# Experimente mit MLflow protokollieren
mlflow.set_experiment("image-classification")
with mlflow.start_run(run_name="efficientnet-v2-finetune"):
# Hyperparameter protokollieren
mlflow.log_params({
"learning_rate": 1e-3,
"batch_size": 32,
"epochs": 20,
"model": "EfficientNetV2B0",
"fine_tune_layers": 50
})
# Training
history = model.fit(train_ds, epochs=20, validation_data=val_ds)
# Metriken protokollieren
mlflow.log_metrics({
"final_accuracy": history.history['accuracy'][-1],
"final_val_accuracy": history.history['val_accuracy'][-1],
"final_loss": history.history['loss'][-1]
})
# Modell protokollieren
mlflow.keras.log_model(model, "model")
2. Datenversionierung#
# DVC (Data Version Control) - Änderungen an Daten nachverfolgen
# dvc init
# dvc add dataset/
# git add dataset.dvc .gitignore
# git commit -m "Add training dataset v1"
# dvc push
3. Reproduzierbarkeit#
import random
import numpy as np
def set_seeds(seed=42):
"""Seeds für Reproduzierbarkeit setzen."""
random.seed(seed)
np.random.seed(seed)
tf.random.set_seed(seed)
# Deterministische Operationen (langsamer, aber reproduzierbar)
tf.config.experimental.enable_op_determinism()
set_seeds(42)
Zusammenfassung#
TensorFlow in Kombination mit Keras bietet ein vollständiges Ökosystem zum Erstellen, Trainieren und Bereitstellen von Machine-Learning-Modellen. Von einfachen Dense-Netzwerken über fortgeschrittene CNN-, RNN- und Transformer-Architekturen bis hin zum Deployment auf Servern, mobilen Geräten und im Browser - TensorFlow liefert Werkzeuge für jede Phase des ML-Modell-Lebenszyklus.
Wichtige Erkenntnisse:
- Beginnen Sie mit Transfer Learning - vortrainierte Modelle liefern hervorragende Ergebnisse mit minimalen Daten
- Optimieren Sie Datenpipelines -
tf.datamit Prefetch und Cache beschleunigt das Training erheblich - Verfolgen Sie Experimente - MLflow oder TensorBoard sind bei ernsthaften Projekten unerlässlich
- Testen Sie das Deployment frühzeitig - TF Serving, TFLite und TF.js haben jeweils unterschiedliche Einschränkungen
Müssen Sie Machine Learning in Ihre Anwendung integrieren? Das Team von MDS Software Solutions Group ist auf die Entwicklung intelligenter Lösungen mit KI und ML spezialisiert. Von der Bildklassifikation über Textanalyse bis hin zu Empfehlungssystemen - wir helfen Ihnen, vom Prototyp zur Produktion zu gelangen. Kontaktieren Sie uns und lassen Sie uns über Ihr Projekt sprechen!
Team von Programmierexperten, die sich auf moderne Webtechnologien spezialisiert haben.