我正在尝试理解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...
目前尚不清楚预先计算这些值的好处是什么。有人可以解释一下吗?
答案 0 :(得分:3)
该表格包含exp
到-6
范围内参数的6
值。该函数在1001点采样。
同一源文件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)
)
答案 1 :(得分: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]范围内。用i / EXP_TABLE_SIZE替换x,你得到代码中的第一行。因此,第一行计算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值得到索引。
最后,你得到后勤(f)
答案 2 :(得分:1)
您经常会看到有限状态机中使用的这些类型的表。这些表通常在运行时生成,并且基本上提供更快的执行时间,代价是分配用于存储它的内存。
计算/生成表后,您需要做的就是正确索引表。我们的想法是,查找和索引现有表比每次从头开始执行计算要快得多。
答案 3 :(得分:0)
这是一个很好的问题,有一些很棒的答案!
什么是 ExpTable 用于? Writing exponential functions from tables
如果你还不熟悉它的使用,可能值得通过exp上的优秀Kahn Academy Series。
你可以在这里看到:
&#39; exp&#39;函数应用于向量(v&#34; 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行,上面的代码片段,再次在:468,以及word2vec.c代码文件中的499,查看是按照刘鹏的说法进行的。
可以在此处阅读精彩的博客以获取更多信息:Word2Vec Implementations of Gradient and expTable