考慮model.summary
函數的github repository。打印連接的功能是print_layer_summary_with_connections
(第76行),它只考慮來自relevant_nodes
陣列的節點。所有不在此陣列中的節點都被認爲是不是網絡的一部分,因此該功能會跳過它們。相關的線是線88-90:
if relevant_nodes and node not in relevant_nodes:
# node is not part of the current network
continue
2.您的模型
現在讓我們看看與您的特定模式會發生什麼。首先讓我們定義relevant_nodes
:
relevant_nodes = []
for v in model.nodes_by_depth.values():
relevant_nodes += v
數組relevant_nodes
的樣子:
[<keras.engine.topology.Node at 0x9dfa518>,
<keras.engine.topology.Node at 0x9dfa278>,
<keras.engine.topology.Node at 0x9d8bac8>,
<keras.engine.topology.Node at 0x9d8ba58>,
<keras.engine.topology.Node at 0x9d74518>]
然而,當我們在每一層打印入站節點,我們將得到:
for i in model.layers:
print(i.inbound_nodes)
[<keras.engine.topology.Node object at 0x0000000009D74518>]
[<keras.engine.topology.Node object at 0x0000000009D8BA58>]
[<keras.engine.topology.Node object at 0x0000000009D743C8>, <keras.engine.topology.Node object at 0x0000000009D8BAC8>]
[<keras.engine.topology.Node object at 0x0000000009DFA278>]
[<keras.engine.topology.Node object at 0x0000000009DFA518>]
你可以看到上面列表中只有一個節點沒有出現在relevant_nodes
中。這是在位置0中的第三陣列中的節點:
<keras.engine.topology.Node object at 0x0000000009D743C8>
它不被認爲是模型的一部分,並且因此沒有出現在relevant_nodes
。此陣列中位置1的節點確實出現在relevant_nodes
中,這就是爲什麼您將其看作model_1[1][0]
。
3。原因
原因是基本上行x=inner_model(input)
。即使您運行小得多模型,如下一個:
input_inner = Input(shape=(4,), name='input_inner')
output_inner = Dense(3, name='inner_dense')(input_inner)
inner_model = Model(inputs=input_inner, outputs=output_inner)
input = Input(shape=(5,), name='input')
output = inner_model(input)
model = Model(inputs=input, outputs=output)
你會看到relevant_nodes
包含兩個元素,同時通過
for i in model.layers:
print(i.inbound_nodes)
你會得到三個節點。
這是因爲第1層(上面的較小模型)有兩個節點,但只有第二個節點被認爲是模型的一部分。特別是,如果你在第1層與layer.get_input_at(node_index)
打印在節點中的每一個輸入,你會得到:
print(model.layers[1].get_input_at(0))
print(model.layers[1].get_input_at(1))
#prints
/input_inner
/input
4.Answers的問題在評論
1) Do you also know what this non-relevant node is good for/where it comes from?
該節點似乎是在應用inner_model
期間創建的「內部節點」。特別是,如果您打印在三個節點中的每一個輸入和輸出形狀(在上面的小模型),您可以:
nodes=[model.layers[0].inbound_nodes[0],model.layers[1].inbound_nodes[0],model.layers[1].inbound_nodes[1]]
for i in nodes:
print(i.input_shapes)
print(i.output_shapes)
print(" ")
#prints
[(None, 5)]
[(None, 5)]
[(None, 4)]
[(None, 3)]
[(None, 5)]
[(None, 3)]
,所以你可以看到,中間節點的形狀(一沒有出現在相關節點列表中)對應於inner_model
中的形狀。
2) Will an inner model with n output nodes always present them with node indices 1 to n instead of 0 to n-1?
我不知道,如果總是因爲我想有各種可能性有多個輸出節點的節點,但如果我認爲上方的小模型的下面很自然的推廣,這的確是這樣的:
input_inner = Input(shape=(4,), name='input_inner')
output_inner = Dense(3, name='inner_dense')(input_inner)
inner_model = Model(inputs=input_inner, outputs=output_inner)
input = Input(shape=(5,), name='input')
output = inner_model(input)
output = inner_model(output)
model = Model(inputs=input, outputs=output)
print(model.summary())
在這裏,我只是加了output = inner_model(output)
小模型。相關節點的名單
[<keras.engine.topology.Node at 0xd10c390>,
<keras.engine.topology.Node at 0xd10c9b0>,
<keras.engine.topology.Node at 0xd10ca20>]
和所有入站節點列表是
[<keras.engine.topology.Node object at 0x000000000D10CA20>]
[<keras.engine.topology.Node object at 0x000000000D10C588>, <keras.engine.topology.Node object at 0x000000000D10C9B0>, <keras.engine.topology.Node object at 0x000000000D10C390>]
節點的確指數爲1和2,當你在註釋中。如果我添加另一個output = inner_model(output)
,節點索引爲1,2,3等,它將繼續類似。
謝謝你非常深思熟慮的答案。你是否也知道這個不相關的節點對它來自哪裏有好處,或者如果具有'n'輸出節點的內部模型總是將它們以節點索引'1'到'n'而不是'0'呈現給'正1'? –
@TobiasHermann請參閱我在答案中添加的「評論中的問題的答案」部分。 –
太棒了,非常感謝。一個小問題:您的[最小化示例](https://ideone.com/JPD0sy)會產生一個錯誤:'ValueError:尺寸必須相同,但對於'model_1/inner_dense/MatMul'爲5和4(op:'MatMul '),輸入形狀爲:[?,5],[4,3]。' –