Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Шолле Ф. - Глубокое обучение на Python (Библиотека программиста) - 2023.pdf
Скачиваний:
6
Добавлен:
07.04.2024
Размер:
11.34 Mб
Скачать

7.2.Разные способы создания моделей Keras    239

7.2.3.Создание производных от класса Model

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

. в.методе.__init __().определяются.слои,.которые.будет.использовать.модель;

.в.методе.call() .с.помощью.созданных.ранее.слоев.определяется.порядок. выполнения.прямого.прохода.модели;

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

Реализация предыдущего примера созданием производного класса от класса Model

Рассмотрим.простой.пример:.реализуем.модель.управления.заявками.в.службу. поддержки.клиентов,.создав.производный.класс.от.класса.Model.

Листинг 7.14. Простой подкласс моделей class CustomerTicketModel(keras.Model):

def __init__(self, num_departments):

Не забудьте вызвать super() —

конструктор родительского класса!

super().__init__()

 

 

 

self.concat_layer = layers.Concatenate()

 

 

 

 

self.mixing_layer = layers.Dense(64, activation="relu")

 

self.priority_scorer = layers.Dense(1, activation="sigmoid")

 

self.department_classifier = layers.Dense(

 

num_departments, activation="softmax")

 

def call(self, inputs):

 

 

Определите слои

 

 

в конструкторе

 

 

title = inputs["title"]

 

 

 

text_body = inputs["text_body"]

 

Определите порядок выполнения

tags = inputs["tags"]

 

прямого прохода в методе call()

features = self.concat_layer([title, text_body, tags]) features = self.mixing_layer(features)

priority = self.priority_scorer(features) department = self.department_classifier(features) return priority, department

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

model = CustomerTicketModel(num_departments=4)

priority, department = model(

{"title": title_data, "text_body": text_body_data, "tags": tags_data})

Структура цели должна точно соответствовать тому, что возвращает метод call(), — в данном случае это список с двумя элементами
Структура входных данных должна точно соответствовать структуре параметров метода call() — в данном случае это словарь с ключами title, text_body и tags

240    Глава 7. Работа с Keras: глубокое погружение

Пока.не.видно.никаких.отличий.от.подклассов.Layer,.которые.мы.создавали.в.главе.3..В.чем.же.тогда.разница.между.подклассом.Layer .и.подклассом. Model?.Все.просто:.слой.—.это.просто.блок,.используемый.при.строительстве. моделей,.а.модель.—.объект.более.высокого.уровня,.который.вы.будете.об- учать,.экспортировать.для.прогнозирования.и.т..д..Проще.говоря,.класс.Model . имеет .методы .fit(), .evaluate() .и .predict(), .а .у .слоев .этих .методов .нет.. В.остальном.данные.два.класса.практически.идентичны..(Еще.одно.отличие:. модель.можно.сохранить .в.файл.на.диске,.о.чем.мы.расскажем.несколькими. разделами.позже.)

Компиляция.и.обучение.подкласса.Model .производятся.точно.так.же,.как.компиляция.последовательных.или.функциональных.моделей:

Структура аргументов, передаваемых в параметрах loss и metrics, должна точно соответствовать тому, что возвращает call() — в данном случае это списки с двумя элементами

model.compile(optimizer="rmsprop",

loss=["mean_squared_error", "categorical_crossentropy"], metrics=[["mean_absolute_error"], ["accuracy"]])

model.fit({"title": title_data, "text_body": text_body_data, "tags": tags_data},

[priority_data, department_data], epochs=1)

model.evaluate({"title": title_data, "text_body": text_body_data, "tags": tags_data}, [priority_data, department_data])

priority_preds, department_preds = model.predict({"title": title_data, "text_body": text_body_data, "tags": tags_data})

Прием,.основанный.на.создании.подклассов.класса.Model .—.наиболее.гибкий. способ.построения.модели..Он.позволяет.конструировать.модели,.которые. нельзя.выразить.в.форме.ориентированного.ациклического.графа.слоев;.представьте,.например,.модель,.в.которой.метод.call() .использует.слои.внутри. цикла.for .или.даже.вызывает.их.рекурсивно..В.подклассе.Model .такое.возмож- но.—.главные.здесь.вы.

Будьте внимательны: что не поддерживают подклассы класса Model

За.такую.свободу.приходится.платить:.определяя.свои.подклассы.класса.Model,. вы.отвечаете.за.реализацию.большей.части.логики.работы.модели,.поэтому. вероятность.допустить.ошибку.намного.больше..Как.следствие,.вам.придется. больше.времени.потратить.на.отладку..Теперь.вы.разрабатываете.новый.объект. на.Python,.а.не.просто.собираете.вместе.кубики.лего.

