টেনসরফ্লোতে গ্রেডিয়েন্ট ক্লিপিং কীভাবে প্রয়োগ করবেন?


97

উদাহরণ কোড বিবেচনা করে ।

আমি জানতে চাই যে আরএনএন-তে এই গ্রেডিয়েন্টে গ্রেডিয়েন্ট ক্লিপিং কীভাবে প্রয়োগ করতে হবে যেখানে গ্রেডিয়েন্ট বিস্ফোরণের সম্ভাবনা রয়েছে।

tf.clip_by_value(t, clip_value_min, clip_value_max, name=None)

এটি এমন উদাহরণ যা ব্যবহার করা যেতে পারে তবে আমি কোথায় এটি পরিচয় করিয়ে দেব? আরএনএন এর ডিফ মধ্যে

    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)

তবে এটি টেন্সর _ এক্স এর ইনপুট এবং ক্লিপটি কী কী ক্লিপ করা হবে তা নয় বলে কোনও অর্থ হয় না?

এর জন্য আমাকে কী আমার নিজস্ব অপটিমাইজার সংজ্ঞায়িত করতে হবে বা এর চেয়ে সহজ বিকল্প আছে?

উত্তর:


145

গ্রেডিয়েন্ট ক্লিপিং গ্রেডিয়েন্টগুলি গণনা করার পরে ঘটতে হবে, তবে মডেলটির পরামিতিগুলি আপডেট করার জন্য সেগুলি প্রয়োগ করার আগে। আপনার উদাহরণে, এই দুটি জিনিসই AdamOptimizer.minimize()পদ্ধতি দ্বারা পরিচালিত হয় ।

আপনার গ্রেডিয়েন্টগুলি ক্লিপ করার জন্য আপনাকে টেনসরফ্লো এর এপিআই ডকুমেন্টেশনে এই বিভাগে বর্ণিত হিসাবে স্পষ্টভাবে গণনা, ক্লিপ এবং সেগুলি প্রয়োগ করতে হবে । বিশেষত আপনাকে minimize()নীচের মতো কিছু সহ পদ্ধতিতে কলটির বিকল্প করতে হবে :

optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
gvs = optimizer.compute_gradients(cost)
capped_gvs = [(tf.clip_by_value(grad, -1., 1.), var) for grad, var in gvs]
train_op = optimizer.apply_gradients(capped_gvs)

4
স্টায়র্ক, পোস্টের জন্য ধন্যবাদ। আপনি কি জানেন যে পরবর্তী পদক্ষেপগুলি আসলে অপ্টিমাইজারটির একটি পুনরাবৃত্তি চালাতে পারে? সাধারণত, একটি অপ্টিমাইজার হিসাবে ইনস্ট্যান্ট হয় optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate).minimize(cost) এবং তারপরে অপটিমাইজারের একটি পুনরাবৃত্তি যেমন করা হয় optimizer.run()তবে ব্যবহারটি optimizer.run()কি এই ক্ষেত্রে কাজ করে না বলে মনে হয়?
অ্যাপ্লিকাইডার

6
ঠিক আছে এটি optimizer.apply_gradients(capped_gvs)এমন কিছু নির্ধারিত হয়ে গেছে যা x = optimizer.apply_gradients(capped_gvs)আপনার সেশনের মধ্যে আপনি প্রশিক্ষণ নিতে পারেনx.run(...)
অ্যাপ্লিকাইডার

4
সুন্দর সম্পাদনার পরামর্শের জন্য @ রিমি-সিউইনেট থেকে চিত্কার করুন । (যা দুর্ভাগ্যবশত তাড়াহুড়া পর্যালোচকরা প্রত্যাখ্যান করেছিলেন)
স্টায়ার্ক

এটি আমাকে দেয় UserWarning: Converting sparse IndexedSlices to a dense Tensor with 148331760 elements. This may consume a large amount of memory.তাই কোনওভাবে আমার স্পার গ্রেডিয়েন্টগুলি ঘন হয়ে যায়। কোন সমস্যা কীভাবে এই সমস্যাটি কাটিয়ে উঠবেন?
পেক্কা

8
আসলে ক্লিপ গ্রেডিয়েন্ট (tensorflow ডক্স, কম্পিউটার বিজ্ঞানীরা, এবং যুক্তি অনুযায়ী) করার সঠিক উপায় সাথে আছেন tf.clip_by_global_normযেমন দ্বারা @danijar প্রস্তাব,
gdelab

118

যা জনপ্রিয় বলে মনে হচ্ছে তা সত্ত্বেও, আপনি সম্ভবত পুরো বিশ্বব্যাপী তার বৈশ্বিক আদর্শ অনুসারে ক্লিপ করতে চান:

optimizer = tf.train.AdamOptimizer(1e-3)
gradients, variables = zip(*optimizer.compute_gradients(loss))
gradients, _ = tf.clip_by_global_norm(gradients, 5.0)
optimize = optimizer.apply_gradients(zip(gradients, variables))

প্রতিটি গ্রেডিয়েন্ট ম্যাট্রিক্স পৃথকভাবে তাদের আপেক্ষিক স্কেল পরিবর্তন করে তবে এটি সম্ভব:

