赞
踩
权重和偏差的实际值在后面决定
梯度:使得损失函数增加最快的方向
负梯度:是损失函数减小最快的方向
在实际中我们很少使用梯度下降,深度学习中最常用的小批量随机梯度下降
选择批量大小
MNIST:手写数字识别(10类)
ImageNet:自然物体分类(1000类)
Kaggle上的分类问题:Kaggle一个数据建模和数据分析竞赛平台
回归
分类
针对分类来讲,不关心他们之间的实际的值,是关心对正确类别的置信度特别大。
假设oy为真实值 oi为预测值,他们不关心oi的大小
他们是关系 oy - oi 大于等于 某个阀值,或者说我们正确的oi要远远大于其他类别的oi
损失函数用来衡量真实值和预测值的区别。介绍三个基本损失函数
橙色线为:梯度
绿色线为:它的似然函数,高斯分布
蓝色线为:y = 0时变换y’的函数
蓝线代表真实值和预测值的差值,当它大时,梯度值也是较大的
这种损失函数的特性:不管预测值和真实值相差多远,我的梯度永远是常数,所以权重更新稳定,但是此函数零点出不可导,所以它具有不平滑性,当你的预测值和真实值靠近时,会有剧烈变化
当你的y’(导数)大于1时,是L1,当y’小于1时,是L2
这个相当于L1和L2的结合,避免L1的不平滑性和L2在开始的不稳定性
import torch from IPython import display from d2l import torch as d2l batch_size = 256 #load_data_fashion_mnist加载 Fashion-MNIST 数据集 10个类别的服饰图片数据集,每个类别包含7000张28x28像素的灰度图像。 #获取了两个迭代器 train_iter 和 test_iter 每次256张图像和对应的标签 train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size) #每张图片是28 * 28 * 1但是Softmax输入为向量,要把图片拉成向量 num_inputs = 784#28*28=784 num_outputs = 10#10个类 #定义权重和偏置 #w 以均值 0、标准差 0.01 的正态分布随机初始化,大小为 (num_inputs, num_outputs) 的张量 W = torch.normal(0, 0.01, size=(num_inputs, num_outputs), requires_grad=True) #b 是一个大小为 (num_outputs,) 的张量,其中 num_outputs 是输出的数量。通过 torch.zeros() 函数以全零初始化 b = torch.zeros(num_outputs, requires_grad=True) #定义一个Softmax def softmax(X): X_exp = torch.exp(X) partition = X_exp.sum(1, keepdim=True) return X_exp / partition # 这里应用了广播机制 #定义网络模型 def net(X): #使用 torch.matmul() 函数计算输入数据 X 与权重 W 的矩阵乘法。 #将偏置 b 加到上述结果中。 #将结果应用 softmax 函数。 #256 * 784 return softmax(torch.matmul(X.reshape((-1, W.shape[0])), W) + b) #定义交叉熵损失函数 def cross_entropy(y_hat, y): return - torch.log(y_hat[range(len(y_hat)), y]) #将预测类别y_hat与真实y元素进行比较 def accuracy(y_hat, y): """计算预测正确的数量""" if len(y_hat.shape) > 1 and y_hat.shape[1] > 1: #axis=1 表示沿着第一个维度(通常是行)进行操作 #y_hat.argmax返回一个一维张量,其中每个元素是对应样本的最大值的索引 y_hat = y_hat.argmax(axis=1) #张量 y_hat 里的数据类型是否与张量 y 里的数据类型相同,并将结果存储在 cmp 变量中 cmp = y_hat.type(y.dtype) == y return float(cmp.type(y.dtype).sum()) #cmp.type(y.dtype) 将张量 cmp 中的数据类型转换为与张量 y 相同的数据类型。这是为了确保类型匹配。 #.sum() 对张量中的所有元素进行求和操作。由于 True 在数值上等价于 1,而 False 在数值上等价于 0,因此求和操作将计算出 cmp 中值为 True 的元素的数量。 #float() 将计算结果转换为浮点数类型。 #这个结果通常用于计算模型预测的准确率,即模型正确预测的样本数量与总样本数量的比例。 #可以评估在任意模型net的准确率 def evaluate_accuracy(net, data_iter): """计算在指定数据集上模型的精度""" if isinstance(net, torch.nn.Module): net.eval() # 将模型设置为评估模式 在评估模式下,模型不会进行参数更新 metric = Accumulator(2) # 正确预测数、预测总数 with torch.no_grad():#一个上下文管理器,它指示 PyTorch 在接下来的代码块中不要进行梯度计算 for X, y in data_iter:#遍历 data_iter 中的数据。在每次迭代中,X 是输入特征的批量,y 是对应的标签。 metric.add(accuracy(net(X), y), y.numel()) #神经网络模型 net 对输入数据 X 进行前向传播,得到预测结果。然后使用 accuracy 函数计算预测结果的准确率。接着调用 metric 对象的 add 方法,将准确率和当前批量数据的样本数量 y.numel() 作为参数传入,用于累积这些值。这样可以在整个评估过程中跟踪模型的平均准确率 return metric[0] / metric[1] #Softmax回归训练,训练模型一个迭代周期 def train_epoch_ch3(net, train_iter, loss, updater): #@save """训练模型一个迭代周期(定义见第3章)""" # 将模型设置为训练模式 if isinstance(net, torch.nn.Module): net.train() # 训练损失总和、训练准确度总和、样本数 metric = Accumulator(3) for X, y in train_iter: # 计算梯度并更新参数 y_hat = net(X) l = loss(y_hat, y)#交叉熵损失函数 if isinstance(updater, torch.optim.Optimizer): # 使用PyTorch内置的优化器和损失函数 updater.zero_grad()#梯度置为0 l.mean().backward()#计算损失函数 l 对模型参数的梯度 updater.step()#计算梯度后,调用优化器的 step() 方法来更新模型的参数 else: # 使用定制的优化器和损失函数 l.sum().backward() updater(X.shape[0]) metric.add(float(l.sum()), accuracy(y_hat, y), y.numel()) # 返回训练损失和训练精度 return metric[0] / metric[2], metric[1] / metric[2] #训练函数 def train_ch3(net, train_iter, test_iter, loss, num_epochs, updater): #@save """训练模型(定义见第3章)""" animator = Animator(xlabel='epoch', xlim=[1, num_epochs], ylim=[0.3, 0.9], legend=['train loss', 'train acc', 'test acc']) for epoch in range(num_epochs): #使用训练数据集,训练一个周期 train_metrics = train_epoch_ch3(net, train_iter, loss, updater) #使用测试数据集,评价精度 test_acc = evaluate_accuracy(net, test_iter) #将当前周期的训练指标和测试准确率添加到动画器中,以便可视化 animator.add(epoch + 1, train_metrics + (test_acc,)) train_loss, train_acc = train_metrics#将训练指标解包,得到训练损失和训练准确率。 assert train_loss < 0.5, train_loss assert train_acc <= 1 and train_acc > 0.7, train_acc assert test_acc <= 1 and test_acc > 0.7, test_acc #小批量随机梯度下降来优化模型的损失函数 lr = 0.1 def updater(batch_size): return d2l.sgd([W, b], lr, batch_size) #训练模型10个迭代周期 num_epochs = 10 train_ch3(net, train_iter, test_iter, cross_entropy, num_epochs, updater)
import torch from torch import nn from d2l import torch as d2l batch_size = 256 train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size) #初始化模型参数 # PyTorch不会隐式(自动)地调整输入的形状。因此, #创建了一个简单的神经网络模型 net #nn.Flatten(): 这是一个用于将输入数据展平的层,将输入的多维数据(比如图像)展平成一维向量 # nn.Linear这是一个全连接层,将输入的 784 维向量映射到一个 10 维的输出向量。 net = nn.Sequential(nn.Flatten(), nn.Linear(784, 10)) def init_weights(m):#接受一个参数 m if type(m) == nn.Linear:#检查当前层 m 是否为线性层 (nn.Linear) nn.init.normal_(m.weight, std=0.01)#如果是线性层,则使用正态分布(normal distribution)随机初始化该层的权重 m.weight,标准差为 0.01 net.apply(init_weights);#将定义的 init_weights 函数应用到神经网络模型 net 的所有层上,以便对每一层的权重进行初始化操作 #在交叉熵损失函数中传递未归一化的预测,并同时计算Softmax及其对数 loss = nn.CrossEntropyLoss(reduction='none') #使用学习率为0.1的小批量随机梯度下降作为优化算法 trainer = torch.optim.SGD(net.parameters(), lr=0.1) #训练 num_epochs = 10 d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。