当前位置: 首页 > news >正文

高端企业网站要多少钱网站后台页面设计

高端企业网站要多少钱,网站后台页面设计,最好看免费观看高清大全老师补课,公众平台微信公众号官网经典的卷积神经网络 在本次笔记中主要介绍一些经典的卷积神经网络模型#xff0c;主要包含以下#xff1a; LeNet#xff1a;最早发布的卷积神经网络之一#xff0c;目的是识别图像中的手写数字#xff1b;AlexNet#xff1a; 是第一个在大规模视觉竞赛中击败传统计算机…经典的卷积神经网络 在本次笔记中主要介绍一些经典的卷积神经网络模型主要包含以下 LeNet最早发布的卷积神经网络之一目的是识别图像中的手写数字AlexNet 是第一个在大规模视觉竞赛中击败传统计算机视觉模型的大型神经网络使用重复块的网络VGG利用许多重复的神经网络块网络中的网络NiN重复使用由卷积层和1×1卷积层用来代替全连接层来构建深层网络;含并行连结的网络GoogLeNet使用并行连结的网络通过不同窗口大小的卷积层和最大汇聚层来并行抽取信息残差网络ResNet它通过残差块构建跨层的数据通道是计算机视觉中最流行的体系架构稠密连接网络DenseNet它的计算成本很高但能带来了更好的效果。轻量化CNNmobileNet旨在优化移动和嵌入式设备上的性能 LeNet 介绍 最早发布的卷积神经网络之一因其在计算机视觉任务中的高效性能而受到广泛关注。 该模型是由ATT贝尔实验室的研究员Yann LeCun在1989年提出的并以其命名目的是识别图像中的手写数字应用与美国邮政服务。 LeNetLeNet-5由两个部分组成 卷积编码器由两个卷积层组成全连接层密集块由三个全连接层组成。 在卷积层块中每个卷积层都使用5 × 5 的窗口并在输出上使用sigmoid激活函数。第一个卷积层输出通道数为6第二个卷积层输出通道数则增加到16。 在图中网络结构中汇聚层就是应用最大池化完成的。其中最大池化的窗口大小为2 × 2且步幅为2。由于池化窗口与步幅形状相同池化窗口在输入上每次滑动所覆盖的区域互不重叠。 该网络使用数据集MNIST数据集 包含50000个训练数据、10000个测试数据样本均为灰度图像28*28输出10类0-9 总结 LeNet是早期成功的神经网络先使用卷积层来学习图片空间信息然后使用全连接层来转换到类别空间 代码实现 # lenet模型的实现import torch from torch import nn from d2l import torch as d2lnet nn.Sequential(nn.Conv2d(1, 6, kernel_size5, padding2), nn.Sigmoid(),nn.AvgPool2d(kernel_size2, stride2),nn.Conv2d(6, 16, kernel_size5), nn.Sigmoid(),nn.AvgPool2d(kernel_size2, stride2),nn.Flatten(),nn.Linear(16 * 5 * 5, 120), nn.Sigmoid(),nn.Linear(120, 84), nn.Sigmoid(),nn.Linear(84, 10) )# 我们对原始模型做了一点小改动去掉了最后一层的高斯激活。除此之外这个网络与最初的LeNet-5一致。# 检查模型 X torch.rand(size(1, 1, 28, 28), dtypetorch.float32) for layer in net:X layer(X)print(layer.__class__.__name__,output shape: \t,X.shape)# 模型训练,上面已经实现了LeNet,接下来让我们看看LeNet在Fashion-MNIST数据集上的表现 batch_size 256 train_iter, test_iter d2l.load_data_fashion_mnist(batch_sizebatch_size)# 评估模型 def evaluate_accuracy_gpu(net, data_iter, deviceNone):if isinstance(net, nn.Module):net.eval() # 设置为评估模式# 如果 device 参数未提供则通过 next(iter(net.parameters())).device 获取模型第一个参数所在的设备将其作为后续计算的设备。if not device:device next(iter(net.parameters())).device# 正常预测的数量,总预测的数量metric d2l.Accumulator(2)# 在评估阶段不需要计算梯度with torch.no_grad():for X, y in data_iter:# 如果输入数据 X 是列表类型通常在 BERT 微调等场景中会遇到将列表中的每个张量迁移到指定设备上。if isinstance(X, list):# BERT 微调所需的(之后讲)X [x.to(device) for x in X]else:# 否则直接将输入数据 X 迁移到指定设备上X X.to(device)# 标签 y 迁移到指定设备上 y y.to(device)# 使用 d2l 库中的 accuracy 函数计算当前批次的预测准确率即正确预测的样本数量。metric.add(d2l.accuracy(net(X), y), y.numel())return metric[0] / metric[1]# 训练函数def train_ch6(net, train_iter, test_iter, num_epochs, lr, device):用GPU训练模型# 1. 初始化模型的权重使用 Xavier 均匀分布初始化线性层和卷积层的权重。def init_weight(m):if type(m) nn.Linear or type(m) nn.Conv2d:nn.init.xavier_uniform_(m.weight)net.apply(init_weight)print(training on, device)# 2. 将模型移动到指定的设备通常是 GPU上进行训练。net.to(device)# 3.定义优化器随机梯度下降 SGD和损失函数交叉熵损失。optimizer torch.optim.SGD(net.parameters(), lrlr)loss nn.CrossEntropyLoss()# 4. 创建一个动画绘制器 Animator 用于实时可视化训练过程中的损失和准确率变化。animator d2l.Animator(xlabelepoch, xlim[1, num_epochs],legend[train loss, train acc, test acc])timer, num_batches d2l.Timer(), len(train_iter)# 5. 开始多个轮次的训练在每个轮次中遍历训练数据集计算损失、反向传播并更新模型参数。for epoch in range(num_epochs):# 训练损失之和,训练准确率之和,样本数metric d2l.Accumulator(3)net.train()for i, (X, y) in enumerate(train_iter):timer.start()optimizer.zero_grad()X, y X.to(device), y.to(device)y_hat net(X)l loss(y_hat, y)l.backward()optimizer.step()with torch.no_grad():metric.add(l * X.shape[0], d2l.accuracy(y_hat, y), X.shape[0])timer.stop()train_l metric[0] / metric[2]train_acc metric[1] / metric[2]if (i 1) % (num_batches // 5) 0 or i num_batches - 1:animator.add(epoch (i 1) / num_batches,(train_l, train_acc ,None))# 6.每个轮次结束后评估模型在测试数据集上的准确率。test_acc evaluate_accuracy_gpu(net, test_iter)animator.add(epoch 1, (None, None, test_acc))# 7.最后输出训练结束后的训练损失、训练准确率、测试准确率以及训练速度。print(floss{train_l:.3f}, train acc {train_acc:.3f},ftest acc {test_acc:.3f})print(f{metric[2] * num_epochs / timer.sum():.1f} examples/secfon {str(device)})# 接下来训练和评估LeNet-5模型 lr, num_epochs 0.9, 10 train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu()) 得到结果: AlexNet 先说点其他的 背景 当时关于特征提取有两种思想 观察图像特征的提取方法2012年 前图像特征都是机械地计算出来的。认为特征本身应该被学习 AlexNet 诞生的关键因素 数据层面深度模型需大量有标签数据才能优于传统方法。早期受存储和预算限制研究多基于小数据集。2009 年 ImageNet 数据集发布并举办挑战赛提供百万样本、千种类别推动了研究发展。硬件层面深度学习计算需求高早期优化凸目标的简单算法因计算资源限制受青睐。GPU 最初用于图形处理其运算与卷积层计算相似英伟达和 ATI 将其优化用于通用计算。GPU 由众多小型处理单元组成虽单个核心性能弱但数量庞大在浮点性能、功耗和内存带宽方面优于 CPU。2012 年Alex Krizhevsky 和 Ilya Sutskever 利用 GPU 实现快速卷积运算推动了深度学习发展。 介绍 网络结构 使用了8层卷积神经网络前5层是卷积层剩下的3层是全连接层具体如下所示。 (由当时GPU内存的限制引起的作者使用两块GPU进行计算因此分为了上下两部分) 与LeNet结构的差异 具体细节 卷积层C1使用96个核对224×224×3的输入图像进行滤波卷积核大小为11×11×3步长为4。将一对55×55×48的特征图分别放入ReLU激活函数生成激活图。激活后的图像进行最大池化size为3×3stride为2池化后的特征图size为27×27×48一对。池化后进行LRN处理。卷积层C2使用卷积层C1的输出响应归一化和池化作为输入并使用256个卷积核进行滤波核大小为5 × 5 × 48。卷积层C3有384个核核大小为3 × 3 × 256与卷积层C2的输出归一化的池化的相连。卷积层C4有384个核核大小为3 × 3 × 192。卷积层C5有256个核核大小为3 × 3 × 192。卷积层C5与C3、C4层相比多了个池化池化核size同样为3×3stride为2。全连接F6此层的全连接实际上是通过卷积进行的输入6×6×2564096个6×6×256的卷积核扩充边缘padding 0, 步长stride 1, 因此其FeatureMap大小为(6-60×21)/1 1即1×1×4096; 创新特点 更深的神经网络结构 AlexNet 是首个真正意义上的深度卷积神经网络它的深度达到了当时先前神经网络的数倍。通过增加网络深度AlexNet 能够更好地学习数据集的特征从而提高了图像分类的精度。 ReLU激活函数的使用 AlexNet 首次使用了修正线性单元ReLU这一非线性激活函数。相比于传统的 sigmoid 和 tanh 函数ReLU 能够在保持计算速度的同时有效地解决了梯度消失问题从而使得训练更加高效。 ReLU激活函数的使用 对于每个特征图上的每个位置计算该位置周围的像素的平方和然后将当前位置的像素值除以这个和。 LRN是在卷积层和池化层之间添加的一种归一化操作。在卷积层中每个卷积核都对应一个特征图feature mapLRN就是对这些特征图进行归一化。具体来说对于每个特征图上的每个位置计算该位置周围的像素的平方和然后将当前位置的像素值除以这个和。 数据增强和Dropout 数据增强通过随机裁剪、水平翻转图像以及对 RGB 通道强度进行 PCA 变换来扩大数据集减少过拟合降低错误率。Dropout在全连接层使用 Dropout 技术以 0.5 概率随机失活神经元减少神经元间复杂的协同适应防止过拟合测试时将神经元输出乘以 0.5。 大规模分布式训练 AlexNet在使用GPU进行训练时可将卷积层和全连接层分别放到不同的GPU上进行并行计算从而大大加快了训练速度。像这种大规模 GPU 集群进行分布式训练的方法在后来的深度学习中也得到了广泛的应用。 分布式GPU的使用方式 将网络分布在两个 GTX 580 GPU 上进行训练。两个 GPU 之间能够直接读写彼此内存无需通过主机内存这为跨 GPU 并行化提供了便利。 在分布式训练时各层在两个 GPU 上有不同的分工如下图 对模型压缩的启发 模型分割与并行化 减少冗余与参数共享 如C4、C5卷积层仅与同GPU的特征图相连。参数共享、剪枝 优化训练策略调整学习率和优化器参数 利用硬件特性使用低精度计算、设计轻量级网络结构 总结 AlexNet的架构与LeNet相似但使用了更多的卷积层和更多的参数来拟合大规模的ImageNet数据集。 现在AlexNet已经被更有效的架构所超越但它是从浅层网络到深层网络的关键一步。 尽管AlexNet的代码只比LeNet多出几行但学术界花了很多年才接受深度学习这一概念并应用其出色的实验结果。这也是由于缺乏有效的计算工具。 Dropout、ReLU和预处理是提升计算机视觉任务性能的其他关键步骤。 代码实现 import torch from torch import nn from d2l import torch as d2lnet nn.Sequential(# 这里使用一个11*11的更大窗口来捕捉对象。# 同时步幅为4以减少输出的高度和宽度。# 另外输出通道的数目远大于LeNetnn.Conv2d(1, 96, kernel_size11, stride4, padding1), nn.ReLU(),nn.MaxPool2d(kernel_size3, stride2),# 减小卷积窗口使用填充为2来使得输入与输出的高和宽一致且增大输出通道数nn.Conv2d(96, 256, kernel_size5, padding2), nn.ReLU(),nn.MaxPool2d(kernel_size3, stride2),# 使用三个连续的卷积层和较小的卷积窗口。# 除了最后的卷积层输出通道的数量进一步增加。# 在前两个卷积层之后汇聚层不用于减少输入的高度和宽度nn.Conv2d(256, 384, kernel_size3, padding1), nn.ReLU(),nn.Conv2d(384, 384, kernel_size3, padding1), nn.ReLU(),nn.Conv2d(384, 256, kernel_size3, padding1), nn.ReLU(),nn.MaxPool2d(kernel_size3, stride2),nn.Flatten(),# 这里全连接层的输出数量是LeNet中的好几倍。使用dropout层来减轻过拟合nn.Linear(6400, 4096),nn.ReLU(),nn.Dropout(p0.5),nn.Linear(4096, 4096), nn.ReLU(),nn.Dropout(p0.5),# 最后是输出层。由于这里使用Fashion-MNIST所以用类别数为10而非论文中的1000nn.Linear(4096, 10) )# 构造一个高度和宽度都为224的(单通道数据来观察每一层输出的形状 X torch.randn(1, 1, 224, 224) for layer in net:X layer(X)print(layer.__class__.__name__,output shape:\t, X.shape)# 读取数据集 batch_size 128 # Fashion-MNIST图像的分辨率 低于ImageNet图像。:我们将它们增加到224 x224;这里是为了在AlexNet上使用该数据集;一般不会使用resize224 train_iter, test_iter d2l.load_data_fashion_mnist(batch_size, resize224)lr, num_epochs 0.01, 10 d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())结果: 可以看到损失比在LeNet上降了很多训练精度和测试精度都大幅提高 这里是在Kaggle上跑的自己电脑根本跑不动(/(ㄒoㄒ)/~~) VGG 设计背景AlexNet 虽证明深层神经网络有效但未提供通用设计模板。随着神经网络架构设计的抽象化发展研究人员转向以块为单位设计网络VGG 网络便是使用块进行设计的典型代表。经典卷积神经网络的基本组成部分 带填充以保持分辨率的卷积层非线性激活函数如ReLU汇聚池化层如最大汇聚池化层。 一个VGG块与之类似由一系列的卷积层组成后面再加上用于空间下采样的最大池化层。 介绍 概念说明卷积层全部为3*3的卷积核用conv3-xxx来表示xxx表示通道数。 在VGG论文中展示了六次实验的结果 其中详细为 A简单的卷积神经网络结构 A-LRN在A的基础上加了LRN B在A的基础上加了两个conv3即多加了两个33卷积核 CB的基础上加了三个conv1即多加了三个11卷积核 DC的基础上把三个conv1换成了三个33卷积核 ED的基础上加了三个conv3即多加了三个33卷积核 从以上的实验中可以得到 A和A-LRN对比LRN并没有得到好的效果可去除C和D对比Conv3 比Conv1 更有效统筹看这六个实验可发现随着网络层数的加深模型的表现会越来越好 总结 VGG使用 可复用的卷积块构造网络。不同的VGG模型可通过每个块中卷积层数量和输出通道数量的 差异来定义。块的使用导致网络定义的非常简洁使用块可以有效地设计复杂的网络。在VGG论文中Simonyan和Ziserman尝试了各种架构。特别是他们发现 深层且窄的卷积即3 × 3比 较浅层且宽的卷积更有效。 代码实现 import torch from torch import nn from d2l import torch as d2l# 实现 VGG块 def vgg_block(num_convs, in_channels, out_channels):layers []for _ in range(num_convs):# 根据需要几个添加 卷积 和 激活函数layers.append(nn.Conv2d(in_channels, out_channels,kernel_size3, padding1))layers.append(nn.ReLU())in_channels out_channelslayers.append(nn.MaxPool2d(kernel_size2, stride2))return nn.Sequential(*layers)# VGG 网络: 主要由卷积层和汇聚层组成第二部分由全连接层组成 # 原始VGG网络有5个卷积块其中前两个块各有一个卷积层后三个块各包含两个卷积层。 # 第一个模块有64个输出通道每个后续模块将输出通道数量翻倍直到该数字达到512。 # 由于该网络使用8个卷积层和3个全连接层因此它通常被称为VGG-11。 conv_arch ((1, 64), (1, 128), (2, 256), (2, 512), (2, 512))# 下面代码实现了VGG-11 def vgg(conv_arch):conv_blks []in_channels 1# 卷积层部分for (num_convs, out_channels) in conv_arch:conv_blks.append(vgg_block(num_convs, in_channels, out_channels))in_channels out_channelsreturn nn.Sequential(*conv_blks, nn.Flatten(),# 全连接层部分nn.Linear(out_channels * 7 * 7, 4096), nn.ReLU(), nn.Dropout(0.5),nn.Linear(4096, 4096), nn.ReLU(), nn.Dropout(0.5),nn.Linear(4096, 10))net vgg(conv_arch)# 接下来,构建一个高度和宽度为224的单通道数据样本,来观察每个层输出的形状 X torch.randn(size(1, 1, 224, 224)) for blk in net:X blk(X)print(blk.__class__.__name__,output shape:\t,X.shape)# 训练模型 # [由于VGG-11比AlexNet计算量更大因此我们构建了一个通道数较少的网络足够用于训练Fashion-MNIST ratio 4 # 这行代码的主要目的是对 conv_arch 列表中的每个元素进行处理将每个元素一个二元组的第二个值除以 ratio 后得到一个新的二元组然后把这些新的二元组组合成一个新的列表 small_conv_arch。 small_conv_arch [(pair[0], pair[1] // ratio) for pair in conv_arch] net vgg(small_conv_arch)lr, num_epochs, batch_size 0.05, 10, 28 train_iter, test_iter d2l.load_data_fashion_mnist(batch_size, resize224) d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())结果 也可以看到训练精度和测试精度的大幅提升。 NiN 共同的设计模式LeNet、AlexNet和VGG通过一系列的卷积层与池化层来提取空间结构特征然后通过全连接层对特征的表征进行处理。AlexNet和VGG对LeNet的改进主要在于如何扩大和加深这两个模块 带来的问题使用了全连接层可能会完全放弃表征的空间结构。 解决网络中的网络NiN提供了一个非常简单的解决方案在每个像素的通道上分别使用多层感知机具体实现使用多个连续的1 × 1 卷积层被视为 MLP对每个像素点进行多层的非线性特征变换。 介绍 NiN块 卷积层输入和输出由四维张量组成每个轴对应样本、通道、高度、宽度。 全连接层输入和输出二维张量对应样本、特征。 NiN的想法在每个像素位置针对每个高度和宽度应用一个全连接层。 1×1 卷积层可看作逐像素的全连接层增 加每像素的非线性变换还能调整通道数 在减少参数的同时丰富特征表达。 总结 NiN使用由一个卷积层和多个1 x 1卷积层组成的块。该块可以在卷积神经网络中使用以允许更多的每像素非线性。 NiN去除了容易造成过拟合的全连接层将它们替换为全局平均汇聚层即在所有位置上进行求和。该汇聚层通道数量为所需的输出数量例如Fashion-MNIST的输出为10。 移除全连接层可减少过拟合同时显著减少NiN的参数。 NiN的设计影响了许多后续卷积神经网络的设计。 代码实现 import torch from torch import nn from d2l import torch as d2l# NiN块 # NiN的想法是在每个像素位置针对每个高度和宽度应用一个全连接层def nin_block(in_channels, out_channels, kernel_size, strides, padding):return nn.Sequential(nn.Conv2d(in_channels, out_channels, kernel_size, strides, padding),nn.ReLU(),nn.Conv2d(out_channels, out_channels, kernel_size1), nn.ReLU(),nn.Conv2d(out_channels, out_channels, kernel_size1), nn.ReLU())# NiN 模型 # NiN使用窗口形状为 11×11 、 5×5 和 3×3 的卷积层输出通道数量与AlexNet中的相同。 # 每个NiN块后有一个最大汇聚层汇聚窗口形状为 3×3 步幅为2。net nn.Sequential(nin_block(1, 96, kernel_size11, strides4, padding0),nn.MaxPool2d(3, stride2),nin_block(96, 256, kernel_size5, strides1, padding2),nn.MaxPool2d(3, stride2),nin_block(256, 384, kernel_size3, strides1, padding1),nn.MaxPool2d(3, stride2),nn.Dropout(0.5),# 标签类别数是10nin_block(384, 10, kernel_size3, strides1, padding1),nn.AdaptiveAvgPool2d((1, 1)),# 将四维的输出转为二维的输出其形状为批量大小10nn.Flatten() )# 创建一个数据样本来[查看每个块的输出形状] X torch.rand(size(1, 1, 224, 224)) for layer in net:X layer(X)print(layer.__class__.__name__,output shape: \t, X.shape)# 使用Fashion-MNIST来训练模型 lr, num_epochs, batch_size 0.1, 10, 128 train_iter, test_iter d2l.load_data_fashion_mnist(batch_size, resize224) d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu()) 结果 GoogleNet 设计思想吸收了NiN中串联网络的思想并在此基础上做了改进。 重点解决了什么样大小的卷积核最合适的问题 介绍 Inception块是 GoogLeNet 的基本卷积块。 由四条并行路径构成前三条路径分别使用 1×1、3×3 和 5×5 的卷积层提取不同空间大小的信息中间两条路径先通过 1×1 卷积层减少通道数以降低模型复杂度。第四条路径先使用 3×3 最大汇聚层再用 1×1 卷积层改变通道数。四条路径都使用合适的填充来使输入与输出的高和宽一致最后将每条线路的输出在通道维度上连结构成输出。在Inception块中通常调整的超参数是每层输出通道数。 模型框架 一共使用9个Inception块和全局平均汇聚层的堆叠来生成其估计值. 总结 Inception块相当于一个有4条路径的子网络。它通过不同窗口形状的卷积层和最大汇聚层来并行抽取信息并使用1 X 1卷积层减少每像素级别上的通道维数从而降低模型复杂度。 GoogLeNet将多个设计精细的Inception块与其他层卷积层、全连接层串联起来。其中Inception块的通道数分配之比是在ImageNet数据集上通过大量的实验得来的。 GoogLeNet和它的后继者们一度是ImageNet上最有效的模型之一它以较低的计算复杂度提供了类似的测试精度。 GoogLeNet有一些后续版本 添加批量规范化层 (Ioffe and Szegedy, 2015)batch normalization 对Inception模块进行调整 (Szegedy et al., 2016) 使用标签平滑label smoothing进行模型正则化 (Szegedy et al., 2016) 加入残差连接 (Szegedy et al., 2017)。 下节将介绍。 代码实现 import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2l# (Inception块) # Inception块由四条并行路径组成。 # 前三条路径使用窗口大小为 1×1 、 3×3 和 5×5 的卷积层从不同空间大小中提取信息class Inception(nn.Module):# c1--c4是每条路径的输出通道数def __init__(self, in_channels, c1, c2, c3, c4, **kwargs):super(Inception, self).__init__(**kwargs)# 线路1单1 x 1 卷积层self.p1_1 nn.Conv2d(in_channels, c1, kernel_size1)# 线路21x1卷积后接 3x3卷积层self.p2_1 nn.Conv2d(in_channels, c2[0], kernel_size1)self.p2_2 nn.Conv2d(c2[0], c2[1], kernel_size3, padding1)# 线路31x1卷积层后接 5 x 5卷积层self.p3_1 nn.Conv2d(in_channels, c3[0], kernel_size1)self.p3_2 nn.Conv2d(c3[0], c3[1], kernel_size5, padding2)# 线路43x3最大汇聚层后接 1x1卷积层self.p4_1 nn.MaxPool2d(kernel_size3, stride1, padding1)self.p4_2 nn.Conv2d(in_channels, c4, kernel_size1)def forward(self, x):p1 F.relu(self.p1_1(x))p2 F.relu(self.p2_2(F.relu(self.p2_1(x))))p3 F.relu(self.p3_2(F.relu(self.p3_1(x))))p4 F.relu(self.p4_2(self.p4_1(x)))# 在通道连结输出return torch.cat((p1, p2, p3, p4), dim1)# 滤波器filter的组合它们可以用各种滤波器尺寸探索图像这意味着不同大小的滤波器可以有效地识别不同范围的图像细节。 # 同时我们可以为不同的滤波器分配不同数量的参数。 # GoogLeNet一共使用9个Inception块和全局平均汇聚层的堆叠来生成其估计值。# 逐一来实现GoogleNet 的每个模块第一个模块使用64个通道、7 x 7 卷积层 b1 nn.Sequential(nn.Conv2d(1, 64, kernel_size7, stride2, padding3),nn.ReLU(),nn.MaxPool2d(kernel_size3, stride2, padding1) )# 第二个模块使用两个卷积层第一个卷积层是64个通道、1 * 1 卷积层 # 第二个人卷积层使用将通道数量增加三倍的3 * 3 卷积层 对应于Inception块中的第二天路径 b2 nn.Sequential(nn.Conv2d(64, 64, kernel_size1),nn.ReLU(),nn.Conv2d(64, 192, kernel_size3, padding1),nn.ReLU(),nn.MaxPool2d(kernel_size3, stride2, padding1) )# 第三个模块串联两个完整的Inception块 # 第三个模块串联两个完整的Inception块。 # 第一个Inception块的输出通道数为 641283232256 四个路径之间的输出通道数量比为 64:128:32:322:4:1:1 。 # 第二个和第三个路径首先将输入通道的数量分别减少到 96/1921/2 和 16/1921/12 然后连接第二个卷积层。 # 第二个Inception块的输出通道数增加到 1281929664480 四个路径之间的输出通道数量比为 128:192:96:644:6:3:2 。 # 第二条和第三条路径首先将输入通道的数量分别减少到 128/2561/2 和 32/2561/8 。b3 nn.Sequential(Inception(192, 64, (96, 128), (16, 32), 32),Inception(256, 128, (128, 192), (32, 96), 64),nn.MaxPool2d(kernel_size3, stride2, padding1) )# 第4个模块串联了五个Inception块 b4 nn.Sequential(Inception(480, 192, (96, 208), (16, 48), 64),Inception(512, 160, (112, 224), (24, 64), 64),Inception(512, 128, (128, 256), (24, 64), 64),Inception(512, 112, (144, 288), (32, 64), 64),Inception(528, 256, (160, 320), (32, 128), 128),nn.MaxPool2d(kernel_size3, stride2, padding1) ) # 第五模块包含输出通道数为 256320128128832 和 3843841281281024 的两个Inception块 b5 nn.Sequential(Inception(832, 256, (160, 320), (32, 128), 128),Inception(832, 384, (192, 384), (48, 128), 128),nn.AdaptiveAvgPool2d((1,1)),nn.Flatten() )net nn.Sequential(b1, b2, b3, b4, b5, nn.Linear(1024, 10))# 模型计算复杂不如VGG那样便于修改通道数 # 为了使Fashion-MNIST上的训练短小精悍我们将输入的高和宽从224降到96] X torch.rand(size(1, 1, 96, 96)) for layer in net:X layer(X)print(layer.__class__.__name__, output shape:\t, X.shape)# 训练模型 lr, num_epochs, batch_size 0.1, 10, 128 train_iter, test_iter d2l.load_data_fashion_mnist(batch_size, resize96) d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())结果 批量规范化 批量规范化是在卷积层或全连接层之后、相应的激活函数之前应用的。 先计算小批量的均值和标准差 BN公式: 输入x∈B 其中, 可学习参数拉伸参数scaleγ和偏移参数shiftβ; 应用标准化后生成的小批量的平均值为0和单位方差为1。 标准化的作用: 标准化输入特征可统一参数量级有助于优化器工作中间层变量变化范围大其分布偏移会阻碍网络收敛。不同层变量值相差较大时需针对性的调整学习率深层网络结构复杂容易出现过拟合现象。 ResNet 函数类角度 具有X特性和y标签的数据集 F: 神经网络架构包含学习率及其他超参数设置 当我们想要训练一个更强大的F’需要满足 F ∈ F’即较复杂函数类包含较小函数类。 也就是说: 新模型的函数类包含了原模型的函数新模型具备原模型的所有能力在处理相同任务时至少能达到与原模型相同的效果。 针对深度神经网络, 将新添加层训练成恒等映射: 残差网络的核心思想每个附加层都应更容易地包含原始函数作为其元素之一。 于是残差块residual blocks便诞生了。 介绍 残差块 对于深度神经网络学习恒等映射相对容易。以残差块为例在残差块中拟合 f(x) - x 残差映射比直接拟合f(x)理想映射更简单。当理想映射f(x)极接近于恒等映射时残差映射更易于捕捉恒等映射的细微波动。将新添加层训练为恒等映射其权重和偏置参数可近似为零从优化的角度这种简单的映射关系使得训练过程更稳定不易出现梯度消失或爆炸等问题从而保证新模型能达到与原模型相同的性能水平。 模型框架 前两层与GoogleNet一样不同之处在于ResNet每个卷积层后增加了批量规范化层。每个模块有4个卷积层不包括恒等映射的1 * 1 卷积层。 加上第一个卷积层和最后一个全连接层共有18层。 因此这种模型通常被称为ResNet-18。 通过配置不同的通道数和模块里的残差块数可以得到不同的ResNet模型例如更深的含152层的ResNet-152。虽然ResNet的主体架构跟GoogLeNet类似但ResNet架构更简单修改也更方便. 总结 学习嵌套函数nested function是训练神经网络的理想情况。在深层神经网络中学习另一层作为恒等映射identity function较容易尽管这是一个极端情况。 残差映射可以更容易地学习同一函数例如将权重层中的参数近似为零。 利用残差块residual blocks可以训练出一个有效的深层神经网络输入可以通过层间的残余连接更快地向前传播。 代码实现 !pip install d2l import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2l# 残差块定义 # 残差块里首先有2个有相同输出通道数的 3×3 卷积层。 每个卷积层后接一个批量规范化层和ReLU激活函数。 # 然后我们通过跨层数据通路跳过这2个卷积运算将输入直接加在最后的ReLU激活函数前。 # 这样的设计要求2个卷积层的输出与输入形状一样从而使它们可以相加# 实现如下 class Residual(nn.Module):def __init__(self, input_channels, num_channels,use_1x1convFalse, strides1):super().__init__()self.conv1 nn.Conv2d(input_channels, num_channels,kernel_size3, padding1, stridestrides)self.conv2 nn.Conv2d(num_channels, num_channels,kernel_size3, padding1)if use_1x1conv:self.conv3 nn.Conv2d(input_channels, num_channels,kernel_size1, stridestrides)else:self.conv3 Noneself.bn1 nn.BatchNorm2d(num_channels)self.bn2 nn.BatchNorm2d(num_channels)def forward(self, X):Y F.relu(self.bn1(self.conv1(X)))Y self.bn2(self.conv2(Y))if self.conv3:X self.conv3(X)Y Xreturn F.relu(Y)# 查看[输入和输出形状一致] blk Residual(3,3) X torch.rand(4, 3, 6, 6) Y blk(X) Y.shape# 增加输出通道数的同时减半输出的高和宽]。 blk Residual(3,6, use_1x1convTrue, strides2) blk(X).shape# ResNet模型 # 前两层跟之前介绍的GoogLeNet中的一样 在输出通道数为64、步幅为2的 7×7 卷积层后接步幅为2的 3×3 的最大汇聚层 b1 nn.Sequential(nn.Conv2d(1, 64, kernel_size7, stride2, padding3),nn.BatchNorm2d(64), nn.ReLU(),nn.MaxPool2d(kernel_size3, stride2, padding1) )# ResNet则使用4个由残差块组成的模块每个模块使用若干个同样输出通道数的残差块。 # 第一个模块的通道数同输入通道数一致 # 注意对第一个模块做了特别处理。 def resnet_block(input_channels, num_channels, num_residuals,first_blockFalse):blk []for i in range(num_residuals):if i 0 and not first_block:blk.append(Residual(input_channels, num_channels,use_1x1convTrue, strides2))else:blk.append(Residual(num_channels, num_channels))return blk# 接着在ResNet加入所有残差块这里每个模块使用2个残差块。 b2 nn.Sequential(*resnet_block(64, 64, 2, first_blockTrue)) b3 nn.Sequential(*resnet_block(64, 128, 2)) b4 nn.Sequential(*resnet_block(128, 256, 2)) b5 nn.Sequential(*resnet_block(256, 512, 2))# 最后在ResNet中加入全局平均汇聚层以及全连接层输出。 net nn.Sequential(b1,b2,b3,b4,b5,nn.AdaptiveAvgPool2d((1,1)),nn.Flatten(), nn.Linear(512, 10) )# 观察一下ResNet中不同模块的输入形状是如何变化的 # X torch.rand(size(1, 1, 224, 224)) # for layer in net: # X layer(X) # print(layer.__class__.__name__,output shape:\t, X.shape)# 训练模型 lr, num_epochs, batch_size 0.05, 10, 256 train_iter, test_iter d2l.load_data_fashion_mnist(batch_size, resize96) d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())结果 使用残差网络可以看出训练损失降了很多并且训练精度和测试精度有大幅提高不过两者存在一定的gap。 DenseNet 从 ResNet 到 DenseNet: 继续拓展: 稠密连接: 稠密网络由2部分构成稠密块dense block和过渡层transition layer。 前者定义如何连接输入和输出而后者则控制通道数量。 介绍 稠密块dense block 由多个使用相同数量输出通道的卷积块组成 卷积块架构 BN - ReLU - Conv bottleneck 主要作用:实现特征重用即对不同“级别”的特征——不同表征进行总体性地再探索 过渡层transition layer 主要用于连接两个相邻的DenseBlock。包括一个1x1卷积用于调整通道数和2x2AvgPooling用于降低特征图大小结构为BNReLU1x1 Conv2x2 AvgPooling。作用:Transition层可以起到压缩模型的作用。 超参数调节 θ取值(0,1]当θ1时feature维度不变即无压缩而θ1时这种结构称为DenseNet-C文中使用θ0.5对于使用bottleneck层的DenseBlock结构和压缩系数小于1的Transition组合结构称为DenseNet-BC。 网络结构 DenseNet的网络结构主要由DenseBlock和Transition组成一个DenseNet中有3个或4个DenseBlock。而一个DenseBlock中也会有多个Bottleneck layers。最后的DenseBlock之后是一个global AvgPooling层然后送入一个softmax分类器得到每个类别所属分数。 总结 代码实现 import torch from torch import nn from d2l import torch as d2l# 使用 ResNet 改良版中 BN、ReLU、Conv架构def conv_block(input_channels, num_channels):return nn.Sequential(nn.BatchNorm2d(input_channels), nn.ReLU(),nn.Conv2d(input_channels, num_channels, kernel_size3, padding1))# 一个稠密块由多个卷积块组成每个卷积块使用相同数量的输出通道。 # 然而在前向传播中我们将每个卷积块的输入和输出在通道维上连结。 class DenseBlock(nn.Module):def __init__(self, num_convs, input_channels, num_channels):super(DenseBlock, self).__init__()layer []for i in range(num_convs):layer.append(conv_block(num_channels * i input_channels, num_channels))self.net nn.Sequential(*layer)def forward(self, X):for blk in self.net:Y blk(X)# 连接通道维度上每个块的输入和输出X torch.cat((X, Y), dim1)return X# 定义一个有2个输出通道数为10的(DenseBlock) # 使用通道数为3的输入时我们会得到通道数为 32×1023 的输出blk DenseBlock(2, 3, 10) X torch.randn(4, 3, 8, 8) Y blk(X) Y.shape# 过渡层 # 由于每个稠密块都会带来通道数的增加使用过多则会过于复杂化模型。 # 而过渡层可以用来控制模型复杂度。 # 它通过 1×1 卷积层来减小通道数并使用步幅为2的平均汇聚层减半高和宽从而进一步降低模型复杂度。 def transition_block(input_channels, num_channels):return nn.Sequential(nn.BatchNorm2d(input_channels), nn.ReLU(),nn.Conv2d(input_channels, num_channels, kernel_size1),nn.AvgPool2d(kernel_size2, stride2))# 使用 通道数为10的[过渡层]。 此时输出的通道数减为10高和宽均减半。 blk transition_block(23, 10) blk(Y).shape# 构造 DenseNet模型 # DenseNet首先使用同ResNet一样的单卷积层和最大汇聚层。 b1 nn.Sequential(nn.Conv2d(1, 64, kernel_size7, stride2, padding3),nn.BatchNorm2d(64), nn.ReLU(),nn.MaxPool2d(kernel_size3, stride2, padding1) )# DenseNet使用的是4个稠密块 # num_channels为当前的通道数 num_channels, growth_rate 64, 32 num_convs_in_dense_blocks [4, 4, 4, 4] blks [] for i, num_convs in enumerate(num_convs_in_dense_blocks):blks.append(DenseBlock(num_convs, num_channels, growth_rate))# 上一个稠密块的输出通道数num_channels num_convs * growth_rate# 在稠密块之间添加一个转换层使通道数量减半if i ! len(num_convs_in_dense_blocks) - 1:blks.append(transition_block(num_channels, num_channels // 2))num_channels num_channels // 2# 最后接上全局汇聚层和全连接层来输出结果 net nn.Sequential(b1, *blks,nn.BatchNorm2d(num_channels), nn.ReLU(),nn.AdaptiveAvgPool2d((1, 1)),nn.Flatten(),nn.Linear(num_channels, 10))# 训练模型lr, num_epochs, batch_size 0.1, 10, 256 train_iter, test_iter d2l.load_data_fashion_mnist(batch_size, resize96) d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())结果 MobileNet 研究小而高效的CNN模型(思想) 一是对训练好的复杂模型进行压缩得到小模型二是直接设计小模型并进行训练。 核心目标:在保持模型性能accuracy的前提下降低模型大小parameters size同时提升模型速度speed, low latency MobileNet 模型是 Google 针对手机等嵌入式设备提出的一种轻量级的深层神经网络. V1 介绍 主要操作 1将普通卷积换成了深度可分离卷积 2引入了两个超参数使得可以根据资源来更加灵活的控制自己模型的大小。 深度可分离卷积Depthwise separable convolution (追溯历史可分为空间可分离卷积和深度可分离卷积) 分解为两个操作: 深度卷积depthwise convolution 和点卷积 pointwise convolution 回忆下标准卷积: 深度卷积depthwise convolution 对输入特征图的每个通道分别应用一个滤波器 点卷积 pointwise convolution 用 1*1 卷积进行升维和降维 与传统卷积的不同: 为什么使用ReLU6 与relu函数区别: 对输入的最大输出值做了约束.主要原因解释: 为了在移动端float16/int8等低精度设备时也能够有很好的数值分辨率。如果对Relu的值没有加以任何限制则输出范围可以从0到无限大这就使得激活值很大分布在一个很大的范围内而低精度的float16等嵌入式设备就无法很好的精确描述如此大的范围从而带来精度损失。创新点1 创新点2虽然MobileNet网络结构和延迟已经比较小了但是很多时候在特定应用下还是需要更小更快的模型为此引入了宽度因子α为了控制模型大小引入了分辨因子ρ。 宽度因子αWidth Mutiplier 通常α在0, 1] 之间比较典型的值由1 0.75 0.5 0.25在每一层对网络的输入输出通道数进行缩减输出通道数由 M 到 αM输出通道数由 N 到 αN变换后的计算量为 分辨因子ρresolution multiplier 通常ρ在0, 1] 之间比较典型的输入分辨为 224 192 160 128;用于控制输入和内部层表示即用分辨率因子控制输入的分辨率深度卷积和逐点卷积的计算量为 在MobileNetV1中深度卷积网络的每个输入通道都应用了单个滤波器。然后逐点卷积应用 1*1 卷积网络来合并深度卷积的输出。这种标准卷积方法既能滤波又能一步将输入合并成一组新的输出。 网络结构 一共由 28层构成不包括AvgPool 和 FC 层且把深度卷积和逐点卷积分开算 其除了第一层采用的是标准卷积核之外剩下的卷积层都是用Depth Wise Separable Convolution。 下面简要对 V2 和 V3 进行一些介绍 MobileNet V2 在V1的基础上引入了倒残差块Inverted Residual Block和线性激活函数Linear Activation。这些改进使得V2在保持轻量级特性的同时实现了更高的准确性和更低的延迟。倒残差块的设计有助于保留和增强特征信息改善了模型在低资源环境中的表现。 MobileNet V3 进一步对V2进行了全面改进采用了HardSwish激活函数、挤压励磁模块Squeeze-and-Excitation Block以及MnasNet和NetAdapt等**网络架构搜索NAS**技术。这些技术使得V3在保持高性能的同时实现了更快的推理速度和更小的模型尺寸。 MobileNet V1代码实现 import torch from torch import nn from d2l import torch as d2l# 定义深度可分离卷积层 class DepthwiseSeparableConv(nn.Module):def __init__(self, in_channels, out_channels, stride1):super(DepthwiseSeparableConv, self).__init__()# 深度卷积self.depthwise nn.Conv2d(in_channels, in_channels, kernel_size3, stridestride, padding1, groupsin_channels, biasFalse)self.bn1 nn.BatchNorm2d(in_channels)self.relu1 nn.ReLU(inplaceTrue)# 逐点卷积self.pointwise nn.Conv2d(in_channels, out_channels, kernel_size1, biasFalse)self.bn2 nn.BatchNorm2d(out_channels)self.relu2 nn.ReLU(inplaceTrue)def forward(self, x):x self.relu1(self.bn1(self.depthwise(x)))x self.relu2(self.bn2(self.pointwise(x)))return x# 定义 MobileNet V1 网络 class MobileNetV1(nn.Module):def __init__(self, num_classes10):super(MobileNetV1, self).__init__()# 初始卷积层self.conv1 nn.Conv2d(1, 32, kernel_size3, stride2, padding1, biasFalse)self.bn1 nn.BatchNorm2d(32)self.relu1 nn.ReLU(inplaceTrue)# 深度可分离卷积层self.layers nn.Sequential(DepthwiseSeparableConv(32, 64, stride1),DepthwiseSeparableConv(64, 128, stride2),DepthwiseSeparableConv(128, 128, stride1),DepthwiseSeparableConv(128, 256, stride2),DepthwiseSeparableConv(256, 256, stride1),DepthwiseSeparableConv(256, 512, stride2),DepthwiseSeparableConv(512, 512, stride1),DepthwiseSeparableConv(512, 512, stride1),DepthwiseSeparableConv(512, 512, stride1),DepthwiseSeparableConv(512, 512, stride1),DepthwiseSeparableConv(512, 512, stride1),DepthwiseSeparableConv(512, 1024, stride2),DepthwiseSeparableConv(1024, 1024, stride1))# 全局平均池化层self.avgpool nn.AdaptiveAvgPool2d((1, 1))# 全连接层self.fc nn.Linear(1024, num_classes)def forward(self, x):x self.relu1(self.bn1(self.conv1(x)))x self.layers(x)x self.avgpool(x)x x.view(x.size(0), -1)x self.fc(x)return x# 初始化模型 net MobileNetV1()# 训练模型 lr, num_epochs, batch_size 0.1, 10, 256 train_iter, test_iter d2l.load_data_fashion_mnist(batch_size, resize96) d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())结果 总结 AlexNet 首次运用大型神经网络在大规模视觉竞赛中战胜传统计算机视觉模型开启深度卷积神经网络应用的新时代。VGG 利用大量重复的神经网络块构建模型探索出一种规整化的网络构建方式提升了网络的可扩展性和性能。NiN 创新性地用卷积层和 1×1 卷积层替代全连接层构建深层网络减少模型参数数量提升计算效率。GoogLeNet 通过设计 Inception 块运用不同窗口大小的卷积层和最大汇聚层并行抽取信息有效提高模型对图像特征的提取能力。(宽度方向)ResNet 引入残差块构建跨层数据通道解决了深层网络训练中的梯度消失等问题极大地加深了网络深度提升模型性能。(深度方向)DenseNet 采用稠密连接方式在通道维上连结各层输入与输出增强了特征传播与复用能力在一定程度上提升了模型效果但计算成本较高。(从feature上入手)MobileNet 阶段针对移动端等资源受限场景提出深度可分离卷积将普通卷积分解为深度卷积和逐点卷积在大幅降低计算量与模型大小的同时保持了较好的分类精度推动了卷积神经网络在移动设备等领域的广泛应用.
http://www.dnsts.com.cn/news/170600.html

