টেনসরফ্লোতে পরিবর্তনশীল এবং get_variable এর মধ্যে পার্থক্য


125

আমি যতদূর জানি, Variableএকটি পরিবর্তনশীল তৈরির জন্য ডিফল্ট অপারেশন এবং get_variableমূলত ওজন ভাগ করে নেওয়ার জন্য ব্যবহৃত হয়।

একদিকে, কিছু লোক রয়েছে যখনই আপনার যখন ভেরিয়েবলের প্রয়োজন হয় তখন get_variableআদিম Variableঅপারেশনটির পরিবর্তে ব্যবহার করার পরামর্শ দিচ্ছেন । অন্যদিকে, আমি কেবল get_variableটেনসরফ্লোয়ের অফিসিয়াল ডকুমেন্টস এবং ডেমোতে কোনও ব্যবহার দেখতে পাচ্ছি ।

এইভাবে আমি এই দুটি প্রক্রিয়াটিকে সঠিকভাবে কীভাবে ব্যবহার করতে পারি তার কিছু নিয়ম জানতে চাই। কোন "মানক" নীতি আছে?


6
get_variable নতুন উপায়, ভেরিয়েবল পুরানো উপায় (যা চিরকালের জন্য সমর্থিত হতে পারে) যেমন Lukasz বলেছেন (পিএস: তিনি TF তে ভেরিয়েবলের বেশিরভাগই লিখেছিলেন)
ইয়ারোস্লাভ বুলাটোভ

উত্তর:


90

আমি সর্বদা ব্যবহারের পরামর্শ দেব tf.get_variable(...)- যদি আপনার যে কোনও সময় ভেরিয়েবলগুলি ভাগ করে নেওয়া প্রয়োজন যেমন কোনও মাল্টি-জিপিইউ সেটিংয়ে (মাল্টি-জিপিইউ সিআইএফআর উদাহরণ দেখুন) আপনার কোডটি রিফ্যাক্টর করা সহজ করে তুলবে। এর কোনও খারাপ দিক নেই।

খাঁটি tf.Variableনিম্ন স্তরের; কিছু সময়ে tf.get_variable()উপস্থিত ছিল না তাই কিছু কোড এখনও নিম্ন-স্তরের উপায় ব্যবহার করে।


5
আপনার উত্তরের জন্য আপনাকে অনেক ধন্যবাদ। তবে সর্বত্র কীভাবে প্রতিস্থাপন tf.Variableকরা tf.get_variableযায় সে সম্পর্কে আমার এখনও একটি প্রশ্ন রয়েছে । এটি হ'ল যখন আমি একটি নম্পি অ্যারে দিয়ে একটি ভেরিয়েবলটি শুরু করতে চাই, আমি এটি করার মতো পরিষ্কার করার এবং কার্যকর উপায়টি খুঁজে পাচ্ছি না tf.Variable। কীভাবে সমাধান করবেন? ধন্যবাদ।
লিফু হুয়াং

68

tf. পরিবর্তনশীল একটি শ্রেণি, এবং tf.Wariable সহ tf.Variable.__init__এবং তৈরি করার বিভিন্ন উপায় রয়েছে tf.get_variable

tf.Variable.__init__: প্রাথমিক_মূল্য সহ একটি নতুন ভেরিয়েবল তৈরি করে ।

W = tf.Variable(<initial-value>, name=<optional-name>)

tf.get_variable: এই পরামিতিগুলির সাথে একটি বিদ্যমান ভেরিয়েবল পায় বা একটি নতুন তৈরি করে। আপনি ইনিশিয়ালাইজারও ব্যবহার করতে পারেন।

W = tf.get_variable(name, shape=None, dtype=tf.float32, initializer=None,
       regularizer=None, trainable=True, collections=None)

ইনিশিয়ালাইজারগুলি ব্যবহার করতে যেমন খুব দরকারী xavier_initializer:

W = tf.get_variable("W", shape=[784, 256],
       initializer=tf.contrib.layers.xavier_initializer())

আরও তথ্য এখানে


হ্যাঁ, Variableআসলে আমি এটি ব্যবহার করে বোঝাতে চাইছি __init__। যেহেতু get_variableখুব সুবিধাজনক তাই আমি অবাক হয়েছি কেন বেশিরভাগ টেনসরফ্লো কোডটি আমি এর Variableপরিবর্তে ব্যবহার করতে দেখেছি get_variable। তাদের মধ্যে নির্বাচন করার সময় কোন কনভেনশন বা বিষয় বিবেচনা করা উচিত। ধন্যবাদ!
লিফু হুয়াং

আপনি যদি একটি নির্দিষ্ট মান পেতে চান তবে ভেরিয়েবল ব্যবহার করা সহজ: x = tf. পরিবর্তনশীল (3)।
সুং কিম

