TensorIterator#
バージョン名: TensorIterator-1
カテゴリー: インフラストラクチャー
簡単な説明: TensorIterator レイヤーは、body で記述されているネットワークの反復実行し、データを反復処理します。
TensorIterator 属性:
Body:
bodyは反復的に実行されるネットワークです。ネットワークは、典型的な IR ネットワークとしてレイヤーごとに記述されます。Body 属性:
利用可能な属性はありません。
ポートマップ:
port_map は、
TensorIteratorレイヤーの入力または出力データテンソルをbodyデータテンソルにマッピングするルールのセットです。port_mapエントリーはinputとoutputが可能です。各エントリーは、対応するマッピングルールを説明します。ポートマップ属性:
external_port_id
説明: external_port_id は
TensorIteratorレイヤーのポート ID です。値の範囲: TensorIterator 出力のインデックス
タイプ:
intデフォルト値: なし
必須: はい
internal_layer_id
説明: internal_layer_id は、マッピング先の
bodyネットワーク内のパラメーターまたは結果レイヤー ID です。値の範囲: TensorIterator レイヤー内のパラメーター・レイヤーの ID
タイプ:
intデフォルト値: なし
必須: はい
axis
説明: axis は反復処理の対象となる軸です。このテンソルのスライス化をトリガーします。指定された場合にのみ、対応する
inputまたはoutputが分割され、開始、終了、およびストライド属性でスライス化の方法が定義されます。値の範囲: 整数。
タイプ:
intデフォルト値: なし
必須: いいえ
start
説明: start は、反復が開始されるインデックスです。負の値はインデックスを最後からカウントすることを意味します。
axis属性が指定されている場合にのみ適用されます。値の範囲: 整数。
タイプ:
intデフォルト値: 0
必須: いいえ
end
説明: end は反復が終了するインデックスです。負の値はインデックスを最後からカウントすることを意味します。
axis属性が指定されている場合にのみ適用されます。値の範囲: 整数。
タイプ:
intデフォルト値: -1
必須: いいえ
stride
説明: stride は反復のステップです。負の値は後方からの反復を意味します。
axis属性が指定されている場合にのみ適用されます。値の範囲: 整数。
タイプ:
intデフォルト値: 1
必須: いいえ
バックエッジ:
back_edges は、ある反復での
body出力から次の反復へのbodyパラメーターにテンソル値を転送するルールのセットです。バックエッジは、body内の一部の結果レイヤーを同じbody内のパラメーター・レイヤーに接続します。バックエッジ属性:
from-layer
説明: from-layer は、
bodyネットワーク内の結果レイヤー ID です。値の範囲: TensorIterator 内の Result レイヤーの ID
タイプ:
intデフォルト値: なし
必須: はい
to-layer
説明: to-layer は、マッピングを終了する
bodyネットワーク内のパラメーター・レイヤー ID です。値の範囲: TensorIterator 内の Parameter レイヤーの ID
タイプ:
intデフォルト値: なし
必須: はい
入力
複数の入力: あらゆるタイプおよび形状のテンソルがサポートされるタイプ。
出力
複数の出力:
bodyの実行結果。あらゆるタイプと形状のテンソル。
詳細な説明
他のレイヤーと同様に、TensorIterator には通常セクションがあります: input と output。これにより、TensorIterator を残りの IR に接続できるようになります。TensorIterator にはいくつかの特別なセクションもあります: body、port_map、back_edges。これら動作原理を以下に説明します。
body がどのように反復されるか:
最初の反復時: TensorIterator は、指定された軸で入力テンソルをスライスし、指定された順序ですべてを反復処理します。body セクションで IR ネットワークで指定された任意のネットワークで入力テンソルを処理します。バックエッジが存在しないため、IR が実行されます。port map のエッジは、TensorIterator の入力ポートをボディー内の Parameters に接続するのに使用されます。
[inputs] - Port map edges -> [Parameters:body:Results]
Parameter および Result レイヤーは body の一部です。Parameters は、body 内の安定したエントリーポイントです。body の実行結果は、安定した Result レイヤーとして表示されます。安定状態はノードを融合できないことを意味します。
次の反復: バックエッジは、TensorIterator body の IR 反復間に、どのデータが結果レイヤーから Parameters レイヤーにコピーされるか定義します。つまり、データをソースレイヤーからターゲットレイヤーに渡します。バックエッジのターゲットである各レイヤーには、入力として受信 port map エッジもあります。バックエッジからの値が、port map の対応するエッジの代わりに使用されます。ネットワークの各反復の後、すべてのバックエッジが実行されます。反復は静的にアンロールされたシーケンスと考えることができます: つまり、2 つの隣接する反復間を流れるすべてのエッジはバックエッジです。したがって、アンロールされたループでは、各バックエッジが通常のエッジに変換されます。
… -> [Parameters:body:Results] - back-edges -> [Parameters:body:Results] - back-edges -> [Parameters:body:Results] - back-edges -> …
結果の計算:
Port map の output エントリーにパーティション化 (axis, begin, end, strides) 属性がない場合、TensorIterator の output の最終値は、最後の反復からの Result ノードの値になります。それ以外の場合、TensorIterator の output の最終値は、すべての body 反復の Result ノード内のテンソルの連結になります。連結順序は stride 属性で指定します。
最後の反復:
[Parameters:body:Results] - Port map edges -> [outputs] (パーティション化属性が設定されない場合)。
パーティション化属性がある場合、出力テンソルはすべてのボディー反復からのテンソルの連結になります。stride > 0 の場合:
output = Concat(S[0], S[1], ..., S[N-1])ここで、Si は、この出力ポートに対応するテンソル反復子ボディーの i 回目の反復における Result 操作の値です。stride < 0 の場合、出力は逆の順序で連結されます。
output = Concat(S[N-1], S[N-2], ..., S[0])例
例 1: 典型的な TensorIterator 構造
<layer type="TensorIterator" ... >
<input> ...</input>
<output>
...</output>
<port_map>
<input external_port_id="0" internal_layer_id="0" axis="1" start="-1" end="0" stride="-1"/>
<input external_port_id="1" internal_layer_id="1"/>
... <output external_port_id="3" internal_layer_id="2" axis="1" start="-1" end="0" stride="-1"/>
...</port_map>
<back_edges>
<edge from-layer="1" to-layer="1"/>
...</back_edges>
<body>
<layers> ...</layers>
<edges> ...</edges>
</body>
</layer>例 2: 完全な TensorIterator レイヤー
<layer type="TensorIterator" ...>
<input>
<port id="0">
<dim>1</dim>
<dim>25</dim>
<dim>512</dim>
</port>
<port id="1">
<dim>1</dim>
<dim>256</dim>
</port>
<port id="2">
<dim>1</dim>
<dim>256</dim>
</port>
</input>
<output>
<port id="3" precision="FP32">
<dim>1</dim>
<dim>25</dim>
<dim>256</dim>
</port>
</output>
<port_map>
<input axis="1" external_port_id="0" internal_layer_id="0" start="0"/>
<input external_port_id="1" internal_layer_id="3"/>
<input external_port_id="2" internal_layer_id="4"/>
<output axis="1" external_port_id="3" internal_layer_id="12"/>
</port_map>
<back_edges>
<edge from-layer="8" to-layer="4"/>
<edge from-layer="9" to-layer="3"/>
</back_edges>
<body>
<layers>
<layer id="0" type="Parameter" ...>
<output>
<port id="0" precision="FP32">
<dim>1</dim>
<dim>1</dim>
<dim>512</dim>
</port>
</output>
</layer>
<layer id="1" type="Const" ...>
<data offset="0" size="16"/>
<output>
<port id="1" precision="I64">
<dim>2</dim>
</port>
</output>
</layer>
<layer id="2" type="Reshape" ...>
<input>
<port id="0">
<dim>1</dim>
<dim>1</dim>
<dim>512</dim>
</port>
<port id="1">
<dim>2</dim>
</port>
</input>
<output>
<port id="2" precision="FP32">
<dim>1</dim>
<dim>512</dim>
</port>
</output>
</layer>
<layer id="3" type="Parameter" ...>
<output>
<port id="0" precision="FP32">
<dim>1</dim>
<dim>256</dim>
</port>
</output>
</layer>
<layer id="4" type="Parameter" ...>
<output>
<port id="0" precision="FP32">
<dim>1</dim>
<dim>256</dim>
</port>
</output>
</layer>
<layer id="5" type="Const" ...>
<data offset="16" size="3145728"/>
<output>
<port id="1" precision="FP32">
<dim>1024</dim>
<dim>768</dim>
</port>
</output>
</layer>
<layer id="6" type="Const" ...>
<data offset="3145744" size="4096"/>
<output>
<port id="1" precision="FP32">
<dim>1024</dim>
</port>
</output>
</layer>
<layer id="7" type="LSTMCell" ...>
<data hidden_size="256"/>
<input>
<port id="0">
<dim>1</dim>
<dim>512</dim>
</port>
<port id="1">
<dim>1</dim>
<dim>256</dim>
</port>
<port id="2">
<dim>1</dim>
<dim>256</dim>
</port>
<port id="3">
<dim>1024</dim>
<dim>768</dim>
</port>
<port id="4">
<dim>1024</dim>
</port>
</input>
<output>
<port id="5" precision="FP32">
<dim>1</dim>
<dim>256</dim>
</port>
<port id="6" precision="FP32">
<dim>1</dim>
<dim>256</dim>
</port>
</output>
</layer>
<layer id="8" type="Result" ...>
<input>
<port id="0">
<dim>1</dim>
<dim>256</dim>
</port>
</input>
</layer>
<layer id="9" type="Result" ...>
<input>
<port id="0">
<dim>1</dim>
<dim>256</dim>
</port>
</input>
</layer>
<layer id="10" type="Const" ...>
<data offset="3149840" size="24"/>
<output>
<port id="1" precision="I64">
<dim>3</dim>
</port>
</output>
</layer>
<layer id="11" type="Reshape" ...>
<input>
<port id="0">
<dim>1</dim>
<dim>256</dim>
</port>
<port id="1">
<dim>3</dim>
</port>
</input>
<output>
<port id="2" precision="FP32">
<dim>1</dim>
<dim>1</dim>
<dim>256</dim>
</port>
</output>
</layer>
<layer id="12" type="Result" ...>
<input>
<port id="0">
<dim>1</dim>
<dim>1</dim>
<dim>256</dim>
</port>
</input>
</layer>
</layers>
<edges>
<edge from-layer="0" from-port="0" to-layer="2" to-port="0"/>
<edge from-layer="1" from-port="1" to-layer="2" to-port="1"/>
<edge from-layer="2" from-port="2" to-layer="7" to-port="0"/>
<edge from-layer="3" from-port="0" to-layer="7" to-port="1"/>
<edge from-layer="4" from-port="0" to-layer="7" to-port="2"/>
<edge from-layer="5" from-port="1" to-layer="7" to-port="3"/>
<edge from-layer="6" from-port="1" to-layer="7" to-port="4"/>
<edge from-layer="7" from-port="6" to-layer="8" to-port="0"/>
<edge from-layer="7" from-port="5" to-layer="9" to-port="0"/>
<edge from-layer="7" from-port="5" to-layer="11" to-port="0"/>
<edge from-layer="10" from-port="1" to-layer="11" to-port="1"/>
<edge from-layer="11" from-port="2" to-layer="12" to-port="0"/>
</edges>
</body>
</layer>