使用Python的线性回归

时间:2018-04-22 20:53:04

标签: python linear-regression

我曾经在python中使用ML包进行线性回归,但为了自我满足,我从头开始编码。损失从0.90左右开始并且由于某种原因不断增加(不学习)。我不明白我可能犯了什么错误。

  1. 将数据集标准化为预处理的一部分
  2. 用参数W的MLE估计初始化权重矩阵,即(X ^ TX)^ - 1X ^ TY
  3. 计算输出
  4. 计算损失函数的梯度SSE(平方误差之和)与参数W和偏差B
  5. 使用渐变来使用渐变下降来更新参数。
  6. 
    
        import preprocess as pre
        import numpy as np
        import matplotlib.pyplot as plt
    
        data = pre.load_file('airfoil_self_noise.dat')
        data = pre.organise(data,"\t","\r\n")
        data = pre.standardise(data,data.shape[1])
    
        t = np.reshape(data[:,5],[-1,1])
        data = data[:,:5]
    
        N = data.shape[0]
        M = 5
        lr = 1e-3
    
        # W = np.random.random([M,1])
        W = np.dot(np.dot(np.linalg.inv(np.dot(data.T,data)),data.T),t)
        data = data.T # Examples are arranged in columns [features,N]
        b = np.random.rand()
        epochs = 1000000
        loss = np.zeros([epochs])
        for epoch in range(epochs):
          if epoch%1000 == 0:
            lr /= 10
          # Obtain the output
          y = np.dot(W.T,data).T + b
          sse = np.dot((t-y).T,(t-y))
          loss[epoch]= sse/N
          var = sse/N
          # log likelihood
          ll = (-N/2)*(np.log(2*np.pi))-(N*np.log(np.sqrt(var)))-(sse/(2*var))
    
          # Gradient Descent
    
          W_grad = np.zeros([M,1])
          B_grad = 0
          for i in range(N):
            err = (t[i]-y[i])
            W_grad += err * np.reshape(data[:,i],[-1,1])
            B_grad += err
    
          W_grad /= N
          B_grad /= N
    
          W += lr * W_grad
          b += lr * B_grad
    
          print("Epoch: %d, Loss: %.3f, Log-Likelihood: %.3f"%(epoch,loss[epoch],ll))
        plt.figure()
        plt.plot(range(epochs),loss,'-r')
        plt.show()
    
    

    现在,如果你运行上面的代码,你可能不会发现任何错误,因为我正在做W += lr * W_grad而不是W -= lr * W_grad。我想知道为什么会这样,因为它是从旧的权重矩阵中减去梯度的梯度下降公式。当我这样做时,错误不断增加。我错过了什么?

1 个答案:

答案 0 :(得分:0)

找到它。问题是我从一张显然不正确的幻灯片中获取了丢失函数的梯度(至少它并非完全错误,而是它已经指向最陡的下降),当我从重量中减去时它开始指向最大的增长方向。这就是我所观察到的结果。

我做了损失函数的偏导数来澄清,得到了这个:

W_grad += data[:,i].reshape([-1,1])*(y[i]-t[i]).reshape([])

这指向了最大增长的方向,当我将它与-lr相乘时,它开始指向最陡的下降,并开始正常工作。