🟧 TensorFlow
Полный справочник: тензоры и Variable, tf.data, модели Keras, обучение и GradientTape, tf.function, сохранение, TensorBoard, GPU и распределение, развёртывание (Serving, Lite, JS) и типичные проблемы.
Шпаргалки · ИИ · #tensorflow #tf #deep-learning #python #keras
Что это
TensorFlow (Google) платформа машинного обучения: тензорные вычисления, автоматическое дифференцирование, Keras как основной высокоуровневый API, tf.data для конвейеров данных и полный набор для развёртывания (Serving, Lite, JS, TFX). Eager-режим по умолчанию (как обычный Python), @tf.function компилирует код в граф для скорости.
pip install tensorflow # CPU; GPU на Linux: pip install "tensorflow[and-cuda]"
python -c "import tensorflow as tf; print(tf.__version__, tf.config.list_physical_devices('GPU'))"
import tensorflow as tf
from tensorflow import keras
Нативная поддержка GPU на Windows закончилась на TF 2.10: используйте WSL2 или DirectML.
Тензоры и переменные
a = tf.constant([[1., 2.], [3., 4.]]) # неизменяемый тензор
v = tf.Variable([1., 2.]) # изменяемое состояние (веса)
v.assign([3., 4.]); v.assign_add([1., 1.])
tf.zeros((2, 3)); tf.ones((2, 3)); tf.fill((2, 2), 7); tf.eye(3); tf.range(10); tf.linspace(0., 1., 5)
tf.random.set_seed(42); tf.random.normal((2, 3)); tf.random.uniform((2, 3)); tf.random.shuffle(a)
a.shape; a.dtype; a.numpy(); tf.shape(a); tf.rank(a); tf.size(a)
tf.cast(a, tf.float32); tf.reshape(a, [-1]); tf.transpose(a); tf.expand_dims(a, 0); tf.squeeze(a)
tf.concat([a, a], axis=0); tf.stack([a, a]); tf.split(a, 2); tf.gather(a, [0]); tf.where(a > 2, a, 0.)
a + a; a * a; a @ a; tf.matmul(a, a); tf.reduce_sum(a); tf.reduce_mean(a, axis=0); tf.argmax(a, axis=1); tf.nn.softmax(a); tf.math.top_k(a, 2)
Тензоры TF неизменяемы (не a[0] = 1): используйте tf.tensor_scatter_nd_update или Variable.
Данные: tf.data
ds = tf.data.Dataset.from_tensor_slices((X, y))
ds = (ds.shuffle(10_000, seed=42, reshuffle_each_iteration=True)
.map(preprocess, num_parallel_calls=tf.data.AUTOTUNE)
.batch(64, drop_remainder=False)
.cache() # кэш после дорогих преобразований
.prefetch(tf.data.AUTOTUNE)) # подготовка следующего батча параллельно с обучением
train_ds = keras.utils.image_dataset_from_directory("data/train", image_size=(224, 224), batch_size=32, validation_split=0.2, subset="training", seed=1)
text_ds = keras.utils.text_dataset_from_directory("texts/")
tf.data.TextLineDataset("a.txt"); tf.data.TFRecordDataset("a.tfrecord"); tf.data.experimental.make_csv_dataset("a.csv", 32, label_name="y")
Порядок: shuffle → map → batch → prefetch. Конвейер данных часто узкое место: проверьте загрузку GPU.
Модель: Sequential
model = keras.Sequential([
keras.layers.Input(shape=(10,)),
keras.layers.Dense(64, activation="relu"),
keras.layers.Dropout(0.2),
keras.layers.Dense(3, activation="softmax"),
])
model.summary()
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=3, restore_best_weights=True),
keras.callbacks.ModelCheckpoint("best.keras", save_best_only=True),
keras.callbacks.TensorBoard("logs")])
model.evaluate(test_ds); model.predict(X_new)
Подробно о слоях, Functional API и transfer learning см. шпаргалку «Keras».
Functional API и подклассы
inp = keras.Input(shape=(64,)); x = keras.layers.Dense(128, activation="relu")(inp); out = keras.layers.Dense(1, activation="sigmoid")(x)
model = keras.Model(inp, out)
class MyModel(keras.Model):
def __init__(self):
super().__init__(); self.d1 = keras.layers.Dense(64, activation="relu"); self.d2 = keras.layers.Dense(10)
def call(self, x, training=False): return self.d2(self.d1(x))
Кастомный шаг обучения (GradientTape)
loss_fn = keras.losses.SparseCategoricalCrossentropy(from_logits=True)
opt = keras.optimizers.Adam(1e-3)
@tf.function # компиляция в граф: быстрее и переносимо
def train_step(x, y):
with tf.GradientTape() as tape:
logits = model(x, training=True)
loss = loss_fn(y, logits)
grads = tape.gradient(loss, model.trainable_variables)
opt.apply_gradients(zip(grads, model.trainable_variables))
return loss
for epoch in range(epochs):
for xb, yb in train_ds: loss = train_step(xb, yb)
Метод train_step можно переопределить в подклассе keras.Model, оставив fit(). Правила @tf.function: используйте тензоры и tf.* операции, избегайте побочных эффектов Python внутри (печать выполнится при трассировке), не создавайте Variable при каждом вызове; tf.print вместо print; следите за ретрассировкой (разные формы и типы аргументов).
Потери, метрики, оптимизаторы
| Задача | Потеря |
|---|---|
| Бинарная | binary_crossentropy |
| Многоклассовая (целые метки) | sparse_categorical_crossentropy |
| Многоклассовая (one-hot) | categorical_crossentropy |
| Регрессия | mse, mae, huber |
Метрики: accuracy, AUC, Precision, Recall, MeanAbsoluteError. Оптимизаторы: Adam, AdamW, SGD(momentum), RMSprop. Скорость обучения: keras.optimizers.schedules.CosineDecay, ExponentialDecay; колбэки ReduceLROnPlateau, LearningRateScheduler. Смешанная точность: keras.mixed_precision.set_global_policy("mixed_float16").
Сохранение и загрузка
model.save("model.keras") # современный формат Keras (архитектура + веса + оптимизатор)
model = keras.models.load_model("model.keras")
model.save_weights("w.weights.h5"); model.load_weights("w.weights.h5")
model.export("saved_model_dir") # SavedModel для сервинга и конвертации
loaded = tf.saved_model.load("saved_model_dir"); loaded.signatures["serving_default"]
Кастомные слои и функции требуют регистрации (@keras.saving.register_keras_serializable()) или custom_objects. Формат .h5 устарел.
Развёртывание
| Куда | Инструмент |
|---|---|
| Сервер, REST и gRPC | TensorFlow Serving (docker run -p 8501:8501 -v $PWD/saved:/models/m -e MODEL_NAME=m tensorflow/serving) |
| Мобильные, встраиваемые | TensorFlow Lite: tf.lite.TFLiteConverter.from_saved_model(d), квантование (Optimize.DEFAULT), delegates (GPU, NNAPI, Core ML) |
| Браузер, Node | TensorFlow.js: tensorflowjs_converter |
| Обмен между фреймворками | ONNX (tf2onnx) |
| Пайплайны MLOps | TFX, Vertex AI, Kubeflow |
| Предобработка в графе | keras.layers.Rescaling, TextVectorization, Normalization внутри модели |
Кладите предобработку внутрь модели, чтобы клиент и обучение не расходились.
Распределённое обучение и GPU
strategy = tf.distribute.MirroredStrategy() # несколько GPU на одной машине
with strategy.scope():
model = build_model(); model.compile(...)
# MultiWorkerMirroredStrategy (несколько машин), TPUStrategy
gpus = tf.config.list_physical_devices("GPU")
for g in gpus: tf.config.experimental.set_memory_growth(g, True) # не занимать всю память сразу
Профилирование: tf.profiler, TensorBoard Profiler.
TensorBoard
tensorboard --logdir logs # http://localhost:6006: кривые, граф, гистограммы весов, профиль, эмбеддинги
writer = tf.summary.create_file_writer("logs/run1")
with writer.as_default(): tf.summary.scalar("loss", loss, step=step)
Типичные проблемы
| Симптом | Причина и действия |
|---|---|
OOM when allocating tensor |
уменьшите батч, mixed_float16, set_memory_growth, меньше модель |
Потеря nan |
слишком большой lr, нет нормализации входов, log(0), clipnorm в оптимизаторе |
| Потеря не падает | неверная активация выхода и функция потери (from_logits), метки не того формата, малый lr |
Форма (None, ...) и ошибки размерности |
проверьте model.summary() и формы данных ds.element_spec |
Постоянная ретрассировка @tf.function |
передаются Python-числа и меняющиеся формы: используйте тензоры и input_signature |
| Медленное обучение при простое GPU | узкое место tf.data: num_parallel_calls, prefetch, cache, TFRecord |
| Предупреждения про версии CUDA и cuDNN | подберите версии под выпуск TF (таблица на tensorflow.org) |
| Результат отличается между запусками | keras.utils.set_random_seed(42), tf.config.experimental.enable_op_determinism() |
TensorFlow или PyTorch
TensorFlow силён в промышленном развёртывании (Serving, Lite, JS, TFX) и мобильных устройствах. PyTorch преобладает в исследованиях и открытых моделях. Keras 3 работает поверх TensorFlow, PyTorch и JAX: один код, выбор бэкенда через KERAS_BACKEND.