[Исходные заметки] Слой, тензор и узел анализа исходного кода Keras | Сяо Шуанлоу

искусственный интеллект TensorFlow глубокое обучение Keras компьютерное зрение

Основная логика архитектуры Keras реализована в/keras/engine/topology.py, есть в основном два базовых классаNode()иLayer(), важная функцияInput(). конкретно,

  • Layer()Это абстракция вычислительного уровня, которая завершает вычислительный процесс Tensor в сети;
  • Node()Абстракция, описывающая отношения связи между двумя слоями, координациюLayer()построить DAG;
  • Input()создание специальногоLayer(InputLayer),будетbackendТензорные объекты, созданные (TensorFlow или Theano), преобразуются в тензорные объекты Keras.

Keras Tensor: улучшенный тензор

По сравнению с исходными тензорными объектами TensorFlow или Theano, Keras Tensor добавляет следующие два свойства, так что Tensor содержит информацию об источнике и масштабе:

  • _Keras_history: сохраняет последний слой, примененный к этому тензору.
  • _keras_shape: стандартизированный интерфейс формы Keras

При построении глубокой сети с помощью Keras входящие данные сначала проходят черезInput()функция. существуетInput()функция, создать экземплярInputLayer()объект, и этоLayer()Объект в качестве первого слоя, примененного к входящему тензору, помещенному в_keras_historyв свойствах. также,InputLayer()иInput()Входящие данные также будут проверены на масштаб и преобразованы для соответствия требованиям последующих операций.

Код реализован следующим образом:

def Input():
  input_layer = InputLayer()
  outputs = InputLayer.inbound_nodes[0].output_tensor
  return outputs

class InputLayer():
  def __init__():
    input_tensor._keras_history = (self, 0, 0)
    Node(self, ...)

Ниже мы увидим, что добавленный_keras_historyРоль, которую атрибуты играют в построении вычислительных графов, имеет решающее значение. Только с входными и выходными тензорами мы можем построить весь вычислительный граф. Но цена этого в том, что объект Tensor слишком тяжелый и содержит информацию Layer.

NodeОбъекты: абстракции связей между слоями

если рассматриватьLayerАбстрактный объект — это тело клетки нейрона, которое завершает вычисление, затемNodeОбъект — это абстракция дендритной структуры нейрона. Главный посыл его сплоченности:

class Node():
  def __init__(self, outbound_layer,
              inbound_layers, node_indices, tensor_indices,
              input_tensors, output_tensors, ...)

вoutbound_layerприкладной расчет (созданиеinput_tensorsстатьoutput_tensors) слой,inbound_layersсоответствуетinput_tensorsисходный слой, аnode_indicesиtensor_indicesзаписаноNodeиLayerинформация о калибровке между.

Nodeобъект всегдаoutbound_layerСоздается при выполнении и добавляетсяoutbound_layerизinbound_nodesв свойствах. существуетNodeПри представлении объекта, когда два слоя A и B имеют отношения связи,Nodeобъект создан и добавленA.outbound_nodesиB.inbound_nodes.

LayerОбъект: Абстракция вычислительного слоя

LayerОбъект представляет собой абстракцию слоя нейронных вычислений в сети, и для его реализации требуются следующие параметры:

allowed_kwargs = {'input_shape',
                  'batch_input_shape',
                  'batch_size',
                  'dtype',
                  'name',
                  'trainable',
                  'weights',
                  'input_dtype',  # legacy
                  }

Большинство из них связаны с типом и масштабом поступающих данных,trainableУказывает, нужно ли слою обновлять веса. Помимо этого естьinbound_nodesиoutbound_nodesсвойства для калибровкиNodeссылка на объект.

LayerНаиболее важным методом объекта является__call__(), в основном выполнить следующие три вещи:

  1. Проверяйте достоверность входящих данных, вызывая внутренние методы:self.assert_input_compatibility(inputs)

  2. Расчетoutputs = self.call(inputs, ...), который конкретно реализуется его подклассами, такими какLinear, DropoutЖдать

  3. Обновите тензор в_keras_historyАтрибут, запись операции вычисления, через внутренний метод_add_inbound_nodes()выполнить

метод_add_inbound_nodes()Обновление для Tensor состоит в том, чтобы построитьLayerКлючевые операции отношения между двумя основными кодами выглядят следующим образом:

for x in input_tensors:
    if hasattr(x, '_keras_history'):
        inbound_layer, node_index, tensor_index = x._keras_history
        inbound_layers.append(inbound_layer)
        node_indices.append(node_index)
        tensor_indices.append(tensor_index)

# Node对象的建立过程中将更新self的inbound_nodes属性
Node(self,
    inbound_layers=inbound_layers,
    node_indices=node_indices,
    tensor_indices=tensor_indices,
    ...)

for i in range(len(output_tensors)):
     output_tensors[i]._keras_history = (self, len(self.inbound_nodes) - 1, i)

Удалите предыдущий кодinput_tensorиз_keras_historyсвойства, создавать новыеNode, и установите текущийLayerинформация обновляется до расчетногоoutput_tensorсередина.

Пример:Node,TensorиLayerПредставление взаимосвязи

Следующий код иллюстрирует взаимосвязь между тремя из тестового кода:

# 建立新的keras Tensor
a = Input(shape=(32,), name='input_a')
b = Input(shape=(32,), name='input_b')

a_layer, a_node_index, a_tensor_index = a._keras_history
assert len(a_layer.inbound_nodes) == 1
assert a_tensor_index is 0

# node和layer之间的关系
node = a_layer.inbound_nodes[a_node_index]
assert node.outbound_layer == a_layer

# 建立连接层,将Tensor传入
dense = Dense(16, name='dense_1')
a_2 = dense(a)
b_2 = dense(b)

assert len(dense.inbound_nodes) == 2
assert len(dense.outbound_nodes) == 0

# 与张量a关联的Node
assert dense.inbound_nodes[0].inbound_layers == [a_layer]
assert dense.inbound_nodes[0].outbound_layer == dense
assert dense.inbound_nodes[0].input_tensors == [a]

# 与张量b关联的Node
assert dense.inbound_nodes[1].inbound_layers == [b_layer]
assert dense.inbound_nodes[1].outbound_layer == dense
assert dense.inbound_nodes[1].input_tensors == [b]

Суммировать

Керас эксплуатируетNodeописание объектаLayerсвязь междуTensorзафиксировать его исходную информацию. существуетСледующийВ разделе мы увидим, как keras создает DAG с этими абстракциями и свойствами расширения, а также обеспечивает прямое распространение и обратное обучение.

@ddlee

Creative Commons License@ddlee
Эта статья соответствуетCreative Commons Attribution-ShareAlike 4.0 International License.
Это означает, что вы можете воспроизводить эту статью с указанием авторства, сопровождаемой этим соглашением.
Если вы хотите получать регулярные обновления о моих сообщениях в блоге, пожалуйста, подпишитесьДонгдон ежемесячно.
Ссылка на эту статью:блог Достиг ой возможности /posts/4943 ой…


Статьи по Теме