Mempertimbangkan kode contoh .
Saya ingin tahu Bagaimana cara menerapkan pemotongan gradien pada jaringan ini di RNN di mana ada kemungkinan gradien yang meledak.
tf.clip_by_value(t, clip_value_min, clip_value_max, name=None)
Ini adalah contoh yang dapat digunakan tetapi di mana saya memperkenalkan ini? Di def dari RNN
lstm_cell = rnn_cell.BasicLSTMCell(n_hidden, forget_bias=1.0)
# Split data because rnn cell needs a list of inputs for the RNN inner loop
_X = tf.split(0, n_steps, _X) # n_steps
tf.clip_by_value(_X, -1, 1, name=None)
Tapi ini tidak masuk akal karena tensor _X adalah input dan bukan grad yang akan dipotong?
Apakah saya harus menentukan Pengoptimal saya sendiri untuk ini atau adakah opsi yang lebih sederhana?
sumber
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost)
dan kemudian pengulangan pengoptimal dilakukanoptimizer.run()
tetapi penggunaanoptimizer.run()
tampaknya tidak berfungsi dalam kasus ini?optimizer.apply_gradients(capped_gvs)
yang perlu ditugaskan ke sesuatux = optimizer.apply_gradients(capped_gvs)
maka dalam sesi Anda, Anda dapat berlatih sebagaix.run(...)
UserWarning: Converting sparse IndexedSlices to a dense Tensor with 148331760 elements. This may consume a large amount of memory.
Jadi entah bagaimana gradien renggang saya diubah menjadi padat. Ada ide bagaimana mengatasi masalah ini?tf.clip_by_global_norm
, seperti yang disarankan oleh @danijarTerlepas dari apa yang tampaknya populer, Anda mungkin ingin memotong seluruh gradien dengan norma globalnya:
Memotong setiap matriks gradien secara individual mengubah skala relatifnya tetapi juga memungkinkan:
Di TensorFlow 2, sebuah pita menghitung gradien, pengoptimal berasal dari Keras, dan kita tidak perlu menyimpan op pembaruan karena ini berjalan secara otomatis tanpa meneruskannya ke sesi:
sumber
clip_by_global_norm()
! Ini juga dijelaskan sepertithe correct way to perform gradient clipping
dalam dokumen tensorflowtf.global_norm(gradients)
untuk melihat kisaran biasanya dan kemudian klip sedikit di atasnya untuk mencegah pencilan mengacaukan pelatihan.opt.minimize()
setelahnya atau apakah Anda akan memanggil sesuatu yang berbeda sepertiopt.run()
yang disarankan dalam beberapa komentar di jawaban lain?optimizer.minimize(loss)
ini hanyalah singkatan untuk menghitung dan menerapkan gradien. Anda dapat menjalankan contoh di jawaban saya dengansess.run(optimize)
.tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op)
dalam fungsi eksperimen, maka Andaoptimize
akan mengganti jawaban sayatrain_op
? Sekarang sayatrain_op = optimizer.minimize(loss, global_step=global_step))
jadi saya mencoba untuk memastikan saya menyesuaikan sesuai ...Ini sebenarnya dijelaskan dengan benar dalam dokumentasi. :
Dan dalam contoh yang mereka berikan, mereka menggunakan 3 langkah berikut:
Berikut
MyCapper
adalah fungsi apa pun yang membatasi gradien Anda. Daftar fungsi yang berguna (selaintf.clip_by_value()
) ada di sini .sumber
opt.minimize()
setelahnya atau apakah Anda akan memanggil sesuatu yang berbeda sepertiopt.run()
yang disarankan dalam beberapa komentar di jawaban lain?opt.apply_gradients(...)
ke variabel sepertitrain_step
misalnya (seperti yang Anda lakukanopt.minimize()
. Dan di loop utama Anda, Anda menyebutnya seperti biasa untuk melatihsess.run([train_step, ...], feed_dict)
tf.clip_by_global_norm(list_of_tensors)
).Bagi mereka yang ingin memahami gagasan pemotongan gradien (menurut norma):
Setiap kali norma gradien lebih besar dari ambang tertentu, kami memotong norma gradien sehingga tetap dalam ambang. Ambang batas ini terkadang disetel ke
5
.Biarkan gradien menjadi g dan max_norm_threshold menjadi j .
Sekarang, jika || g || > j , kami melakukan:
g = ( j * g ) / || g ||
Ini adalah implementasi yang dilakukan di
tf.clip_by_norm
sumber
IMO solusi terbaik adalah membungkus pengoptimal Anda dengan dekorator penaksir TF
tf.contrib.estimator.clip_gradients_by_norm
:Dengan cara ini Anda hanya perlu mendefinisikan ini sekali, dan tidak menjalankannya setelah setiap perhitungan gradien.
Dokumentasi: https://www.tensorflow.org/api_docs/python/tf/contrib/estimator/clip_gradients_by_norm
sumber
Pemotongan Gradien pada dasarnya membantu jika gradien meledak atau menghilang. Katakan kerugian Anda terlalu tinggi yang akan mengakibatkan gradien eksponensial mengalir melalui jaringan yang dapat menghasilkan nilai Nan. Untuk mengatasinya, kami memotong gradien dalam rentang tertentu (-1 hingga 1 atau rentang apa pun sesuai kondisi).
clipped_value=tf.clip_by_value(grad, -range, +range), var) for grad, var in grads_and_vars
di mana lulusan _and_vars adalah pasangan gradien (yang Anda hitung melalui tf.compute_gradients) dan variabelnya akan diterapkan.
Setelah pemotongan, kami hanya menerapkan nilainya menggunakan pengoptimal.
optimizer.apply_gradients(clipped_value)
sumber