Глава 5. Перенос обучения: переиспользование предобученных нейронных сетей
219
Следует отметить несколько важных нюансов кода из листинга 5.8.
z
z
После каждого блокирования или разблокирования слоев (изменяя значение их
атрибута
trainable
) необходимо еще раз вызвать метод
compile()
модели, чтобы
изменения вступили в силу. Мы уже упоминали это при обсуждении примера
transferlearning для MNIST в подразделе 5.1.1.
z
z
Часть данных выделяется для проверки того, насколько хорошо полученные зна
чения потерь и безошибочности отражают работу модели на данных, не виденных
ею во время обратного распространения ошибки. Впрочем, мы выделяем часть
собранных данных для проверки иначе, чем раньше, так что стоит остановиться
на этом подробнее.
z
z
В примере сверточной сети MNIST (см. листинг 4.2) последние 15–20 % данных
выделялись на проверку с помощью параметра
validationSplit
метода
Model.fit()
.
Здесь такой подход работает не слишком хорошо. Почему? А потому, что раз
мер обучающего набора данных в таком случае намного меньше объемов данных
в предыдущих примерах. В результате отделение вслепую нескольких последних
примеров данных для проверки может привести к недостаточной представленно
сти отдельных слов в проверочном подмножестве данных. Допустим, мы собрали
по восемь примеров данных для каждого из четырех слов:
feel
,
seal
,
veal
и
zeal
—
и взяли для проверки последние 25 % из 32 примеров данных (восемь примеров).
В среднем на каждое слово в проверочном подмножестве приходится по два
примера данных. Но изза случайности выбора на какието слова в проверочном
наборе придется лишь один пример данных, а на какието — вообще ни одного!
Ясно, что не содержащий определенных слов проверочный набор данных плохо
подходит для оценки безошибочности модели. Именно поэтому нам пришлось
воспользоваться собственной функцией (
balancedTrainValSplit
в листинге 5.8),
учитывающей истинные метки примеров данных и гарантирующей, что все слова
будут представлены должным образом как в обучающем, так и в проверочном
наборе. Рекомендуем вам поступать аналогичным образом для всех приложений
с переносом
обучения, в которых наборы данных столь же невелики.
Итак, что дает нам тонкая настройка? Какой дополнительный
вклад она вносит
после начального этапа переноса обучения? Для иллюстрации построим график
кривых потерь и безошибочности с начального этапа и этапа тонкой настройки,
объединив их в непрерывные кривые (рис. 5.12, блок A). Набор данных для пере
носа обучения здесь состоит из тех же четырех слов, которые мы уже видели на
рис. 5.9. Первые 100 эпох каждой кривой соответствуют начальному этапу, а по
следние 300 — этапу тонкой настройки. Как видите, к концу 100 эпох начального