একটি প্রশ্ন আছে? টেনসরফ্লো ফোরাম ভিজিট ফোরামের সম্প্রদায়ের সাথে সংযুক্ত হন

কার্যকর টেনসরফ্লো 2

টেনসরফ্লো ব্যবহারকারীদের আরও উত্পাদনশীল করতে টেনসরফ্লো ২.০ এ একাধিক পরিবর্তন রয়েছে। টেনসরফ্লো ২.০ রিডানড্যান্ট এপিআইগুলি সরিয়ে দেয়, এপিআইগুলিকে আরও সুসংগত করে তোলে ( ইউনিফাইড আরএনএন , ইউনিফাইড অপ্টিমাইজার ), এবং ইজিার এক্সিকিউশনের সাথে পাইথন রানটাইমের সাথে আরও ভাল সংহত করে।

টেনসরফ্লো ২.০ তৈরিতে যে পরিবর্তনগুলি হয়েছে তা অনেকগুলি আরএফসি ব্যাখ্যা করেছে। টেনসরফ্লো ২.০-তে কী কী বিকাশ হওয়া উচিত তার জন্য এই গাইডটি একটি দৃষ্টিভঙ্গি উপস্থাপন করে। এটি ধরে নেওয়া হয়েছে যে টেনসরফ্লো 1.x এর সাথে আপনার কিছুটা পরিচিতি রয়েছে

বড় পরিবর্তনগুলির একটি সংক্ষিপ্তসার

এপিআই ক্লিনআপ

অনেকগুলি API গুলি হয় চলে গেছে বা টিএফ 2.0 তে সরানো হয়েছে। কিছু বড় পরিবর্তনগুলির মধ্যে রয়েছে tf.app , tf.flags মুছে ফেলা এবং tf.logging এখন ওপেন-সোর্স অ্যাবসেল- পাই, tf.contrib- এ বসবাসকারী প্রকল্পগুলির পুনরায় tf.contrib , এবং মূল tf.* tf.math মতো সাব-প্যাকেজে কম ব্যবহৃত ফাংশন সরিয়ে tf.math । কিছু এপিআই তাদের ২.০ সমতুল্য - tf.summary , tf.keras.metrics , এবং tf.keras.optimizers দিয়ে প্রতিস্থাপন করা হয়েছে। এই নামগুলি স্বয়ংক্রিয়ভাবে প্রয়োগ করার সহজ উপায় হ'ল ভি 2 আপগ্রেড স্ক্রিপ্টটি ব্যবহার করা।

আগ্রহী মৃত্যুদণ্ড কার্যকর

টেনসরফ্লো 1.X এর জন্য ব্যবহারকারীদের tf.* এপিআই কল করে ম্যানুয়ালি একটি বিমূর্ত সিনট্যাক্স ট্রি (গ্রাফ) একসাথে সেলাই করতে হবে। এরপরে ব্যবহারকারীগণকে একটি session.run() কলটিতে আউটপুট টেনার এবং ইনপুট টেনারগুলির একটি সেট পাস করে ম্যানুয়ালি বিমূর্ত সিনট্যাক্স ট্রি সংকলন করতে হবে। টেনসরফ্লো ২.০ আগ্রহীভাবে কার্যকর করে (পাইথন যেমন সাধারণত হয়) এবং ২.০-তে গ্রাফ এবং সেশনগুলি প্রয়োগের বিশদগুলির মতো বোধ করা উচিত।

উত্সাহী মৃত্যুদণ্ডের একটি উল্লেখযোগ্য tf.control_dependencies() আর প্রয়োজন নেই, যেহেতু কোডের সমস্ত লাইন ক্রম অনুসারে কার্যকর করা হয় (একটি tf.function , পার্শ্ব প্রতিক্রিয়াযুক্ত কোড লিখিত ক্রমে কার্যকর করা হয়)।

আর কোনও গ্লোবাল নেই