optimizer = tf.train.AdamOptimizer(1e-3)
gradients, variables = zip(*optimizer.compute_gradients(loss))
gradients = [
    None if gradient is None else tf.clip_by_norm(gradient, 5.0)
    for gradient in gradients]
optimize = optimizer.apply_gradients(zip(gradients, variables))

টেনসরফ্লো 2-তে, একটি টেপ গ্রেডিয়েন্টগুলি গণনা করে, কেরাস থেকে অপ্টিমাইজার আসে, এবং আমাদের আপডেট অপশন সংরক্ষণ করার দরকার নেই কারণ এটি একটি সেশনে পাস না করে স্বয়ংক্রিয়ভাবে চলে:

optimizer = tf.keras.optimizers.Adam(1e-3)
# ...
with tf.GradientTape() as tape:
  loss = ...
variables = ...
gradients = tape.gradient(loss, variables)
gradients, _ = tf.clip_by_global_norm(gradients, 5.0)
optimizer.apply_gradients(zip(gradients, variables))

10
সঙ্গে ভাল উদাহরণ clip_by_global_norm()! এটি the correct way to perform gradient clippingটেনসরফ্লো ডক্স হিসাবেও বর্ণনা করা হয়েছে: tensorflow.org/versions/r1.2/api_docs/python/tf/…
এমজেডএইচএম

9
@ এসচাটোর এটি অভিজ্ঞতাবাদী এবং এটি আপনার মডেল এবং সম্ভবত টাস্কের উপর নির্ভর করবে। আমি যা করি তা হ'ল গ্রেডিয়েন্ট নিয়মটি tf.global_norm(gradients)দেখার জন্য এটির স্বাভাবিক পরিসীমা দেখতে এবং তারপরে কিছুটা উপরে ক্লিপ করা যাতে প্রশিক্ষণে গোলমাল হতে না পারে from
দানিজার

4
আপনি কি তার পরেও কল opt.minimize()করবেন নাকি opt.run()অন্য উত্তরের মন্তব্যে কিছু পরামর্শ দেওয়া হয়েছে ঠিক তেমন কিছু বলবে ?
reese0106

4
@ reese0106 না, optimizer.minimize(loss)গ্রেডিয়েন্টগুলি গণনা এবং প্রয়োগের জন্য কেবলমাত্র একটি শর্টহ্যান্ড। আপনি আমার উত্তর দিয়ে উদাহরণ চালাতে পারেন sess.run(optimize)
দানিজার

4
সুতরাং আমি যদি tf.estimator.EstimatorSpec(mode, loss=loss, train_op=train_op)একটি পরীক্ষামূলক ফাংশনের মধ্যে ব্যবহার করছিলাম , তবে আপনি optimizeআমার train_opসঠিকটি প্রতিস্থাপন করবেন ? এই মুহূর্তে আমার train_op = optimizer.minimize(loss, global_step=global_step))তাই আমি সে অনুযায়ী সামঞ্জস্য করার চেষ্টা করার চেষ্টা করছি ...
reese0106

10

ডকুমেন্টেশনে এটি যথাযথভাবে ব্যাখ্যা করা হয়েছে। :

কলিং মিনিমাইজ () গ্রেডিয়েন্টগুলি গণনা করা এবং ভেরিয়েবলগুলিতে প্রয়োগ করার উভয়ের যত্ন নেয়। আপনি যদি গ্রেডিয়েন্টগুলি প্রয়োগ করার আগে তাদের প্রক্রিয়া করতে চান তবে পরিবর্তে তিনটি ধাপে অপ্টিমাইজারটি ব্যবহার করতে পারেন:

  • কম্পিউট_ গ্রেডিয়েন্টস () দিয়ে গ্রেডিয়েন্টগুলি গণনা করুন।
  • আপনার ইচ্ছামতো গ্রেডিয়েন্টগুলি প্রক্রিয়া করুন।
  • প্রয়োগ_ গ্রেডিয়েন্টস () সহ প্রক্রিয়াজাত গ্রেডিয়েন্টগুলি প্রয়োগ করুন।

এবং তারা প্রদত্ত উদাহরণে তারা এই 3 টি পদক্ষেপ ব্যবহার করে:

# Create an optimizer.
opt = GradientDescentOptimizer(learning_rate=0.1)

# Compute the gradients for a list of variables.
grads_and_vars = opt.compute_gradients(loss, <list of variables>)

# grads_and_vars is a list of tuples (gradient, variable).  Do whatever you
# need to the 'gradient' part, for example cap them, etc.
capped_grads_and_vars = [(MyCapper(gv[0]), gv[1]) for gv in grads_and_vars]

# Ask the optimizer to apply the capped gradients.
opt.apply_gradients(capped_grads_and_vars)

MyCapperআপনার গ্রেডিয়েন্টটি ক্যাপ করে এমন কোনও ফাংশন এখানে । দরকারী ফাংশনগুলির তালিকা (ব্যতীত tf.clip_by_value()) এখানে রয়েছে


