Формат концентратора TF1

При запуске в 2018 году TensorFlow Hub предлагал один тип ресурсов: формат TF1 Hub для импорта в программы TensorFlow 1.

На этой странице объясняется, как использовать формат TF1 Hub в TF1 (или режим совместимости TF1 с TF2) с классом hub.Module и связанными API. (Обычное использование — создание tf.Graph , возможно, внутри TF1 Estimator , путем объединения одной или нескольких моделей в формате TF1 Hub с tf.compat.layers или tf.layers ).

Пользователи TensorFlow 2 (вне режима совместимости с TF1) должны использовать новый API с hub.load() hub.KerasLayer . Новый API загружает новый тип ресурса TF2 SavedModel, но также имеет ограниченную поддержку загрузки формата TF1 Hub в TF2 .

Использование модели в формате TF1 Hub

Создание экземпляра модели в формате TF1 Hub

Модель в формате TF1 Hub импортируется в программу TensorFlow путем создания объекта hub.Module из строки с его URL-адресом или путем к файловой системе, например:

m = hub.Module("path/to/a/module_dir")

Примечание. Дополнительную информацию о других допустимых типах дескрипторов см. здесь .

Это добавит переменные модуля в текущий график TensorFlow. Запуск их инициализаторов будет считывать предварительно обученные значения с диска. Аналогично в граф добавляются таблицы и другое состояние.

Модули кэширования

При создании модуля по URL-адресу содержимое модуля загружается и кэшируется во временном каталоге локальной системы. Место кэширования модулей можно переопределить с помощью переменной среды TFHUB_CACHE_DIR . Подробности см. в разделе Кэширование .

Применение модуля

После создания экземпляра модуль m можно вызывать ноль или более раз, как функцию Python, от тензорных входов до тензорных выходов:

y = m(x)

Каждый такой вызов добавляет операции к текущему графу TensorFlow для вычисления y из x . Если речь идет о переменных с обученными весами, они используются всеми приложениями.

Модули могут определять несколько именованных сигнатур , чтобы их можно было применять более чем одним способом (аналогично тому, как объекты Python имеют методы ). Документация модуля должна описывать доступные подписи. Вызов выше применяет подпись с именем "default" . Любую подпись можно выбрать, передав ее имя в необязательный аргумент signature= .

Если подпись имеет несколько входных данных, они должны быть переданы как dict с ключами, определенными подписью. Аналогично, если подпись имеет несколько выходных данных, их можно получить как dict, передав as_dict=True под ключами, определенными подписью (ключ "default" предназначен для одного выходного сигнала, возвращаемого, если as_dict=False ). Итак, наиболее общая форма применения Модуля выглядит так:

outputs = m(dict(apples=x1, oranges=x2), signature="fruit_to_pet", as_dict=True)
y1 = outputs["cats"]
y2 = outputs["dogs"]

Вызывающая сторона должна предоставить все входные данные, определенные сигнатурой, но нет необходимости использовать все выходные данные модуля. TensorFlow будет запускать только те части модуля, которые в конечном итоге становятся зависимостями цели в tf.Session.run() . Действительно, издатели модулей могут по своему усмотрению предоставлять различные выходные данные для расширенного использования (например, активацию промежуточных слоев) наряду с основными выходными данными. Потребители модулей должны корректно обрабатывать дополнительные выходные данные.

Пробуем альтернативные модули

Всякий раз, когда для одной задачи используется несколько модулей, TensorFlow Hub рекомендует снабдить их совместимыми сигнатурами (интерфейсами), чтобы попробовать разные модули так же просто, как изменить дескриптор модуля как гиперпараметр со строковым значением.

С этой целью мы поддерживаем коллекцию рекомендуемых общих сигнатур для популярных задач.

Создание нового модуля

Примечание о совместимости

Формат TF1 Hub ориентирован на TensorFlow 1. Он лишь частично поддерживается TF Hub в TensorFlow 2. Вместо этого рассмотрите возможность публикации в новом формате TF2 SavedModel .

Формат TF1 Hub похож на формат SavedModel TensorFlow 1 на синтаксическом уровне (те же имена файлов и сообщения протокола), но семантически отличается, позволяя повторно использовать, компоновать и переобучать модули (например, другое хранилище инициализаторов ресурсов, разные теги). соглашения для метаграфов). Самый простой способ отличить их на диске — наличие или отсутствие файла tfhub_module.pb .

