我提的问题是:
“我使用单层GRU训练minist数据集时,准确率一直处于下图的状态是为什么?
什么原因引起的?”
这种debug就比较难受,因为程序是能跑的,任何“error”都没有出。这就表明在程序中有某些小细节没有调试好。
后来我在问答区中博主“皮皮宽”的回答中受到了一些启发,大佬说“MNIST数据集是个10分类的问题,完全随机判断也有10%的概率蒙对。。说明这个模型完全没起到作用”。因此我怀疑是模型搭建的问题。
于是我在从模型的最开始一直到最后能加print的地方都加上了输出,比对结果是否合理与正确。让我费解的地方来了,从头到尾输出都是合理的,这说明模型的搭建是没有问题的。
模型没问题的话,那就只能是输入到模型的数据(初始化)有问题了。(此处也特别鸣谢 “皮皮宽”大佬的指点,也推荐各位去这位大佬的博客逛一逛,会有收获的)
果然下图所示的76行引起了我的注意,这里的输出每行都一样,这个显然不对,因为每行都一样的话就说明输入的mnist特征都是一样的,但是我们知道minist数据集每张图片是28*28的,它每行的特征不可能一样。所以这里需要好好看一下是怎么回事。
76行的输入hidden引起了我的注意,我发现吧中间的-1改为-16时,准确率会从第一个epoch高达20+%开始到52%封顶。这个是让我比较疑惑的地方。然后改成-16之后的数的时候封顶的准确率又会逐渐的降下去。这里其实理论上应该付-1,因为我理解的是因为这里是全连接层,全连接层的输入就应当是隐藏层的最后一个维度的输出,因此需要付-1也就是隐藏层的最后一层。这里我理解得可能不是很准确,如果有明白的大佬希望可以批评指正。
然后我主要关注了一下隐藏状态h的来龙去脉,最后我无意中把GRUcell类中的前向传播方法的第一行改为了下图所示的方式,程序就很神奇的正常了!这里我的理解就是第二段中所说的意思:如果写成h_input=h[0]的话,那也就说明我输入的隐藏状态只输入了0维的数据,其他维就不管了,这也就导致上面的输出每一行都是一样的。那么把“【0】”去掉后,就能正常的把隐藏状态的所有维度的特征都给输入进去了。应该就是这么个原理。
PS:我之前还遇到过一次这种情况(准确率一直输出11.35)。当时的问题背景是:有一个剪枝算法它需要和掩膜矩阵进行配合,而掩膜最后的输出应该不是0就是1,但是我把最后的输出弄成了若干个小数,因此程序直接把小数都默认成0了,这也导致了上面图的情况。
随手记录一下我debug的过程与疑点,供大家参考。若有不足之处请大佬们批评指正。