Created by AIImproved by people
Riqli · living documents · updated continuously
Where AI knowledge meets human practice.
Share with friends

Введение
Аннотация. Данный курс посвящен фундаментальным основам и практическим аспектам работы с двумя ведущими фреймворками в области глубокого обучения — PyTorch и TensorFlow. В эпоху стремительного развития искусственного интеллекта и машинного обучения, умение эффективно проектировать, обучать и развертывать нейронные сети становится критически важным навыком для специалиста в области Data Science. Курс решает проблему фрагментарности знаний, предоставляя целостное и структурированное представление о жизненном цикле моделей глубокого обучения, начиная от подготовки данных и заканчивая их оптимизацией и эксплуатацией. Материал ориентирован на слушателей, стремящихся систематизировать свои навыки и перейти от разрозненных примеров к осознанному проектированию сложных архитектур. Особое внимание уделяется сравнительному анализу двух фреймворков, что позволит вам сделать обоснованный выбор для конкретных исследовательских и производственных задач.
Цель курса. После прохождения курса вы сможете самостоятельно разрабатывать, обучать и оптимизировать нейросетевые модели на базе PyTorch и TensorFlow 2.x для решения прикладных задач анализа данных, компьютерного зрения, обработки естественного языка и временных рядов, принимая взвешенное решение о выборе фреймворка и архитектуры на каждом этапе проекта.
Результаты обучения.
- Знать: принципы работы, архитектуру и внутреннее устройство PyTorch и TensorFlow; математические основы оптимизации нейросетей; критерии сравнения и выбора фреймворка для проекта; методы регуляризации, аугментации и борьбы с переобучением.
- Уметь: создавать кастомные циклы обучения и сложные архитектуры в PyTorch; разрабатывать и обучать модели с использованием высокоуровневого API Keras и TensorFlow; реализовывать сверточные, рекуррентные сети и трансформеры; применять распределенное обучение и запускать эксперименты на GPU/TPU.
- Владеть: инструментарием для отладки и визуализации обучения (TensorBoard, Weights & Biases); техниками оптимизации гиперпараметров и мониторинга производительности моделей; практиками MLOps по развертыванию моделей с помощью TensorFlow Serving и TorchServe.
Для кого этот курс.
Курс предназначен для практикующих data-инженеров, машин-листов и исследователей, желающих углубить свои знания в области глубокого обучения и освоить современные инструменты индустриального уровня. Материал будет полезен разработчикам, стремящимся расширить свой стек технологий за счет мощных фреймворков PyTorch и TensorFlow, а также студентам, заканчивающим математические и компьютерные специальности, чтобы подготовиться к решению реальных бизнес-задач. Слушатели должны иметь базовое понимание языка Python, линейной алгебры и математического анализа, а также начальный опыт работы с библиотеками для обработки данных (например, NumPy, Pandas). Это не курс «с нуля» для абсолютных новичков, а программа для тех, кто уже знаком с основами классического машинного обучения и хочет перейти на уровень глубоких нейронных сетей.
Модуль 1. Основы глубокого обучения и вычислительные графы
В основе глубокого обучения лежит концепция искусственной нейронной сети, вдохновленная биологией мозга. Нейросеть состоит из множества соединенных между собой нейронов, организованных в слои. Каждый нейрон выполняет простую операцию: взвешенную сумму входных сигналов плюс смещение, результат которой пропускается через функцию активации. В глубоком обучении «глубина» означает наличие большого количества скрытых слоев (от десятков до сотен), что позволяет модели выявлять сложные иерархические закономерности. Вычислительный граф — это математическая абстракция, описывающая сеть как ориентированный граф, где узлы — это операции (матричное умножение, свертка, сложение и пр.), а ребра — передаваемые тензоры. PyTorch использует динамический граф, который строится заново на каждом шаге, что удобно для отладки и исследования. В то же время TensorFlow применяет статический граф (в версии 1.x) или режим активного выполнения (Eager Execution) в версии 2.x, делая работу более интуитивной. Глубокое понимание вычислительных графов критично для оптимизации производительности и распределенного обучения.
Ключевая практика: при изучении нового фреймворка всегда начинайте с визуализации графа в TensorBoard или с помощью инструментов PyTorch. Это поможет выявить узкие места и ошибки в соединениях.
Центральный объект в обоих фреймворках — тензор, многомерный массив данных. В PyTorch тензоры (torch.Tensor) являются аналогом NumPy ndarrays, но с возможностью выполнения операций на GPU. Ключевая особенность — тензоры PyTorch сохраняют историю операций для автоматического дифференцирования. TensorFlow работает с тензорами (tf.Tensor), используя механизм tf.GradientTape для записи вычислений с целью расчета градиентов. Построение эффективного конвейера данных неразрывно связано с управлением тензорами. В PyTorch для этого активно используется DataLoader, который позволяет параллельно загружать и предобрабатывать данные. В TensorFlow эквивалентом служит tf.data.Dataset, предоставляющий богатый API для пайплайна, включая кэширование, перемешивание и пакетную обработку. Ошибки новичков часто связаны с неправильным приведением типов данных и размерностей тензоров — всегда проверяйте форму (shape) тензора при отладке.
Совет: используйте функцию .item() в PyTorch для извлечения скалярного значения из тензора с одним элементом. В TensorFlow для этого применяется .numpy().
Автоматическое дифференцирование (Autograd) — это технология, лежащая в основе обучения нейросетей, освобождающая разработчика от ручного вычисления градиентов. В PyTorch Autograd реализован через систему torch.autograd. Когда вы выполняете операции с тензорами, для которых установлен флаг requires_grad=True, фреймворк строит вычислительный граф и сохраняет градиентную функцию. Обратный проход (.backward()) вычисляет градиенты для всех параметров модели. В TensorFlow аналогичную функциональность предоставляет tf.GradientTape. Контекстный менеджер GradientTape записывает все операции, выполняемые внутри его области. После завершения записи вы можете вызвать tape.gradient(loss, model.trainable_variables) для получения градиентов. Эта концепция является ключевой для понимания процесса обратного распространения ошибки. Умение правильно использовать Autograd позволяет реализовывать кастомные слои и функции потерь, не беспокоясь о математических выкладках.
Антипаттерн: избегайте изменения in-place у тензоров с requires_grad=True, так как это нарушает граф вычислений и приводит к ошибкам при обратном распространении.
Функции активации придают нейросетям нелинейность, позволяя им аппроксимировать сложные зависимости. В современных архитектурах наибольшее распространение получила ReLU (Rectified Linear Unit) и её вариации (Leaky ReLU, ELU, Swish). ReLU проста и эффективна: , но страдает проблемой «умирающего ReLU», когда большая часть нейронов выключается. Leaky ReLU решает эту проблему, добавляя небольшой коэффициент для отрицательных значений: . Для выходного слоя выбор активации зависит от задачи: сигмоида (бинарная классификация), софтмакс (многоклассовая классификация), линейная (регрессия). В PyTorch и TensorFlow все стандартные функции активации доступны как готовые модули в пакетах torch.nn и tf.keras.layers.
Рекомендация: на практике начинайте с ReLU для скрытых слоев, это стандартный выбор. При использовании сигмоиды или гиперболического тангенса для глубоких сетей будьте осторожны с затуханием градиента.
Сердцем обучения глубоких сетей является процесс оптимизации функции потерь с помощью градиентного спуска и его вариантов. Параметр скорость обучения (learning rate) контролирует величину шага обновления весов: . Слишком большая скорость может привести к расходимости, слишком малая — к застреванию в локальных минимумах и медленной сходимости. Чтобы улучшить процесс обучения, используют адаптивные методы оптимизации: Adam, RMSprop, Adagrad. Adam (Adaptive Moment Estimation) комбинирует преимущества момента и адаптивной скорости обучения, что делает его наиболее популярным выбором в исследованиях. В PyTorch оптимизаторы доступны в torch.optim, в TensorFlow — в tf.keras.optimizers. Важно также использовать политики расписания скорости обучения (learning rate scheduling), например, снижение по эпохам или косинусное затухание, что помогает точнее настраивать модель в конце обучения.
Практический совет: начните с Adam со скоростью 1e-3 для большинства задач. Для обучения генеративных сетей (GAN) часто требуется подборка более сложных расписаний.
Ключевой вызов в глубоком обучении — переобучение (overfitting), когда модель хорошо работает на обучающей выборке, но плохо обобщается на новых данных. Основные методы борьбы: регуляризация L1 и L2, Dropout, пакетная нормализация и ранняя остановка. L2-регуляризация (weight decay) добавляет к функции потерь штраф за большие веса: . Dropout случайным образом «выключает» часть нейронов во время обучения, вынуждая сеть изучать более робастные признаки. Пакетная нормализация стабилизирует распределение активаций внутри слоя, что позволяет использовать более высокие скорости обучения и ускоряет сходимость. Все эти методы интегрированы в API PyTorch и TensorFlow в виде отдельных модулей (например, torch.nn.Dropout, torch.nn.BatchNorm2d, или соответствующие слои в Keras).
Совет: всегда отслеживайте динамику ошибок на тренировочной и валидационной выборках. Если ошибка на тренировочной падает, а на валидационной растет — это явный признак переобучения.
Модуль 2. Введение в PyTorch: базовые компоненты
PyTorch — это открытая библиотека машинного обучения, разработанная Facebook AI Research. Она предлагает два основных режима работы: подмодуль torch для низкоуровневых тензорных операций и torch.nn для построения нейронных сетей. Базовый элемент любой модели в PyTorch — это класс torch.nn.Module. Переопределяя методы __init__ (определение слоев) и forward (вычисление результата), вы можете создавать кастомные архитектуры. PyTorch славится своим динамическим вычислительным графом, который строится в процессе выполнения forward-прохода. Это делает код очень похожим на обычный Python и упрощает отладку. Для быстрого прототипирования можно использовать Sequential, но для сложных сетей с множеством ветвлений рекомендуется писать собственные классы.
Пример реализации: класс наследуется от nn.Module, в forward передается входной тензор, возвращается выходной. При вызове .cuda() вся модель перемещается на GPU, если он доступен.
Управление данными в PyTorch строится на двух ключевых классах: Dataset и DataLoader. Класс torch.utils.data.Dataset требует реализации методов __len__ (размер набора) и __getitem__ (возврат образца и метки). Это позволяет гибко загружать данные из любых источников — файлов, баз данных, изображений. DataLoader оборачивает Dataset и добавляет важные функции: пакетную обработку (batch_size), перемешивание (shuffle=True), параллельную загрузку (num_workers), что критично для ускорения обучения. При работе с большими данными всегда используйте DataLoader, чтобы избежать переполнения памяти и эффективно загружать данные на GPU. Для стандартных задач PyTorch предоставляет готовые датасеты, такие как MNIST, CIFAR-10, ImageNet, в модуле torchvision.datasets.
Совет по оптимизации: увеличивайте num_workers пропорционально числу ядер CPU для максимальной загрузки. Но будьте внимательны, слишком большое количество воркеров может создать избыточную нагрузку.
Кастомный цикл обучения в PyTorch дает максимальный контроль над процессом. Типичный цикл включает: сброс градиентов (optimizer.zero_grad()), forward-проход (outputs = model(inputs)), вычисление функции потерь (loss = criterion(outputs, labels)), обратный проход (loss.backward()) и шаг оптимизатора (optimizer.step()). Такой подход позволяет внедрять сложные логики: градиентное накопление, смешанная точность (AMP — Automatic Mixed Precision), отслеживание метрик. Для ускорения вычислений рекомендуется оборачивать модель и данные в with torch.cuda.amp.autocast() и использовать scaler для амплификации градиентов при использовании FP16. PyTorch также поддерживает распределенное обучение через torch.distributed, что позволяет запускать обучение на нескольких GPU и узлах.
Рекомендация: пишите цикл обучения в виде отдельной функции, передавая в нее модель, даталоадер, оптимизатор и функцию потерь. Это улучшает модульность и переиспользование кода.
Для сохранения прогресса и дальнейшего использования обученных моделей PyTorch предоставляет гибкие инструменты. Сохранение модели с помощью torch.save(model.state_dict(), 'model.pth') рекомендуется, так как state_dict содержит веса модели в виде словаря, что компактнее и надежнее, чем сохранение всей модели. Загрузка происходит через model.load_state_dict(torch.load('model.pth')). Важно также сохранять состояние оптимизатора и метаданные (эпоху, функцию потерь) для возобновления обучения. В PyTorch есть встроенный механизм Checkpointing, который позволяет автоматически сохранять лучшую модель по метрике на валидации, используя torch.save внутри колбэков или самописных функций. Для больших моделей полезно использовать сохранение с шардингом, когда веса разбиваются на части для экономии памяти.
Важно: всегда загружайте модель на том же устройстве, где она была обучена, или явно указывайте map_location при загрузке, чтобы избежать ошибок CUDA.
В отличие от многих других фреймворков, PyTorch предлагает мощный и гибкий API для создания кастомных слоев и функций потерь. Для создания собственного слоя достаточно унаследоваться от nn.Module и переопределить forward, в котором описываются все преобразования. Веса слоя можно определить как nn.Parameter, чтобы они автоматически отслеживались оптимизатором. Кастомные функции потерь создаются аналогично — как класс, наследующий nn.Module, или как обычная функция, принимающая предсказания и истинные значения и возвращающая скалярный тензор. Это позволяет реализовывать специфические метрики, например, Dice Loss для сегментации, Triplet Loss для метрического обучения или Contrastive Loss. PyTorch также предоставляет готовые функции в torch.nn.functional, которые можно использовать как строительные блоки.
Антипаттерн: не используйте циклы по батчу внутри forward для поэлементных операций, предпочитайте векторизованные вычисления на тензорах.
Эффективная отладка — ключ к успешной разработке на PyTorch. Благодаря динамическому графу, вы можете использовать привычный отладчик Python (pdb) или вставлять точки остановки (breakpoint()) внутри forward, чтобы исследовать тензоры и их градиенты. Для анализа производительности используйте PyTorch Profiler, который показывает время выполнения операций на CPU и GPU, помогая находить узкие места. Важным инструментом является torchinfo (ранее torchsummary), позволяющий получить краткую информацию о модели: количество параметров, размерность входных и выходных данных каждого слоя. Для визуализации графа модели можно использовать TensorBoard через torch.utils.tensorboard или Weights & Biases для более глубокого мониторинга экспериментов.
Совет: всегда проверяйте градиенты на наличие NaN или бесконечных значений. Это часто связано с взрывом градиента, особенно в рекуррентных сетях. Используйте градиентное клиппирование (torch.nn.utils.clip_grad_norm_) для борьбы с этой проблемой.
Модуль 3. Работа с TensorFlow 2.x и Keras
TensorFlow 2.x представляет собой полную экосистему для машинного обучения, поддерживающую как исследовательские, так и производственные задачи. Ключевым нововведением версии 2.x является Eager Execution, который делает код императивным и интуитивно понятным, аналогичным PyTorch. Высокоуровневым API является Keras, интегрированный как tf.keras, который предлагает простой и понятный синтаксис для построения моделей. Основные способы построения моделей в Keras: Sequential (последовательный стек слоев), Functional API (позволяет создавать нелинейные топологии с несколькими входами и выходами) и Model Subclassing (максимальная гибкость через наследование от tf.keras.Model). TensorFlow также поддерживает TensorFlow Probability для вероятностного программирования, TensorFlow Lite для мобильных устройств и TensorFlow.js для веб-приложений.
Рекомендация: начинайте с Sequential для простых сетей. Для сложных архитектур, например, с пропускными соединениями (ResNet), используйте Functional API, а для максимальной кастомизации — Model Subclassing.
В TensorFlow 2.x предпочтительный способ построения конвейера данных — tf.data.Dataset. Этот API позволяет создавать эффективные и масштабируемые пайплайны. Данные могут загружаться из памяти (NumPy), из файлов (CSV, TFRecord) или генерироваться на лету. Ключевые методы: batch() для группировки в батчи, shuffle() для перемешивания, map() для применения преобразований к каждому элементу, cache() для кэширования данных в памяти или на диске, ускоряя последующие эпохи. При работе с большими наборами данных рекомендуется использовать TFRecord — бинарный формат, оптимизированный для TensorFlow. Для распределенного обучения можно использовать tf.distribute.Strategy вместе с Dataset, чтобы автоматически разбивать данные по устройствам.
Совет по оптимизации: используйте .prefetch(tf.data.AUTOTUNE), чтобы перекрыть подготовку данных и вычисления модели, что значительно повышает пропускную способность.
Keras API предлагает три способа создания слоев: tf.keras.layers.Dense (полносвязный слой), Conv2D (сверточный), LSTM (рекуррентный) и многие другие. Каждый слой автоматически управляет своими весами и может быть легко скомбинирован. В функциональном стиле вы определяете входной слой, затем применяете последовательность слоев, получая выходной тензор, и создаете модель через Model(inputs=inputs, outputs=outputs). Этот подход идеален для «сетей с несколькими головами», где одна модель решает несколько задач одновременно. Подклассифицируя Model, вы можете переопределять call (аналог forward в PyTorch) и добавлять собственные обучаемые параметры. Keras также предлагает удобные функции для смешанной точности через tf.keras.mixed_precision, что ускоряет обучение на совместимых GPU.
Важно: при использовании Model Subclassing вы теряете возможность сохранять архитектуру модели в файл HDF5, поэтому для загрузки модели потребуется код её определения.
Цикл обучения в TensorFlow 2.x может быть реализован двумя способами: через высокоуровневый метод model.fit() и через кастомный цикл с использованием tf.GradientTape. Метод fit() является наиболее простым и подходит для большинства стандартных сценариев. Он автоматически обрабатывает эпохи, батчи, валидацию и колбэки (например, EarlyStopping, ModelCheckpoint, ReduceLROnPlateau). Кастомный цикл предоставляет полный контроль над каждой итерацией: вы сами вычисляете потери, градиенты и применяете обновления. Он необходим для реализации сложных архитектур, таких как GAN или RL. В кастомном цикле важно использовать with tf.GradientTape() as tape:, чтобы записать операции, а затем вычислить градиенты через tape.gradient и применить их через optimizer.apply_gradients.
Совет: для большинства задач используйте model.fit() из-за его простоты и богатого набора колбэков. Кастомный цикл применяйте только когда требуется нестандартная логика обучения.
Сохранение и загрузка моделей в TensorFlow 2.x реализована через форматы SavedModel и HDF5. model.save('path/model', save_format='tf') создает папку с SavedModel, содержащую архитектуру, веса и граф вычислений. Это основной формат для развертывания, так как он не зависит от версии Python и может быть загружен в TensorFlow Serving, TFLite или другие среды. Формат HDF5 (.h5) сохраняет только веса и архитектуру, но не позволяет восстанавливать кастомные классы при наследовании. Для сохранения промежуточных результатов рекомендуется использовать ModelCheckpoint, который сохраняет модель после каждой эпохи или при улучшении метрики. Важно: при использовании кастомных слоев или функций потерь необходимо передать их в словаре custom_objects при загрузке через tf.keras.models.load_model.
Рекомендация: всегда сохраняйте модель в формате SavedModel для производственных сред, чтобы гарантировать совместимость с другими инструментами экосистемы TensorFlow.
Для создания кастомных слоев и моделей в TensorFlow используется наследование от tf.keras.layers.Layer и tf.keras.Model. В методе __init__ вы определяете внутренние слои или обучаемые переменные через self.add_weight(). Метод call(self, inputs) описывает преобразование входных данных. Кастомные функции потерь определяются как функции, принимающие y_true и y_pred, и возвращающие тензор с потерями. Для сложных метрик (например, F1 Score) можно использовать tf.keras.metrics.Metric и переопределить методы update_state, result и reset_state. Это дает гибкость, но требует внимательного отношения к автоматической дифференцируемости — все операции должны быть производными в TensorFlow (не должны использовать обычные списки или NumPy без обертки).
Антипаттерн: не используйте внутри call конструкции Python, которые зависят от формы входных данных, если форма меняется динамически — это нарушает построение графа. Вместо этого используйте tf.shape.
TensorFlow предлагает мощный инструментарий для профилирования и отладки. TensorBoard — это панель мониторинга, которая визуализирует скалярные метрики (потери, точность), гистограммы весов, активации и граф модели. Для использования в кастомном цикле необходимо создать tf.summary.create_file_writer и записывать значения через tf.summary.scalar. tf.debugging содержит функции для проверки условий (assert_equal, assert_greater) и отслеживания NaN в градиентах (через tf.debugging.check_numerics). TensorFlow Profiler позволяет детально проанализировать время выполнения операций на устройстве, что особенно важно при распределенном обучении. Для поиска ошибок в производительности используйте Trace Viewer в TensorBoard, который показывает временную шкалу выполнения операций.
Совет: добавьте колбэк tf.keras.callbacks.TensorBoard в model.fit(), чтобы автоматически получать логи для TensorBoard без написания дополнительного кода.
Модуль 4. Сверточные нейронные сети (CNN)
Сверточные нейронные сети (CNN) являются основой современного компьютерного зрения. Их ключевой компонент — слой свертки (Convolution), который применяет обучаемые фильтры (ядра) к входному изображению для выделения признаков: краев, текстур, объектов. Процесс свертки описывается формулой: . Фильтры движутся по входу с шагом (stride), а количество фильтров определяет глубину выхода. Свертка сохраняет пространственную структуру данных, используя локальные связи и общие веса, что значительно уменьшает количество параметров по сравнению с полносвязной сетью. После свертки часто применяется слой пулинга (Pooling), обычно MaxPooling, который уменьшает размерность карт признаков, сохраняя наиболее важные активации, обеспечивая инвариантность к малым изменениям позиции.
Практический совет: размер ядра обычно выбирают 3x3 или 5x5. Небольшие фильтры позволяют создавать более глубокие сети с меньшим числом параметров.
Архитектура современных CNN часто включает пропускные соединения (skip connections), как в знаменитой сети ResNet. Идея заключается в том, чтобы добавить входной сигнал к выходу одного или нескольких слоев: . Это позволяет градиентам лучше распространяться через сеть, решая проблему затухания градиента в очень глубоких сетях (более 50 слоев). Другой важный принцип — архитектурные паттерны, такие как VGG (простая последовательность сверток и пулинга) и Inception (параллельные свертки с разными размерами ядер). Понимание этих архитектур необходимо для выбора подходящей основы под вашу задачу. В PyTorch и TensorFlow есть предобученные модели этих архитектур в модулях torchvision.models и tf.keras.applications, что позволяет использовать трансферное обучение.
Рекомендация: при ограниченных вычислительных ресурсах используйте предобученные модели (например, ResNet-50) в качестве экстрактора признаков, а дообучайте только последние слои под вашу задачу.
Для задач, где размеченных данных мало, исключительно эффективным подходом является трансферное обучение и тонкая настройка (fine-tuning). Берется модель, предобученная на большом наборе данных (например, ImageNet), удаляется последний классификационный слой и заменяется на новый, соответствующий вашей задаче. На первом этапе обучаются только веса нового слоя, а веса предобученной части фиксируются. На втором этапе можно «разморозить» верхние слои предобученной модели и дообучать всю модель с низкой скоростью обучения. Это позволяет достичь высокой точности даже с набором данных в несколько сотен изображений. В PyTorch для трансферного обучения используются функции torchvision.models для загрузки моделей и requires_grad=False для заморозки слоев. В TensorFlow — аналогичные возможности через tf.keras.applications.
Совет: при дообучении используйте скорость обучения на порядок меньше, чем при обучении с нуля, чтобы не разрушить уже изученные веса.
Аугментация данных (Data Augmentation) — это метод искусственного увеличения размера обучающей выборки путем применения случайных преобразований к изображениям: поворотов, сдвигов, масштабирования, изменения яркости, контраста, отражений. Это один из самых мощных приемов борьбы с переобучением в компьютерном зрении. В PyTorch аугментация реализуется через трансформы из torchvision.transforms, которые применяются к изображению перед подачей в DataLoader. Например, transforms.RandomHorizontalFlip(p=0.5), transforms.RandomRotation(10), transforms.ColorJitter. В TensorFlow аугментация интегрирована в слои tf.keras.layers.experimental.preprocessing или может быть выполнена через tf.image и Dataset.map. Важно применять аугментацию на лету (on-the-fly) для создания новых вариаций на каждой эпохе.
Антипаттерн: не применяйте аугментацию к валидационному набору, только к обучающему. Это исказит оценку качества модели.
Архитектуры современных CNN эволюционировали от простых сетей, таких как AlexNet, до сложных, таких как EfficientNet. Ключевые вехи: VGG продемонстрировал важность глубины, ResNet ввел остаточные связи, позволив тренировать сети с сотнями слоев, DenseNet соединяет каждый слой со всеми последующими, улучшая поток информации. Inception (GoogLeNet) использует модули с параллельными свертками разных размеров. MobileNet и ShuffleNet оптимизированы для мобильных устройств благодаря глубинной свертке (depthwise convolution). При выборе архитектуры для своей задачи учитывайте компромисс между точностью и скоростью инференса. В PyTorch и TensorFlow все эти модели доступны для загрузки с предобученными весами.
Совет: для бенчмарков используйте EfficientNet — она обеспечивает лучший баланс точности и производительности по сравнению с другими архитектурами.
В задачах компьютерного зрения, где важна пространственная точность (например, сегментация или распознавание объектов), используются специальные архитектуры. U-Net — это архитектура с симметричной сверточной структурой «кодировщик-декодировщик», которая широко применяется для медицинской сегментации. Она использует пропускные соединения между уровнями кодировщика и декодировщика, чтобы сохранить детали изображения. Mask R-CNN расширяет Faster R-CNN, добавляя ветвь для предсказания бинарной маски каждого объекта, что позволяет выполнять сегментацию экземпляров. Эти сети требуют больше вычислительных ресурсов и данных для обучения. В PyTorch есть реализация этих моделей в torchvision.models.detection, а в TensorFlow — в tensorflow-models (TF Model Garden).
Рекомендация: для начала работы с сегментацией используйте предобученную модель U-Net на PyTorch из библиотеки segmentation-models-pytorch.
Модуль 5. Рекуррентные нейронные сети и обработка последовательностей
Рекуррентные нейронные сети (RNN) предназначены для обработки последовательностей данных: текста, временных рядов, аудио. В отличие от полносвязных сетей, RNN используют циклы, сохраняя внутреннее состояние (hidden state) на каждом шаге, которое передается на следующий шаг: . Это позволяет сети запоминать информацию о предыдущих элементах последовательности. Однако, простые RNN страдают от проблемы затухающих градиентов при обработке длинных последовательностей. Для решения этой проблемы были разработаны более сложные архитектуры: LSTM (Long Short-Term Memory) и GRU (Gated Recurrent Unit). LSTM вводит специальные вентили (вход, забывания и выход), которые управляют потоком информации, позволяя сети запоминать важную информацию на протяжении длительных промежутков времени.
Ключевое отличие: LSTM имеет механизм «ячейки памяти» (cell state), который сохраняется и обновляется независимо от скрытого состояния.
LSTM является основным инструментом для сложных задач НЛП, таких как машинный перевод и генерация текста. Внутренняя структура LSTM включает три основных вентиля, управляемых сигмоидными слоями и операциями поэлементного умножения. Вентиль забытия решает, какую информацию из ячейки памяти удалить: . Входной вентиль решает, какую новую информацию сохранить: и . Выходной вентиль решает, что будет выведено на основе состояния ячейки: и . Эти уравнения реализованы в модулях torch.nn.LSTM и tf.keras.layers.LSTM. Параметры num_layers и bidirectional позволяют создавать глубокие и двунаправленные LSTM, повышая качество модели.
Совет: при работе с LSTM всегда нормализуйте входные данные (например, с помощью BatchNormalization или LayerNormalization), так как RNN чувствительны к масштабу входных значений.
GRU (Gated Recurrent Unit) — это упрощенная версия LSTM, объединяющая вентиль забытия и входа в один вентиль обновления и использующая один вентиль сброса. Она имеет меньше параметров, что делает её быстрее в обучении и требующей меньше вычислительных ресурсов, сохраняя при этом сопоставимую производительность на многих задачах. Вектор состояний обновляется следующим образом: (вентиль обновления), (вентиль сброса), , . В PyTorch GRU доступна через torch.nn.GRU, в TensorFlow — tf.keras.layers.GRU. Выбор между LSTM и GRU часто зависит от размера данных и времени обучения. Для небольших наборов данных GRU часто работает лучше.
Рекомендация: начните с GRU как более простой и быстрой альтернативы. Если качество недостаточно, попробуйте LSTM.
При работе с текстовыми данными первым шагом является токенизация — разбиение текста на отдельные слова (токены) и векторизация — преобразование токенов в числовые векторы. Традиционные методы включают One-Hot Encoding и Bag of Words, но они не учитывают семантику. Современный подход — Word Embeddings, такие как Word2Vec, GloVe и FastText, которые отображают слова в непрерывное векторное пространство, где семантически близкие слова находятся рядом. В PyTorch для работы с эмбеддингами используется torch.nn.Embedding, в TensorFlow — tf.keras.layers.Embedding. Предобученные эмбеддинги можно загружать из библиотек, например, gensim или использовать специальный слой torchtext.vocab.GloVe. Важно помнить, что эмбеддинги могут быть дообучены на вашей задаче для учета специфики предметной области.
Антипаттерн: не используйте One-Hot Encoding для больших словарей (более 10k токенов) — это приведет к огромной размерности и разреженным данным. Всегда используйте эмбеддинги.
Классический подход к анализу текста с использованием RNN имеет ограничение — предложения читаются последовательно, что не позволяет учитывать контекст всего документа одновременно. Механизм внимания (Attention) решает эту проблему, позволяя модели взвешивать важность каждого входного токена при генерации каждого выходного токена. Внимание вычисляется как , где Q — запросы, K — ключи, V — значения. Это позволяет модели «сосредотачиваться» на наиболее релевантных частях входной последовательности в зависимости от контекста. Внимание является основой архитектуры Трансформера. В PyTorch механизм внимания реализован через torch.nn.MultiheadAttention, в TensorFlow — через tf.keras.layers.MultiHeadAttention.
Совет: механизм внимания особенно полезен для длинных последовательностей, где RNN теряют информацию. Используйте его как альтернативу или дополнение к LSTM.
Модуль 6. Трансформеры и современные архитектуры
Трансформер, представленный в статье «Attention Is All You Need», совершил революцию в НЛП. В отличие от RNN, трансформер обрабатывает всю последовательность параллельно, используя механизм самовнимания. Архитектура состоит из энкодеров (понимание входного текста) и декодеров (генерация выходного текста). Ключевые компоненты: Multi-Head Self-Attention, который позволяет модели одновременно фокусироваться на разных частях входных данных; позиционное кодирование, добавляющее информацию о порядке слов; Feed-Forward слои (полносвязные) и Layer Normalization. Отсутствие рекуррентности позволяет обучать трансформеры на огромных корпусах текста, что привело к созданию больших языковых моделей, таких как BERT и GPT. В PyTorch и TensorFlow есть реализации трансформеров в torch.nn.Transformer и tf.keras.layers.Transformer.
Ключевое преимущество: трансформеры захватывают долгосрочные зависимости намного лучше, чем RNN, благодаря механизму внимания.
На основе трансформеров были созданы крупные предобученные модели, которые изменили подход к НЛП. BERT (Bidirectional Encoder Representations from Transformers) — это модель, обучаемая с помощью маскирования слов (MLM) и предсказания следующего предложения (NSP). Она позволяет получать контекстуальные эмбеддинги слов и используется для классификации текстов, вопросно-ответных систем. GPT (Generative Pre-trained Transformer) — это модель-декодер, обучаемая на языковой модели с авторегрессией, предназначенная для генерации текста. В PyTorch можно использовать библиотеку Transformers от Hugging Face, которая предоставляет единый интерфейс для работы с тысячами предобученных моделей (bert-base-uncased, gpt2 и др.). В TensorFlow также есть интеграция с той же библиотекой. Использование готовых моделей позволяет достигать высоких результатов без обучения с нуля.
Рекомендация: для начала работы с трансформерами установите библиотеку transformers (pip install transformers) и используйте `pipeline` для быстрой инференса.
Vision Transformer (ViT) — это адаптация архитектуры трансформера для задач компьютерного зрения. Вместо пикселей изображения разбиваются на патчи, которые линейно проецируются в пространство эмбеддингов, добавляется позиционное кодирование, и все это подается на вход стандартному трансформеру. ViT показывает конкурентоспособные результаты с CNN на больших наборах данных (например, ImageNet-21k). Однако, ViT требует больше данных для обучения, чем CNN. Для задач с ограниченным объемом данных часто эффективнее использовать CNN или гибридные архитектуры, например, Swin Transformer, который вводит иерархическое внимание с подвижными окнами. В PyTorch ViT доступен через torchvision.models.vision_transformer, в TensorFlow — через tf.keras.applications.ViT.
Совет: при использовании ViT с небольшим набором данных обязательно применяйте сильную аугментацию и трансферное обучение из предобученных чекпоинтов.
Для задач, связанных со временем (временные ряды, видео, аудио), разработаны специализированные модели, комбинирующие трансформеры и свертки. Time Series Transformer применяет механизм внимания для захвата долгосрочных зависимостей во временных рядах, часто показывая результаты лучше, чем LSTM. Video Vision Transformer обрабатывает видео как последовательность пространственно-временных патчей. Audio Spectrogram Transformer работает со спектрограммами аудио. Эти модели часто имеют большую вычислительную сложность. Для повышения эффективности используются методы sparse attention и low-rank approximations. В экосистеме TensorFlow и PyTorch есть реализации этих подходов в специализированных библиотеках, таких как pytorch-forecasting для временных рядов и pytorchvideo для видео.
Рекомендация: для прогнозирования временных рядов с трансформерами используйте библиотеку pytorch-forecasting, которая предоставляет готовые модели и модули обработки данных.
Эффективное тонкое донастройка (fine-tuning) больших трансформеров требует учета ряда факторов: выбора скорости обучения, размера батча и методов регуляризации. Обычно используется скорость обучения на порядок меньше, чем при обучении с нуля (например, 2e-5 для BERT). Постепенная разморозка (gradual unfreezing) — это метод, при котором сначала дообучаются верхние слои, а затем постепенно размораживаются нижние. Дистилляция знаний (knowledge distillation) позволяет сжать большую модель в меньшую, сохраняя при этом высокое качество, что критично для деплоя на мобильные устройства. В библиотеке Hugging Face есть методы Trainer и TrainingArguments, которые упрощают этот процесс. Для мониторинга обучения используйте Weights & Biases или MLflow.
Совет: при тонкой настройке на небольшом датасете используйте Early Stopping и Dropout с увеличенным коэффициентом, чтобы избежать переобучения.
Модуль 7. Продвинутые методы обучения и оптимизации
Пакетная нормализация (Batch Normalization) — это техника, которая нормализует активации каждого слоя по батчу: , а затем применяет масштабирование и сдвиг (γ и β). Она ускоряет обучение, позволяет использовать более высокие скорости обучения, уменьшает зависимость от инициализации и оказывает регуляризующий эффект. В PyTorch реализована как torch.nn.BatchNorm1d (для 1D), BatchNorm2d (для 2D изображений) и BatchNorm3d. В TensorFlow — tf.keras.layers.BatchNormalization. Однако, BatchNorm имеет недостатки: она менее эффективна для малых батчей (<32) и для рекуррентных сетей. Альтернативой является Layer Normalization, которая нормализует активации независимо для каждого образца, что делает её более подходящей для RNN и трансформеров.
Совет: при обучении с распределением на нескольких GPU синхронизируйте статистику BatchNorm между устройствами, чтобы не нарушать нормализацию.
Градиентное клиппирование (Gradient Clipping) — это техника, предотвращающая проблему взрыва градиентов в глубоких сетях, особенно в RNN. Она ограничивает величину градиентов либо по норме (norm clipping), либо по значению (value clipping). В PyTorch используется torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm) для нормировки градиентов до заданной нормы, и clip_grad_value_ для ограничения абсолютного значения. В TensorFlow аналоги: tf.clip_by_norm и tf.clip_by_value. Применение клиппирования обычно улучшает стабильность обучения. Важно правильно выбрать порог — он зависит от модели и задачи. Для LSTM и GRU часто используются значения max_norm в диапазоне 0.1 – 1.0.
Рекомендация: добавляйте градиентное клиппирование как стандартную практику при обучении глубоких сетей, особенно если вы замечаете нестабильную сходимость.
Смешанная точность (Mixed Precision Training) использует как 16-битные (FP16), так и 32-битные (FP32) числа с плавающей точкой для ускорения обучения и уменьшения потребления памяти GPU. Ключевые операции (как умножение матриц и свертки) выполняются в FP16, что почти вдвое уменьшает размер тензоров и ускоряет вычисления на архитектурах с тензорными ядрами (NVIDIA Volta, Turing, Ampere). Однако, градиенты и обновления весов для стабильности хранятся в FP32. PyTorch поддерживает смешанную точность через torch.cuda.amp, используя контекстный менеджер autocast() и GradScaler для масштабирования потерь, чтобы избежать потери точности градиентов. В TensorFlow это реализовано через tf.keras.mixed_precision. Применение смешанной точности может ускорить обучение в 2-3 раза без потери точности.
Совет: всегда проверяйте, поддерживает ли ваша модель и версия CUDA смешанную точность. Используйте torch.cuda.is_available() и torch.cuda.get_device_capability().