TensorFlow
TensorFlow — фреймворк глубокого обучения от Google: построение и обучение нейронных сетей от простого перцептрона до трансформеров.
1. Что такое TensorFlow
TensorFlow работает с тензорами — многомерными массивами чисел (эволюция ndarray из NumPy). Поверх низкоуровневых операций построен высокоуровневый API Keras — именно с ним работают 99% задач.
Экосистема: TF Serving (сервер моделей), TF Lite (мобильные), TF.js (браузер), TensorBoard (визуализация).
2. Установка
pip install tensorflowimport tensorflow as tf
print(tf.__version__)Версия для GPU требует CUDA с совместимым драйвером; для обучения видео на CPU слабее — проверяй tf.config.list_physical_devices('GPU').
3. Тензоры
a = tf.constant([[1., 2.], [3., 4.]])
print(a.shape) # (2, 2)
b = tf.random.normal((3, 2))
c = a @ tf.linalg.transpose(a) # умножение матрицОперации окружены автодифференцированием: TF сам считает производные по всем параметрам при обратном распространении ошибки.
4. Первая модель: Keras Sequential
from tensorflow import keras
from tensorflow.keras import layers
model = keras.Sequential([
layers.Input(shape=(784,)),
layers.Dense(128, activation='relu'),
layers.Dense(10, activation='softmax')
])
model.summary()5. Компиляция и обучение
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
metrics=['accuracy']
)
history = model.fit(
X_train, y_train,
epochs=10,
validation_data=(X_val, y_val)
)epochs — проходы по данным; batch_size — размер порции (по умолчанию 32).
6. Обработка изображений (CNN)
model = keras.Sequential([
layers.Input(shape=(28, 28, 1)),
layers.Conv2D(32, 3, activation='relu'),
layers.MaxPooling2D(2),
layers.Conv2D(64, 3, activation='relu'),
layers.Flatten(),
layers.Dense(128, activation='relu'),
layers.Dense(10, activation='softmax')
])Свертка (Conv2D) ищет локальные паттерны, пулинг уменьшает размерность.
7. Оценка и TensorBoard
loss, acc = model.evaluate(X_test, y_test)
print(loss, acc)
tensorboard_cb = keras.callbacks.TensorBoard(log_dir='logs')
model.fit(X_train, y_train, epochs=10, callbacks=[tensorboard_cb])Затем tensorboard --logdir logs — графики потерь и метрик в браузере.
8. Ранняя остановка и регуляризация
early = keras.callbacks.EarlyStopping(
monitor='val_loss', patience=3, restore_best_weights=True)
model.fit(X_train, y_train,
epochs=100,
validation_split=0.2,
callbacks=[early])Без Dropout скрытые слои «запоминают» данные — слой Dropout отключает случайные нейроны и борется с переобучением.
9. Сохранение и загрузка
model.save('model.keras') # полный формат
model = keras.models.load_model('model.keras')
# для модели кода/продакшена
model.export('saved_model_path') # SavedModel для продакшена10. Трудности обучения
- Градиенты взрываются — нормализуй данные и следи за лоссом.
- Лосс не уменьшается — уменьши lr, проверь данные (классы? дисбаланс?).
- Переобучение: val_loss растёт, а на train_loss — падает: добавь Dropout и раннюю остановку.
11. Деплой модели
- TF Serving — REST/gRPC сервер, разворачивается в Docker.
- TF Lite — конвертация
tf.lite.TFLiteConverterдля мобильных. - TensorFlow.js — запуск в браузере.
12. Перенос обучения (Transfer Learning)
Обучать сеть с нуля для новой задачи дорого. Перенос обучения использует готовую модель (например, MobileNetV2 на ImageNet) как «веса-признаки» и обучает только последние слои под ваши классы.
from tensorflow.keras.applications import MobileNetV2
base = MobileNetV2(include_top=False, weights='imagenet',
input_shape=(224, 224, 3))
base.trainable = False
model = keras.Sequential([
base,
layers.GlobalAveragePooling2D(),
layers.Dense(3, activation='softmax')
])
model.compile(optimizer='adam', loss='categorical_crossentropy')
model.fit(generator, epochs=5)Сначала база заморожена (trainable=False) — обучается только классификатор. Затем можно разморозить несколько верхних слоёв для тонкой настройки с очень низким lr.
Если датасет маленький (сотни картинок на класс), берите предобученную базу и не размораживайте её: финальные слои быстро приспосабливаются. С ростом данных размораживайте по одному блоку сверху вниз и следите за val_loss после каждой разморозки.
tf.keras.layers.RandomFlip и RandomRotation внутри самой модели — данные «дрожат» прямо во время обучения.13. Пайплайны данных: tf.data
Собственный датасет редко влезает в память целиком. Класс tf.data.Dataset читает данные батчами, параллельно и вперемешку, не загружая всё сразу.
ds = tf.data.Dataset.from_tensor_slices((x, y))
ds = ds.shuffle(10_000) \
.batch(32) \
.map(augment_fn, num_parallel_calls=tf.data.AUTOTUNE) \
.prefetch(tf.data.AUTOTUNE)
model.fit(ds, epochs=10)Цепочка shuffle → batch → map → prefetch — стандарт: перемешивание до батчей, а подготовка образцов идёт в фоне, пока GPU занят.
| Метод | Задача |
|---|---|
| shuffle | перемешивание порядка |
| batch | сборка батчей |
| map | аугментация каждой записи |
| prefetch | подготовка следующего батча заранее |
Для CSV и текстовых данных есть TextLineDataset и make_csv_dataset — они читают файлы построчно без ручного парсинга. Большие наборы держите в формате TFRecord и готовьте заранее в фоновом процессе, а не в памяти Python.
14. Воспроизводимость экспериментов
Исследования, которые нельзя повторить, обесцениваются. Зафиксируйте случайность, версии библиотек и параметры обучения ещё до первого запуска.
import random, numpy as np, tensorflow as tf
seed = 42
random.seed(seed)
np.random.seed(seed)
tf.random.set_seed(seed)- фиксируйте seed в начале скрипта и версию TF в
requirements.txt; - логируйте гиперпараметры в имя эксперимента:
resnet_lr1e-4_bs32_seed42; - записывайте метрики в TensorBoard и сохраняйте лучшие веса через
ModelCheckpoint.
Фиксируйте и окружение: версии Python, CUDA и cuDNN меняют результат. Метка с датой запуска и бюджетом времени позволяет сравнивать эксперименты честно, а не «на глаз».
15. Текст и последовательности
Нейросети для текста устроены иначе, чем для картинок: вход — последовательность токенов, и порядок важен. Стандартный стек в Keras — токенизация, эмбеддинги и рекуррентные слои.
vectorizer = tf.keras.layers.TextVectorization(
max_tokens=10_000, output_sequence_length=200)
vectorizer.adapt(raw_texts)
model = tf.keras.Sequential([
vectorizer,
tf.keras.layers.Embedding(10_000, 128),
tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)),
tf.keras.layers.Dense(1, activation="sigmoid")
])TextVectorizationрежет текст на токены и приводит к фиксированной длине;Embeddingпревращает индексы токенов в плотные векторы смысла;- LSTM/GRU учитывают порядок;
Bidirectionalдобавляет контекст с обеих сторон.
16. Распределённое обучение: tf.distribute
Когда одна видеокарта не справляется или данные не влезают в память, обучение раскидывают на несколько устройств. tf.distribute делает это стандартным API — без ручного обмена градиентами.
strategy = tf.distribute.MirroredStrategy()
with strategy.scope():
model = create_model()
model.compile(optimizer="adam",
loss="sparse_categorical_crossentropy",
metrics=["accuracy"])
model.fit(dataset, epochs=10)MirroredStrategy— данные реплицируются на каждую GPU, градиенты усредняются;MultiWorkerMirroredStrategy— обучение на нескольких машинах сразу;- модель создавайте внутри
strategy.scope(), иначе распределение не подхватится.
17. Квантизация и развёртывание на мобильных (TFLite)
Модель в float32 весит много и требует ресурсов. Для смартфонов и встраиваемых устройств её конвертируют в TensorFlow Lite и сжимают квантизацией — веса из 32-бит в 8-бит.
converter = tf.lite.TFLiteConverter.from_keras_model(model)
converter.optimizations = [tf.lite.Optimize.DEFAULT]
tflite_model = converter.convert()
open("model.tflite", "wb").write(tflite_model)- квантизация даёт ускорение в 2–3 раза при небольшой потере точности;
- int8-модели пригодны для Android, iOS и микроконтроллеров (TFLite Micro);
- после конвертации пересчитывайте метрики на валидации — качество могло просесть.
18. ML-модель в продакшене: мониторинг и дрейф
Задеплоенная модель — начало эксплуатации, а не финиш. Данные меняются, и качество медленно деградирует без видимой ошибки — это Concept/Data Drift.
- регистрируйте версии моделей и метаданные (MLflow, W&B): «какая модель сейчас в проде»;
- логируйте входные данные и прогнозы, чтобы сравнивать распределения;
- пересчитывайте метрики на отложенных данных или теневой доле трафика;
- настраивайте алерты: метрика упала ниже порога — это инцидент, а не «что-то странное».
# Простой индикатор дрейфа: смещение среднего прогноза
new_mean = model.predict(X_live).mean()
drift = abs(new_mean - train_mean)19. Тонкая настройка: колбэки, расписания и Keras Tuner
Модель редко работает с первого запуска: приходится играть со скоростью обучения, сохранять лучшие веса и подбирать гиперпараметры. В Keras всё это — колбэки и Tuner.
callbacks = [
ModelCheckpoint("best.weights.h5", save_best_only=True),
EarlyStopping(patience=5, restore_best_weights=True),
ReduceLROnPlateau(factor=0.5, patience=2),
]
model.fit(X, y, callbacks=callbacks)ModelCheckpointхранит лучший снимок, а не последний;ReduceLROnPlateauснижает lr при застое — сглаживает переобучение;EarlyStoppingостанавливает обучение при отсутствии прогресса.
Keras Tuner перебирает комбинации гиперпараметров (случайный поиск, Optuna/Bayesian): search() запускает трёх-четырёх «раундов» — вы получаете лучший набор значений с числами.
20. Автоэнкодеры и генеративные модели
Автоэнкодер сжимает данные до «узкого горлышка» (latent) и восстанавливает обратно — это один из кирпичей представлений. Генеративные техники (VAE, GAN) учатся создавать новые объекты по распределению входных данных.
# Простая архитектура VAE (фрагмент)
inputs = Input(shape=(28, 28, 1))
x = Conv2D(32, 3, activation="relu", padding="same")(inputs)
z_mean = Dense(2)(x_flat) # латентный код
decoder = ... # восстановление- классика: автоэнкодер для детекции аномалий (ошибка восстановления = аномалия);
- VAE добавляет вероятностный сэмплинг — стабильные сгенерированные сэмплы;
- GAN: генератор + дискриминатор соревнуются — реалистичные изображения.
Для игр и дизайна это инструмент прототипирования: генерация вариаций текстур, персонажей, звуков — быстрее и дешевле ручной сборки.
21. Functional API и Subclassing: гибкие архитектуры
Sequential подходит для линейных моделей; для ветвлений, двух входов, внимания или точного контроля жизни слоёв есть два более мощных способа — Functional API и Subclassing.
# Functional API: два входа
text_input = Input(shape=(100,))
img_input = Input(shape=(32, 32, 3))
merged = Concatenate()([Dense(64)(text_input),
Flatten()(img_input)])
out = Dense(1, activation="sigmoid")(merged)
model = Model([text_input, img_input], out)- Functional: декларативный граф — ветвления, слияния, повторное использование слоёв;
- Subclassing: наследуется от
keras.Model— переопределяетеcall(), получая максимум свободы; - для прототипа чаще хватает Functional: он читается и легко сериализуется.
Subclassing удобен для исследовательских решений, но не для продуктового кода: динамический граф труднее инспектировать и фиксировать. Общее правило — начинать с Sequential/Functional.
22. Перенос модели: ONNX и запуск вне TensorFlow
Модель создана в TensorFlow, а запускать её нужно на сервере с PyTorch, в браузере или на микроконтроллере. Промежуточный стандарт — ONNX: единый формат, читаемый разными рантаймами.
import tf2onnx
tf2onnx.convert.from_keras(model,
output_path="model.onnx")
# PyTorch-проект может грузить этот файл через onnxruntime
import onnxruntime as ort
session = ort.InferenceSession("model.onnx")
out = session.run(None, {"keras_input": x})- начальный лог: tf2onnx переводит Keras-модель за один вызов;
- после конвертации перепроверяйте выходы на одинаковых данных;
- ONNX Runtime на CPU быстрее и легче TensorFlow во многих продуктовых задачах.
Альтернативы: TFLite (мобильные, из раздела 17), TensorFlow Serving (готовая серверная обвязка), Web платформы — js-рантайм. Выбор — требование платформы.
Что дальше
Если нужны динамические модели и исследовательская гибкость — смотри PyTorch, а удобный верхний уровень — Keras.