深度学习-梯度下降

一,梯度下降求最小值:

        1,配方法

        2,求导

        3,梯度下降法

        首先,什么是梯度

        ​​​​​

我的理解

方向导数是在某函数定义域内一点对某方向求导所得的导数,当该函数在某一方向取得最大值时,这时的方向导数就是梯度,此时,函数的变化率最大,变化最快

然后

再来看梯度下降法的代码怎么写

选用 Y = x^2-6x+9 作为参考

 1,选择初始化数据:(x,步长,迭代次数的值)

        令x=6,则y=81

        步长(学习率):lr = 0.3(步长是指数值型数据在每次迭代中更新的幅度,通常表示为一个小数。)

        迭代次数:Num = 45

图像如图:

 2,开始迭代:

        先将函数的导数自己算出:y = 2*x - 6

        用for循环完成每次迭代:

      

for i in range(Num):
    x = x-lr*(2*x-6)
3,最后打印出来x

完整代码

import matplotlib.pyplot as plt
import torch
import numpy as np
#函数图象:
x = np.linspace(-1,7,100)
y = x**2 - 6*x + 9
plt.plot(x,y)
plt.show()
#y`=2x-6
#初始化:
x = 6
lr = 0.3 #步长
Num = 45 #迭代次数
for i in range(Num):
    x = x-lr*(2*x-6)
    print("第",i+1,"次迭代:",x)

运行结果

可以看出到41次时就可以迭代到我们这个函数的最小值

实际上当相邻两次迭代的x的值相差不大时基本就可以确定最小值了 

 特别情况:

有时会出现x的值在来回震荡,说明步长选取稍大,导致函数不太容易去收敛

有时会出现x的值变化太小,说明步长选取过小,每次迭代x的值基本不变

 二,梯度下降法求线性回归方程

数据

猜测线性回归方程:

y = wx

即,初始化:

w=6

lr=50

num=20

类比

        一(梯度下降法求最小值):

        一 中的x相当于成了现在的w    
        而,

        猜测值与真实值之差越小(w*x-y),就代表w的值越准确

        用一个损失方程表示:

        loss = 1/2.0 * np.sum((w*x-y)**2)

                因为可能是负数故而用平方避免

               1/2为了方便求导

        然后

        对(x*w-y)**2进行求导得

        2 *(x*w-y)* x

     迭代

for i in range(num):
    w_gra = np.mean((w*x-y)*x)
    w = w - lr * w_gra
    loss = 1/2.0 * np.sum((w*x-y)**2)
    

完整代码

import matplotlib.pyplot as plt
import torch
import numpy as np
x = np.array([0.18,0.1,0.16,0.08,0.09,0.11,0.12,0.17,0.15,0.14,0.13])
y = np.array([0.36,0.2,0.32,0.16,0.18,0.22,0.24,0.34,0.30,0.28,0.26])
lr = 50
w = 6
num = 20
for i in range(num):
    w_gra = np.mean((w*x-y)*x)
    w = w - lr * w_gra
    loss = 1/2.0 * np.sum((w*x-y)**2)
    print("迭代第",i+1,"次,","梯度:",w_gra,",权重:",w,",损失:",loss)

结果 

第一种方法用pytoch顺序结构实现梯度下降求线性回归

 使用工具pytorch可以让我们更加便捷的去用梯度下降求线性回归方程

数据的准备和初始化:

 torch.mm(a,b):矩阵a,b相乘

loss. backward():自动求损失函数的导数

迭代

这里进行模型的前向传播、反向传播和权重更新

for i in range(num):
    y_pre = torch.mm( x_data , w)+b
    loss = ((y_pre-y_data)**2).mean()
    losses.append(loss)
    if w.grad is not None:
        w.grad.data.zero_()
    if b.grad is not None:
        b.grad.data.zero_()
    loss.backward()
    w.data = w.data - lr * w.grad
    b.data = b.data - lr * b.grad

完整代码:

import matplotlib.pyplot as plt
import torch
import numpy as np
#准备数据
x_data = torch.tensor([[0.18],[0.1],[0.16],[0.08],[0.09],[0.11],[0.12],[0.17],[0.15],[0.14],[0.13]])
y_data = torch.tensor([[1.36],[1.2],[1.32],[1.16],[1.18],[1.22],[1.24],[1.34],[1.30],[1.28],[1.26]])

#定义参数(初始化)
w = torch.tensor([[10]],requires_grad=True,dtype=torch.float32)
b = torch.tensor([0],requires_grad=True,dtype=torch.float32)
lr = 0.9
num = 5000
losses = []
for i in range(num):
    y_pre = torch.mm( x_data , w)+b
    loss = ((y_pre-y_data)**2).mean()
    losses.append(loss)
    if w.grad is not None:
        w.grad.data.zero_()
    if b.grad is not None:
        b.grad.data.zero_()
    loss.backward()
    w.data = w.data - lr * w.grad
    b.data = b.data - lr * b.grad
    print("权值(w):",w.item(),"b:",b.item(),"loss:",loss.item(),"迭代次数:",i+1)
plt.figure(figsize=(10, 5))
plt.plot(range(num), losses, label='Loss')
plt.title('f_loss`s picture')
plt.xlabel('epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()

 

 丢失图像:

第二种方法封装类实现梯度下降拟合线性回归 :

        这个方法相当于是y_pre,loss的计算和loss,w,b的求导以及步长(学习率),迭代次数等数据的初始化写成了函数方便于调用,将这些函数归到一个类里

        数据的初始化:

         y_pre,loss的计算:

         loss,w,b的求导:

 最后

一这组数据为例,通过这种方法求线性回归方程

x_data = torch.tensor([[0.18],[0.1],[0.16],[0.08],[0.09],[0.11],[0.12],[0.17],[0.15],[0.14],[0.13]])
y_data = torch.tensor([[1.36],[1.2],[1.32],[1.16],[1.18],[1.22],[1.24],[1.34],[1.30],[1.28],[1.26]])
num = 5000
lss = Lss(lr=0.9)
for i in range(num):
    lss.forward(x_data,y_data)
    lss.backward()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值