@ সুংকিম সাধারণত যখন আমরা ব্যবহার tf.Variable()করি তখন আমরা এটিকে একটি ছাঁটাই সাধারণ বিতরণ থেকে এলোমেলো মান হিসাবে শুরু করতে পারি। এখানে আমার উদাহরণ w1 = tf.Variable(tf.truncated_normal([5, 50], stddev = 0.01), name = 'w1')। এর সমমান কী হবে? আমি কীভাবে এটি বলব যে আমি একটি কাটা কাটা স্বাভাবিক চাই? আমার শুধু করা উচিত w1 = tf.get_variable(name = 'w1', shape = [5,50], initializer = tf.truncated_normal, regularizer = tf.nn.l2_loss)?
Euler_Salter

@ আয়লার_সাল্টার: আপনি tf.truncated_normal_initializer()পছন্দসই ফলাফল পেতে ব্যবহার করতে পারেন ।
বিটা

46

আমি একটি এবং অন্যটির মধ্যে দুটি প্রধান পার্থক্য খুঁজে পেতে পারি:

  1. প্রথমটি এটি tf.Variableসর্বদা একটি নতুন ভেরিয়েবল তৈরি করবে, যেখানে গ্রাফ থেকে নির্দিষ্ট পরামিতিগুলির সাথে tf.get_variableএকটি বিদ্যমান ভেরিয়েবল পাওয়া যায় এবং যদি এটি উপস্থিত না থাকে তবে একটি নতুন তৈরি করে।

  2. tf.Variable একটি প্রাথমিক মান নির্দিষ্ট করা প্রয়োজন।

এটি স্পষ্ট করে জানা দরকার যে ফাংশনটি tf.get_variableপুনরায় ব্যবহারের চেকগুলি সম্পাদন করতে বর্তমান পরিবর্তনশীল স্কোপ সহ নামটির সাথে উপসর্গ করে। উদাহরণ স্বরূপ:

with tf.variable_scope("one"):
    a = tf.get_variable("v", [1]) #a.name == "one/v:0"
with tf.variable_scope("one"):
    b = tf.get_variable("v", [1]) #ValueError: Variable one/v already exists
with tf.variable_scope("one", reuse = True):
    c = tf.get_variable("v", [1]) #c.name == "one/v:0"

with tf.variable_scope("two"):
    d = tf.get_variable("v", [1]) #d.name == "two/v:0"
    e = tf.Variable(1, name = "v", expected_shape = [1]) #e.name == "two/v_1:0"

assert(a is c)  #Assertion is true, they refer to the same object.
assert(a is d)  #AssertionError: they are different objects
assert(d is e)  #AssertionError: they are different objects

সর্বশেষ দৃser় ত্রুটিটি আকর্ষণীয়: একই স্কোপের অধীনে একই নামের দুটি ভেরিয়েবল একই ভেরিয়েবল হতে পারে বলে মনে করা হচ্ছে। তবে আপনি যদি ভেরিয়েবলের নামগুলি পরীক্ষা করেন dএবং eআপনি বুঝতে পারবেন টেনসরফ্লো ভেরিয়েবলের নাম পরিবর্তন করেছে e:

d.name   #d.name == "two/v:0"
e.name   #e.name == "two/v_1:0"

দুর্দান্ত উদাহরণ! সম্পর্কিত d.nameএবং e.name, আমি সবেমাত্র টেনসর গ্রাফের নামকরণ অপারেশনের একটি টেনসরফ্লো ডকটি পেরিয়ে এসেছি যা এটি ব্যাখ্যা করে:If the default graph already contained an operation named "answer", the TensorFlow would append "_1", "_2", and so on to the name, in order to make it unique.
আটলাস

2

আরেকটি পার্থক্য রয়েছে যেটি একটি ('variable_store',)সংগ্রহের মধ্যে রয়েছে তবে অন্যটি নয়।

উত্স কোড দেখুন :

def _get_default_variable_store():
  store = ops.get_collection(_VARSTORE_KEY)
  if store:
    return store[0]
  store = _VariableStore()
  ops.add_to_collection(_VARSTORE_KEY, store)
  return store

আমাকে উদাহরণস্বরূপ:

import tensorflow as tf
from tensorflow.python.framework import ops

embedding_1 = tf.Variable(tf.constant(1.0, shape=[30522, 1024]), name="word_embeddings_1", dtype=tf.float32) 
embedding_2 = tf.get_variable("word_embeddings_2", shape=[30522, 1024])

graph = tf.get_default_graph()
collections = graph.collections

for c in collections:
    stores = ops.get_collection(c)
    print('collection %s: ' % str(c))
    for k, store in enumerate(stores):
        try:
            print('\t%d: %s' % (k, str(store._vars)))
        except:
            print('\t%d: %s' % (k, str(store)))
    print('')

আউটপুট:

collection ('__variable_store',): 0: {'word_embeddings_2': <tf.Variable 'word_embeddings_2:0' shape=(30522, 1024) dtype=float32_ref>}

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