(pytorch-深度学习系列)pytorch避免过拟合-dropout丢弃法的实现-学习笔记

pytorch避免过拟合-dropout丢弃法的实现

对于一个单隐藏层的多层感知机,其中输入个数为4,隐藏单元个数为5,且隐藏单元hih_ihii=1,…,5i=1, \ldots, 5i=1,,5)的计算表达式为:
hi=ϕ(x1w1i+x2w2i+x3w3i+x4w4i+bi)h_i = \phi\left(x_1 w_{1i} + x_2 w_{2i} + x_3 w_{3i} + x_4 w_{4i} + b_i\right) hi=ϕ(x1w1i+x2w2i+x3w3i+x4w4i+bi)
这里ϕ\phiϕ是激活函数,x1,…,x4x_1, \ldots, x_4x1,,x4是输入,隐藏单元iii的权重参数为w1i,…,w4iw_{1i}, \ldots, w_{4i}w1i,,w4i,偏差参数为bib_ibi。当对该隐藏层使用丢弃法时,该层的隐藏单元将有一定概率被丢弃掉。设丢弃概率为ppp,那么有ppp的概率hih_ihi会被清零,有1−p1-p1p的概率hih_ihi会除以1−p1-p1p做拉伸。丢弃概率是丢弃法的超参数。具体来说,设随机变量ξi\xi_iξi为0和1的概率分别为ppp1−p1-p1p。使用丢弃法时我们计算新的隐藏单元hi′h_i'hi
hi′=ξi1−phih_i' = \frac{\xi_i}{1-p} h_i hi=1pξihi
(这个公式就表示 hi′h_i'hi1−p1-p1p的概率为hih_ihi

由于E(ξi)=1−pE(\xi_i) = 1-pE(ξi)=1p,因此

E(hi′)=E(ξi)1−phi=hiE(h_i') = \frac{E(\xi_i)}{1-p}h_i = h_i E(hi)=1pE(ξi)hi=hi
即丢弃法不改变其输入的期望值。我们对隐藏层使用丢弃法,一种可能的结果是h2h_2h2h5h_5h5被清零。这时输出值的计算不再依赖h2h_2h2h5h_5h5,在反向传播时,与这两个隐藏单元相关的权重的梯度均为0。由于在训练中隐藏层神经元的丢弃是随机的,即h1,…,h5h_1, \ldots, h_5h1,,h5都有可能被清零,输出层的计算无法过度依赖h1,…,h5h_1, \ldots, h_5h1,,h5中的任一个,从而在训练模型时起到正则化的作用,并可以用来应对过拟合。在测试模型时,我们为了拿到更加确定性的结果,一般不使用丢弃法。

开始实现drop丢弃法避免过拟合

定义dropout函数:

%matplotlib inline
import torch
import torch.nn as nn
import numpy as npdef dropout(X, drop_prob):X = X.float()assert 0 <= drop_prob <= 1keep_prob = 1 - drop_prob# 这种情况下把全部元素都丢弃if keep_prob == 0:return torch.zeros_like(X)mask = (torch.rand(X.shape) < keep_prob).float()return mask * X / keep_prob

定义模型参数:

num_inputs, num_outputs, num_hiddens1, num_hiddens2 = 784, 10, 256, 256W1 = torch.tensor(np.random.normal(0, 0.01, size=(num_inputs, num_hiddens1)), dtype=torch.float, requires_grad=True)
b1 = torch.zeros(num_hiddens1, requires_grad=True)
W2 = torch.tensor(np.random.normal(0, 0.01, size=(num_hiddens1, num_hiddens2)), dtype=torch.float, requires_grad=True)
b2 = torch.zeros(num_hiddens2, requires_grad=True)
W3 = torch.tensor(np.random.normal(0, 0.01, size=(num_hiddens2, num_outputs)), dtype=torch.float, requires_grad=True)
b3 = torch.zeros(num_outputs, requires_grad=True)params = [W1, b1, W2, b2, W3, b3]

定义模型将全连接层和激活函数ReLU串起来,并对每个激活函数的输出使用丢弃法。分别设置各个层的丢弃概率。通常的建议是把靠近输入层的丢弃概率设得小一点。在这个实验中,我们把第一个隐藏层的丢弃概率设为0.2,把第二个隐藏层的丢弃概率设为0.5。我们可以通过参数is_training来判断运行模式为训练还是测试,并只在训练模式下使用丢弃法。

drop_prob1, drop_prob2 = 0.2, 0.5def net(X, is_training=True):X = X.view(-1, num_inputs)H1 = (torch.matmul(X, W1) + b1).relu()if is_training:  # 只在训练模型时使用丢弃法H1 = dropout(H1, drop_prob1)  # 在第一层全连接后添加丢弃层H2 = (torch.matmul(H1, W2) + b2).relu()if is_training:H2 = dropout(H2, drop_prob2)  # 在第二层全连接后添加丢弃层return torch.matmul(H2, W3) + b3def evaluate_accuracy(data_iter, net):acc_sum, n = 0.0, 0for X, y in data_iter:if isinstance(net, torch.nn.Module):net.eval() # 评估模式, 这会关闭dropoutacc_sum += (net(X).argmax(dim=1) == y).float().sum().item()net.train() # 改回训练模式else: # 自定义的模型if('is_training' in net.__code__.co_varnames): # 如果有is_training这个参数# 将is_training设置成Falseacc_sum += (net(X, is_training=False).argmax(dim=1) == y).float().sum().item() else:acc_sum += (net(X).argmax(dim=1) == y).float().sum().item() n += y.shape[0]return acc_sum / n

训练和测试模型:

num_epochs, lr, batch_size = 5, 100.0, 256
loss = torch.nn.CrossEntropyLoss()def load_data_fashion_mnist(batch_size, resize=None, root='~/Datasets/FashionMNIST'):"""Download the fashion mnist dataset and then load into memory."""trans = []if resize:trans.append(torchvision.transforms.Resize(size=resize))trans.append(torchvision.transforms.ToTensor())transform = torchvision.transforms.Compose(trans)mnist_train = torchvision.datasets.FashionMNIST(root=root, train=True, download=True, transform=transform)mnist_test = torchvision.datasets.FashionMNIST(root=root, train=False, download=True, transform=transform)if sys.platform.startswith('win'):num_workers = 0  # 0表示不用额外的进程来加速读取数据else:num_workers = 4train_iter = torch.utils.data.DataLoader(mnist_train, batch_size=batch_size, shuffle=True, num_workers=num_workers)test_iter = torch.utils.data.DataLoader(mnist_test, batch_size=batch_size, shuffle=False, num_workers=num_workers)return train_iter, test_iterdef train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size,params=None, lr=None, optimizer=None):for epoch in range(num_epochs):train_l_sum, train_acc_sum, n = 0.0, 0.0, 0for X, y in train_iter:y_hat = net(X)l = loss(y_hat, y).sum()# 梯度清零if optimizer is not None:optimizer.zero_grad()elif params is not None and params[0].grad is not None:for param in params:param.grad.data.zero_()l.backward()if optimizer is None:sgd(params, lr, batch_size)else:optimizer.step()  # “softmax回归的简洁实现”一节将用到train_l_sum += l.item()train_acc_sum += (y_hat.argmax(dim=1) == y).sum().item()n += y.shape[0]test_acc = evaluate_accuracy(test_iter, net)print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f'% (epoch + 1, train_l_sum / n, train_acc_sum / n, test_acc))
train_iter, test_iter = load_data_fashion_mnist(batch_size)
train_ch3(net, train_iter, test_iter, loss, num_epochs, batch_size, params, lr)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/507995.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(pytorch-深度学习系列)正向传播与反向传播-学习笔记

正向传播与反向传播 1. 正向传播 正向传播是指对神经网络沿着从输入层到输出层的顺序&#xff0c;依次计算并存储模型的中间变量&#xff08;包括输出&#xff09;。 假设输入是一个特征为x∈Rd\boldsymbol{x} \in \mathbb{R}^dx∈Rd的样本&#xff0c;且不考虑偏差项&#x…

(pytorch-深度学习系列)简单实现kaggle房价预测-学习笔记

实现kaggle房价预测 导入所需模块&#xff1a; %matplotlib inline import torch import torch.nn as nn import numpy as np import pandas as pdprint(torch.__version__) torch.set_default_tensor_type(torch.FloatTensor)读取数据集&#xff1a; &#xff08;具体以自己…

(pytorch-深度学习系列)ResNet残差网络的理解-学习笔记

ResNet残差网络的理解 ResNet伴随文章 Deep Residual Learning for Image Recognition 诞生&#xff0c;该文章是MSRA何凯明团队在2015年ImageNet上使用的网络&#xff0c;在当年的classification、detection等比赛中&#xff0c;ResNet均获了第一名&#xff0c;这也导致了Res…

(pytorch-深度学习系列)pytorch构造深度学习模型-学习笔记

pytorch构造深度学习模型 1. 通过继承module类的方式来构造模型 Module类是nn模块里提供的一个模型构造类&#xff0c;是所有神经网络模块的基类。 可以继承基类并重构 __init()__函数和forward()forward()forward()函数的方式来构造模型。 以下是一个构造一个模型的例子&am…

(pytorch-深度学习系列)模型参数的初始化与访问操作-学习笔记

模型参数的初始化与访问操作 学习 如何初始化以及访问模型参数&#xff0c;以及如何在多层之间共享模型参数 首先定义一个含有单个隐藏层的多层感知机&#xff0c;使用默认方式初始化该模型的参数&#xff0c;并且进行一次前向计算&#xff1a; import torch from torch impo…

(pytorch-深度学习系列)pytorch实现自定义网络层,并自设定前向传播路径-学习笔记

pytorch实现自定义网络层&#xff0c;并自设定前向传播路径-学习笔记 1. 不包含模型参数的自定义网络层 首先我们自定义一个网络层&#xff0c; 定义一个网络层&#xff0c;使其不包含模型参数&#xff0c;并在forward()函数中进行运算&#xff1a; import torch from torc…

(pytorch-深度学习系列)读取和存储数据-学习笔记

读取和存储数据 我们可以使用pt文件存储Tensor数据&#xff1a; import torch from torch import nnx torch.ones(3) torch.save(x, x.pt)这样我们就将数据存储在名为x.pt的文件中了 我们可以从文件中将该数据读入内存&#xff1a; x2 torch.load(x.pt) print(x2)还可以存…

(pytorch-深度学习系列)pytorch使用GPU计算-学习笔记

pytorch使用GPU计算 在之前的blog中早已经讲过如何配置pytorch的GPU加速环境 查看GPU加速是否可用&#xff1a; import torch from torch import nnprint(torch.cuda.is_available()) # true 查看GPU是否可用print(torch.cuda.device_count()) #GPU数量&#xff0c; 1torch.…

(pytorch-深度学习系列)CNN二维卷积层-学习笔记

二维卷积层 在二维互相关运算中&#xff0c;卷积窗口从输入数组的最左上方开始&#xff0c;按从左往右、从上往下的顺序&#xff0c;依次在输入数组上滑动。当卷积窗口滑动到某一位置时&#xff0c;窗口中的输入子数组与核数组按元素相乘并求和&#xff0c;得到输出数组中相应…

(pytorch-深度学习系列)卷积神经网络中的填充(padding)和步幅(stride)

卷积神经网络中的填充(padding)和步幅(stride) 之前写过一篇blog&#xff0c;描述CNN网络层的输入和输入尺寸的计算关系&#xff0c;但是并没有描述的很全面&#xff0c;这里全面描述了影响输出尺寸的两个超参数padding和stride&#xff0c;查阅了相关资料&#xff0c;编码理解…

(pytorch-深度学习系列)CNN的多输入通道和多输出通道

CNN的多输入通道和多输出通道 之前的输入都视为二维数组&#xff0c;但是真实数据往往具有更高的维度&#xff0c;彩色图像有RGB三个颜色通道&#xff0c;那么这个图像&#xff08;高为h&#xff0c;宽为w&#xff09;可以表示为3∗h∗w3*h*w3∗h∗w的多维数组&#xff0c;一般…

(pytorch-深度学习系列)CNN中的池化层-学习笔记

CNN中的池化层 首先&#xff0c;池化&#xff08;pooling&#xff09;层的提出是为了缓解卷积层对位置的过度敏感性。 什么意思&#xff1f; 比如在图像边缘检测问题中&#xff0c;实际图像里&#xff0c;我们的目标物体不会总出现在固定位置&#xff0c;即使我们连续拍摄同…

(pytorch-深度学习系列)卷积神经网络LeNet-学习笔记

卷积神经网络LeNet 先上图&#xff1a;LeNet的网络结构 卷积(6个5∗5的核)→降采样(池化)(2∗2的核&#xff0c;步长2)→卷积(16个5∗5的核)→降采样(池化)(2∗2的核&#xff0c;步长2)→全连接16∗5∗5→120→全连接120→84→全连接84→10\begin{matrix}卷积 \\ (6个5*5的核…

(pytorch-深度学习系列)深度卷积神经网络AlexNet

深度卷积神经网络AlexNet 文字过多&#xff0c;但是重点已经标出来了 背景 在LeNet提出后的将近20年里&#xff0c;神经网络一度被其他机器学习方法超越&#xff0c;如支持向量机。虽然LeNet可以在早期的小数据集上取得好的成绩&#xff0c;但是在更大的真实数据集上的表现并…

(pytorch-深度学习系列)使用重复元素的网络(VGG)

使用重复元素的网络&#xff08;VGG&#xff09; VGG的名字来源于论文作者所在的实验室Visual Geometry Group&#xff0c;VGG提出了可以通过重复使用简单的基础块来构建深度模型的思路。 VGG Block(VGG 块) VGG块的组成规律是&#xff1a;连续使用数个相同的填充为1、窗口形…

(pytorch-深度学习系列)网络中的网络(NiN)

网络中的网络&#xff08;NiN&#xff09; LeNet、AlexNet和VGG在设计上的共同之处是&#xff1a;先以由卷积层构成的模块充分抽取空间特征&#xff0c;再以由全连接层构成的模块来输出分类结果。其中&#xff0c;AlexNet和VGG对LeNet的改进主要在于如何对这两个模块加宽&…

(pytorch-深度学习)包含并行连结的网络(GoogLeNet)

包含并行连结的网络&#xff08;GoogLeNet&#xff09; 在2014年的ImageNet图像识别挑战赛中&#xff0c;一个名叫GoogLeNet的网络结构大放异彩。它虽然在名字上向LeNet致敬&#xff0c;但在网络结构上已经很难看到LeNet的影子。GoogLeNet吸收了NiN中网络串联网络的思想&#…

(pytorch-深度学习)批量归一化

批量归一化 批量归一化&#xff08;batch normalization&#xff09;层能让较深的神经网络的训练变得更加容易 通常来说&#xff0c;数据标准化预处理对于浅层模型就足够有效了。随着模型训练的进行&#xff0c;当每层中参数更新时&#xff0c;靠近输出层的输出较难出现剧烈变…

(pytorch-深度学习)实现残差网络(ResNet)

实现残差网络(ResNet) 我们一般认为&#xff0c;增加神经网络模型的层数&#xff0c;充分训练后的模型理论上能更有效地降低训练误差。理论上&#xff0c;原模型解的空间只是新模型解的空间的子空间。也就是说&#xff0c;如果我们能将新添加的层训练成恒等映射f(x)xf(x) xf(…

(pytorch-深度学习)实现稠密连接网络(DenseNet)

稠密连接网络&#xff08;DenseNet&#xff09; ResNet中的跨层连接设计引申出了数个后续工作。稠密连接网络&#xff08;DenseNet&#xff09;与ResNet的主要区别在于在跨层连接上的主要区别&#xff1a; ResNet使用相加DenseNet使用连结 ResNet&#xff08;左&#xff09;…