李宏毅机器学习2017 拟合宝可梦CP值代码 GradientDescentDemo 并利用adagrad进行优化

import matplotlib.pyplot as plt
import numpy as np


# 进化前CP数据(10组)
x_data = [338., 333., 328., 207., 226., 25., 179., 60., 208.,  606.]  

# 进化后CP数据(10组)
y_data = [640., 633., 619., 393., 428., 27., 193., 66., 226., 1591.]  

# y_data = b + w * x_data(假设模型)


# bias(b),从-200~-100,以步长1为间隔返回数组(100)
x = np.arange(-200, -100, 1)    

# weight(w),同上(100)
y = np.arange(-5, 5, 0.1)       

# 形状为len(x)*len(y)零数组(100*100),存放loss值的矩阵(x,y组成的数据对共100*100个)
Z = np.zeros((len(x), len(y)))  

# 生成坐标矩阵
X, Y = np.meshgrid(x, y)        

# 计算loss functon(遍历x,y,计算出每组数据的loss):当b = x[i],w = y[j]时,loss(f(w,b)) = Σ(y_data[n]-b-w*x_data[n])**2
for i in range(len(x)):
    
    for j in range(len(y)):
        
        # 利用x,y中所有元素
        b = x[i]
        w = y[j]
        
        # 初始化loss值,用于累加
        Z[j][i] = 0             
        
        for n in range(len(x_data)):
            
            # 计算数据对b = x[i],w = y[j]时总的loss值(利用十组样本数据)
            Z[j][i] = Z[j][i] + (y_data[n] - b - w * x_data[n]) ** 2  
            
        # 求b = x[i],w = y[j]时的平均loss值
        Z[j][i] = Z[j][i] / len(x_data)  


# y_data = b + w * x_data

# 初始化w,b(随机的初始化,保证w,b在范围内即可)
b = -120  
w = -4

# learning rate(步长)
lr = 0.0000001  

# 迭代数
iteration = 100000  

# store initial values for plotting
# 存储b,w的历史值用于画图
b_history = [b]
w_history = [w]

# iterations
for i in range(iteration):
    
    # b_grad,w_grad用于累加,所以初始化为0(≠b,w)
    b_grad = 0.0  
    w_grad = 0.0
    
    for n in range(len(x_data)):
        
        # loss函数对b求偏导
        b_grad = b_grad - 2.0 * (y_data[n] - b - w * x_data[n]) * 1.0  
        
        # loss函数对w求偏导
        w_grad = w_grad - 2.0 * (y_data[n] - b - w * x_data[n]) * x_data[n]  
        
    # update parameters
    # 向loss值减小方向移动,更新b,w值
    b = b - lr * b_grad  
    w = w - lr * w_grad
    
    # store parameters for plotting
    # 将更新后的b,w值加入列表,绘制等高线
    b_history.append(b)  
    w_history.append(w)

# plot the figure

# 输入x,y,Z(loss值)生成等高线,按照高度分为50层(颜色代表Z大小),并设置属性--透明度0.5,颜色‘jet’一种过度色
plt.contourf(x, y, Z, 50, alpha=0.5,cmap=plt.get_cmap('jet'))  

# markeredgewidth设置标记的宽度,‘+’表示标记的形状
plt.plot([-188.4], [2.67], '+', ms=12, markeredgewidth=2, color='orange')  

plt.plot(b_history, w_history, 'o-', ms=3, lw=1.5, color='black')

# 限制x,y坐标范围
plt.xlim(-200, -100)  
plt.ylim(-5, 5)

# 设置坐标标签及其属性
plt.xlabel(r'$b$', fontsize=16)  
plt.ylabel(r'$w$', fontsize=16)
plt.show()

#显示最终w,b的最佳值:2.4834016183794727 -123.6921749751593
print(w,b)

运行结果1
图中’+‘为w,b的最优解位置,黑色即为w,b的变化路线,背景色表示Z(loss)值的大小。

对learning rate进行优化:
设置自适应learning rate(开始时lr大,随后逐渐变小),同时对不同的参数采取不同的lr,也即adagrad方法。

下面是改进后的梯度下降(修改后半段代码):

# 版本2-优化模型使得b,w的learning rate不一样(adagrad方法)

b = -120  
w = -4

# learning rate(步长)
# 改进四
lr = 1  

iteration = 100000  

b_history = [b]
w_history = [w]

# 改进一,分别给予参数b,w不同的learning rate
lr_b = 0
lr_w = 0  

# iterations
for i in range(iteration):
    
    b_grad = 0.0  
    w_grad = 0.0
    
    for n in range(len(x_data)):
        
        b_grad = b_grad - 2.0 * (y_data[n] - b - w * x_data[n]) * 1.0  
        w_grad = w_grad - 2.0 * (y_data[n] - b - w * x_data[n]) * x_data[n]  
    
    # 改进二
    lr_b = lr_b + b_grad ** 2  
    lr_w = lr_w + w_grad ** 2
    
    # update parameters
    # 向loss值减小方向移动,更新b,w值
    # 改进三
    b = b - lr / np.sqrt(lr_b) * b_grad  
    w = w - lr / np.sqrt(lr_w) * w_grad
    
    b_history.append(b)  
    w_history.append(w)

# plot the figure
plt.contourf(x, y, Z, 50, alpha=0.5,cmap=plt.get_cmap('jet'))  
plt.plot([-188.4], [2.67], '+', ms=12, markeredgewidth=2, color='orange')  
plt.plot(b_history, w_history, 'o-', ms=3, lw=1.5, color='black')
plt.xlim(-200, -100)  
plt.ylim(-5, 5)
plt.xlabel(r'$b$', fontsize=16)  
plt.ylabel(r'$w$', fontsize=16)
plt.show()

#显示最终w,b的最佳值:2.6692640713379903 -188.3668387495323
print(w,b)

运行结果2
图1
图2
图3
图4
图5
图6

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值