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

import matplotlib.pyplot as plt
import numpy as np

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.]  # 进化后CP数据(10组)
# y_data=b+w*x_data(假设模型)
x = np.arange(-200, -100, 1)  # bias(b),从-200~-100,以步长1为间隔返回数组(100)
y = np.arange(-5, 5, 0.1)  # weight(w),同上(100)
Z = np.zeros((len(x), len(y)))  # 形状为len(x)*len(y)零数组(100*100),存放loss值的矩阵(x,y组成的数据对共100*100个)

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]
        Z[j][i] = 0  # 初始化loss值,用于累加
        for n in range(len(x_data)):
            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)  # 求b=x[i],w=y[j]时的平均loss值
# y_data=b+w*x_data
b = -120  # 初始化w,b(随机的初始化,保证w,b在范围内即可)
w = -4
lr = 0.0000001  # learning rate(步长)
iteration = 100000  # 迭代数
# 存储b,w的历史值用于画图
b_history = [b]
w_history = [w]
# iterations
for i in range(iteration):
    b_grad = 0.0  # b_grad,w_grad用于累加,所以初始化为0(≠b,w)
    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  # loss函数对b求偏导
        w_grad = w_grad - 2.0 * (y_data[n] - b - w * x_data[n]) * x_data[n]  # loss函数对w求偏导
    # update parameters
    b = b - lr * b_grad  # 向loss值减小方向移动,更新b,w值
    w = w - lr * w_grad
    # store parameters for plotting
    b_history.append(b)  # 将更新后的b,w值加入列表,绘制等高线
    w_history.append(w)
# plot the figure
plt.contourf(x, y, Z, 50, alpha=0.5,
             cmap=plt.get_cmap('jet'))  # 输入x,y,Z(loss值)生成等高线,按照高度分为50层(颜色代表Z大小),并设置属性--透明度0.5,颜色‘jet’一种过度色
plt.plot([-188.4], [2.67], '+', ms=12, markeredgewidth=2, color='orange')  # markeredgewidth设置标记的宽度,‘+’表示标记的形状
plt.plot(b_history, w_history, 'o-', ms=3, lw=1.5, color='black')
plt.xlim(-200, -100)  # 限制x,y坐标范围
plt.ylim(-5, 5)
plt.xlabel(r'$b$', fontsize=16)  # 设置坐标标签及其属性
plt.ylabel(r'$w$', fontsize=16)
plt.show()
print(w,b)#显示最终w,b的最佳值:2.6692640713379903 -188.3668387495323

代码主要是两部分:
1-loss矩阵(每对w,b的loss平均值)的求解
2-梯度下降法求解优化后的w,b(主要)
loss值以等高线的形式展示;
w,b为坐标轴
图中’+‘为w,b的最优解位置,黑色即为w,b的变化路线,背景色表示Z(loss)值的大小。
在这里插入图片描述
对learning rate进行优化—设置自适应learning rate(开始时lr大,随后逐渐变小),同时对不同的参数采取不同的lr,也即adagrad方法
公式为
在这里插入图片描述
其中g为第t次迭代的梯度,η为自己所设置的学习率。公式推导如下:
在这里插入图片描述
在这里插入图片描述
为RMS-均方根。下面是改进后的梯度下降:

# 版本2-优化模型使得b,w的learning rate不一样(adagrad方法)
import matplotlib.pyplot as plt
import numpy as np

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.]  # 进化后CP数据(10组)
# y_data=b+w*x_data(假设模型)
x = np.arange(-200, -100, 1)  # bias(b),从-200~-100,以步长1为间隔返回数组(100)
y = np.arange(-5, 5, 0.1)  # weight(w),同上(100)
Z = np.zeros((len(x), len(y)))  # 形状为len(x)*len(y)零数组(100*100),存放loss值的矩阵(x,y组成的数据对共100*100个)

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]
        Z[j][i] = 0  # 初始化loss值,用于累加
        for n in range(len(x_data)):
            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)  # 求b=x[i],w=y[j]时的平均loss值
# y_data=b+w*x_data
b = -120  # 初始化w,b(随机的初始化,保证w,b在范围内即可)
w = -4
lr = 1  # 改进四
iteration = 100000  # 迭代数
# 存储b,w的历史值用于画图
b_history = [b]
w_history = [w]
lr_b = 0
lr_w = 0  # 改进一,分别给予参数b,w不同的learning rate

# iterations
for i in range(iteration):
    b_grad = 0.0  # b_grad,w_grad用于累加,所以初始化为0(≠b,w)
    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  # loss函数对b求偏导
        w_grad = w_grad - 2.0 * (y_data[n] - b - w * x_data[n]) * x_data[n]  # loss函数对w求偏导
    lr_b = lr_b + b_grad ** 2  # 改进二
    lr_w = lr_w + w_grad ** 2
    # update parameters
    b = b - lr / np.sqrt(lr_b) * b_grad  # 改进三
    w = w - lr / np.sqrt(lr_w) * w_grad
    # store parameters for plotting
    b_history.append(b)  # 将更新后的b,w值加入列表,绘制等高线
    w_history.append(w)
# plot the figure
plt.contourf(x, y, Z, 50, alpha=0.5,
             cmap=plt.get_cmap('jet'))  # 输入x,y,Z(loss值)生成等高线,按照高度分为50层(颜色代表Z大小),并设置属性--透明度0.5,颜色‘jet’一种过度色
plt.plot([-188.4], [2.67], '+', ms=12, markeredgewidth=2, color='orange')  # markeredgewidth设置标记的宽度,‘+’表示标记的形状
plt.plot(b_history, w_history, 'o-', ms=3, lw=1.5, color='black')
plt.xlim(-200, -100)  # 限制x,y坐标范围
plt.ylim(-5, 5)
plt.xlabel(r'$b$', fontsize=16)  # 设置坐标标签及其属性
plt.ylabel(r'$w$', fontsize=16)
plt.show()

在这里插入图片描述

如有不妥请指正,谢谢!

发布了24 篇原创文章 · 获赞 8 · 访问量 2180

猜你喜欢

转载自blog.csdn.net/weixin_44839513/article/details/100544628