টেনসরফ্লো 1.X এক্সটিক্যালি গ্লোবাল নেমস্পেসের উপর প্রচুর নির্ভর করে। আপনি যখন tf.Variable() , এটি ডিফল্ট গ্রাফের মধ্যে স্থাপন করা হবে এবং পাইথন ভেরিয়েবলটির দিকে ইশারা করার ট্র্যাকটি হারিয়ে tf.Variable() তা সেখানেই থাকবে। তারপরে আপনি সেই tf.Variable পুনরুদ্ধার করতে পারেন tf.Variable , তবে কেবল যদি আপনি নামটি জানতেন তবে এটি তৈরি করা হয়েছিল। আপনি ভেরিয়েবলের তৈরির নিয়ন্ত্রণে না রাখলে এটি করা কঠিন ছিল। ফলস্বরূপ, সমস্ত ধরণের প্রক্রিয়া ব্যবহারকারীদের আবার তাদের ভেরিয়েবলগুলি tf.get_global_step() জন্য এবং ফ্রেমওয়ার্কগুলির জন্য ব্যবহারকারী দ্বারা তৈরি ভেরিয়েবলগুলি সন্ধান করার জন্য প্রসারিত: ভেরিয়েবল tf.get_global_step() , গ্লোবাল সংগ্রহ, tf.get_global_step() , tf.global_variables_initializer() , অপ্টিমাইজারগুলি সমস্ত প্রশিক্ষণযোগ্য ভেরিয়েবলগুলির উপর স্পষ্টতই গ্রেডিয়েন্টগুলি গণনা করছে, ইত্যাদি on টেনসরফ্লো ২.০ ডিফল্ট পদ্ধতির পক্ষে এই সমস্ত প্রক্রিয়া ( ভেরিয়েবল ২.০ আরএফসি ) মুছে ফেলে: আপনার ভেরিয়েবলগুলি ট্র্যাক করুন! আপনি যদি কোনও tf.Variable ট্র্যাক হারিয়ে tf.Variable , তবে এটি আবর্জনা সংগ্রহ করে।

ভেরিয়েবলগুলি ট্র্যাক করার প্রয়োজনীয়তা ব্যবহারকারীর জন্য কিছু অতিরিক্ত কাজ তৈরি করে তবে কেরাস অবজেক্ট (নীচে দেখুন) দিয়ে বোঝা হ্রাস করা হয়।

ফাংশন, সেশন নয়

একটি session.run() কলটি প্রায় একটি ফাংশন কলের মতো: আপনি ইনপুট এবং কল করতে হবে এমন ফাংশনটি নির্দিষ্ট করে দেন এবং আপনি আউটপুটগুলির একটি সেট ফিরে পান। টেনসরফ্লো ২.০-তে, আপনি tf.function() ব্যবহার করে পাইথন ফাংশনটি জেআইটি সংকলনের জন্য চিহ্নিত করতে পারেন যাতে টেনসরফ্লো এটিকে একটি একক গ্রাফ ( ফাংশনস ২.০ আরএফসি ) হিসাবে চালায়। এই প্রক্রিয়াটি টেনসরফ্লো ২.০ কে গ্রাফ মোডের সমস্ত সুবিধা অর্জন করতে দেয়:

  • পারফরম্যান্স: ফাংশনটি অপ্টিমাইজ করা যায় (নোড ছাঁটাই, কার্নেল ফিউশন ইত্যাদি)
  • বহনযোগ্যতা: ফাংশনটি রফতানি / পুনরায় রফতানি করা যায় ( সেভডমোডেল ২.০ আরএফসি ), ব্যবহারকারীদের মডিউলার টেনসরফ্লো ফাংশনগুলি পুনরায় ব্যবহার এবং ভাগ করতে দেয়।
# TensorFlow 1.X
outputs = session.run(f(placeholder), feed_dict={placeholder: input})
# TensorFlow 2.0
outputs = f(input)

অবাধে পাইথন এবং টেনসরফ্লো কোড ছেদ করার ক্ষমতা সহ ব্যবহারকারীরা পাইথনের অভিব্যক্তিটির সুবিধা নিতে পারেন। কিন্তু পোর্টেবল টেনসরফ্লো মোবাইল, সি ++ এবং জাভাস্ক্রিপ্টের মতো পাইথন দোভাষী ছাড়া প্রসঙ্গে প্রযোজ্য। @tf.function যোগ করার সময় ব্যবহারকারীদের তাদের কোডটি পুনরায় লিখতে সহায়তা করতে অটোগ্রাফ পাইথন নির্মাণের একটি উপসেটকে তাদের টেনসরফ্লো সমতলে রূপান্তর করে:

  • for / while -> tf.while_loop ( break এবং continue সমর্থিত)
  • if -> tf.cond
  • dataset.reduce for _ in dataset -> dataset.reduce

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

আইডেম্যাটিক টেনসরফ্লো ২.০ এর জন্য প্রস্তাবনা

আপনার কোডটিকে ছোট ফাংশনে রিফ্যাক্টর করুন

