本篇文章来源于专栏《Python从入门到人工智能》,更多内容可复制链接到此查看:https://blog.csdn.net/qq_44731019/category_11717408.html 对于一个算法(模型)。在深度学习中,简要的处理方式是: 准备数据集(Datasets)—>> Model(选择模型) —>> Training (模型训练) —>> 推理(进行推理预测)。 至于优化等,可以理解为后续的补充。 监督学习:数据集需要 交付给算法模型 进行训练,利用所训练的模型,在获得 新的数据时 可以得到相应的输出。 线性模型的基本模型如下,其中的ω和 ![]() 在模型训练中 会先随机取得一个值,继而 计算其和标准量之间的 偏移量,从而判断 当前模型 是否符合预期。 记实际值为 通常,该公式定义为Training Loss (Error) 本例中,原题目中的几种 其中的每行 为 对于单个样本,loss 可用于 指代样本误差。对于所有样本,可同理用Mean Square Error (MSE)来指代 整体样本的平均平方误差(均方差cost) MSE:均方误差(Mean Square Error)。,即 每个样本对应的损失值 (平方) 求和,再除以样本总个数。 由cost的计算公式可知,当平均损失为0时,模型最佳,但由于 仅当数据无噪声 且 模型完美贴合数据 的情况下才会出现这种情况,因此 模型训练的目的 应当是 误差(损失)尽可能小,而非找到 误差为0的情况。 不同 1.1.1 基础练习 根据上面的分析,code如下:注释我已经写的比较清楚啦。 # 昵 称:XieXu # 时 间: 2023/2/12/0012 21:10
# 导入必要的工具包 import numpy as np import matplotlib.pyplot as plt
# 自定义 简单数据集。x与y 一一对应 (训练集) x_data = [1.0, 2.0, 3.0] y_data = [2.0, 4.0, 6.0]
# 模型,(前馈) def forward(x): return x * w
# 损失函数 def loss(x, y): y_pred = forward(x) # 即 y_hat。相当于 预测的值 return (y_pred - y) * (y_pred - y) # 平方(均方误差)。简单形式的均方误差。这个计算的 为单个样本的误差
# 【穷举法】 # 如下两个列表 保存 权重 及其对应的损失值 w_list = [] mse_list = []
# [0.0,4.1),间隔为0.1。即 0.0, 0.1, 0.2, 0.3 ... 4.0 起始值(含),停止值(不含),步长 for w in np.arange(0.0, 4.1, 0.1): # 外层循环 控制权重 2023.2.13 08:20 print('w=', w) l_sum = 0 # zip 将x_data 和 y_data 打包为一个tuple(元组),方便同时遍历。 for x_val, y_val in zip(x_data, y_data): # 内层循环控制进行 权重:调用forward函数 对应的预测,以及 调用上面定义的loss函数 进行损失值计算 y_pred_val = forward(x_val) # 计算 每个样本的 预测值 loss_val = loss(x_val, y_val) # 计算 每个样本的 损失值 l_sum += loss_val # 将 所有样本的 损失求和(这里没做均值) print('\t', x_val, y_val, y_pred_val, loss_val) # 打印出 每一个样本:x,x对应的y,预测值y_hat,损失值 print('MSE=', l_sum / 3) # 这里 除以样本总数,进行均值,即 均方误差 w_list.append(w) # 将每次 用完的 权重添加到列表中,用以 下面画图 的横坐标~ mse_list.append(l_sum / 3) # 除以样本总数。每个权重 对应的 所有样本的平均误差(均方误差) MSE,也叫均值吧。下面绘图的纵坐标
# 绘制图形 plt.plot(w_list, mse_list) # 横坐标、纵坐标 的取值 plt.ylabel('Loss') # 纵坐标y的标签 plt.xlabel('w') # 横坐标w的标签 plt.show()
可以得到结果:红色为我做的标注~ 从下面 控制台打印的日志中,我们 可以 很容易看出来上图 的由来: 开始时,随着W增加,平均损失MSE逐渐减小,
1.1.2 练习 同样地,基于上面的例子,练习: 实现线性模型 不同之处在于,定义的模型,与上面相比,加了个 偏置项B。
可以得到如下图形:这就是 ( 其中,控制台输出的日志中,含有警告:
ax = Axes3D(fig) 翻译一下上面的警告:大意即 由于版本不同,可暂时忽略。 1.1.3 其它:在深度学习训练中,横轴往往是Epoch在深度学习训练的可视化图形中,一般横轴是Epoch,即训练轮数:往往在训练集上表现是,随着训练轮数增多,损失越来越低;而在测试集(老师读 开发集)上的效果是,损失在刚开始会下降,而后到某个点,又会逐渐上升。而我们的目标就是,想找到损失最低的那个点;从而进一步 对超参数进行处理等其它操作。 深度学习中可能需要考虑更多问题,比如 老师提到了 Pytorch可视化工具——Visdom。目前我没有用到…稍微大型的项目可能会用到吧。可以在百度搜索Visdom并查看它的相关信息,以及其GitHub官网。 💧1.2 Gradient Descent(梯度下降)1.2.1 梯度下降法 的由来:问题背景在上面 线性模型的方法中,所使用的思想是基于穷举,即 但是,这种思想 在多维的情况下,即多个参数的时候,会引起 那么,使用 分治法 如何? 即:大化小,小化无,先对整体 进行分割采样,在相对最低点进行进一步采样,直到其步长与误差符合条件。 但是,分治法有两个缺点:
同时,由于以上问题的存在,引起了参数优化的问题,即求解使loss最小时的参数的值。 简言之,即求得 如何优化,求得符合条件的 1.2.2 何为梯度?梯度,即 导数变化最大的值,其方向为 这里,可以使用高等数学中关于 一个点处 导数的定义: (这里仅简单理解,并非严谨数学推导)对于 下面的图将便于理解: 1.2.3 梯度下降在深度学习中,所说的凸函数,是与高等数学定义中的 凸函数,完全反过来的,知道这一点就好。如下图所示,在深度学习中,将其看做一个凸函数。 当前, 那么,取值点 需要 向下更新,所取的梯度即为 局限性:
1.2.4 梯度下降的公式 如何得来的?(理解)通过线性模型,我们知道 均方误差的公式即:其中 进一步地,可以对 根据数学知识,由于是对 而( 因此,梯度下降的更新公式为: 下图即上述公式的推导过程: 梯度的求解公式,应用到code中的示例: 1.2.5 随机梯度下降(Stochastic gradient descent,SGD);Mini-batch!平时用的比较多的,是随机梯度下降(SGD)。 SGD采用单个训练样本的损失来近似平均损失,故 SGD 用单个训练数据即可对模型参数进行一次更新,大大加快了训练速度。 随机梯度下降 每次 只需要计算 一个样本关于
同时,为了降低随机梯度的方差,使迭代算法更加稳定,在真实操作中,会同时处理若干训练数据,该方法叫做小批量随机梯度下降法(Mini_Batch Gradient Densent)。,这才是真正地运用了 随机梯度下降(SGD),目前,在实际应用中,我们所说的 小结
将若干个样本分为一组,记录一组的梯度 用以代替随机梯度下降中的单个样本。 该方法最为常用,也是默认接口。一般,mini-batch可以在2的幂次中挑选最优取值。例如16、32、64、128、256等。 1.2.6 梯度下降练习:方法一(推荐 完全 自己 多手写几遍)给定一个数据集,x_data、y_data。寻找y=wx模型的w最优解。 code练习如下,注释中,我已经介绍的比较详细啦!我想这可以帮助绝大多数朋友理解。
得到结果:可以看到,在20轮左右,损失值就已经很接近0了。
1.2.7 方法二(与法一类似,不过这里 纵轴 是 权值的第二种方式:与第一种类似,只不过这里纵坐标取的是 权值,另外,直接把梯度下降 放到Epoch训练里面了。代码如下: # 方法二 import numpy as np import matplotlib.pyplot as plt
x_data = [1.0, 2.0, 3.0] y_data = [2.0, 4.0, 6.0]
scope_list = [] # 轮数 w_list = [] # 权值W
w = 60 # 我们给W一个初始值
# 学习率 k = 0.01 # 定义学习率
# 开始训练 for i in range(1,201,1): # 计算cost(loss的和) loss_sum = 0
# 求梯度 for x_val, y_val in zip(x_data, y_data): loss_sum += 2 * x_val * (w * x_val - y_val) cost = loss_sum / 3
# 计算本轮w w = w - k * cost print('Epoch:',i,'W:',w) scope_list.append(i) w_list.append(w)
# 按说纵坐标不应该取权值的,既然取了,那么可以从图形中,看出来大概 50左右,权值就收敛了 plt.plot(scope_list, w_list) # 横坐标 取值 依然是 轮数,纵坐标取值是按照W来取的值 plt.xlabel('scope') plt.ylabel('W') plt.show() 结果如下所示:
1.2.8 随机梯度下降练习(一),可视化这里,即普通的随机梯度下降,每轮训练中,每次计算的 关于 即 注:这里,随机梯度主要是指,每次拿一个训练数据来训练,然后更新梯度参数。
1.2.9 随机梯度下降练习(二),可视化上面的随机梯度下降算法中,貌似仅仅 是只计算了 每一个样本的梯度,好像没有体现“随机”。 这里再换个类似的算法,基本一样,但用到了random随机。 该方法与目录1.2.6类似。 # 方法二 import random import numpy as np import matplotlib.pyplot as plt
x_data = [1.0, 2.0, 3.0] y_data = [2.0, 4.0, 6.0]
scope_list = [] # 训练轮数 w_list = [] # 权值
w = 60
# 学习率 k = 0.01
for i in range(1, 201, 1): # 计算cost(即随机一个loss当cost用) rand = random.randint(0, 2) # 取值为[0,2],即 随机生成0~2内的 某个 整数,包含0和2。(三个样本,随机取一个) cost = 2 * x_data[rand] * (w * x_data[rand] - y_data[rand]) # 从而计算得到 关于W的偏导数
# 计算本轮w w = w - k * cost # 更新W print('Epoch=', i, 'W=', w) # 本轮更新后的W 2023.2.13 20:30 scope_list.append(i) w_list.append(w)
plt.plot(scope_list, w_list) # 横坐标为轮数,纵坐标为权值。 plt.xlabel('scope') plt.ylabel('W') plt.show() 如下图所示,可以看出,75轮左右,权值就已经逐渐收敛了~
|
|
来自: taotao_2016 > 《数学》