tf.nn.embedding_lookup 함수는 무엇을합니까?


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

이 기능의 의무를 이해할 수 없습니다. 조회 테이블과 같은가요? 각 id (ids)에 해당하는 매개 변수를 반환하는 방법은 무엇입니까?

예를 들어 skip-gram모델에서을 사용 tf.nn.embedding_lookup(embeddings, train_inputs)하면 각각 train_input에 해당하는 임베딩을 찾습니다.


"조회 테이블과 같은가요?" tldr-예. 각 x (ids)에 대해 동료 y (params)를 제공하십시오.
David Refaeli '8

답변:


147

embedding_lookup함수는 params텐서의 행을 검색합니다 . 이 동작은 numpy에서 배열을 사용하여 인덱싱을 사용하는 것과 유사합니다. 예 :

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 텐서의 목록 제공 [2, 64], 기본 동작이 나타내는 것입니다 ids: [0, 3], [1, 4], [2, 5].

partition_strategyids목록 사이에 배포 방법을 제어합니다 . 파티셔닝은 매트릭스가 너무 커서 한 조각으로 유지하기 어려운 대규모 문제에 유용합니다.


21
왜 이런 식으로 부르지 select_rows않습니까?
Lenar Hoyt

12
@LenarHoyt는 이러한 검색 개념이 Word Embeddings에서 비롯 되었기 때문입니다. "행"은 단어의 표현 (삽입)이며 벡터 공간으로 표현되며 그 자체로 유용합니다. 실제 네트워크보다 더 많은 경우가 많습니다.
Lyndon White

2
tensorflow는 임베딩 구조를 어떻게 학습합니까? 이 기능도 그 프로세스를 관리합니까?
vgoklani 2012 년

19
@vgoklani는 아니오의 embedding_lookupid에 해당하는 임베딩을 검색하는 편리한 (및 병렬) 방법을 제공합니다 ids. params손실 함수 (예로서, 직접 또는 간접적으로 그 구성 요소에 사용되는 TF 변수 - 텐서는 통상 훈련 과정의 일부로서 학습하는 TF 변수로 tf.l2_loss옵티 마이저 (예에 의해 최적화된다) tf.train.AdamOptimizer).
Shobhit

5
@ Rafał Józefowicz 왜 "기본 동작은 ID를 나타내는 것입니다 : [0, 3], [1, 4], [2, 5]"? 설명해 주시겠습니까?
Aerin

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]params의 첫 번째 요소 (인덱스 0)가이고 params 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파티션 전략 에 따라 텐서 요소에 해당 하며 기본 파티션 전략은 'mod'입니다.

'mod'전략에서 인덱스 0은 목록에서 첫 번째 텐서의 첫 번째 요소에 해당합니다. 인덱스 1 은 두 번째 텐서 의 첫 번째 요소에 해당합니다 . 인덱스 2 는 세 번째 텐서 의 첫 번째 요소에 해당 합니다. params가 텐서 목록이라고 가정하면 모든 인덱스에 대해 단순히 index 는 (i + 1) 텐서의 첫 번째 요소에 해당합니다 .i0..(n-1)n

이제 n목록 params에는 n텐서 만 포함 되므로 인덱스 는 텐서 n + 1에 해당 할 수 없습니다 . 따라서 index 는 첫 번째 텐서 n두 번째 요소에 해당합니다 . 마찬가지로 index 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은 두 번째 텐서의 첫 번째 요소에 해당합니다.

인덱스 2는 첫 번째 텐서의 두 번째 요소에 해당합니다.

인덱스 3은 두 번째 텐서의 두 번째 요소에 해당합니다.

따라서 결과는 다음과 같습니다.

[ 2  1  2 10  2 20]

8
참고 :을 사용할 수 partition_strategy='div'있고 얻을 수 있습니다 [10, 1, 10, 2, 10, 20]. 즉 id=1첫 번째 매개 변수의 두 번째 요소입니다. 기본적으로 : partition_strategy=mod(기본값) id%len(params): params의 매개 변수 id//len(params)색인 : 위 매개 변수 partition_strategy=*div*의 요소 색인 다른 방법
Mario Alemi

3
@ asher-stern 왜 "mod"전략이 기본인지 설명 할 수 있습니까? "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 임베드 매트릭스에서 찾습니다.


추신 : 그것은 embedding_dimension응용 프로그램에 맞게 조정해야하지만 Word2VecGloVe 와 같은 인기있는 모델 인 하이퍼 매개 변수입니다.300 은 각 단어를 나타내는 차원 벡터를 사용 합니다.

보너스 읽기 word2vec 스킵 그램 모델


17

조회를 포함하는 과정을 묘사 한 이미지는 다음과 같습니다.

이미지 : 임베딩 조회 프로세스

간결하게, ID 목록으로 지정된 포함 레이어의 해당 행을 가져 와서 텐서로 제공합니다. 다음 프로세스를 통해 달성됩니다.

  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

매개 변수 텐서의 치수가 높은 경우 ID는 상단 치수 만 나타냅니다. 어쩌면 대부분의 사람들에게 명백 할 수도 있지만 이해하기 위해 다음 코드를 실행해야합니다.

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

그것을 보는 또 다른 방법은 텐서를 1 차원 배열로 평평하게 한 다음 조회를 수행한다고 가정합니다.

(예) 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 센트를 줄 것이다.

2D 경우에서 보는 방식은 행렬 곱셈과 같습니다 (다른 차원으로 일반화하기 쉽습니다).

N 개의 기호가있는 어휘를 고려하십시오. 그런 다음 기호 x를 나타낼 수 있습니다 를 1- 핫 인코딩 된 차원 Nx1의 벡터로 .

그러나이 기호를 Nx1의 벡터가 아니라 y 라는 Mx1 크기의 벡터로 표현하려고합니다 .

따라서 xy 로 변환하기 위해 MxN 차원의 행렬 E를 사용하고 포함 할 수 있습니다 .

y = E x .

이것은 본질적으로 tf.nn.embedding_lookup (params, ids, ...) 이하는 일이며, id 는 one-hot-encoded vector x 에서 1의 위치를 ​​나타내는 하나의 숫자라는 미묘한 차이가 있습니다.


0

Asher Stern의 답변에 추가 params하면 파티션으로 해석됩니다. 하면 큰 임베딩 텐서 로 . 완전한 임베딩 텐서를 나타내는 단일 텐서이거나 샤드 된 임베딩 텐서를 나타내는 첫 번째 차원을 제외한 모든 모양이 동일한 X 텐서 목록 일 수 있습니다.

이 함수 tf.nn.embedding_lookup는 내장 (매개 변수)이 클 것이라는 사실을 고려하여 작성되었습니다. 따라서 우리는 필요합니다 partition_strategy.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.