টেনসরফ্লো ১. এক্স-এর একটি সাধারণ ব্যবহারের প্যাটার্নটি ছিল "রান্নাঘর সিঙ্ক" কৌশল, যেখানে সম্ভাব্য সমস্ত কম্পিউটেশনের ইউনিয়ন পূর্বনির্ধারিতভাবে প্রস্তুত করা হয়েছিল এবং তারপরে নির্বাচিত টেনারগুলি session.run() মাধ্যমে মূল্যায়ন করা হয়েছিল। টেনসরফ্লো ২.০-তে ব্যবহারকারীদের তাদের কোডটিকে ছোট ছোট ফাংশনগুলিতে রিফ্যাক্টর করা উচিত যা প্রয়োজনীয় হিসাবে ডাকা হয়। সাধারণভাবে, tf.function দিয়ে এই ছোট ক্রিয়াকলাপগুলির প্রতিটি সাজাইয়া রাখা প্রয়োজন হয় না; শুধুমাত্র উচ্চ-স্তরের গণনাগুলি সাজানোর জন্য tf.function ব্যবহার করুন - উদাহরণস্বরূপ, প্রশিক্ষণের এক ধাপ বা আপনার মডেলের ফরোয়ার্ড পাস।

ভেরিয়েবলগুলি পরিচালনা করতে কেরাস স্তর এবং মডেলগুলি ব্যবহার করুন

কেরাস মডেল এবং স্তরগুলি সুবিধাজনক variables এবং trainable_variables বৈশিষ্ট্য সরবরাহ করে, যা সমস্ত নির্ভরশীল ভেরিয়েবলগুলি পুনরাবৃত্তভাবে সংগ্রহ করে। এটি স্থানীয়ভাবে ভেরিয়েবলগুলি যেখানে ব্যবহৃত হচ্ছে সেখানে পরিচালনা করা সহজ করে তোলে।

বিপরীতে:

def dense(x, W, b):
  return tf.nn.sigmoid(tf.matmul(x, W) + b)

@tf.function
def multilayer_perceptron(x, w0, b0, w1, b1, w2, b2 ...):
  x = dense(x, w0, b0)
  x = dense(x, w1, b1)
  x = dense(x, w2, b2)
  ...

# You still have to manage w_i and b_i, and their shapes are defined far away from the code.

কেরাস সংস্করণ সহ:

# Each layer can be called, with a signature equivalent to linear(x)
layers = [tf.keras.layers.Dense(hidden_size, activation=tf.nn.sigmoid) for _ in range(n)]
perceptron = tf.keras.Sequential(layers)

# layers[3].trainable_variables => returns [w3, b3]
# perceptron.trainable_variables => returns [w0, b0, ...]

কেরাস স্তরগুলি / মডেলগুলি tf.train.Checkpointable থেকে উত্তরাধিকার সূত্রে tf.train.Checkpointable এবং @tf.function সাথে সংহত হয়েছে, যা কেরাস অবজেক্ট থেকে সরাসরি চেকপয়েন্ট বা রক্ষিত মডেলগুলি রফতানি করা সম্ভব করে। এই .fit() সুবিধা নেওয়ার জন্য আপনাকে .fit() এপিআই ব্যবহার করতে হবে না।

এখানে ট্রান্সফার শেখার উদাহরণ যা দেখায় যে কীভাবে কেরাস প্রাসঙ্গিক ভেরিয়েবলগুলির একটি উপসেট সংগ্রহ করা সহজ করে। ধরা যাক আপনি একটি ভাগযুক্ত ট্রাঙ্ক সহ একটি বহু-মাথা মডেল প্রশিক্ষণ দিচ্ছেন:

trunk = tf.keras.Sequential([...])
head1 = tf.keras.Sequential([...])
head2 = tf.keras.Sequential([...])

path1 = tf.keras.Sequential([trunk, head1])
path2 = tf.keras.Sequential([trunk, head2])

# Train on primary dataset
for x, y in main_dataset:
  with tf.GradientTape() as tape:
    # training=True is only needed if there are layers with different
    # behavior during training versus inference (e.g. Dropout).
    prediction = path1(x, training=True)
    loss = loss_fn_head1(prediction, y)
  # Simultaneously optimize trunk and head1 weights.
  gradients = tape.gradient(loss, path1.trainable_variables)
  optimizer.apply_gradients(zip(gradients, path1.trainable_variables))

# Fine-tune second head, reusing the trunk
for x, y in small_dataset:
  with tf.GradientTape() as tape:
    # training=True is only needed if there are layers with different
    # behavior during training versus inference (e.g. Dropout).
    prediction = path2(x, training=True)
    loss = loss_fn_head2(prediction, y)
  # Only optimize head2 weights, not trunk weights
  gradients = tape.gradient(loss, head2.trainable_variables)
  optimizer.apply_gradients(zip(gradients, head2.trainable_variables))