আপনি কি তার পরেও কল opt.minimize()করবেন নাকি opt.run()অন্য উত্তরের মন্তব্যে কিছু পরামর্শ দেওয়া হয়েছে ঠিক তেমন কিছু বলবে ?
reese0106

@ রিজ0106 না, আপনাকে উদাহরণস্বরূপ opt.apply_gradients(...)একটি ভেরিয়েবলের নিয়োগ train_stepকরতে হবে (যেমনটি আপনি চান ঠিক তেমনভাবে opt.minimize()। এবং আপনার মূল sess.run([train_step, ...], feed_dict)
লুপটিতে

মনে রাখবেন যে গ্রেডিয়েন্টটি মডেলটির সমস্ত পরামিতিগুলিতে লোকসানের কব্জাগুলির ডেরিভেটিভসের ভেক্টর হিসাবে সংজ্ঞায়িত। টেনসরফ্লো এটিকে পাইথন তালিকা হিসাবে উপস্থাপন করে যা প্রতিটি ভেরিয়েবল এবং এর গ্রেডিয়েন্টের জন্য একটি টিপল ধারণ করে। এর অর্থ গ্রেডিয়েন্ট নিয়মটি ক্লিপ করা, আপনি প্রতিটি টেন্সরকে পৃথকভাবে ক্লিপ করতে পারবেন না, আপনাকে একবারে তালিকাটি বিবেচনা করতে হবে (যেমন ব্যবহার করে tf.clip_by_global_norm(list_of_tensors))।
দানিজার

8

যারা গ্রেডিয়েন্ট ক্লিপিং (আদর্শ অনুসারে) ধারণাটি বুঝতে চান তাদের জন্য:

যখনই গ্রেডিয়েন্ট আদর্শটি একটি নির্দিষ্ট প্রান্তিকের চেয়ে বেশি হয়, আমরা গ্রেডিয়েন্ট আদর্শটি ক্লিপ করি যাতে এটি প্রান্তিকের মধ্যে থাকে। এই প্রান্তিক সময় কখনও কখনও সেট করা হয় 5

গ্রেডিয়েন্টটি g এবং সর্বোচ্চ_নরম_ত্রেস্টલ્ડটি j হতে দিন ।

এখন, যদি || || > জে , আমরা কি:

g = ( জে * জি ) / || ||

এটি বাস্তবায়ন হয় tf.clip_by_norm


যদি আমাকে হাত দিয়ে প্রান্তিক নির্বাচন করতে হয় তবে এটি করার কোনও সাধারণ পদ্ধতি আছে কি?
নিংহু

এটি কিছু কাগজে প্রস্তাবিত একটি কালো যাদু এর ধরণ। অন্যথায়, আপনাকে প্রচুর পরীক্ষা-নিরীক্ষা করতে হবে এবং কোনটি আরও ভাল কাজ করে তা খুঁজে বের করতে হবে।
কুমারী 23

4

আইএমও সেরা সমাধানটি আপনার অপটিমাইজারকে টিএফ এর অনুমানক ডেকরেটারের সাথে মোড়ক করছে tf.contrib.estimator.clip_gradients_by_norm:

original_optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)
optimizer = tf.contrib.estimator.clip_gradients_by_norm(original_optimizer, clip_norm=5.0)
train_op = optimizer.minimize(loss)

এইভাবে আপনাকে কেবল একবার এটি সংজ্ঞায়িত করতে হবে এবং প্রতিটি গ্রেডিয়েন্ট গণনার পরে চালানো হবে না।

ডকুমেন্টেশন: https://www.tensorflow.org/api_docs/python/tf/contrib/estimator/ ক্লিপ_ গ্রেডিয়েন্টস_বাই_নর্ম


2

গ্রেডিয়েন্ট ক্লিপিং মূলত বিস্ফোরিত হওয়া বা গ্রেডিয়েন্টগুলি নিখোঁজ হওয়ার ক্ষেত্রে সহায়তা করে ay আপনার ক্ষতি খুব বেশি, যার ফলে ন্যানের মান হতে পারে এমন নেটওয়ার্কের মধ্য দিয়ে ক্ষতিকারক গ্রেডিয়েন্টগুলি প্রবাহিত হবে। এটিকে কাটিয়ে উঠতে আমরা একটি নির্দিষ্ট পরিসরের মধ্যে গ্রেডিয়েন্টগুলি ক্লিপ করি (শর্ত অনুযায়ী কোনও -1 থেকে 1 বা কোনও ব্যাপ্তি)।

clipped_value=tf.clip_by_value(grad, -range, +range), var) for grad, var in grads_and_vars

যেখানে গ্রেড _ এবং_ভারগুলি গ্রেডিয়েন্টের জোড়া (যা আপনি tf.compute_gradient এর মাধ্যমে গণনা করেন) এবং তাদের ভেরিয়েবলগুলি এগুলিতে প্রয়োগ করা হবে।

ক্লিপিংয়ের পরে আমরা কেবলমাত্র একটি অপ্টিমাইজার ব্যবহার করে এর মান প্রয়োগ করি। optimizer.apply_gradients(clipped_value)


আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.