Часть III • Продвинутые возможности глубокого обучения с TensorFlow.js
Заглянем глубже в метод градиентного подъема
в пространстве входных данных
Основная логика градиентного подъема в пространстве входных данных в примере
visualizeconvnet заключена в функции
inputGradientAscent()
из файла
main.js
и показана в листинге 7.9. Код выполняется в Node.js, поскольку по природе своей
требует значительных ресурсов в смысле памяти и затрачиваемого времени
1
. Отме
тим, что хотя основная идея градиентного подъема в пространстве входных данных
аналогична обучению модели на основе градиентного спуска в пространстве весовых
коэффициентов (см. рис. 7.10), напрямую переиспользовать
tf.Model.fit()
мы
не можем, поскольку эта функция ориентирована на блокирование входного сигнала
и обновление весовых коэффициентов. Вместо этого нам придется описать пользо
вательскую функцию вычисления «потерь» для заданного входного изображения.
Эта функция описывается такой строкой кода:
const lossFunction = (input) =>
auxModel.apply(input, {training: true}).gather([filterIndex], 3);
auxModel
здесь — объект вспомогательной модели, созданный нами с помощью
привычной функции
tf.model()
. У него тот же входной сигнал, что и у исходной
модели, но на выходе — активация заданного сверточного слоя. Мы вызываем метод
apply()
вспомогательной модели, чтобы получить значение активации слоя.
apply()
аналогичен методу
predict()
в том, что осуществляет прямой проход модели.
Впрочем,
apply()
обеспечивает более тонкие возможности управления, например
позволяет задать значение
true
опции
training
, как в предыдущей строке кода.
Без значения
true
опции
training
обратное распространение ошибки невозможно,
поскольку при прямом проходе выделяемая под промежуточные активации память
в конце освобождается для большей эффективности ее использования. Метод
apply()
при значении
true
флага
training
сохраняет эти внутренние активации, что
дает возможность выполнять обратное распространение ошибки. А вызов
gather()
извлекает активацию конкретного фильтра. Это необходимо, поскольку наиболее
активирующий входной сигнал вычисляется по каждому фильтру отдельно и ре
зультаты различаются для разных фильтров даже одного слоя (см. результаты при
мера на рис. 7.10).
Мы передаем нашу специальную функцию потерь в
tf.grad()
и получаем функ
цию, возвращающую градиент функции потерь по входному сигналу:
const gradFunction = tf.grad(lossFunction);
Важно понимать, что
tf.grad()
возвращает не сами значения градиента, а функ
цию (
gradFunction
в предыдущей строке кода), которая уже возвращает значения
градиента.
1
В случае меньших, чем VGG16, сверточных сетей (например, MobileNet и MobileNetV2)
этот алгоритм может отработать за приемлемое время и в браузере.
Do'stlaringiz bilan baham: |