多层感知机的从零开始实现 讨论区


#1

http://zh.diveintodeeplearning.org/chapter_deep-learning-basics/mlp-scratch.html


#2

为什么weight_scale变大变小都 会导致精度下降???

weight_scale应该只是控制正态分布的sigma, 也就是权重的集中(于0附近)还是分散,


#3

权重的大小应该大体上跟unit个数反相关,这样算出来的值差不多在一个比较合适的范围,防止diverge或者vanish


#4

有没有比较详细的讨论这个的文章, 或者搜索什么关键词???

还不是很明白, 为什么控制权重的初始分布影响会这么大. 只知道scale小的话, weights会集中在0附近.


#5

Andrew Ng在coursera的课程提到过这个,dl的书上应该都会讲到类似的问题吧,参数初始化的策略。


于置顶 #6

#7

我测试过 变小 精度会上升啊; 变大 loss会变大 精度会下降


#8

请问一下 这个输出层为什么不用加上activation参数 ??? 之前一章从零开始的多层感知机中 就加了激活函数的操作。image


#9

之前的版本里从零开始的章节里relu好像加多了…现在应该已经删了,可以更新一下


#10

是吗?:joy: 感觉在输出层加入了激活函数好像影响不大 这是为什么?


#11

记得Ng讲的初始权重应该在0附近取随机数,


#12

CS231n的课程里有讲到权重初始化的问题,https://zhuanlan.zhihu.com/p/21560667?refer=intelligentunit。 这是知乎上面一个专栏翻译的,想深入了解还有一些论文的链接。可以参考下。


#13

多增加一层隐含层,感觉效果并不是很好。。。。是什么原因呢?


#14

还有请问一下小伙伴们,隐含层神经元个数是256与batchsize大小有关吗,还是随便取得256?效果最好的隐含层个数是需要实验验证出来吧?


#15

初始结果:Loss:0.78-0.38,Train acc:0.70-0.86,Test acc:0.81-0.87

  • 我们使用了 weight_scale 来控制权重的初始化值大小,增大或者变小这个值会怎么样?
    • weight_scale:0.05,Loss:0.70-0.35,Train acc:0.73-0.86,Test acc:0.82-0.88
    • weight_scale:0.002,Loss:0.89-0.38,Train acc:0.66-0.86,Test acc:0.82-0.87
    • 此时看出,5倍的差距对结果影响不大。
      • weight_scale:0.1,Loss:0.75-0.36,Train acc:0.74-0.87,Test acc:0.82-0.87
      • weight_scale:0.001,Loss:0.87-0.37,Train acc:0.66-0.86,Test acc:0.81-0.87
    • 目前没看出来结果之间的差距。
  • 尝试改变 num_hiddens 来控制模型的复杂度
    • num_hiddens:1024,Loss:0.75-0.35,Train acc:0.71-0.87,Test acc:0.83-0.88
    • num_hiddens:64,Loss:0.81-0.39,Train acc:0.69-0.86,Test acc:0.82-0.86
  • 尝试加入一个新的隐含层
    • num_hiddens:256,num_hiddens2:64,Loss:1.27-0.39,Train acc:0.50-0.86,Test acc:0.78-0.86
    • num_hiddens:256,num_hiddens2:256,Loss:1.24-0.48,Train acc:0.52-0.83,Test acc:0.78-0.86

为啥改变weight_scale对结果几乎没有影响,而且,改变隐藏层的神经元数量影响也不大;增加隐藏层也没有什么影响(感觉就是起始变差了,收敛变快了)。希望能找到解答


#16

我尝试先添加一个隐层,这时感觉收敛速度稍微变快,但是精度没什么变化,然后我又尝试添加了六个隐层,这时候模型已经不收敛了,精度一直为0.1左右,这是什么原因呢?是由于使用太多的relu函数导致数据本身的信息丢失么?


#17

应该不是relu函数的问题,我觉得可能是因为隐藏层太多,而数据集比较简单,收敛太快导致过拟合了,你的train acc也是0.1吗?你可以试试把lr调低一些,然后多跑几个epcho看看。


#18

如图。因为没有太多工程代码的经验,求问。


#19

__call__在Block里,会call forward,然后Loss们本身是HybridBlock所以会调用HybridBlock里的forward, 这个forward会call hybrid_forward


#20
from mxnet import autograd as autograd

learning_rate = .5

for epoch in range(5):
    train_loss = 0.
    train_acc = 0.
    for data, label in train_data:
        with autograd.record():
            output = net(data)
            loss = softmax_cross_entropy(output, label)
        loss.backward()
        utils.SGD(params, learning_rate/batch_size)

        train_loss += nd.mean(loss).asscalar()
        train_acc += utils.accuracy(output, label)

    test_acc = utils.evaluate_accuracy(test_data, net)
    print("Epoch %d. Loss: %f, Train acc %f, Test acc %f" % (
        epoch, train_loss/len(train_data),
        train_acc/len(train_data), test_acc))

为什么每次迭代计算图都要重新生成一次呢?@mli

        with autograd.record():
            output = net(data)
            loss = softmax_cross_entropy(output, label)
        loss.backward()