我一直在编写一个神经网络,用于识别和标记英语的词性(用 Java 编写)。代码本身没有“错误”或明显缺陷。尽管如此,它并不是在学习——我训练得越多,它预测测试数据的能力也不会改变。以下是有关我所做工作的信息,如果我遗漏了重要内容,请让我更新这篇文章。
我编写了神经网络并在几个不同的问题上对其进行了测试,以确保网络本身能够正常工作。我训练它学习如何将数字加倍、XOR、立方数字,并以相当准确的方式学习 sin 函数。所以,我相当有信心实际的算法是有效的。
使用 sigmoid 激活函数的网络。学习率为 0.3,动量为 0.6。权重初始化为 rng.nextFloat() -.5) * 4
然后我得到了 Brown Corpus 数据集,并使用 NLTK 将标签集简化为“通用”。我使用 NLTK 生成和保存所有语料库和字典数据。出于测试目的,我从语料库中删除了最后 15,000 个句子。我使用语料库的其余部分(大约 40,000 句标记词)进行训练。
神经网络布局如下:每个标签都有一个输入神经元。输出层:每个标签都有一个输出神经元。该网络正在输入 3 个单词:第一个:我们要标记的单词之前的单词,第二个:需要标记的单词,第三个:第二个单词之后的单词。因此,输入的总数是 3x(可能的标签总数)。输入值是 0 到 1 之间的数字。输入层的 3 个单词中的每一个都在字典中进行搜索(由 40,000 个语料库组成,与用于训练的语料库相同)。字典保存了每个单词在语料库中被标记为词性的次数。
例如,单词“cover”被标记为名词 1 次和动词 3 次。
为与该词关联的每个词性计算被标记的百分比,这就是为该特定词输入网络的内容。因此,指定为 NOUN 的输入神经元将接收 0.33,而 VERB 将接收 0.66。保存该单词标签的其他输入神经元接收 0.0 的输入。这是针对要输入的 3 个单词中的每一个进行的。如果一个词是句子的第一个词,则第一组标签全部为 0。如果一个词是句子的最后一个词,则保存下一个词的标签概率的最后一组输入神经元保留为 0 . 我一直在使用 10 个隐藏节点(我已经阅读了许多论文,这似乎是开始测试的好地方)
15,000 个测试句子中没有一个用于制作“词典”。所以,当用这个部分语料库测试网络时,会有一些网络从未见过的词。无法识别的单词将去掉其后缀,并在另一个“字典”中搜索它们的后缀。然后将该单词最可能的任何内容用作它的输入。
这是我的设置,我开始尝试训练网络。我一直在用所有 40,000 个句子训练网络。1 epoch = 40,000 个训练集的每个句子中每个单词的 1 次前向和反向传播。所以,仅仅做 1 个 epoch 就需要几秒钟。仅仅知道概率这个词,网络就做得很好,但是我训练得越多,什么也没有发生。纪元后面的数字是正确标记的单词数除以总单词数。
首次运行 50 个 epoch:0.928218786
100 个时代:0.933130661
500 epochs: 0.928614499 花了大约 30 分钟来训练这个
尝试了 10 个 epoch:0.928953683
仅使用 1 个 epoch 的结果在 0.92 和 0.93 之间变化很大
所以,它似乎没有工作......
然后,我从语料库中取出 55 个句子,并使用同一本词典,该词典包含所有 40,000 个单词的概率。对于这个,我以与训练 XOR 相同的方式训练它——我只使用了这 55 个句子,并且只测试了这 55 个句子的训练网络权重。该网络能够很容易地学习这 55 个句子。使用 120 个 epoch(花费几秒钟),网络从错误标记 3768 和 56 个正确标记(在前几个 epoch)到在第 120 个 epoch 正确标记 3772 和 52 个错误。
这就是我所在的位置,我已经尝试调试了一天多,但还没有弄清楚任何事情。