用梯度下降法求解w,b。

预设函数 Hypothesis Function
z=wx+bz = wx+bz=wx+b

损失函数 Loss Function
J(w,b)=12(z−y)2J(w,b) = \frac{1}{2}(z-y)^2J(w,b)=21(zy)2

z是预测值,y是样本标签值。

求w的梯度
我们用J的值作为基准,去求w对它的影响,也就是J对w的偏导数(链式求导):

∂J(w,b)∂w=∂J∂z∂z∂w \frac{\partial{J(w,b)}}{\partial{w}} = \frac{\partial{J}}{\partial{z}}\frac{\partial{z}}{\partial{w}} wJ(w,b)=zJwz

因为:

∂J∂z=∂∂z[12(z−y)2]=z−y \frac{\partial{J}}{\partial{z}} = \frac{\partial{}}{\partial{z}}[\frac{1}{2}(z-y)^2] = z-y zJ=z[21(zy)2]=zy ∂z∂w=∂∂w(wx+b)=x \frac{\partial{z}}{\partial{w}} = \frac{\partial{}}{\partial{w}}(wx+b) = x wz=w(wx+b)=x

所以组合起来:

∂J∂w=∂J∂z∂z∂w=(z−y)⋅x \frac{\partial{J}}{\partial{w}} = \frac{\partial{J}}{\partial{z}}\frac{\partial{z}}{\partial{w}} = (z-y) \cdot x wJ=zJwz=(zy)x

求b的梯度
∂J∂b=∂J∂z∂z∂b \frac{\partial{J}}{\partial{b}} = \frac{\partial{J}}{\partial{z}}\frac{\partial{z}}{\partial{b}} bJ=zJbz

其中第一项前面算w的时候已经有了,而:

∂z∂b=∂(wx+b)∂b=1 \frac{\partial{z}}{\partial{b}} = \frac{\partial{(wx+b)}}{\partial{b}} = 1 bz=b(wx+b)=1

所以:

∂J∂b=∂J∂z∂z∂b=(z−y)⋅1=z−y \frac{\partial{J}}{\partial{b}} = \frac{\partial{J}}{\partial{z}}\frac{\partial{z}}{\partial{b}} = (z-y) \cdot 1 = z-y bJ=zJbz=(zy)1=zy

代码

if __name__ == '__main__':
    eta = 0.1
    X, Y = ReadData()
    w, b = 0.0, 0.0
    #w,b = np.random.random(),np.random.random()
    # count of samples
    num_example = X.shape[0]
    for i in range(num_example):
        # get x and y value for one sample
        x = X[i]
        y = Y[i]
        # get z from x,y
        z = w*x+b
        # calculate gradient of w and b
        dz = z - y
        db = dz
        dw = dz * x
        # update w,b
        w = w - eta * dw
        b = b - eta * db

    print(w,b)

dw=(z−y)⋅x,db=z−ydw = (z-y) \cdot x,db = z-ydw=(zy)xdb=zy,这个和公式推导完全一样。之所以有个dz是想保存中间计算结果,不重复劳动。因为这个函数是每次内循环都被调用的,所以要尽量优化。

另外,大家可以看到,在代码中,我们并没有直接计算损失函数值,而只是把它融入在公式推导中。

木头:哦!我明白了,原来大名鼎鼎的梯度下降,其实就是把推导的结果转化为数学公式和代码,直接放在迭代过程里!

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