# You can publish just the trunk computation for other people to reuse.
tf.saved_model.save(trunk, output_path)

Tf.data.Datasets এবং @ tf.function একত্রিত করুন

স্মৃতিতে ফিট হওয়া প্রশিক্ষণ ডেটা নিয়ে পুনরাবৃত্তি করার সময়, নিয়মিত পাইথন পুনরাবৃত্তিটি ব্যবহার করতে দ্বিধা বোধ করবেন। অন্যথায়,tf.data.Dataset ডিস্ক থেকে প্রশিক্ষণ ডেটা স্ট্রিম করার সেরা উপায়। ডেটাসেটগুলি পুনরাবৃত্ত হয় (পুনরাবৃত্তকারী নয়) , এবং ইজিার মোডে অন্য পাইথন পুনরাবৃত্তের মতো কাজ করে। আপনি আপনার কোডটি tf.function() মোড়ানো করে ডেটাসেট অ্যাসিঙ্ক প্রিফেচিং / স্ট্রিমিং বৈশিষ্ট্যগুলি পুরোপুরি ব্যবহার করতে পারেন, যা পাইথন পুনরাবৃত্তিকে অটোগ্রাফ ব্যবহার করে সমান গ্রাফ ক্রিয়াকলাপের সাথে প্রতিস্থাপন করে।

@tf.function
def train(model, dataset, optimizer):
  for x, y in dataset:
    with tf.GradientTape() as tape:
      # training=True is only needed if there are layers with different
      # behavior during training versus inference (e.g. Dropout).
      prediction = model(x, training=True)
      loss = loss_fn(prediction, y)
    gradients = tape.gradient(loss, model.trainable_variables)
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))

আপনি যদি কেরাস। .fit() এপিআই ব্যবহার করেন, আপনাকে ডেটাসেট পুনরাবৃত্তির বিষয়ে চিন্তা করতে হবে না।

model.compile(optimizer=optimizer, loss=loss_fn)
model.fit(dataset)

পাইথন নিয়ন্ত্রণ প্রবাহের সাথে অটোগ্রাফের সুবিধা নিন

অটোগ্রাফ ডেটা নির্ভর নির্ভর নিয়ন্ত্রণ প্রবাহকে গ্রাফ-মোড সমতুল্য যেমন tf.cond এবং tf.while_loop . tf.while_loop রূপান্তর করার একটি উপায় সরবরাহ করে।

একটি সাধারণ জায়গা যেখানে ডেটা-নির্ভর নিয়ন্ত্রণ নিয়ন্ত্রণ প্রবাহ প্রদর্শিত হয় তা হল সিক্যুয়েন্স মডেলগুলি। tf.keras.layers.RNN একটি আরএনএন সেল tf.keras.layers.RNN , যা আপনাকে স্থিতিশীলভাবে বা গতিশীলভাবে পুনরাবৃত্তিটি tf.keras.layers.RNN করতে দেয়। বিক্ষোভের খাতিরে, আপনি নিম্নরূপে গতিশীল তালিকাভুক্তি পুনরায় প্রতিস্থাপন করতে পারেন:

class DynamicRNN(tf.keras.Model):

  def __init__(self, rnn_cell):
    super(DynamicRNN, self).__init__(self)
    self.cell = rnn_cell

  def call(self, input_data):
    # [batch, time, features] -> [time, batch, features]
    input_data = tf.transpose(input_data, [1, 0, 2])
    outputs = tf.TensorArray(tf.float32, input_data.shape[0])
    state = self.cell.zero_state(input_data.shape[1], dtype=tf.float32)
    for i in tf.range(input_data.shape[0]):
      output, state = self.cell(input_data[i], state)
      outputs = outputs.write(i, output)
    return tf.transpose(outputs.stack(), [1, 0, 2]), state

অটোগ্রাফ এর বৈশিষ্ট্য আরো বিস্তারিত ওভারভিউ জন্য, দেখুন নির্দেশিকা

tf.metrics ডেটা একত্রিত করে এবং tf.summary এগুলি লগ করে

সংক্ষিপ্তাগুলি লগ করতে tf.summary.(scalar|histogram|...) ব্যবহার tf.summary.(scalar|histogram|...) এবং প্রসঙ্গে পরিচালক ব্যবহার করে এটি কোনও লেখকের কাছে পুনর্নির্দেশ করুন। (আপনি যদি প্রসঙ্গ পরিচালককে বাদ দেন তবে কিছুই হয় না)) টিএফ 1.x এর বিপরীতে সংক্ষিপ্তসারগুলি সরাসরি লেখকের কাছে নির্গত হয়; কোনও পৃথক "মার্জ" বিকল্প নেই এবং পৃথক add_summary() কল নেই, যার অর্থ step মানটি কলসাইটে সরবরাহ করতে হবে।

