Введение
Простейшие примеры Keras API models
Исходник для тестирования Keras API models
Functional API model с двумя ветвями
Полезные ссылки
Введение
При использовании Sequential API мы создаем модель слой за слоем. Это очень просто и удобно. Но Functional API более мощный, чем Sequential API, в том смысле, что здесь разрешено ветвление или совместное использование слоев. А также у него может быть несколько входов и выходов.
Keras позволяет использовать различные типы данных, используя структуру с несколькими входами через функциональный API . А затем вы можете объединить их для создания единой модели машинного обучения. Основная идея такая:
Например, в медицинском приложении, которое в основном полагается на изображение, также можно учитывать пол, возраст и т. п.
Numeric values, such as age, heart rate, blood pressure
Categorical values, including gender and ethnicity
Image data, such as any MRI, X-ray, etc.
Простейшие примеры Keras API models
Ниже приведены примеры использования Sequential и Functional API а также Model Subclassing для создания одной и той же модели (последовательной):
Sequential API
В Sequential API нам нужно создать объект Sequential из модуля tensorflow.keras.models. Затем просто передаем все слои как один аргумент в формате списка.
import tensorflow as tf from tensorflow.keras.layers import * from tensorflow.keras.models import Sequential l0= Dense(units=3, input_shape=[2]) ln = Dense(units=2) model = Sequential([l0,ln]) model.summary()
Вывод результата на печать:
Общее количество параметров в сети 17 (веса связей и смещения). Для слоя dense количество параметров равно 9. Это получается следующим образом: 2 (количество входов) * 3 (количество нейронов в скрытом слое) + 3 (смещения — по одному на нейрон в скрытом слое). Для слоя dense_1 количество параметров равно 8: 3 (нейроны на скрытом слое) * 2 (нейроны на выходном слое) + 2 (значения смещения для нейронов на выходном слое). Подробнее см. Keras model.summary() результат-понимание # параметров
Functional API
Весь функциональный API строится на конструкции, которая текущий слой layer связывает с previous_layer:
layer = Layer(*args)(previos_layer)
При использовании функционального API нам нужно отдельно определять экземпляр класса Input(), который в качестве параметра принимает аргумент shape, который обозначает форму входных данных.. Затем нам нужно создать выходной объект, также создав все слои, которые связаны друг с другом и с выходом. Наконец, мы создаем объект класса models, который будет принимать входные и выходные данные в качестве аргументов.
import tensorflow as tf from tensorflow.keras.layers import * from tensorflow.keras.models import Model l0 = Input(2) l1 = Dense(3)(l0) ln = Dense(2)(l1) model = Model(inputs=l0,outputs=ln) model.summary()
Вывод результата на печать:
Model Subclassing
При создании подклассов модели мы начинаем с создания класса, расширяющего класс tf.keras.Model. В подклассе модели есть две важные функции:
- Функция __init__ действует как конструктор. Благодаря __init__ мы можем инициализировать атрибуты ( например, слои ) нашей модели.
- super вызывает родительский конструктор (конструктор в tf.keras.Model ), а self используется для ссылки на атрибуты экземпляра ( например, слои ).
- Функция call — это то место, где операции определяются после определения слоев в функции __init__ .
from tensorflow.keras.layers import * from tensorflow.keras.models import Model import numpy as np class CustomModel(Model): def __init__(self, **kwargs): super(CustomModel, self).__init__(**kwargs) self.layer_1 = Flatten() self.layer_2 = Dense(3) self.layer_3 = Dense(2) def call(self, inputs): x = self.layer_1(inputs) x = self.layer_2(x) x = self.layer_3(x) return x model = CustomModel() model.compile(loss='mse') # Данные для обучения модели X = np.array([[1, 2]]) y= np.array([[2, 3]]) # Обучение модели history = model.fit(X, y, epochs=100, verbose=False) model.summary()
Функция flatten сглаживает многомерные входные тензоры в одно измерение, поэтому вы можете смоделировать свой входной слой и построить модель нейронной сети, а затем эффективно передать эти данные в каждый нейрон модели. На рисунке ниже для сравнения приводится результат выполнения кода без функции flatten и с ней.
from tensorflow.keras.layers import * from tensorflow.keras.models import Sequential import numpy as np model = Sequential() model.add(Dense(4, input_shape=(3,2))) model.add(Flatten()) model.compile() model.summary() x = np.array([[[1, 2], [3, 4], [5, 6]]]) y = model.predict(x) print (y) print (y.shape)
В примере входная форма в слой Flatten (1,3,4) была изменена к форме (1, 12). Сглаживание тензора означает удаление всех измерений, кроме одного. Это именно то, что делает слой Flatten. Операция сглаживания тензора изменяет форму тензора, чтобы он имел форму, равную количеству элементов, содержащихся в тензоре, без учета размера партии. По сути реализуется действие, обратное делению dataset на партии.
Исходник для тестирования Keras API models
import tensorflow as tf from tensorflow.keras.layers import * from tensorflow.keras.models import Sequential from tensorflow.keras.models import Model import numpy as np import matplotlib.pyplot as plt np.random.seed(100) #activation="linear" relu sigmoid tanh softmax softplus ... #Sequential API "" l0 = Dense(units=3,activation="sigmoid", input_shape=[2]) l1 = Dense(units=3) l2 = Dense(units=2) # By default, Linear Activation is used model = Sequential([l0, l1,l2]) "" #Functional API l0 = Input(2) l1 = Dense(3, activation='sigmoid')(l0) l2 = Dense(3)(l1) ln = Dense(2)(l2) model = Model(inputs=l0,outputs=ln) #Model Subclassing "" class CustomModel(Model): def __init__(self, **kwargs): super(CustomModel, self).__init__(**kwargs) self.layer_1 = Flatten() self.layer_2 = Dense(3) self.layer_3 = Dense(3) self.layer_4 = Dense(2) def call(self, inputs): x = self.layer_1(inputs) x = self.layer_2(x) x = self.layer_3(x) x = self.layer_4(x) return x model = CustomModel(name='my_model') "" model.compile(loss='mse', metrics='mae', optimizer=tf.keras.optimizers.Adam(0.1)) # Данные для обучения модели X = np.array([[1, 2], [3, 4], [5, 6]], dtype=float) #y= np.array([[2, 3], [4, 5],[6, 7]], dtype=float) # линейные преобразования y= np.array([[2, 3], [4, 5], [7, 8]], dtype=float) # нелинейные преобразования # Обучение модели history = model.fit(X, y, epochs=100, verbose=False) model.summary() # Данные для оценивания модели #X = np.array([[2, 3], [4, 5],[6, 7]], dtype=float) #y= np.array([[3, 4], [5, 6], [8, 9]], dtype=float) print("\nОценивание модели") print("Данные на входе:") print(X) print("Ожидаемый результат:") print(y) # Оценивание модели mse,mae = model.evaluate(X, y, verbose=False) print('\nmse:',mse) print('mae:',mae) result=model.predict(X) print('\nПолученный результат:\n',result) print("\nВывод на плоттер history loss(mse) и mae") f, (ax1, ax2) = plt.subplots(1, 2) plt.xlabel('Epoch') ax1.set_title('loss (mse)') ax1.plot(history.history['loss']) ax2.set_title('mae') ax2.plot(history.history['mae']) plt.show()
Functional API model с двумя ветвями
Используем архитектуру модели НС с двумя ветвями для решения задачи калибровки проектора:
import tensorflow as tf from tensorflow.keras.layers import * from tensorflow.keras.models import Model import numpy as np up_input = Input(shape=(1)) up_branch = Dense(3)(up_input) up_out = Dense(1)(up_branch) down_input = Input(shape=(1)) down_branch = Dense(3)(down_input) down_out = Dense(1)(down_branch) layer_cb = concatenate([up_out, down_out]) layer_cb1 = Dense(1)(layer_cb) layer_out = Dense(2)(layer_cb) model = Model(inputs=[up_input, down_input], outputs=layer_out) model.summary() input_data_1=np.array([[1], [3], [5]], dtype=float) input_data_2=np.array([[2], [4], [6]], dtype=float) targets=np.array([[2, 3], [4, 5], [7, 8]], dtype=float) print (input_data_1) print (input_data_2) print (targets) model.compile(loss='mse', metrics='mae', optimizer=tf.keras.optimizers.Adam(0.1)) model.fit([input_data_1, input_data_2], targets, epochs=100, verbose=False) y = model.predict([input_data_1, input_data_2]) print (y) print (y.shape)
Параметры модели:
см. A `Concatenate` layer should be called on a list of at least 2 inputs и Understanding Concatenate
from tensorflow.keras.layers import Concatenate import numpy as np #Preparing for 2D Tensor x1 = np.array([[1, 2], [3, 4], [5, 6]]) x2 = np.array([[1, 2], [3, 4], [5, 6]]) #Concantenate Layer # axis = 0,Vertical coupling y1 = Concatenate(axis=0)([x1,x2]) print('y1=',y1)
Полезные ссылки:
- Функциональный API библиотеки Keras
- Какова роль Flatten в Керасе?
- 3 способа создания нейронных сетей в TensorFlow с помощью API Keras
- Keras functional API for Python deep learning
- Functional API model with Tensorflow 2.0 (Y-network)
- Understanding Concatenate
- Keras: создание модели нейронной сети с несколькими входами и смешанными входами данных.
- A `Concatenate` layer should be called on a list of at least 2 inputs
- How to Use the Keras Functional API for Deep Learning
- guide/keras/sequential_model
- guide/keras/functional
- Your First Deep Learning Project in Python with Keras Step-By-Step
- How to Index, Slice and Reshape NumPy Arrays for Machine Learning
- 3 ways to create a Keras model with TensorFlow 2.0 (Sequential, Functional, and Model Subclassing)
- Keras: Multiple Inputs and Mixed Data
- How do I combine models trained on different data to increase classification accuracy?
- Understanding Sequential Vs Functional API in Keras