第三次作业:使用minibatch的方式进行梯度下降
一、作业要求
项目 | 内容 |
---|---|
这个作业属于哪个课程 | 人工智能实战 |
这个作业的要求在哪里 | click_here |
我在这个课程的目标是 | 获得实战经验 |
这个作业在哪个具体方面帮助我实现目标 | 理论知识的实战运用 |
课堂讲义 | click_here |
示例代码位置 | click_here |
二、python代码实现
由于数据集较小,导致不同的batchsize大小对结果影响不大
import numpy as np
import matplotlib.pyplot as plt
from pathlib import Path
# 超参数
EPOCH = 100
BATCH_SIZE_5 = 5
BATCH_SIZE_10 = 10
BATCH_SIZE_15 = 15
LR = 0.01
# 读入数据
x_data_name = "TemperatureControlXData.dat"
y_data_name = "TemperatureControlYData.dat"
X = np.load(Path(x_data_name))
Y = np.load(Path(y_data_name))
def Sample(batchsize):
LOSS_MSE = np.zeros(EPOCH)
Index = np.array(range(0, 200))
# 初始化w,b参数
w = np.random.normal()
b = np.random.normal()
for epoch in range(EPOCH):
# 随机取样
batch_index = np.random.choice(Index, batchsize, replace=False)
batch_x = X[batch_index]
batch_y = Y[batch_index]
# 反向传播,重新计算参数w,b
value = w * batch_x + b
temp = (value - batch_y) * batch_x / batchsize
delta_w = temp.sum()
temp = (value - batch_y) / batchsize
delta_b = temp.sum()
w = w - delta_w
b = b - delta_b
# 计算均方误差loss
temp = (value - batch_y) * (value - batch_y) / batchsize / 2
loss = temp.sum()
LOSS_MSE[epoch] = loss;
print("epoch_times:%d, w = %.8f, b = %.8f, LOSS = %.8f" % (epoch + 1, w, b, loss))
return LOSS_MSE
if __name__ == '__main__':
plt.figure()
x = np.linspace(0, EPOCH, EPOCH)
plt.xlabel("epoch_times")
plt.ylabel("LOSS_MSE")
LOSS_MSE_5 = Sample(BATCH_SIZE_5)
LOSS_MSE_10 = Sample(BATCH_SIZE_10)
LOSS_MSE_15 = Sample(BATCH_SIZE_15)
plt.title("learing_rate = 0.01")
plt.plot(x, LOSS_MSE_5, label="batch_size=5")
plt.plot(x, LOSS_MSE_10, label="batch_size=10")
plt.plot(x, LOSS_MSE_15, label="batch_size=15")
plt.legend(loc='upper right')
plt.show()
三、问题解答
问题2:为什么是椭圆而不是圆?如何把这个图变成一个圆?
若将均方误差loss看作z,在空间直角坐标系中,该方差对应的曲面为椭圆抛物面,
故在xy平面上的投影为椭圆。
在数学上,由解析几何知识可知,当二次式w*b的系数为0,且w^2和b^2的系数相同且非零,
抛物面不再是椭圆抛物面,在xy平面的投影也退化为圆。
问题3:为什么中心是个椭圆区域而不是一个点?
因为loss的最小值点(loss=0的点)可以被取到的充分必要条件是所有这些散点都在一条直线上,
显然这是很困难的。所以,对应loss值相近的(w,b)投影在xy平面上,形成了椭圆(曲面本身为椭圆抛物面)