summary_writer = tf.summary.create_file_writer('/tmp/summaries')
with summary_writer.as_default():
  tf.summary.scalar('loss', 0.1, step=42)

সংক্ষিপ্ত হিসাবে লগ ইন করার আগে ডেটা সমষ্টি করতে, tf.metrics ব্যবহার tf.metrics । মেট্রিকগুলি রাষ্ট্রীয়: তারা মান সংগ্রহ করে এবং যখন আপনি .result() কল করেন তখন একটি .result() ফলাফল প্রদান করে। .reset_states() দিয়ে সঞ্চিত মানগুলি সাফ করুন।

def train(model, optimizer, dataset, log_freq=10):
  avg_loss = tf.keras.metrics.Mean(name='loss', dtype=tf.float32)
  for images, labels in dataset:
    loss = train_step(model, optimizer, images, labels)
    avg_loss.update_state(loss)
    if tf.equal(optimizer.iterations % log_freq, 0):
      tf.summary.scalar('loss', avg_loss.result(), step=optimizer.iterations)
      avg_loss.reset_states()

def test(model, test_x, test_y, step_num):
  # training=False is only needed if there are layers with different
  # behavior during training versus inference (e.g. Dropout).
  loss = loss_fn(model(test_x, training=False), test_y)
  tf.summary.scalar('loss', loss, step=step_num)

train_summary_writer = tf.summary.create_file_writer('/tmp/summaries/train')
test_summary_writer = tf.summary.create_file_writer('/tmp/summaries/test')

with train_summary_writer.as_default():
  train(model, optimizer, dataset)

with test_summary_writer.as_default():
  test(model, test_x, test_y, optimizer.iterations)

সংক্ষিপ্ত লগ ডিরেক্টরিতে টেনসরবোর্ডকে নির্দেশ করে উত্পন্ন সংক্ষিপ্তগুলি ভিজ্যুয়ালাইজ করুন:

tensorboard --logdir /tmp/summaries

ডিবাগ করার সময় tf.config.experimental_run_funitions_eagerly () ব্যবহার করুন

টেনসরফ্লো ২.০-তে, আগ্রহী সম্পাদন আপনাকে আকার, ডেটা ধরণের এবং মানগুলি পরীক্ষা করার জন্য ধাপে ধাপে কোড চালাতে দেয়। tf.function , tf.keras , ইত্যাদির মতো কিছু নির্দিষ্ট API গুলি পারফরম্যান্স এবং বহনযোগ্যতার জন্য গ্রাফের প্রয়োগের জন্য ডিজাইন করা হয়েছে। ডিবাগ করার সময়, এই কোডের অভ্যন্তরে tf.config.experimental_run_functions_eagerly(True) এক্সিকিউশনটি ব্যবহার করতে tf.config.experimental_run_functions_eagerly(True) ব্যবহার করুন।

উদাহরণ স্বরূপ:

@tf.function
def f(x):
  if x > 0:
    import pdb
    pdb.set_trace()
    x = x + 1
  return x

tf.config.experimental_run_functions_eagerly(True)
f(tf.constant(1))
>>> f()
-> x = x + 1
(Pdb) l
  6     @tf.function
  7     def f(x):
  8       if x > 0:
  9         import pdb
 10         pdb.set_trace()
 11  ->     x = x + 1
 12       return x
 13
 14     tf.config.experimental_run_functions_eagerly(True)
 15     f(tf.constant(1))
[EOF]

এটি কেরাস মডেল এবং অন্যান্য এপিআইপিগুলির মধ্যেও কাজ করে যা উত্সর মৃত্যুদণ্ড সমর্থন করে:

class CustomModel(tf.keras.models.Model):

  @tf.function
  def call(self, input_data):
    if tf.reduce_mean(input_data) > 0:
      return input_data
    else:
      import pdb
      pdb.set_trace()
      return input_data // 2


tf.config.experimental_run_functions_eagerly(True)
model = CustomModel()
model(tf.constant([-2, -4]))
>>> call()
-> return input_data // 2
(Pdb) l
 10         if tf.reduce_mean(input_data) > 0:
 11           return input_data
 12         else:
 13           import pdb
 14           pdb.set_trace()
 15  ->       return input_data // 2
 16
 17
 18     tf.config.experimental_run_functions_eagerly(True)
 19     model = CustomModel()
 20     model(tf.constant([-2, -4]))