Посмотреть на TensorFlow.org | Запустить в Google Colab | Посмотреть исходный код на GitHub | Скачать блокнот |
Мы рекомендуем использовать tf.keras
в качестве высокоуровневого API для построения нейронных сетей. Тем не менее, большинство API-интерфейсов TensorFlow можно использовать с быстрым выполнением.
import tensorflow as tf
print(tf.config.list_physical_devices('GPU'))
[PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]
Слои: общие наборы полезных операций
Большую часть времени при написании кода для моделей машинного обучения вы хотите работать на более высоком уровне абстракции, чем отдельные операции и манипулирование отдельными переменными.
Многие модели машинного обучения можно выразить как композицию и наложение относительно простых слоев, а TensorFlow предоставляет как набор многих общих слоев, так и простые способы написания собственных слоев для конкретного приложения либо с нуля, либо в виде композиции слоев. существующие слои.
TensorFlow включает в себя полный API Keras в пакете tf.keras, а слои Keras очень полезны при создании собственных моделей.
# In the tf.keras.layers package, layers are objects. To construct a layer,
# simply construct the object. Most layers take as a first argument the number
# of output dimensions / channels.
layer = tf.keras.layers.Dense(100)
# The number of input dimensions is often unnecessary, as it can be inferred
# the first time the layer is used, but it can be provided if you want to
# specify it manually, which is useful in some complex models.
layer = tf.keras.layers.Dense(10, input_shape=(None, 5))
Полный список уже существующих слоев можно увидеть в документации . Он включает в себя Dense (полностью подключенный слой), Conv2D, LSTM, BatchNormalization, Dropout и многие другие.
# To use a layer, simply call it.
layer(tf.zeros([10, 5]))
<tf.Tensor: shape=(10, 10), dtype=float32, numpy= array([[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], [0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)>
# Layers have many useful methods. For example, you can inspect all variables
# in a layer using `layer.variables` and trainable variables using
# `layer.trainable_variables`. In this case a fully-connected layer
# will have variables for weights and biases.
layer.variables
[<tf.Variable 'dense_1/kernel:0' shape=(5, 10) dtype=float32, numpy= array([[-0.4370762 , 0.6231566 , -0.44082257, -0.48535 , 0.17860883, -0.521853 , -0.45774594, -0.5409817 , 0.29194772, -0.18690601], [ 0.3304953 , -0.27142242, -0.48322448, -0.19328138, -0.14415592, 0.05973059, 0.56227285, 0.5323917 , -0.4914217 , 0.62182254], [-0.5313885 , 0.54680306, 0.1632638 , -0.10741419, -0.04727739, -0.35414204, 0.07529551, -0.06515282, -0.19732419, 0.25217015], [ 0.49743277, 0.31172627, 0.04989761, 0.1200847 , 0.42642146, 0.5887727 , 0.5771937 , 0.08720696, 0.43024355, -0.17298424], [-0.07610255, 0.04131562, 0.3136508 , -0.6197298 , 0.2331146 , 0.04888463, -0.54215366, 0.41208786, 0.27439958, 0.08524591]], dtype=float32)>, <tf.Variable 'dense_1/bias:0' shape=(10,) dtype=float32, numpy=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)>]
# The variables are also accessible through nice accessors
layer.kernel, layer.bias
(<tf.Variable 'dense_1/kernel:0' shape=(5, 10) dtype=float32, numpy= array([[-0.4370762 , 0.6231566 , -0.44082257, -0.48535 , 0.17860883, -0.521853 , -0.45774594, -0.5409817 , 0.29194772, -0.18690601], [ 0.3304953 , -0.27142242, -0.48322448, -0.19328138, -0.14415592, 0.05973059, 0.56227285, 0.5323917 , -0.4914217 , 0.62182254], [-0.5313885 , 0.54680306, 0.1632638 , -0.10741419, -0.04727739, -0.35414204, 0.07529551, -0.06515282, -0.19732419, 0.25217015], [ 0.49743277, 0.31172627, 0.04989761, 0.1200847 , 0.42642146, 0.5887727 , 0.5771937 , 0.08720696, 0.43024355, -0.17298424], [-0.07610255, 0.04131562, 0.3136508 , -0.6197298 , 0.2331146 , 0.04888463, -0.54215366, 0.41208786, 0.27439958, 0.08524591]], dtype=float32)>, <tf.Variable 'dense_1/bias:0' shape=(10,) dtype=float32, numpy=array([0., 0., 0., 0., 0., 0., 0., 0., 0., 0.], dtype=float32)>)
Реализация пользовательских слоев
Лучший способ реализовать свой собственный слой — расширить класс tf.keras.Layer и реализовать:
-
__init__
, где вы можете выполнить всю независимую от ввода инициализацию -
build
, где вы знаете формы входных тензоров и можете выполнить остальную часть инициализации -
call
, где вы выполняете форвардные вычисления
Обратите внимание, что вам не нужно ждать вызова build
для создания ваших переменных, вы также можете создать их в __init__
. Однако преимущество их создания в build
заключается в том, что это позволяет позднее создавать переменные на основе формы входных данных, с которыми будет работать слой. С другой стороны, создание переменных в __init__
будет означать, что формы, необходимые для создания переменных, должны быть указаны явно.
class MyDenseLayer(tf.keras.layers.Layer):
def __init__(self, num_outputs):
super(MyDenseLayer, self).__init__()
self.num_outputs = num_outputs
def build(self, input_shape):
self.kernel = self.add_weight("kernel",
shape=[int(input_shape[-1]),
self.num_outputs])
def call(self, inputs):
return tf.matmul(inputs, self.kernel)
layer = MyDenseLayer(10)
_ = layer(tf.zeros([10, 5])) # Calling the layer `.builds` it.
print([var.name for var in layer.trainable_variables])
['my_dense_layer/kernel:0']
В целом код легче читать и поддерживать, если он по возможности использует стандартные слои, так как другие читатели будут знакомы с поведением стандартных слоев. Если вы хотите использовать слой, которого нет в tf.keras.layers
, рассмотрите возможность регистрации проблемы на github или, что еще лучше, отправьте нам запрос на включение!
Модели: Составление слоев
Многие интересные многослойные вещи в моделях машинного обучения реализуются путем составления существующих слоев. Например, каждый остаточный блок в реснете представляет собой композицию сверток, пакетных нормализации и ярлыка. Слои могут быть вложены в другие слои.
Обычно вы наследуете от keras.Model
, когда вам нужны методы модели, такие как: Model.fit
, Model.evaluate
и Model.save
(подробности см. в разделе Пользовательские слои и модели Keras).
Еще одна функция, предоставляемая keras.Model
(вместо keras.layers.Layer
), заключается в том, что в дополнение к отслеживанию переменных keras.Model
также отслеживает свои внутренние слои, что упрощает их проверку.
Например, вот блок ResNet:
class ResnetIdentityBlock(tf.keras.Model):
def __init__(self, kernel_size, filters):
super(ResnetIdentityBlock, self).__init__(name='')
filters1, filters2, filters3 = filters
self.conv2a = tf.keras.layers.Conv2D(filters1, (1, 1))
self.bn2a = tf.keras.layers.BatchNormalization()
self.conv2b = tf.keras.layers.Conv2D(filters2, kernel_size, padding='same')
self.bn2b = tf.keras.layers.BatchNormalization()
self.conv2c = tf.keras.layers.Conv2D(filters3, (1, 1))
self.bn2c = tf.keras.layers.BatchNormalization()
def call(self, input_tensor, training=False):
x = self.conv2a(input_tensor)
x = self.bn2a(x, training=training)
x = tf.nn.relu(x)
x = self.conv2b(x)
x = self.bn2b(x, training=training)
x = tf.nn.relu(x)
x = self.conv2c(x)
x = self.bn2c(x, training=training)
x += input_tensor
return tf.nn.relu(x)
block = ResnetIdentityBlock(1, [1, 2, 3])
_ = block(tf.zeros([1, 2, 3, 3]))
block.layers
[<keras.layers.convolutional.Conv2D at 0x7fc7e439bf90>, <keras.layers.normalization.batch_normalization.BatchNormalization at 0x7fc7dc1e5dd0>, <keras.layers.convolutional.Conv2D at 0x7fc7dc1a1cd0>, <keras.layers.normalization.batch_normalization.BatchNormalization at 0x7fc7dc12c490>, <keras.layers.convolutional.Conv2D at 0x7fc7dc12c8d0>, <keras.layers.normalization.batch_normalization.BatchNormalization at 0x7fc7dc12cf50>]
len(block.variables)
18
block.summary()
Model: "" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d (Conv2D) multiple 4 batch_normalization (BatchN multiple 4 ormalization) conv2d_1 (Conv2D) multiple 4 batch_normalization_1 (Batc multiple 8 hNormalization) conv2d_2 (Conv2D) multiple 9 batch_normalization_2 (Batc multiple 12 hNormalization) ================================================================= Total params: 41 Trainable params: 29 Non-trainable params: 12 _________________________________________________________________
Однако в большинстве случаев модели, состоящие из множества слоев, просто вызывают один слой за другим. Это можно сделать в очень небольшом коде, используя tf.keras.Sequential
:
my_seq = tf.keras.Sequential([tf.keras.layers.Conv2D(1, (1, 1),
input_shape=(
None, None, 3)),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Conv2D(2, 1,
padding='same'),
tf.keras.layers.BatchNormalization(),
tf.keras.layers.Conv2D(3, (1, 1)),
tf.keras.layers.BatchNormalization()])
my_seq(tf.zeros([1, 2, 3, 3]))
<tf.Tensor: shape=(1, 2, 3, 3), dtype=float32, numpy= array([[[[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]], [[0., 0., 0.], [0., 0., 0.], [0., 0., 0.]]]], dtype=float32)>
my_seq.summary()
Model: "sequential" _________________________________________________________________ Layer (type) Output Shape Param # ================================================================= conv2d_3 (Conv2D) (None, None, None, 1) 4 batch_normalization_3 (Batc (None, None, None, 1) 4 hNormalization) conv2d_4 (Conv2D) (None, None, None, 2) 4 batch_normalization_4 (Batc (None, None, None, 2) 8 hNormalization) conv2d_5 (Conv2D) (None, None, None, 3) 9 batch_normalization_5 (Batc (None, None, None, 3) 12 hNormalization) ================================================================= Total params: 41 Trainable params: 29 Non-trainable params: 12 _________________________________________________________________
Следующие шаги
Теперь вы можете вернуться к предыдущей записной книжке и адаптировать пример линейной регрессии, чтобы лучше структурировать слои и модели.