您的位置:首页 > 娱乐 > 八卦 > 华为云虚拟主机_免费网站链接_做搜索引擎推广多少钱_怎么做好网络推广销售

华为云虚拟主机_免费网站链接_做搜索引擎推广多少钱_怎么做好网络推广销售

2025/2/27 14:00:22 来源:https://blog.csdn.net/lele_ne/article/details/145624850  浏览:    关键词:华为云虚拟主机_免费网站链接_做搜索引擎推广多少钱_怎么做好网络推广销售
华为云虚拟主机_免费网站链接_做搜索引擎推广多少钱_怎么做好网络推广销售

SGD随机梯度下降算法的作用

它是一种优化算法,自动调整模型参数,提升模型的性能。
我们今天要在MNIST_SAMPLE数据集上实现SGD算法。

MNIST_SAMPLE数据集

MNIST_SAMPLE数据集只有数字3和数字7的图片。

from fastai.vision.all import *
path = untar_data(URLs.MNIST_SAMPLE)
from fastbook import *
import torch
matplotlib.rc('image', cmap='Greys')threes = (path/'train'/'3').ls().sorted()
sevens = (path/'train'/'7').ls().sorted()seven_tensors = [tensor(Image.open(o)) for o in sevens]
three_tensors = [tensor(Image.open(o)) for o in threes]stacked_sevens = torch.stack(seven_tensors).float()/255
stacked_threes = torch.stack(three_tensors).float()/255valid_3_tens = torch.stack([tensor(Image.open(o)) for o in (path/'valid'/'3').ls()])
valid_3_tens = valid_3_tens.float() / 255
valid_7_tens = torch.stack([tensor(Image.open(o)) for o in (path/'valid'/'7').ls()])
valid_7_tens = valid_7_tens.float() / 255train_x = torch.cat([stacked_threes, stacked_sevens]).view(-1, 28*28)
train_y = tensor([1]*len(threes) + [0]*len(sevens)).unsqueeze(1)
dset = list(zip(train_x, train_y))
dl = DataLoader(dset, 128)# create the train dset
valid_x = torch.cat([valid_3_tens, valid_7_tens]).view(-1, 28*28)
valid_y = tensor([1]*len(valid_3_tens) + [0]*len(valid_7_tens)).unsqueeze(1)
valid_dset = list(zip(valid_x, valid_y))
valid_dl = DataLoader(valid_dset, 128)dls = DataLoaders(dl, valid_dl)

SGD算法的七大步骤

Step1. 初始化模型参数

使用torch.randn()随机初始化参数,然后使用require_grad_方法表示需要追踪模型参数的梯度。

def init_params(size, std=1.0):return (torch.randn(size)*std).requires_grad_()bias = init_params(1)
weights = init_params((28*28,1))

Step2. 计算预测值predictions

先定义一个简单的网络模型,只有一个全连接层。然后使用这个网络模型计算预测值。
为什么需要bias?
y=w*x, 如果x=0是输入,那么预测值始终为0,不利于模型的训练;
y=w*x+b, 加入了bias,将使得模型更加灵活。

我们用训练集的前4个图片数据,作为样例测试这个函数。在pytorch中,@表示矩阵乘法运算符。

def linear1(xb):return xb@weights + bias
batch = train_x[:4]
preds = linear1(batch)
>>> preds

在这里插入图片描述

Step3. 计算损失loss

loss:基于预测值(predictions)和目标值(targets),使用某种损失函数loss_function,计算两者有多相近。
先定义损失函数:把预测值变成0-1之间的值,如果预测的目标是数字3,就计算预测值和1之间的距离;如果预测的目标是数字7,那么预测值本身就是它到0之间的距离。
sigmoid方法的作用:把任何输入值(无论正负)变成0-1之间的值。
在这里插入图片描述

def mnist_loss(predictions, targets):predictions = predictions.sigmoid()return torch.where(targets==1, 1-predictions, predictions).mean()
loss = mnist_loss(preds, train_y[:4])

在这里插入图片描述

Step4. 计算梯度gradients

梯度:指的是我们将怎么改变模型参数,它指明了具体的方向。
我们不需要手动计算梯度,因为深度学习库会自动帮助我们计算,只需要在初始化模型参数的时候,指明require_grad=True,它会自动保存模型参数的梯度。
backward()方法指的是反向传播算法,调用此方法会帮助我们自动计算每一层参数的梯度。相应地,因为设置了requires_grad=True, 新的梯度也会被自动保存。
当我们计算一个神经网络的导数的时候,这被称为向后传播过程。

loss.backward()
weights.grad.shape, weights.grad.mean(), bias.grad

在这里插入图片描述

把代码封装到calc_grad方法中,便于模块化地调用:

def calc_grad(xb, yb, model):preds = model(xb)loss = mnist_loss(preds, yb)loss.backward()
calc_grad(batch, train_y[:4], linear1)
weights.grad.mean(), bias.grad

在这里插入图片描述

为什么两次的输出结果不一样呢,因为pytorch自动将第一次计算的梯度保存了,第二次会在第一次的基础上再计算梯度,所以当然就结果不一样了,因此我们需要再下一次梯度前,将模型参数的梯度置为0.

weights.grad.zero_()
bias.grad.zero_();

Step5. 更新模型参数

学习率learning rate决定了每次更新模型参数的大小程度(也称为步长)。通常都设置得很小。

lr = 1.
weights.grad -= weights.grad * lr
bias.grad -= bias.grad * lr

Step6. 重复Step2-5

在这里我们需要将整个训练数据集分成mini_batches,然后将一个个batch喂入网络,为什么这样子做?

  • 一次性预测整个训练数据集会花费太长时间和太多内存
  • 如果一张张图片训练的话,梯度将变得不稳定和不精确

所以我们迭代整个训练集的子集来完成训练,即将数据集分成mini_batches

现在我们要在整个训练集的基础上更新参数。

将训练集分成很多mini batches,然后训练。

def train_epoch(model, lr, params):for xb,yb in dl:calc_grad(xb, yb, model)for p in params:p.data -= p.grad*lrp.grad.zero_()
for i in range(10):train_epoch(model, lr, params)

Step7. 停止

这是最基本的SGD算法。
在fastai深度学习库中,已经被封装成一个类了,我们只需要在创建Learner的时候指明loss_func=SGD.

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com