相关文章:

  • 网站的开发语言有哪些wordpress文章 插件
  • 网站推广的方法有sem推广wordpress添加子项目
  • 婚恋网站制作要多少钱网站布局选择
  • 山东建设局网站 王局传媒有限公司
  • asp网站建设制作建e室内设计网址
  • 手机与pc的网站开发谷歌网站流量统计
  • wordpress建站后wordpress如何删主题
  • p2p网站建设时间网络营销的多种形式和特点
  • 厦门35网站建设公司怎么用wordpress打开网站吗
  • 免费的自建视频网站网站程序源码下载
  • 成都网站设计公司价格品牌建设 网站
  • 漳州网站建设哪家最正规美客多电商平台入驻链接
  • 佛山网站推广seo网站设计布局
  • 网站建设一般用哪种语言开发购物网站的建设时间
  • 安徽网站设计平台龙之向导的发展前景
  • 网站 多语国内10大搜索引擎
  • 中山品牌网站建设推广网站建设策划书百度文库
  • 河南省建设教育中心的网站亦庄网站建设
  • 第三方做网站电子商务综合实训报告网站建设
  • 做配资网站多少钱开发app需要哪些审批
  • 简约个人博客html代码德州做网站优化
  • 爱奇艺做视频网站的湘潭平台公司
  • 网站推广必做维影企业网站管理系统
  • 网站cms管理后台电话号码电子商务网站建设核心是
  • 兰州网站建设兼职女性广告
  • 网站建设技术入股合同上海文化传媒公司排名
  • 网站建站在线制作手机制作价格表的软件
  • 网站怎么样被百度收录365建站网
  • 山东专业网站建设公司随州网络优化网站建设公司
  • 嘉兴型网站系统总部文章管理系统网站模板