7.2. Разные способы создания моделей Keras    241

Кроме.того,.модели.на.основе.подклассов.по.своей.природе.существенно.от- личаются.от.функциональных.моделей..Функциональная.модель.—.это.явная. структура.данных:.граф.слоев,.который.можно.просматривать,.исследовать.и.из- менять..Модель.на.основе.подкласса.—.это.фрагмент.байт-кода,.класс.Python. с.методом.call(),.который.содержит.нестандартный.код..Подклассы.дают.до- полнительную.гибкость.—.вы.можете.реализовать.любые.функции,.какие.только. пожелаете..Но.также.это.накладывает.определенные.ограничения.

Например,.поскольку.способ.соединения.слоев.друг.с.другом.скрыт.в.теле.метода. call(),.вы.не.сможете.получить.доступ.к.этой.информации..Вызов.summary() . не.покажет.связи.между.слоями,.а.plot_model().не.сможет.построить.топологию. модели..Точно.так.же.вы.не.доберетесь.к.узлам.графа.слоев.в.модели.на.основе. подкласса,.чтобы.извлечь.признаки,.потому.что.графа.просто.не.существует..

После.создания.экземпляра.модели.логика.ее.прямого.прохода.становится.настоящим.черным.ящиком.

7.2.4. Смешивание и согласование различных компонентов

Важно.отметить,.что.выбор.одного.из.описанных.подходов.к.созданию.моде- лей.—.с.помощью.класса.Sequential,.функционального.API.или.путем.создания. подкласса.класса.Model .—.не.препятствует.использованию.других.подходов.. Все.модели.в.Keras.API.способны.беспрепятственно.взаимодействовать.друг. с.другом,.будь.то.модели.Sequential,.функциональные.модели.или.подклассы. класса.Model,.написанные.с.нуля..Все.они.являются.частью.общего.спектра. рабочих.процессов.

Например,.подкласс.класса.Layer .или.Model .можно.использовать.в.функциональной.модели.

Листинг 7.15. Создание функциональной модели, включающей подкласс класса Model

class Classifier(keras.Model):

def __init__(self, num_classes=2): super().__init__()

if num_classes == 2: num_units = 1 activation = "sigmoid"

else:

num_units = num_classes activation = "softmax"

self.dense = layers.Dense(num_units, activation=activation)

def call(self, inputs): return self.dense(inputs)

242    Глава 7. Работа с Keras: глубокое погружение

inputs = keras.Input(shape=(3,))

features = layers.Dense(64, activation="relu")(inputs) outputs = Classifier(num_classes=10)(features)

model = keras.Model(inputs=inputs, outputs=outputs)

И.наоборот,.функциональную.модель.можно.применить.в.подклассе.класса.

Layer .или.Model.

Листинг 7.16. Создание подкласса класса Model, использующего функциональную модель

inputs = keras.Input(shape=(64,))

outputs = layers.Dense(1, activation="sigmoid")(inputs) binary_classifier = keras.Model(inputs=inputs, outputs=outputs)

class MyModel(keras.Model):

def __init__(self, num_classes=2): super().__init__()

self.dense = layers.Dense(64, activation="relu") self.classifier = binary_classifier

def call(self, inputs):

features = self.dense(inputs) return self.classifier(features)

model = MyModel()

7.2.5. Используйте правильный инструмент

Вы.познакомились.со.спектром.рабочих.процессов.построения.моделей.Keras:. от.простейшего.процесса.создания.последовательной.модели.Sequential .до. самого .продвинутого, .основанного .на .создании .подклассов .класса .Model.. Но.в.каких.случаях.лучше.использовать.тот.или.другой.подход?.У.каждого.из. них.есть.свои.плюсы.и.минусы.—.выбирайте,.исходя.из.конкретной.стоящей. перед.вами.задачи.

Обычно.функциональный.API.является.хорошим.компромиссным.решением. в.плане.простоты.использования.и.гибкости..Он.открывает.прямой.доступ. к.связям.между.слоями,.что.может.пригодиться.при.отладке.процедуры.построения.модели.или.для.извлечения.признаков..Если.есть.возможность.взять. функциональный.API.—.например,.если.модель.можно.выразить.в.виде.ори- ентированного.ациклического.графа.слоев,.—.рекомендую.ею.воспользоваться. вместо.создания.подклассов.класса.Model.

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