多层感知器不收敛

数据挖掘 神经网络 梯度下降 毫升
2022-02-26 04:06:34

我一直在 MATLAB 中编写自己的多层感知器,它编译时没有错误。我的训练数据特征 x 的值从 1 到 360,训练数据输出 y 的值是sin(x)

问题是我的 MLP 只会降低前几次迭代的成本,并且会卡在 0.5。我试过包括动量,但它没有帮助,增加层数或增加神经元根本没有帮助。我不确定为什么会这样。

我已在此处上传文件供您参考。

我的代码摘要是:

  1. 我使用 min-max 或 zscore 规范化我的输入数据

  2. 在 -1 到 1 的范围内初始化随机权重和偏差

    for i = 1:length(nodesateachlayer)-1    
     weights{i} = 2*rand(nodesateachlayer(i),nodesateachlayer(i+1))-1; 
     bias{i} = 2*rand(nodesateachlayer(i+1),1)-1; 
    end
    
  3. 然后,我做一个前向传递,其中输入乘以权重并加上偏差,然后由传递函数(sigmoid)激活

    for i = 2:length(nodesateachlayer)
         stored{i} = nactivate(bsxfun(@plus,(weights{i-1}'*stored{i-1}),bias{i-1}),activation);    
     end
    
  4. 然后计算误差然后做一个反向传递

    dedp = 1/length(normy)*error;
     for i = length(stored)-1:-1:1
         dpds = derivative(stored{i+1},activation);
         deds = dpds'.*dedp;
         dedw = stored{i}*deds; 
         dedb = ones(1,rowno)*deds;
         dedp = (weights{i}*deds')';
         weights{i}=weights{i}-rate.*dedw;
         bias{i}=bsxfun(@minus,bias{i},rate.*dedb');
     end
    
  5. 我在每次迭代中都绘制了成本以查看下降情况

我认为代码有问题,那么错误可能出在哪里?

1个回答

我对您的问题的看法是,小型网络很少起作用。上述方法使用神经网络来学习函数虽然这个问题看起来很简单,但不能指望通过一个非常小的网络来解决(上面的模型使用了一个 5 层的 MLP,隐藏大小 [5,6,7],很小)。y=sin(x)

即使正确实施了反向传播,模型会学到什么吗?不,我想 Tensorflow 正确地实现了反向传播,这是使用 Tensorflow 的结果: 图。1

你看,它几乎什么都没学到。事实上,如上所述,MSE 损失非常接近 0.5。

我的建议是尝试隐藏大小为 256 的 3 层 MLP。结果如下:

图2

你可以看到它好多了。现在 MSE<0.1。

- - - - - - - - - 代码 - - - - - - - - - - -

x_ =np.atleast_2d(np.arange(0,360,1)).T
y_ = np.atleast_2d(np.sin(x_/180*np.pi))
g = tf.Graph()
使用 g.as_default():
    使用 tf.variable_scope("mlp"):
        input_x = tf.placeholder(shape=[None, 1], dtype=tf.float32)
        input_y = tf.placeholder(shape=[None,1], dtype=tf.float32)
        layer1 = tf.layers.dense(输入=input_x,单位=256,激活=tf.nn.sigmoid)
        #layer2 = tf.layers.dense(输入=input_x,单位=6,激活=tf.nn.sigmoid)
        #layer3 = tf.layers.dense(输入=input_x,单位=7,激活=tf.nn.sigmoid)
        output_y = tf.layers.dense(inputs=layer1, units=1) #inputs=layer1
        损失 = tf.losses.mean_squared_error(input_y, output_y)
        train_op = tf.train.AdagradOptimizer(0.01).minimize(loss)
    使用 tf.Session() 作为 sess:
        sess.run(tf.global_variables_initializer())
        对于范围内的纪元(300):
            _, loss_ = sess.run((train_op, loss), feed_dict={input_x:x_, input_y:y_})
        y_hat_ = sess.run(output_y, feed_dict={input_x:x_, input_y:y_})
        打印(损失_,结束='\t')
plt.plot(x_,y_, 'g', x_,y_hat_,'b')
plt.legend(['基本事实', '预测'])