web-dev-qa-db-ja.com

tf.data.Datasetに異なるサイズのリストのリストを入力する方法

Tf.dataライブラリを使用してフィードする整数のリスト(さまざまなサイズのそれぞれを表す)のリストの長いリストがあります。 (リストのリストの)リストごとに長さが異なり、エラーが発生します。ここで再現できます。

t = [[4,2], [3,4,5]]
dataset = tf.data.Dataset.from_tensor_slices(t)

私が得るエラーは:

ValueError: Argument must be a dense tensor: [[4, 2], [3, 4, 5]] - got shape [2], but wanted [2, 2].

これを行う方法はありますか?

編集1:明確にするために、私はリストの入力リストをパディングしたくありません(これは100万を超える要素を含み、さまざまな長さの文のリストです)、tf.dataライブラリを使用して、適切な方法、さまざまな長さのリストのリスト。

19
Escachator

tf.data.Dataset.from_generator() を使用して、任意の反復可能なPythonオブジェクト(リストのリストのような)をDatasetに変換できます:

t = [[4, 2], [3, 4, 5]]

dataset = tf.data.Dataset.from_generator(lambda: t, tf.int32, output_shapes=[None])

iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()

with tf.Session() as sess:
  print(sess.run(next_element))  # ==> '[4, 2]'
  print(sess.run(next_element))  # ==> '[3, 4, 5]'
13
mrry

@mrryの回答に加えて、(イメージ、ラベル)ペアを作成する場合は、次のコードも可能です。

import itertools
data = tf.data.Dataset.from_generator(lambda: itertools.izip_longest(images, labels),
                                      output_types=(tf.float32, tf.float32),
                                      output_shapes=(tf.TensorShape([None, None, 3]), 
                                                     tf.TensorShape([None])))

iterator = dataset.make_one_shot_iterator()
next_element = iterator.get_next()

with tf.Session() as sess:
    image, label = sess.run(next_element)  # ==> shape: [320, 420, 3], [20]
    image, label = sess.run(next_element)  # ==> shape: [1280, 720, 3], [40]
0
Dat Nguyen

Tensorflowは、与えられた次元に沿ってさまざまな数の要素を持つテンソルをサポートしているとは思いません。

ただし、簡単な解決策は、ネストされたリストの末尾にゼロを埋め込むことです(必要な場合)。

t = [[4,2], [3,4,5]]
max_length = max(len(lst) for lst in t)
t_pad = [lst + [0] * (max_length - len(lst)) for lst in t]
print(t_pad)
dataset = tf.data.Dataset.from_tensor_slices(t_pad)
print(dataset)

出力:

[[4, 2, 0], [3, 4, 5]]
<TensorSliceDataset shapes: (3,), types: tf.int32>

ゼロはモデルにとって大きな問題ではないはずです。意味的には、ゼロは実際の文の各リストの最後にあるサイズが0の余分な文にすぎません。

0
scrpy

TensorFlow 2で作業していて答えを探している人のために、ぼろぼろのテンソルで直接動作する次のことがわかりました。データセット全体がメモリに収まる限り、ジェネレータよりもはるかに高速です。

t = [[[4,2]],
     [[3,4,5]]]

rt=tf.ragged.constant(t)
dataset = tf.data.Dataset.from_tensor_slices(rt)

for x in dataset:
  print(x)

作り出す

<tf.RaggedTensor [[4, 2]]>
<tf.RaggedTensor [[3, 4, 5]]>

何らかの理由で、個々の配列に少なくとも2次元があることは非常に特殊です。

0
FlashDD