649453932 / Chinese-Text-Classification-Pytorch

中文文本分类,TextCNN,TextRNN,FastText,TextRCNN,BiLSTM_Attention,DPCNN,Transformer,基于pytorch,开箱即用。
MIT License
5.27k stars 1.23k forks source link

您好,能问下以下FastText两个函数里面的的数值和公式是怎么来的嘛? #6

Open YYGe01 opened 5 years ago

YYGe01 commented 5 years ago

def biGramHash(sequence, t, buckets): t1 = sequence[t - 1] if t - 1 >= 0 else 0 return (t1 * 14918087) % buckets

def triGramHash(sequence, t, buckets):
    t1 = sequence[t - 1] if t - 1 >= 0 else 0
    t2 = sequence[t - 2] if t - 2 >= 0 else 0
    return (t2 * 14918087 * 18408749 + t1 * 14918087) % buckets

您好,有几个问题: 1、buckets=self.n_gram_vocab = 250499 ,这个参数数值250499是怎么来的呢。 2、4918087、14918087、 18408749的数值是怎么来的呢。 3、这种return的计算方式不太明白呢,可以给个学习参考链接嘛。 非常谢谢!

649453932 commented 4 years ago

就是用几个质数做的简单的哈希函数,这些数都是可以改的,你也可以自己定义一个哈希函数,目的就是把所有n-gram都映射到一个词表中。 (每个n-gram会得到一个数值,该数值对词表大小取模,得到它在词表中的位置) 词表大小也是自己定的,理论上词表越大,效果越好;词表越小,不同的n-gram就越有可能映射到词表的同一个位置。 但是这里要考虑到内存、耗时的问题(性价比),还有就是有的n-gram组合可能永远不会出现,所以词表也不是越大越好的。

TestNLP commented 4 years ago

就是用几个质数做的简单的哈希函数,这些数都是可以改的,你也可以自己定义一个哈希函数,目的就是把所有n-gram都映射到一个词表中。 (每个n-gram会得到一个数值,该数值对词表大小取模,得到它在词表中的位置) 词表大小也是自己定的,理论上词表越大,效果越好;词表越小,不同的n-gram就越有可能映射到词表的同一个位置。 但是这里要考虑到内存、耗时的问题(性价比),还有就是有的n-gram组合可能永远不会出现,所以词表也不是越大越好的。

你好,我想问一下,你这个函数计算,比如t1 = sequence[t - 1] if t - 1 >= 0 else 0 return (t1 * 14918087) % buckets 输入是一个句子的token的idx列表,然后依次输入idx,通过这个公式算的值是buckets中的一个位置,我想问的是,这个位置如何体现2-gram思想的呢?还有那个3-gram公式映射和2-gram相似,怎么体现出2-gram和3-gram的差异的呢?

TestNLP commented 4 years ago

就是用几个质数做的简单的哈希函数,这些数都是可以改的,你也可以自己定义一个哈希函数,目的就是把所有n-gram都映射到一个词表中。 (每个n-gram会得到一个数值,该数值对词表大小取模,得到它在词表中的位置) 词表大小也是自己定的,理论上词表越大,效果越好;词表越小,不同的n-gram就越有可能映射到词表的同一个位置。 但是这里要考虑到内存、耗时的问题(性价比),还有就是有的n-gram组合可能永远不会出现,所以词表也不是越大越好的。

正常的逻辑不应该是构造一个2-gram和3-gram字典,然后根据这个字典对句子进行idx转换吗?不理解使用哈希的目的。个人觉得没有体现出gram思想中的上下文顺序,因为只要字相同,其n-gram就一样,实际的情况是字一样,上下文也不一定一样。

LChanger commented 4 years ago

就是用几个质数做的简单的哈希函数,这些数都是可以改的,你也可以自己定义一个哈希函数,目的就是把所有n-gram都映射到一个词表中。 (每个n-gram会得到一个数值,该数值对词表大小取模,得到它在词表中的位置) 词表大小也是自己定的,理论上词表越大,效果越好;词表越小,不同的n-gram就越有可能映射到词表的同一个位置。 但是这里要考虑到内存、耗时的问题(性价比),还有就是有的n-gram组合可能永远不会出现,所以词表也不是越大越好的。

正常的逻辑不应该是构造一个2-gram和3-gram字典,然后根据这个字典对句子进行idx转换吗?不理解使用哈希的目的。个人觉得没有体现出gram思想中的上下文顺序,因为只要字相同,其n-gram就一样,实际的情况是字一样,上下文也不一定一样。

我也感觉应该把t也加上,否则的话2-gram无法体现上下字的联系,3-gram在此变成了2-gram

