Halaman ini diterjemahkan oleh Cloud Translation API.
Switch to English

tf.while_loop

TensorFlow 1 versi Lihat sumber di GitHub

Ulangi body sedangkan kondisi cond benar. (Usang nilai argumen)

Digunakan di notebook

Digunakan dalam tutorial

cond adalah callable mengembalikan tensor skalar boolean. body adalah callable kembali (mungkin bersarang) tupel, namedtuple atau daftar tensor dari arity yang sama (panjang dan struktur) dan jenis sebagai loop_vars . loop_vars adalah (mungkin bersarang) tupel, namedtuple atau daftar tensor yang dilewatkan ke kedua cond dan body . cond dan body kedua take sebanyak argumen karena ada loop_vars .

Selain Tensors biasa atau IndexedSlices, tubuh dapat menerima dan kembali TensorArray objek. Mengalir dari objek TensorArray akan tepat diteruskan antara loop dan selama perhitungan gradien.

Perhatikan bahwa while_loop panggilan cond dan body tepat sekali (dalam panggilan untuk while_loop , dan tidak sama sekali selama Session.run() ). while_loop jahitan bersama-sama fragmen grafik dibuat selama cond dan body panggilan dengan beberapa node grafik tambahan untuk membuat aliran grafik yang berulang body sampai cond kembali palsu.

Untuk kebenaran, tf.while_loop() ketat memberlakukan invariants bentuk untuk variabel lingkaran. Sebuah invarian bentuk adalah (mungkin sebagian) bentuk yang tidak berubah di seluruh iterasi dari loop. Kesalahan akan dimunculkan jika bentuk dari variabel loop setelah iterasi ditentukan untuk menjadi lebih umum dari atau tidak sesuai dengan invarian bentuknya. Misalnya, bentuk [11, Tidak] lebih umum daripada bentuk [11, 17], dan [11, 21] tidak kompatibel dengan [11, 17]. Secara default (jika argumen shape_invariants tidak ditentukan), diasumsikan bahwa bentuk awal dari setiap tensor di loop_vars adalah sama di setiap iterasi. The shape_invariants argumen memungkinkan penelepon untuk menentukan kurang spesifik bentuk invarian untuk setiap variabel loop, yang diperlukan jika bentuk bervariasi antara iterasi. The tf.Tensor.set_shape fungsi juga dapat digunakan dalam body fungsi untuk menunjukkan bahwa variabel keluaran loop memiliki bentuk tertentu. Bentuk invarian untuk SparseTensor dan IndexedSlices diperlakukan khusus sebagai berikut:

a) Jika variabel loop adalah SparseTensor, bentuk invarian harus TensorShape ([r]) di mana r adalah rank dari tensor padat diwakili oleh tensor jarang. Ini berarti bentuk dari tiga tensor dari SparseTensor adalah ([None], [None, r], [r]). CATATAN: Bentuk invarian di sini adalah bentuk properti SparseTensor.dense_shape. Ini harus menjadi bentuk vektor.

b) Jika variabel loop adalah IndexedSlices, bentuk invarian harus menjadi invarian bentuk nilai-nilai tensor dari IndexedSlices. Ini berarti bentuk dari tiga tensor dari IndexedSlices adalah (bentuk, [bentuk [0]], [shape.ndims]).

while_loop alat semantik non-ketat, memungkinkan beberapa iterasi untuk menjalankan secara paralel. Jumlah maksimum iterasi paralel dapat dikendalikan oleh parallel_iterations , yang memberikan pengguna kontrol atas konsumsi memori dan perintah eksekusi. Untuk program yang benar, while_loop harus mengembalikan hasil yang sama untuk setiap parallel_iterations> 0.

Untuk pelatihan, TensorFlow menyimpan tensor yang diproduksi di inferensi maju dan diperlukan dalam propagasi kembali. tensor ini merupakan sumber utama konsumsi memori dan sering menyebabkan kesalahan Oom ketika melatih di GPU. Ketika bendera swap_memory benar, kita menukar tensor ini dari GPU ke CPU. Hal ini misalnya memungkinkan kita untuk melatih model RNN dengan urutan yang sangat panjang dan batch besar.

