Tf.nn.embedding_lookup फ़ंक्शन क्या करता है?


158
tf.nn.embedding_lookup(params, ids, partition_strategy='mod', name=None)

मैं इस फ़ंक्शन के कर्तव्य को नहीं समझ सकता। क्या यह लुकअप टेबल की तरह है? प्रत्येक आईडी (आईडी में) के अनुरूप पैरामीटर वापस करने का मतलब है?

उदाहरण के लिए, skip-gramमॉडल में यदि हम उपयोग करते हैं tf.nn.embedding_lookup(embeddings, train_inputs), तो प्रत्येक के लिए train_inputयह पत्र एम्बेडिंग पाता है?


"क्या यह लुकअप टेबल की तरह है?" tldr - हाँ। प्रत्येक x (ids) के लिए मुझे एसोसिएट y (params) दें।
डेविड रेफेली

जवाबों:


147

embedding_lookupफ़ंक्शन paramsटेंसर की पंक्तियों को पुनः प्राप्त करता है। व्यवहार खस्ता में सरणियों के साथ अनुक्रमण का उपयोग करने के समान है। उदाहरण के लिए

matrix = np.random.random([1024, 64])  # 64-dimensional embeddings
ids = np.array([0, 5, 17, 33])
print matrix[ids]  # prints a matrix of shape [4, 64] 

paramsतर्क टेंसरों की एक सूची भी हो सकती है, जिस स्थिति idsमें दहाई के बीच वितरित किया जाएगा। उदाहरण के लिए, 3 tensors की एक सूची दी गई [2, 64], तो डिफ़ॉल्ट रूप है कि वे प्रतिनिधित्व करते हैं जाएगा ids: [0, 3], [1, 4], [2, 5]

partition_strategyidsसूची के बीच वितरित किए जाने के तरीके को नियंत्रित करता है । विभाजन बड़े पैमाने पर समस्याओं के लिए उपयोगी होता है जब मैट्रिक्स एक टुकड़े में रखने के लिए बहुत बड़ा हो सकता है।


21
वे इसे इस तरह क्यों कहेंगे और नहीं select_rows?
लेनार होयट

12
@LenarHoyt क्योंकि लुकअप का यह विचार वर्ड एंबेडिंग से आता है। और "पंक्तियों" शब्दों का प्रतिनिधित्व (एम्बेडिंग) एक वेक्टर अंतरिक्ष में - और उनमें से एक में उपयोगी होते हैं। अक्सर वास्तविक नेटवर्क की तुलना में अधिक।
लिंडन व्हाइट

2
टेंसरफ़्लो एम्बेडिंग संरचना कैसे सीखता है? क्या यह फ़ंक्शन उस प्रक्रिया को भी प्रबंधित करता है?
vgoklani

19
@vgoklani, नहीं, embedding_lookupबस आईडी के अनुरूप एम्बेडिंग प्राप्त करने के लिए एक सुविधाजनक (और समानांतर) तरीका प्रदान करता है idsparamsएक tf चर जिसका घटकों उपयोग किया जाता है, एक नुकसान समारोह (जैसे में प्रत्यक्ष या परोक्ष रूप - टेन्सर एक tf चर कि प्रशिक्षण की प्रक्रिया के हिस्से के रूप में पता चला है आमतौर पर है tf.l2_loss) जो कि एक अनुकूलक (जैसे द्वारा अनुकूलित है tf.train.AdamOptimizer)।
शोभित

5
@ Rafał Józefowicz "डिफ़ॉल्ट व्यवहार क्यों है कि वे आईडी का प्रतिनिधित्व करेंगे: [0, 3], [1, 4], [2, 5]।" क्या आप समझाएँगे?
एरिन

219

हां, यह फ़ंक्शन समझना मुश्किल है, जब तक कि आपको बिंदु नहीं मिलता।

अपने सरलतम रूप में, यह समान है tf.gather। यह paramsनिर्दिष्ट सूचकांक के अनुसार तत्वों को लौटाता हैids

