Шаг 179.
Глубокое обучение на Python. Работа с Keras: глубокое погружение. Разные способы создания моделей Keras. Последовательная модель Sequential

    На этом шаге мы рассмотрим особенности использования этой модели.

    Самый простой способ создать модель Keras - использовать уже знакомый вам класс моделей Sequential.


Пример 7.1. Класс Sequential
from tensorflow import keras
from tensorflow.keras import layers

model = keras.Sequential([
    layers.Dense(64, activation="relu"),
    layers.Dense(10, activation="softmax")
])

    Обратите внимание, что эту модель также можно построить, последовательно вызывая метод add(), который действует подобно методу append() списков в языке Python.


Пример 7.2. Последовательное создание модели Sequential
model = keras.Sequential()
model.add(layers.Dense(64, activation="relu"))
model.add(layers.Dense(10, activation="softmax"))

    Мы знаем, что слои (точнее, их веса) создаются только в момент первого вызова. Причина подобного поведения в том, что форма слоев зависит от формы входных данных: пока форма входных данных неизвестна, слои не могут быть созданы.

    В силу этого предыдущая модель Sequential не будет иметь весов (пример 7.3) до передачи ей некоторых данных или до вызова ее метода build() с описанием формы входных данных (пример 7.4).


Пример 7.3. Непостроенные модели не имеют весов
print(model.weights) # В этой точке модель еще не построена

[]

Пример 7.4. Первый вызов модели для ее построения
# Этот вызов построит модель - после него модель будет 
# готова принимать образцы с формой (3,). 
# None в форме входных данных означает, 
# что размер пакета может быть любым
model.build(input_shape=(None, 3))
# Теперь можно получить веса модели
print(model.weights)

[<KerasVariable shape=(3, 64), dtype=float32, path=sequential_4/dense_8/kernel>, 
<KerasVariable shape=(64,), dtype=float32, path=sequential_4/dense_8/bias>, 
<KerasVariable shape=(64, 10), dtype=float32, path=sequential_4/dense_9/kernel>, 
<KerasVariable shape=(10,), dtype=float32, path=sequential_4/dense_9/bias>]

    После того как модель будет построена, ее содержимое можно вывести вызовом метода summary(), что очень удобно на этапе отладки. Пример 7.5. Метод summary()

print(model.summary())

Model: "sequential_1"
 Layer (type)                          Output Shape                         Param # 
 dense_2 (Dense)                       (None, 64)                             256 
 dense_3 (Dense)                       (None, 10)                             650

 Total params: 906 (3.54 KB)
 Trainable params: 906 (3.54 KB)
 Non-trainable params: 0 (0.00 B)

    Как видите, эта модель получила имя sequential_1. В Keras имя можно присвоить чему угодно - каждой модели, каждому слою.


Пример 7.6. Присваивание имен моделям и слоям путем передачи аргумента name
model = keras.Sequential(name="my_example_model")
model.add(layers.Dense(64, activation="relu", name="my_first_layer"))
model.add(layers.Dense(10, activation="softmax", name="my_last_layer"))
model.build((None, 3))
print(model.summary())

Model: "my_example_model"
 Layer (type)                          Output Shape                         Param # 
 my_first_layer (Dense)                (None, 64)                             256
 my_last_layer (Dense)                 (None, 10)                             650

 Total params: 906 (3.54 KB)
 Trainable params: 906 (3.54 KB)
 Non-trainable params: 0 (0.00 B)

    При пошаговом построении модели Sequential удобно иметь возможность посмотреть на ее текущее состояние после добавления очередного слоя. Но сводку невозможно получить, пока модель не построена! Эту проблему можно решить, строя модель Sequential на лету, для чего достаточно заранее объявить форму входных данных. Это можно сделать с помощью класса Input.


Пример 7.7. Предварительное определение формы входных данных модели с помощью класса Input
model = keras.Sequential()
# Использование Input для объявления формы входных данных. 
# Обратите внимание, что аргумент shape должен определять 
# форму одного образца, но не пакета
model.add(keras.Input(shape=(3,)))
model.add(layers.Dense(64, activation="relu"))

    Теперь вы сможете вызывать summary() и наблюдать, как меняется форма выходных данных модели по мере добавления дополнительных слоев:


print(model.summary())

Model: "sequential_2"
 Layer (type)                          Output Shape                         Param # 
 dense_4 (Dense)                       (None, 64)                             256

 Total params: 256 (1.00 KB)
 Trainable params: 256 (1.00 KB)
 Non-trainable params: 0 (0.00 B)

model.add(layers.Dense(10, activation="softmax"))
print(model.summary())

Model: "sequential_2"
 Layer (type)                          Output Shape                         Param # 
 dense_4 (Dense)                       (None, 64)                             256 
 dense_5 (Dense)                       (None, 10)                             650

 Total params: 906 (3.54 KB)
 Trainable params: 906 (3.54 KB)
 Non-trainable params: 0 (0.00 B)

Блокнот с этим примером можно взять здесь.

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

    На следующем шаге мы начнем знакомиться с функциональным API.




Предыдущий шаг Содержание Следующий шаг