クロの制作日記

tensorflowでのジャグ配列の扱い(tf.ragged.stackとtf.stack・tf.concatの違い)

最初に

Tensorflowではnumpyやlistのように標準のTensorオブジェクトではジャグ配列に対応していません。ですが、tf.raggedを使用すればジャグ配列にも対応することができます。

今回はそのtf.raggedの簡単な使い方とtf.concatやtf.ragged.stackの違いを解説していきます。

注意

動作環境はTensorflow2.0.0です。tf.ragged自体はtensorflow1.x系でも使えますが、tf.ragged.stackという関数はtensorflow1.15.0から実装されているので、注意してください。




ジャグ配列とは

そもそもジャグ配列とは以下の画像のように行ごとの要素数が不規則な行列なことです。

f:id:kurora-shumpei:20200427170013p:plain
配列とジャグ配列

行列計算を行う場合にはジャグ配列を使うことはないと思いますが、異なるデータを保存しておきたい場合などで使うことがあります。

Tensorflowでのジャグ配列

numpyやpythonのlistはジャグ配列に対応していますが、TensorflowのTensorオブジェクトではジャグ配列に対応していません。ただし、tf.raggedを使用して配列を作成、またはtf.raggedの関数を用いれればジャグ配列を作成することができます。

tf.ragged.constantで作成

ジャグ配列を定義するためには「tf.ragged_constant」を使用します

ragged_x = tf.ragged.constant([[0,1,2],[3,4],[5],[6,7,8,9]])
実行結果
<tf.RaggedTensor [[0, 1, 2], [3, 4], [5], [6, 7, 8, 9]]>

tf.concatで作成

tf.ragged.constantで作成した配列ならtf.concatでジャグ配列にすることができます。

array_x = tf.ragged.constant([[0,1,2]])
array_y = tf.ragged.constant([[3,4,5,6,7]])
ragged_xy_0 = tf.concat([array_x, array_y], axis=0)

print(ragged_xy_0)
実行結果
<tf.RaggedTensor [[0, 1, 2], [3, 4, 5, 6, 7]]>

tf.stackで作成

同様にtf.stackでジャグ配列にすることもできます。

array_x = tf.ragged.constant([[0,1,2]])
array_y = tf.ragged.constant([[3,4,5,6,7]])
ragged_xy_0 = tf.stack([array_x, array_y], axis=0)

print(ragged_xy_0)
実行結果
<tf.RaggedTensor [[[0, 1, 2]], [[3, 4, 5, 6, 7]]]>

tf.ragged.stackで作成

tf.ragged.stackでもtf.stackと同じような事ができます。

array_x = tf.ragged.constant([[0,1,2]])
array_y = tf.ragged.constant([[3,4,5,6,7]])
ragged_xy_1 = tf.ragged.stack([array_x, array_y], axis=0)

print(ragged_xy_1)
実行結果
<tf.RaggedTensor [[[0, 1, 2]], [[3, 4, 5, 6, 7]]]>

tf.ragged.stackとtf.stack・tf.concatの違い

tf.cocast・tf.stackは渡した配列がRaggedTenosrでないとジャグ配列になりませんが、tf.ragged.stackはTensorオブジェクトでもジャグ配列にすることができます。

tf.concat
tensor_array_x = tf.convert_to_tensor([[0,1,2]])
tensor_array_y = tf.convert_to_tensor([[3,4,5,6,7]])

ragged_xy_2 = tf.concat([tensor_array_x,tensor_array_y],axis=0)
ragged_xy_2 = tf.stack([tensor_array_x,tensor_array_y],axis=0)
実行結果(エラー)
*** tensorflow.python.framework.errors_impl.InvalidArgumentError: ConcatOp : Dimensions of inputs should match: shape[0] = [1,3] vs. shape[1] = [1,5] [Op:ConcatV2] name: concat
tf.ragged.stack
tensor_array_x = tf.convert_to_tensor([[0,1,2]])
tensor_array_y = tf.convert_to_tensor([[3,4,5,6,7]])
ragged_xy_2 = tf.ragged.stack([tensor_array_x,tensor_array_y],axis=0)

print(ragged_xy_2)
実行結果
<tf.RaggedTensor [[[0, 1, 2]], [[3, 4, 5, 6, 7]]]>




最後に

今回はtensorflowでびジャグ配列の扱いについて解説しました。

tensorflow1.14.0まではtf.ragged.stackがなく少し面倒なのでTensorflow2.x系を今後は使っていった方が良いかもしれませんね。