cond Sebuah callable yang mewakili kondisi penghentian loop.
body Sebuah callable yang mewakili badan loop.
loop_vars A (mungkin bersarang) tupel, namedtuple atau daftar array numpy, Tensor , dan TensorArray objek.
shape_invariants Bentuk invariants untuk variabel lingkaran.
parallel_iterations Jumlah iterasi diizinkan untuk berjalan secara paralel. Ini harus bilangan bulat positif.
back_prop (Opsional) Usang. Menonaktifkan palsu dukungan untuk propagasi kembali. Lebih suka menggunakan tf.stop_gradient gantinya.
swap_memory Apakah Swap memori GPU-CPU diaktifkan untuk loop ini.
maximum_iterations jumlah maksimum opsional iterasi dari loop sementara untuk menjalankan. Jika disediakan, cond output AND-ed dengan kondisi tambahan memastikan jumlah iterasi dieksekusi tidak lebih dari maximum_iterations .
name nama awalan opsional untuk tensor kembali.

Output tensor untuk variabel lingkaran setelah loop. Nilai kembali memiliki struktur yang sama seperti loop_vars .

TypeError jika cond atau body tidak callable.
ValueError jika loop_vars kosong.

Contoh:

 i = tf.constant(0)
c = lambda i: tf.less(i, 10)
b = lambda i: (tf.add(i, 1), )
r = tf.while_loop(c, b, [i])
 

Misalnya dengan bersarang dan namedtuple a:

 import collections
Pair = collections.namedtuple('Pair', 'j, k')
ijk_0 = (tf.constant(0), Pair(tf.constant(1), tf.constant(2)))
c = lambda i, p: i < 10
b = lambda i, p: (i + 1, Pair((p.j + p.k), (p.j - p.k)))
ijk_final = tf.while_loop(c, b, ijk_0)
 

Misalnya menggunakan shape_invariants:

 i0 = tf.constant(0)
m0 = tf.ones([2, 2])
c = lambda i, m: i < 10
b = lambda i, m: [i+1, tf.concat([m, m], axis=0)]
tf.while_loop(
    c, b, loop_vars=[i0, m0],
    shape_invariants=[i0.get_shape(), tf.TensorShape([None, 2])])
 

Contoh yang menunjukkan semantik non-ketat: Dalam contoh berikut, nilai akhir dari counter i tidak tergantung pada x . Jadi while_loop dapat kenaikan counter sejajar dengan update dari x . Namun, karena loop counter di satu loop iterasi tergantung pada nilai pada iterasi sebelumnya, loop kontra itu sendiri tidak dapat bertambah secara paralel. Oleh karena itu jika kita hanya ingin nilai akhir dari counter (yang kita mencetak pada baris print(sess.run(i)) ), maka x akan pernah bertambah, tapi counter akan diperbarui pada satu benang. Sebaliknya, jika kita ingin nilai output (yang kita mencetak pada baris print(sess.run(out).shape) ), maka counter dapat bertambah pada thread sendiri, sedangkan x dapat bertambah secara paralel pada thread terpisah. Dalam kasus ekstrim, dapat dibayangkan bahwa benang incrementing counter berjalan sampai selesai sebelum x bertambah bahkan satu waktu. Satu-satunya hal yang tidak pernah bisa terjadi adalah bahwa memperbarui benang x tidak pernah bisa maju dari benang kontra karena benang incrementing x tergantung pada nilai dari counter.

 import tensorflow as tf

n = 10000
x = tf.constant(list(range(n)))
c = lambda i, x: i < n
b = lambda i, x: (tf.compat.v1.Print(i + 1, [i]), tf.compat.v1.Print(x + 1,
[i], "x:"))
i, out = tf.while_loop(c, b, (0, x))
with tf.compat.v1.Session() as sess:
    print(sess.run(i))  # prints [0] ... [9999]

    # The following line may increment the counter and x in parallel.
    # The counter thread may get ahead of the other thread, but not the
    # other way around. So you may see things like
    # [9996] x:[9987]
    # meaning that the counter thread is on iteration 9996,
    # while the other thread is on iteration 9987
    print(sess.run(out).shape)