【问题标题】:Stochastic Gradient Descent for Linear Regression on partial derivatives偏导数线性回归的随机梯度下降
【发布时间】:2018-10-24 00:13:07
【问题描述】:

我正在通过考虑偏导数 (df/dm) 和 (df/db) 手动实现线性回归的随机梯度下降

目标是我们必须随机选择 w0(权重)然后收敛它们。 由于这是随机的,我们必须在每次运行时抽取数据集的样本

学习率最初应该是 1,每次运行后它应该减少 2 所以当 wK+1 等于 wK (k=1,2,3,......) 那么循环应该停止

这是在 Sklearn 中的波士顿数据集上实现的

因为我是 python 新手,所以没有使用函数 下面是代码:

r= 1
m_deriv = 0
b_deriv = 0
learning_rate = 1
it = 1
w0_random = np.random.rand(13)
w0 = np.asmatrix(w0_random).T
b = np.random.rand()
b0 = np.random.rand()
while True:
    df_sample = bos.sample(100)

    price = df_sample['price']

    price = np.asmatrix(price)

    xi = np.asmatrix(df_sample.drop('price',axis=1))

    N = len(xi)

    for i in range(N):
   # -2x * (y-(mx +b))     
        m_deriv += np.dot(-2*xi[i].T , (price[:,i] - np.dot(xi[i] , w0_random) + b))

    # -2(y - (mx + b))
        b_deriv += -2*(price[:,i] - (np.dot(xi[i] , w0_random) + b))

    w0_new = m_deriv * learning_rate
    b0_new = b_deriv * learning_rate
    w1 = w0 - w0_new
    b1 = b0 - b0_new

    it += 1
    if (w0==w1).all():
        break
    else:
        w0 = w1
        b0 = b1
        learning_rate = learning_rate/2

当循环运行时,w 和 b 的值都很大。他们没有正确收敛 循环哪里出错了,所以它导致了更高的值以及如何解决它。

【问题讨论】:

    标签: python pandas numpy gradient-descent


    【解决方案1】:

    在上述情况下,在处理xi 之前使用StandardScaler 会产生良好的结果,并使用w1 而不是w0_random

    from sklearn.preprocessing import StandardScaler
    import numpy as np
    bos['PRICE'] = boston.target
    X = bos.drop('PRICE', axis = 1)
    Y = bos['PRICE']
    df_sample =X[:100]
    price =Y[:100]
    xi_1=[]
    price_1=[]
    N = len(df_sample)
    for j in range(N):
        scaler = StandardScaler()
        scaler.fit(df_sample) 
        xtrs = scaler.transform(df_sample)
        xi_1.append(xtrs)
        yi=np.asmatrix(price)
        price_1.append(yi)
    #print(price_1)
    #print(xi_1)
    xi=xi_1   
    price=price_1
    r= 1
    m_deriv = 0
    b_deriv = 0
    learning_rate = 1
    it = 1
    w0_random = np.random.rand(13)
    w0 = np.asmatrix(w0_random).T
    b = np.random.rand()
    b0 = np.random.rand() 
    while True:
       for i in range(N):
           # -2x * (y-(mx +b))
           w1=w0
           b1=b0
           m_deriv = np.dot(-2*xi[i].T , (price[i] - np.dot(xi[i] , w1) + b1))
           # -2(y - (mx + b))
           b_deriv = -2*(price[i] - (np.dot(xi[i] , w1) + b1))
       w0_new = m_deriv * learning_rate
       b0_new = b_deriv * learning_rate
       w1 = w0 - w0_new
       b1 = b0 - b0_new
       it += 1
       if (w0==w1).all():
           break
       else:
           w0 = w1
           b0 = b1
           learning_rate = learning_rate/2
    print("m_deriv=",m_deriv)
    print("b_driv",b_deriv) 
    

    【讨论】:

      【解决方案2】:

      您不会在每次迭代后更新w 系数。在你的内部循环中,你总是使用w0_random,而你应该使用更新的权重w1。您需要在每次迭代后存储更新的值w1,以便在下一次迭代中使用它们来计算导数。

      我还建议将您的数据标准化为具有 mean=0std=1 以避免大数字。

      算法收敛主要是因为经过一些迭代后学习率变得非常小,因此默认为w1==w0-learing_rate*diff*derivative。它没有收敛,因为它找到了当前形式的解决方案。

      【讨论】:

      • 感谢您的帮助,尽管我将 w0_random 更改为 w0,但我得到了更高的值。
      • 权重越来越高的事实没有错。您想要最小化的是成本函数。当然,如果你没有标准化你的特征和目标,你的权重可能会变大并变得不稳定。我认为通过如此快地降低学习率,您也没有时间学习。最后你应该允许一个小的精度偏差,而不是检查w0==w1
      猜你喜欢
      • 1970-01-01
      • 2021-06-19
      • 1970-01-01
      • 1970-01-01
      • 2017-06-20
      • 2019-10-09
      • 1970-01-01
      • 2016-10-22
      • 1970-01-01
      相关资源
      最近更新 更多