Основная логика архитектуры 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__(), в основном выполнить следующие три вещи:
-
Проверяйте достоверность входящих данных, вызывая внутренние методы:
self.assert_input_compatibility(inputs) -
Расчет
outputs = self.call(inputs, ...), который конкретно реализуется его подклассами, такими какLinear,DropoutЖдать -
Обновите тензор в
_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 Attribution-ShareAlike 4.0 International License.
Это означает, что вы можете воспроизводить эту статью с указанием авторства, сопровождаемой этим соглашением.
Если вы хотите получать регулярные обновления о моих сообщениях в блоге, пожалуйста, подпишитесьДонгдон ежемесячно.
Ссылка на эту статью:блог Достиг ой возможности /posts/4943 ой…