Общий подход

Чтобы определить новый модуль, издатель вызывает hub.create_module_spec() с помощью функции module_fn . Эта функция создает график, представляющий внутреннюю структуру модуля, используя tf.placeholder() для входных данных, которые будут предоставлены вызывающей стороной. Затем он определяет подписи, вызываяhub.add_signature hub.add_signature(name, inputs, outputs) один или несколько раз.

Например:

def module_fn():
  inputs = tf.placeholder(dtype=tf.float32, shape=[None, 50])
  layer1 = tf.layers.dense(inputs, 200)
  layer2 = tf.layers.dense(layer1, 100)
  outputs = dict(default=layer2, hidden_activations=layer1)
  # Add default signature.
  hub.add_signature(inputs=inputs, outputs=outputs)

...
spec = hub.create_module_spec(module_fn)

hub.create_module_spec() можно использовать вместо пути для создания экземпляра объекта модуля в определенном графе TensorFlow. В таком случае контрольная точка отсутствует, и вместо этого экземпляр модуля будет использовать инициализаторы переменных.

Любой экземпляр модуля можно сериализовать на диск с помощью метода export(path, session) . Экспорт модуля сериализует его определение вместе с текущим состоянием его переменных в session в переданный путь. Это можно использовать при первом экспорте модуля, а также при экспорте точно настроенного модуля.

Для совместимости с оценщиками TensorFlow hub.LatestModuleExporter экспортирует модули из последней контрольной точки, точно так же, как tf.estimator.LatestExporter экспортирует всю модель из последней контрольной точки.

Издатели модулей должны по возможности использовать общую подпись , чтобы потребители могли легко обмениваться модулями и находить лучший для своей проблемы.

Реальный пример

Взгляните на наш экспортер модулей встраивания текста, чтобы увидеть реальный пример того, как создать модуль из распространенного формата встраивания текста.

Тонкая настройка

Обучение переменных импортированного модуля вместе с переменными модели вокруг него называется тонкой настройкой . Точная настройка может привести к улучшению качества, но добавляет новые сложности. Мы советуем потребителям приступать к тонкой настройке только после изучения более простых настроек качества и только в том случае, если издатель модуля рекомендует это.

Для потребителей

Чтобы включить тонкую настройку, создайте экземпляр модуля с hub.Module(..., trainable=True) чтобы сделать его переменные обучаемыми, и импортируйте REGULARIZATION_LOSSES TensorFlow. Если в модуле имеется несколько вариантов графиков, обязательно выберите тот, который подходит для обучения. Обычно это тот, у которого есть теги {"train"} .

Выбирайте режим тренировок, который не испортит предварительно натренированные веса, например, более низкую скорость обучения, чем при тренировках с нуля.

Для издателей

Чтобы облегчить потребителям точную настройку, обратите внимание на следующее:

  • Тонкая настройка требует регуляризации. Ваш модуль экспортируется с коллекцией REGULARIZATION_LOSSES , которая превращает ваш выбор tf.layers.dense(..., kernel_regularizer=...) и т. д. в то, что потребитель получает от tf.losses.get_regularization_losses() . Предпочитайте этот способ определения потерь регуляризации L1/L2.

  • В модели издателя избегайте определения регуляризации L1/L2 с помощью параметров l1_ и l2_regularization_strength tf.train.FtrlOptimizer , tf.train.ProximalGradientDescentOptimizer и других проксимальных оптимизаторов. Они не экспортируются вместе с модулем, и глобальная настройка уровня регуляризации может оказаться неприемлемой для потребителя. За исключением регуляризации L1 в широких (т. е. разреженных линейных) или широких и глубоких моделях, вместо этого должна быть возможность использовать отдельные потери регуляризации.

  • Если вы используете отсев, пакетную нормализацию или аналогичные методы обучения, установите для их гиперпараметров значения, которые имеют смысл во многих ожидаемых случаях использования. Процент отсева, возможно, придется скорректировать с учетом склонности целевой задачи к переобучению. При пакетной нормализации импульс (он же коэффициент затухания) должен быть достаточно мал, чтобы обеспечить точную настройку с небольшими наборами данных и/или большими пакетами. Для опытных пользователей рассмотрите возможность добавления подписи, которая предоставляет контроль над критическими гиперпараметрами.