TensorIterator#

バージョン名: TensorIterator-1

カテゴリー: インフラストラクチャー

簡単な説明: TensorIterator レイヤーは、body で記述されているネットワークの反復実行し、データを反復処理します。

TensorIterator 属性:

  • Body:

    body は反復的に実行されるネットワークです。ネットワークは、典型的な IR ネットワークとしてレイヤーごとに記述されます。

    • Body 属性:

      利用可能な属性はありません。

  • ポートマップ:

    port_map は、TensorIterator レイヤーの入力または出力データテンソルを body データテンソルにマッピングするルールのセットです。port_map エントリーは inputoutput が可能です。各エントリーは、対応するマッピングルールを説明します。

    • ポートマップ属性:

      • external_port_id

        • 説明: external_port_idTensorIterator レイヤーのポート 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 には通常セクションがあります: inputoutput。これにより、TensorIterator を残りの IR に接続できるようになります。TensorIterator にはいくつかの特別なセクションもあります: bodyport_mapback_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 mapoutput エントリーにパーティション化 (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>