ABBlankSpace commented 4 years ago

楼主,能问一下self.n_gram_vocab = 250499 # ngram 词表大小 这个词表大小的值是怎么得到的吗?

li199603 commented 4 years ago

那两个函数看起来2-gram变成1-gram,3-gram变成2-gram了。是不是应该把t也考虑进去?

zelin-x commented 3 years ago

那两个函数看起来2-gram变成1-gram,3-gram变成2-gram了。是不是应该把t也考虑进去?

请问您有已经测试过了吗,为什么我将t加上之后,测试集的正确率下降了2%

zelin-x commented 3 years ago

就是用几个质数做的简单的哈希函数,这些数都是可以改的,你也可以自己定义一个哈希函数,目的就是把所有n-gram都映射到一个词表中。 (每个n-gram会得到一个数值,该数值对词表大小取模,得到它在词表中的位置) 词表大小也是自己定的,理论上词表越大,效果越好;词表越小,不同的n-gram就越有可能映射到词表的同一个位置。 但是这里要考虑到内存、耗时的问题(性价比),还有就是有的n-gram组合可能永远不会出现,所以词表也不是越大越好的。

正常的逻辑不应该是构造一个2-gram和3-gram字典,然后根据这个字典对句子进行idx转换吗?不理解使用哈希的目的。个人觉得没有体现出gram思想中的上下文顺序,因为只要字相同,其n-gram就一样,实际的情况是字一样,上下文也不一定一样。

我也感觉应该把t也加上,否则的话2-gram无法体现上下字的联系,3-gram在此变成了2-gram

我觉得在模型输入的时候,将unigram,bigram和trigram embedding之后张量拼接就已经可以保证语序信息的输入了,因为n-gram词表大小是固定的,例如‘我是’和‘我像’,‘像’和‘是’的bigram映射到词表的同一位置,是不是可以保证相似特征的提取呢?而将t加入后这两个词映射之后就完全不同了,与普通的词袋模型似乎没有区别? (仅代表个人想法,希望大佬指正)

li199603 commented 3 years ago

就是用几个质数做的简单的哈希函数,这些数都是可以改的,你也可以自己定义一个哈希函数,目的就是把所有n-gram都映射到一个词表中。 (每个n-gram会得到一个数值,该数值对词表大小取模,得到它在词表中的位置) 词表大小也是自己定的,理论上词表越大,效果越好;词表越小,不同的n-gram就越有可能映射到词表的同一个位置。 但是这里要考虑到内存、耗时的问题(性价比),还有就是有的n-gram组合可能永远不会出现,所以词表也不是越大越好的。

正常的逻辑不应该是构造一个2-gram和3-gram字典,然后根据这个字典对句子进行idx转换吗?不理解使用哈希的目的。个人觉得没有体现出gram思想中的上下文顺序,因为只要字相同,其n-gram就一样,实际的情况是字一样,上下文也不一定一样。

我也感觉应该把t也加上,否则的话2-gram无法体现上下字的联系,3-gram在此变成了2-gram

我觉得在模型输入的时候,将unigram,bigram和trigram embedding之后张量拼接就已经可以保证语序信息的输入了,因为n-gram词表大小是固定的,例如‘我是’和‘我像’,‘像’和‘是’的bigram映射到词表的同一位置,是不是可以保证相似特征的提取呢?而将t加入后这两个词映射之后就完全不同了,与普通的词袋模型似乎没有区别? (仅代表个人想法,希望大佬指正)

我没测试过把t加进去的情况。这里变量命名容易混淆,准确的说应该是把sequence[t]也考虑进哈希函数中更合理。bigram只用了sequence[t-1]做哈希,那对于‘我是’和‘我像’的bigram哈希结果是一样的,感觉很不合理

Mingrg commented 3 years ago

楼主,能问一下self.n_gram_vocab = 250499 # ngram 词表大小 这个词表大小的值是怎么得到的吗?

您好,请问这个是怎么得到的现在您知道了吗?我也好奇

gosundy commented 10 months ago

我理解是将n-gram映射成n_gram_vocab里相应的位置,n_gram_vocab是远大于实际的vocab的。举个例子:“我是中国人”在vocab里是:"我","是","中","国","人",如果是bigram:"我是","是中","中国","国人",将"我是"给hash了一下映射到比vocab更远的位置,该位置的范围是n_gram_vocab,这样尽量不会和vocab里的冲突。trigram也是如此

Josoope commented 5 months ago

想问问为啥出现这个问题AttributeError: 'Config' object has no attribute 'n_gram_vocab' 是哪里没赋值吗