उदाहरण के लिए (आप अंदर हैं tf.InteractiveSession())

params = tf.constant([10,20,30,40])
ids = tf.constant([0,1,2,3])
print tf.nn.embedding_lookup(params,ids).eval()

वापस आ जाएगा [10 20 30 40], क्योंकि परम का पहला तत्व (इंडेक्स 0), परम का 10दूसरा तत्व (इंडेक्स 1) है 20, आदि।

इसी तरह,

params = tf.constant([10,20,30,40])
ids = tf.constant([1,1,3])
print tf.nn.embedding_lookup(params,ids).eval()

लौट आएंगे [20 20 40]

लेकिन embedding_lookupइससे कहीं ज्यादा है। यह paramsतर्क एक टेंसर के बजाय टेंसर्स की एक सूची हो सकती है ।

params1 = tf.constant([1,2])
params2 = tf.constant([10,20])
ids = tf.constant([2,0,2,1,2,3])
result = tf.nn.embedding_lookup([params1, params2], ids)

ऐसे मामले में, निर्दिष्ट सूचकांक, विभाजन की रणनीति केids अनुसार टेंसरों के तत्वों के अनुरूप हैं , जहां डिफ़ॉल्ट विभाजन रणनीति 'मॉड' होती है।

'मॉड' रणनीति में, इंडेक्स 0 सूची में पहले टेंसर के पहले तत्व से मेल खाती है। इंडेक्स 1 दूसरे टेंसर के पहले तत्व से मेल खाता है । इंडेक्स 2 तीसरे टेंसर के पहले तत्व से मेल खाता है , और इसी तरह। बस सूचकांक (i + 1) वें टेंसर के पहले तत्व से मेल खाता है, सभी अनुक्रमणिकाओं के लिए , मान लिया गया कि पारम् की सूची हैi0..(n-1)n

अब, अनुक्रमणिका nदशांश n + 1 के अनुरूप नहीं हो सकती, क्योंकि सूची paramsमें केवल nदशांश शामिल हैं। इसलिए इंडेक्स पहले टेंसर nके दूसरे तत्व से मेल खाता है । इसी तरह, सूचकांक n+1दूसरे टेंसर के दूसरे तत्व से मेल खाता है, आदि।

तो, कोड में

params1 = tf.constant([1,2])
params2 = tf.constant([10,20])
ids = tf.constant([2,0,2,1,2,3])
result = tf.nn.embedding_lookup([params1, params2], ids)

सूचकांक 0 पहले टेंसर के पहले तत्व से मेल खाता है: 1

इंडेक्स 1 दूसरे टेंसर के पहले तत्व से मेल खाता है: 10

सूचकांक 2 पहले टेंसर के दूसरे तत्व से मेल खाता है: 2

इंडेक्स 3 दूसरे टेंसर के दूसरे तत्व से मेल खाता है: 20

इस प्रकार, परिणाम होगा:

[ 2  1  2 10  2 20]

8
एक नोट: आप उपयोग कर सकते हैं partition_strategy='div', और प्राप्त करेंगे [10, 1, 10, 2, 10, 20], अर्थात id=1पहला परम का दूसरा तत्व है। मूल रूप से: partition_strategy=mod(डिफ़ॉल्ट) id%len(params): परम में id//len(params)सूचकांक का सूचकांक: उपरोक्त परम में तत्व का सूचकांक partition_strategy=*div*दूसरे तरीके से
मारियो एलेमी

3
@ आशेर-कठोर आपको समझा सकता है कि "आधुनिक" रणनीति डिफ़ॉल्ट क्यों है? ऐसा लगता है कि "div" रणनीति मानक टैंसर स्लाइसिंग (दिए गए सूचकांकों द्वारा चयन-पंक्तियों) के समान है। क्या "div" के मामले में कुछ प्रदर्शन के मुद्दे हैं?
svetlov.vsevolod

