1

我正在尝试理解word2vec项目中的代码。我指的文件是word2vec.c。代码片段是:

#define EXP_TABLE_SIZE 1000
#define MAX_EXP 6
//...snip...
expTable = (real *)malloc((EXP_TABLE_SIZE + 1) * sizeof(real));
  for (i = 0; i < EXP_TABLE_SIZE; i++) {
    // Precompute the exp() table
    expTable[i] = exp((i / (real)EXP_TABLE_SIZE * 2 - 1) * MAX_EXP); 
    // Precompute f(x) = x / (x + 1)
    expTable[i] = expTable[i] / (expTable[i] + 1);
  }
//...snip...

目前尚不清楚预先计算这些值有什么好处。有人可以解释一下吗?

4

4 回答 4

3

这段代码计算 [-6, 6) 范围内的逻辑函数表,步长为 1 / EXP_TABLE_SIZE * 2 = 0.002。我会详细解释。

如果 x 在 [0, 1) 范围内,则 x * 2 - 1 将在 [-1, 1) 范围内,并且 (x * 2 - 1) * MAX_EXP 将在 [-MAX_EXP, MAX_EXP) 范围内。将 x 替换为 i / EXP_TABLE_SIZE,您将得到代码的第一行。因此,第一行计算 EXP(x),x 在 [-6, 6) 范围内,步长为 1 / EXP_TABLE_SIZE * 2。第二行,EXP(X) / (EXP(X) + 1) 为一个逻辑函数。

使用表格时,需要将 (-6, 6) 范围内的实数转换为 [0, 1000) 范围内的索引号。在代码中 f 在范围 (-6, 6) 内。f + MAX_EXP 在 (0, 12) 范围内,(f + MAX_EXP) / MAX_EXP / 2 在 (0, 1) 范围内。将此值与 EXP_TABLE_SIZE 相乘,您将根据 f 值获得索引。

最后,你得到logistic(f)

于 2015-01-24T14:21:14.937 回答
2

该表保存范围为 至exp的参数的值。该函数在 1001 个点处采样。-66

同一源文件中的以下代码word2vec.c使用此表来计算指数:

    ...
    if (f <= -MAX_EXP) continue;
    else if (f >= MAX_EXP) continue;
    else f = expTable[(int)((f + MAX_EXP) * (EXP_TABLE_SIZE / MAX_EXP / 2))];
    ...

(因此,如果您想知道表格的第一个单元格有什么值 - 它是exp(-6)

于 2014-02-01T21:15:47.520 回答
1

您经常会在有限状态机中看到这些类型的表。这些表通常在运行时生成,基本上以牺牲分配用于存储它的内存为代价提供更快的执行时间。

计算/生成表格后,您需要做的就是正确索引表格。这个想法是查找和索引现有表比每次从头开始计算要快得多。

于 2014-02-01T19:10:38.833 回答
0

这是一个很好的问题,有一些很好的答案!

ExpTable有什么用?从表中编写指数函数

如果您还不熟悉它们的用途,那么可能值得通过 exp 上优秀的卡恩学院系列。

你可以在这里看到:

在此处输入图像描述

'exp' 函数应用于向量 (v"sub wo Transpose) 乘以 (v sub wI)

你可以在这里阅读关于 Word2Vec 的论文,Distributed Representations of Words and Phrases and their Compositionality

else f = expTable[(int)((f + MAX_EXP) * (EXP_TABLE_SIZE / MAX_EXP / 2))];

如您所见,在代码段上方的第 443 行,再次在 word2vec.c 代码文件的第 468 和 499 行,按照 Peng Liu 的说法执行查找。

可以在此处阅读精彩的博客以获取更多信息:渐变和 expTable 的 Word2Vec 实现

于 2017-01-25T09:35:22.890 回答