Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

tf.map_fn

Versi TensorFlow 1 Lihat sumber di GitHub

Mentransformasi elems dengan menerapkan fn ke setiap elemen yang tidak ditumpuk pada sumbu 0. (argumen usang)

Digunakan di notebook

Digunakan dalam panduan ini Digunakan dalam tutorial

Lihat juga tf.scan .

map_fn unstacks elems pada sumbu 0 untuk mendapatkan urutan elemen; memanggil fn untuk mengubah setiap elemen; dan kemudian menumpuk nilai-nilai yang diubah kembali bersama.

Memetakan fungsi dengan input dan output Tensor tunggal

Jika elems adalah tensor tunggal dan tanda tangan fn adalah tf.Tensor->tf.Tensor , maka map_fn(fn, elems) setara dengan tf.stack([fn(elem) for elem in tf.unstack(elems)]) . Misalnya:

tf.map_fn(fn=lambda t: tf.range(t, t + 3), elems=tf.constant([3, 5, 2]))
<tf.Tensor: shape=(3, 3), dtype=int32, numpy=
  array([[3, 4, 5],
         [5, 6, 7],
         [2, 3, 4]], dtype=int32)>

map_fn(fn, elems).shape = [elems.shape[0]] + fn(elems[0]).shape .

Memetakan fungsi dengan input dan output multi-arity

map_fn juga mendukung fungsi dengan input dan output multi-arity:

  • Jika elems adalah tupel (atau struktur bersarang) dari tensor, maka tensor itu semua harus memiliki ukuran dimensi luar yang sama ( num_elems ); dan fn digunakan untuk mengubah setiap tuple (atau struktur) dari irisan yang sesuai dari elems . Misalnya, jika elems adalah tupel (t1, t2, t3) , maka fn digunakan untuk mengubah setiap tupel irisan (t1[i], t2[i], t3[i]) (di mana 0 <= i < num_elems ) .

  • Jika fn mengembalikan tupel (atau struktur bersarang) dari tensor, maka hasilnya dibentuk dengan menumpuk elemen yang sesuai dari struktur tersebut.

Menentukan tanda tangan keluaran fn

Jika input dan output tanda tangan fn berbeda, maka tanda tangan output harus ditentukan dengan menggunakan fn_output_signature . (Tanda tangan input dan output berbeda jika strukturnya, tipe, atau tipe tensor tidak cocok). Misalnya:

tf.map_fn(fn=tf.strings.length,  # input & output have different dtypes
          elems=tf.constant(["hello", "moon"]),
          fn_output_signature=tf.int32)
<tf.Tensor: shape=(2,), dtype=int32, numpy=array([5, 4], dtype=int32)>
tf.map_fn(fn=tf.strings.join,  # input & output have different structures
          elems=[tf.constant(['The', 'A']), tf.constant(['Dog', 'Cat'])],
          fn_output_signature=tf.string)
<tf.Tensor: shape=(2,), dtype=string,
 numpy=array([b'TheDog', b'ACat'], dtype=object)>

fn_output_signature dapat ditentukan menggunakan salah satu dari yang berikut:

Sensor Ragged

map_fn mendukung input dan output tf.RaggedTensor . Khususnya:

  • Jika elems adalah RaggedTensor , maka fn akan dipanggil dengan setiap baris dari tensor yang compang-camping.

    • Jika elems hanya memiliki satu dimensi yang tidak rata, maka nilai yang diteruskan ke fn adalah tf.Tensor s.
    • Jika elems memiliki beberapa dimensi ragged, maka nilai yang diteruskan ke fn adalah tf.RaggedTensor dengan satu dimensi ragged yang lebih sedikit.
  • Jika hasil map_fn harus RaggedTensor , maka gunakan tf.RaggedTensorSpec untuk menentukan fn_output_signature .

    • Jika fn mengembalikan tf.Tensor dengan ukuran yang bervariasi, maka gunakan tf.RaggedTensorSpec dengan ragged_rank=0 untuk menggabungkannya menjadi tensor kasar tunggal (yang akan memiliki ragged_rank = 1).
    • Jika fn kembali tf.RaggedTensor s, kemudian menggunakan tf.RaggedTensorSpec dengan sama ragged_rank .
# Example: RaggedTensor input
rt = tf.ragged.constant([[1, 2, 3], [], [4, 5], [6]])
tf.map_fn(tf.reduce_sum, rt, fn_output_signature=tf.int32)
<tf.Tensor: shape=(4,), dtype=int32, numpy=array([6, 0, 9, 6], dtype=int32)>
# Example: RaggedTensor output
elems = tf.constant([3, 5, 0, 2])
tf.map_fn(tf.range, elems,
          fn_output_signature=tf.RaggedTensorSpec(shape=[None],
                                                  dtype=tf.int32))
<tf.RaggedTensor [[0, 1, 2], [0, 1, 2, 3, 4], [], [0, 1]]>

Misalnya:

rt = tf.ragged.constant([[1, 2, 3], [], [4, 5], [6]])
tf.ragged.map_flat_values(lambda x: x + 2, rt)
<tf.RaggedTensor [[3, 4, 5], [], [6, 7], [8]]>

Sensor Jarang

map_fn mendukung input dan output tf.sparse.SparseTensor . Khususnya:

  • Jika elems adalah SparseTensor , maka fn akan dipanggil dengan setiap baris dari tensor jarang itu. Secara khusus, nilai yang diteruskan ke fn akan menjadi tf.sparse.SparseTensor dengan satu dimensi lebih sedikit daripada elems .

  • Jika hasil map_fn harus SparseTensor , maka gunakan tf.SparseTensorSpec untuk menentukan fn_output_signature . SparseTensor individu yang dikembalikan oleh fn akan ditumpuk menjadi SparseTensor tunggal dengan satu dimensi lagi.

# Example: SparseTensor input
st = tf.sparse.SparseTensor([[0, 0], [2, 0], [2, 1]], [2, 3, 4], [4, 4])
tf.map_fn(tf.sparse.reduce_sum, st, fn_output_signature=tf.int32)
<tf.Tensor: shape=(4,), dtype=int32, numpy=array([2, 0, 7, 0], dtype=int32)>
# Example: SparseTensor output
tf.sparse.to_dense(
    tf.map_fn(tf.sparse.eye, tf.constant([2, 3]),
              fn_output_signature=tf.SparseTensorSpec(None, tf.float32)))
<tf.Tensor: shape=(2, 3, 3), dtype=float32, numpy=
  array([[[1., 0., 0.],
          [0., 1., 0.],
          [0., 0., 0.]],
         [[1., 0., 0.],
          [0., 1., 0.],
          [0., 0., 1.]]], dtype=float32)>
  • Jika fungsi ini dapat dinyatakan sebagai operasi TensorFlow, gunakan:
 tf.sparse.SparseTensor(st.indices, fn(st.values), st.dense_shape)
 
  • Jika tidak, gunakan:
 tf.sparse.SparseTensor(st.indices, tf.map_fn(fn, st.values),
                       st.dense_shape)
 

operasi map_fn vs. vektor

map_fn akan menerapkan operasi yang digunakan oleh fn untuk setiap elemen elems , menghasilkan O(elems.shape[0]) total operasi. Ini agak dimitigasi oleh fakta bahwa map_fn dapat memproses elemen secara paralel. Namun, transformasi yang diekspresikan menggunakan map_fn masih biasanya kurang efisien daripada transformasi setara yang diekspresikan menggunakan ope