46

हां, tf.nn.embedding_lookup()फ़ंक्शन का उद्देश्य एम्बेडिंग मैट्रिक्स में एक लुकअप करना और शब्दों के एम्बेडिंग (या सरल शब्दों में वेक्टर प्रतिनिधित्व) को वापस करना है।

एक साधारण एम्बेडिंग मैट्रिक्स (आकार का vocabulary_size x embedding_dimension) : नीचे की तरह दिखेगा। (यानी प्रत्येक शब्द को संख्याओं के एक वेक्टर द्वारा दर्शाया जाएगा ; इसलिए नाम word2vec )


मैट्रिक्स को एम्बेड करना

the 0.418 0.24968 -0.41242 0.1217 0.34527 -0.044457 -0.49688 -0.17862
like 0.36808 0.20834 -0.22319 0.046283 0.20098 0.27515 -0.77127 -0.76804
between 0.7503 0.71623 -0.27033 0.20059 -0.17008 0.68568 -0.061672 -0.054638
did 0.042523 -0.21172 0.044739 -0.19248 0.26224 0.0043991 -0.88195 0.55184
just 0.17698 0.065221 0.28548 -0.4243 0.7499 -0.14892 -0.66786 0.11788
national -1.1105 0.94945 -0.17078 0.93037 -0.2477 -0.70633 -0.8649 -0.56118
day 0.11626 0.53897 -0.39514 -0.26027 0.57706 -0.79198 -0.88374 0.30119
country -0.13531 0.15485 -0.07309 0.034013 -0.054457 -0.20541 -0.60086 -0.22407
under 0.13721 -0.295 -0.05916 -0.59235 0.02301 0.21884 -0.34254 -0.70213
such 0.61012 0.33512 -0.53499 0.36139 -0.39866 0.70627 -0.18699 -0.77246
second -0.29809 0.28069 0.087102 0.54455 0.70003 0.44778 -0.72565 0.62309 

मैंने उपरोक्त एम्बेडिंग मैट्रिक्स को विभाजित किया और केवल लोड किया शब्दों को किया है vocabजिसमें हमारी शब्दावली और embसरणी में संबंधित वैक्टर होंगे ।

vocab = ['the','like','between','did','just','national','day','country','under','such','second']

emb = np.array([[0.418, 0.24968, -0.41242, 0.1217, 0.34527, -0.044457, -0.49688, -0.17862],
   [0.36808, 0.20834, -0.22319, 0.046283, 0.20098, 0.27515, -0.77127, -0.76804],
   [0.7503, 0.71623, -0.27033, 0.20059, -0.17008, 0.68568, -0.061672, -0.054638],
   [0.042523, -0.21172, 0.044739, -0.19248, 0.26224, 0.0043991, -0.88195, 0.55184],
   [0.17698, 0.065221, 0.28548, -0.4243, 0.7499, -0.14892, -0.66786, 0.11788],
   [-1.1105, 0.94945, -0.17078, 0.93037, -0.2477, -0.70633, -0.8649, -0.56118],
   [0.11626, 0.53897, -0.39514, -0.26027, 0.57706, -0.79198, -0.88374, 0.30119],
   [-0.13531, 0.15485, -0.07309, 0.034013, -0.054457, -0.20541, -0.60086, -0.22407],
   [ 0.13721, -0.295, -0.05916, -0.59235, 0.02301, 0.21884, -0.34254, -0.70213],
   [ 0.61012, 0.33512, -0.53499, 0.36139, -0.39866, 0.70627, -0.18699, -0.77246 ],
   [ -0.29809, 0.28069, 0.087102, 0.54455, 0.70003, 0.44778, -0.72565, 0.62309 ]])


emb.shape
# (11, 8)

TensorFlow में एंबेडिंग लुकअप

अब हम देखेंगे कि हम कुछ मनमाने इनपुट वाक्य के लिए एम्बेडिंग लुकअप कैसे कर सकते हैं ।

In [54]: from collections import OrderedDict

# embedding as TF tensor (for now constant; could be tf.Variable() during training)
In [55]: tf_embedding = tf.constant(emb, dtype=tf.float32)

# input for which we need the embedding
In [56]: input_str = "like the country"

# build index based on our `vocabulary`
In [57]: word_to_idx = OrderedDict({w:vocab.index(w) for w in input_str.split() if w in vocab})

# lookup in embedding matrix & return the vectors for the input words
In [58]: tf.nn.embedding_lookup(tf_embedding, list(word_to_idx.values())).eval()
Out[58]: 
array([[ 0.36807999,  0.20834   , -0.22318999,  0.046283  ,  0.20097999,
         0.27515   , -0.77126998, -0.76804   ],
       [ 0.41800001,  0.24968   , -0.41242   ,  0.1217    ,  0.34527001,
        -0.044457  , -0.49687999, -0.17862   ],
       [-0.13530999,  0.15485001, -0.07309   ,  0.034013  , -0.054457  ,
        -0.20541   , -0.60086   , -0.22407   ]], dtype=float32)

निरीक्षण करें कि हमने अपनी शब्दावली में शब्दों के सूचकांकों का उपयोग करके अपने मूल एम्बेडिंग मैट्रिक्स (शब्दों के साथ) से एम्बेडिंग कैसे प्राप्त की ।

आमतौर पर, इस तरह के एक एम्बेडिंग लुकअप पहली परत (कहा जाता है) द्वारा किया जाता है एंबेडिंग लेयर ) जो बाद में इन एम्बेडिंग को आगे की प्रक्रिया के लिए RNN / LSTM / GRU लेयर्स तक पहुंचाता है।


साइड नोट : आमतौर पर शब्दावली में एक विशेष भी होगाunk टोकन । इसलिए, यदि हमारी इनपुट वाक्य से एक टोकन हमारी शब्दावली में मौजूद नहीं है, तो अनुक्रमणिका unkमैट्रिक्स में देखे जाने वाले अनुक्रमणिका को देखा जाएगा।


PS ध्यान दें कि embedding_dimensionएक हाइपरपैरेट है जो किसी को अपने आवेदन के लिए ट्यून करना पड़ता है लेकिन Word2Vec जैसे लोकप्रिय मॉडल और GloVe300 प्रत्येक शब्द का प्रतिनिधित्व करने के लिए आयाम वेक्टरका उपयोगकरते हैं।

बोनस रीडिंग word2vec स्किप-ग्राम मॉडल


17

यहाँ लुकअप एम्बेडिंग की प्रक्रिया का चित्रण है।

चित्र: लुकअप प्रक्रिया एम्बेड करना

चिंता की बात है, यह एक एम्बेडिंग परत की इसी पंक्तियों को प्राप्त करता है, जिसे आईडी की सूची द्वारा निर्दिष्ट किया गया है और एक टेंसर के रूप में प्रदान करता है। यह निम्नलिखित प्रक्रिया के माध्यम से प्राप्त किया जाता है।

  1. एक प्लेसहोल्डर को परिभाषित करें lookup_ids = tf.placeholder([10])
  2. एक एम्बेडिंग परत को परिभाषित करें embeddings = tf.Variable([100,10],...)
  3. टेंसरफ़्लो ऑपरेशन को परिभाषित करें embed_lookup = tf.embedding_lookup(embeddings, lookup_ids)
  4. दौड़कर परिणाम प्राप्त करें lookup = session.run(embed_lookup, feed_dict={lookup_ids:[95,4,14]})

6

जब परम दसियों उच्च आयामों में होता है, तो आईडी केवल शीर्ष आयाम को संदर्भित करता है। हो सकता है कि अधिकांश लोगों के लिए यह स्पष्ट हो लेकिन मुझे यह समझने के लिए निम्नलिखित कोड चलाना होगा:

embeddings = tf.constant([[[1,1],[2,2],[3,3],[4,4]],[[11,11],[12,12],[13,13],[14,14]],
                          [[21,21],[22,22],[23,23],[24,24]]])
ids=tf.constant([0,2,1])
embed = tf.nn.embedding_lookup(embeddings, ids, partition_strategy='div')

with tf.Session() as session:
    result = session.run(embed)
    print (result)

बस 'div' रणनीति की कोशिश कर रहा है और एक टेंसर के लिए, इससे कोई फर्क नहीं पड़ता।

यहाँ उत्पादन है:

[[[ 1  1]
  [ 2  2]
  [ 3  3]
  [ 4  4]]

 [[21 21]
  [22 22]
  [23 23]
  [24 24]]

 [[11 11]
  [12 12]
  [13 13]
  [14 14]]]

3

इसे देखने का एक और तरीका है, मान लें कि आप दसियों को एक आयामी सरणी में समतल करते हैं, और फिर आप एक लुकअप कर रहे हैं

(उदाहरण) Tensor0 = [1,2,3], Tensor1 = [4,5,6], Tensor2 = [7,8,9]

चपटा आउट टेंसर इस प्रकार होगा [1,4,7,2,5,8,3,6,9]

अब जब आप [0,3,4,1,7] की खोज करते हैं, तो यह [1,2,5,4,6] को झुका देगा।

(i, e) यदि लुकअप वैल्यू उदाहरण के लिए 7 है, और हमारे पास 3 टेनर्स (या 3 पंक्तियों के साथ एक टेन्सर) है, तो

7/3: (अनुस्मारक 1 है, उद्धरण 2 है) इसलिए Tensor1 का दूसरा तत्व दिखाया जाएगा, जो 6 है


2

चूँकि मुझे भी इस फंक्शन से इंट्रस्ट किया गया था, इसलिए मैं अपने दो सेंट दे दूँगा।

जिस तरह से मैं इसे 2 डी मामले में देखता हूं वह सिर्फ एक मैट्रिक्स गुणा के रूप में है (यह अन्य आयामों के लिए सामान्यीकृत करना आसान है)।

एन प्रतीकों के साथ एक शब्दावली पर विचार करें। उसके बाद, आप एक प्रतीक x का प्रतिनिधित्व कर सकते हैं आयाम Nx1, एक-गर्म-एन्कोडेड के वेक्टर के रूप में ।

लेकिन आप इस प्रतीक का प्रतिनिधित्व Nx1 के वेक्टर के रूप में नहीं, बल्कि Mx1 के आयामों के साथ करना चाहते हैं, जिसे y कहा जाता है ।

तो, x को y में बदलने के लिए , आप MxN के आयामों के साथ मैट्रिक्स E का उपयोग और एम्बेड कर सकते हैं :

y = एक्स

यह अनिवार्य रूप से tf.nn.embedding_lookup (params, ids, ...) कर रहा है, इस बारीकियों के साथ कि आईडी सिर्फ एक संख्या है जो एक-गर्म-एन्कोडेड वेक्टर x में 1 की स्थिति का प्रतिनिधित्व करती है ।


0

अशर स्टर्न के जवाब में जोड़कर, paramsएक विभाजन के रूप में व्याख्या की गई है एक बड़े एम्बेडिंग टेंसर के के । यह पूर्णतया एम्बेडिंग टेंसर का प्रतिनिधित्व करने वाला एकल टेंसर हो सकता है, या पहले आयाम को छोड़कर सभी समान आकार के एक्स टेंसर्स की सूची हो सकती है, शार्प्ड एम्बेडिंग टेनर्स का प्रतिनिधित्व करता है।

फ़ंक्शन tf.nn.embedding_lookupको इस तथ्य पर विचार करते हुए लिखा गया है कि एम्बेडिंग (परम) बड़े होंगे। इसलिए हमें जरूरत है partition_strategy

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.