• [其他] OpenCV(17)---图像平滑处理
    什么是图像平滑处理在尽量保留图像原有信息的情况下,过滤掉图像内部的噪声,这一过程我们称之为图像的平滑处理,所得到的图像称为平滑图像。那么什么是图像的噪声呢?图像的噪声就是图像中与周围像素点差异较大的像素点。噪声的处理就是将其更改为临近像素点的近似值,使图像更平滑。图像平滑处理的噪声取值的方式有以下6种:(1)均值滤波(2)方框滤波(3)高斯滤波(4)中值滤波(5)双边滤波(6)2D卷积(自定义滤波)均值滤波均值滤波是指用当前像素点周围N*N个像素点的均值来代替当前像素值。使用该方法遍历处理图像内的每一个像素点,即可完成整幅图像的均值滤波。在进行均值滤波处理时,我们需要考虑对周围多少个像素点取平均值。通常情况下,我们会以当前像素点为中心,对行数和列数相等的一块区域内的所有像素点取平均值。但是边缘像素点可能不能这样做,毕竟比如左上角的像素点是没有左上像素点的,这个时候我们常常会取图像内存在的周围邻域点的平均值。在OpenCV中,它给我们提供的均值滤波函数为cv2.blur(),其完整定义如下:def blur(src, ksize, dst=None, anchor=None, borderType=None):  src:原始图像kszie:滤波中心的大小,也就是取平均值的周围像素点的高度与宽度,比如(5,5),就是取5*5邻域像素点均值作为结果。anchor:锚点,其默认值为(-1,1),表示当前计算均值的点位于核的中心点位置。一般使用默认值即可。borderType:边界样式,该值决定了以何种方式处理边界,一般情况下不需要更改。了解了该函数的定义,下面我们简单的来完成一个去噪图像,具体代码如下所示:import cv2 img = cv2.imread("5.jpg") result_5img = cv2.blur(img, (5, 5)) result_30img= cv2.blur(img, (30, 30)) cv2.imshow("img", img) cv2.imshow("result_5img", result_5img) cv2.imshow("result_30img", result_30img) cv2.waitKey() cv2.destroyAllWindows() 运行之后,效果如下所示:从上图可以看出来,使用(5,5)卷积进行均值滤波处理后图像虽然模糊,但还可以辨认。而使用(30,30)卷积进行均值滤波,图像失真非常严重。所以,我们可以得出来,卷积核越大,去噪效果越好,花费的时间越长,同时图像失真也越严重。而实际的处理中,我们需要在失真与去噪之间取得平衡,选取合适的卷积大小。方框滤波方框滤波与均值滤波的不同之处在于,方框滤波不会计算像素均值,它可以自由选择是否对均值滤波的结果进行归一化,即可以自由选择滤波结果是邻域像素值之和的平均值,还是邻域像素值之和。在OpenCV中,它提供cv2.boxFilter()函数来实现方框滤波,其完整定义如下:def boxFilter(src, ddepth, ksize, dst=None, anchor=None, normalize=None, borderType=None): 复制代码src:原始图像ddepth:处理结果图像的图像深度,一般使用-1表示与原图像使用相同的图像深度ksize:滤波核心的大小normalize:是否在滤波时进行归一化处理。当它为1时,表示要进行归一化处理,也就是邻域像素值的和除以面积,比如(3,3),公式如下:当它为0时,表示不需要进行归一化处理,直接使用邻域像素值的和。下面,我们来用程序分别实现归一化与不归一化的效果,代码如下:import cv2 img = cv2.imread("5.jpg") result1 = cv2.boxFilter(img, -1, (5, 5)) result2 = cv2.boxFilter(img, -1, (30, 30)) result3 = cv2.boxFilter(img, -1, (2, 2),normalize=0) cv2.imshow("img", img) cv2.imshow("result1", result1) cv2.imshow("result2", result2) cv2.imshow("result3", result3) cv2.waitKey() cv2.destroyAllWindows() 复制代码运行之后,显示的效果如下所示:可以看到,左下角不需要归一化处理,这里只取(2,2),如果你取大了,可以试试。因为范围大了,和一般都会大于255,那么就会造成图像全是白色。高斯滤波在进行均值滤波与方框滤波时,其邻域内每个像素的权重是相等的。而高斯滤波会将中心点的权重加大,远离中心点的权重减小,以此来计算邻域内各个像素值不同权重的和。在OpenCV中,它给我们提供cv2.GaussianBlur()函数进行高斯滤波,其完整定义如下:def GaussianBlur(src, ksize, sigmaX, dst=None, sigmaY=None, borderType=None): 复制代码src:原始图像ksize:滤波核的大小sigmaX:卷积和在水平方向上(X轴方向)的标准差,其控制的是权重比例sigmaY:卷积和在垂直方向上(Y轴方向)的标准差,也是控制的是权重比例。如果它为0,只采用sigmaX的值,如果sigmaX与sigmaY都是0,则通过ksize.width和ksize.height计算得到(可选参数)下面,我们来使用高斯滤波看看效果,代码如下所示:import cv2 img = cv2.imread("5.jpg") result = cv2.GaussianBlur(img, (3, 3), 0, 0) cv2.imshow("img", img) cv2.imshow("result", result) cv2.waitKey() cv2.destroyAllWindows() 复制代码运行之后,效果如下所示:来源:掘金著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • [API使用] 【inceptionv2网络】中自定义【Depthwise Separable】卷积层时当输入输出通道数不一致时会报错
    【功能模块】算子定义【操作步骤&问题现象】1、在我自定义Depthwise Separable(深度可分离)算子时,会用到mindspore的Conv2d算子,这里要设置其中参数group>12、而在华为线下机上跑时,代码会报错,其要求group>1时  ,应满足group=in_channel=out_channel。但是在华为mindspore官网上查该算子时,并没有该要求。3、虽然目前我找到其他方法绕过这个问题,但这个问题仍不算真正解决,特别是当temp_channel是in-channel的很多倍时,这个问题尤显突出。【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [API使用] 【mindspore】【DCN】请问目前有在开发可变形卷积算子(deform_conv2d)吗?
    请问目前对于dcn算子有在开发吗,pytorch的具体实现为torchvision.ops.deform_conv2d,目前有提供类似算子的计划吗?
  • [技术干货] PyTorch 官方教程:撸一个神经网络
    本文为 PyTorch 官方教程中:如何构建神经网络。基于 PyTorch 专门构建神经网络的子模块 torch.nn 构建一个简单的神经网络。神经网络由对数据执行操作的层/模块组成。torch.nn 提供了构建神经网络所需的所有模块。PyTorch 中的每个模块都是 nn.module 的子类。 在下面的部分中,我们将构建一个神经网络来进行10种类别的分类。建立神经网络神经网络由对数据执行操作的层/模块组成。torch.nn 提供了构建神经网络所需的所有模块。PyTorch 中的每个模块都是 nn.module 的子类。 在下面的部分中,我们将构建一个神经网络来进行10种类别的分类。import os import torch from torch import nn from torch.utils.data import DataLoader from torchvision import datasets, transforms加载训练设备我们希望能够在硬件加速器,比如 GPU 上训练我们的模型。可以通过 torch.cuda 来检测 GPU 是否可用。device = 'cuda' if torch.cuda.is_available() else 'cpu' #检测gpu是否可用,不可用使用cpu print('Using {} device'.format(device)) #输出使用设备类型 定义类我们通过 nn.Module 来定义神经网络,并在__init__ 中初始化神经网络。每个 nn.Module 子类在 forward 方法中实现对输入数据的操作。class NeuralNetwork(nn.Module): def __init__(self): #定义网络结构 super(NeuralNetwork, self).__init__() self.flatten = nn.Flatten() self.linear_relu_stack = nn.Sequential( nn.Linear(28*28, 512), nn.ReLU(), nn.Linear(512, 512), nn.ReLU(), nn.Linear(512, 10), nn.ReLU() ) def forward(self, x): #前向传播 x = self.flatten(x) logits = self.linear_relu_stack(x) return logits 在使用模型前需要先实例化模型,并将其移动到 GPU 上model = NeuralNetwork().to(device) #实例化模型 print(model)为了在模型的输入和输出之间创建复杂的非线性映射,需要使用非线性的激活函数。它们在线性变换后引入非线性,帮助神经网络学习各种各样的复杂映射。在这个模型中,我们在线性层之间使用 nn.ReLU,也可以使用其他激活函数来引入非线性。X = torch.rand(1, 28, 28, device=device) #生成(1,28,28)的数据 logits = model(X) #向模型输入数据 pred_probab = nn.Softmax(dim=1)(logits) #调用softmax 将预测值映射为(0,1)间的概率 y_pred = pred_probab.argmax(1) #最大概率对应分类 print(f"Predicted class: {y_pred}") 神经网络各层说明接下来,我们分解网络来具体讲述每一层的功能。为了说明这一点,我们将取小批量的3个尺寸为28x28的图像样本输入网络input_image = torch.rand(3,28,28) #生成(3,28,28)的数据 print(input_image.size()) nn.Flatten 层Flatten 层用来把多维的输入一维化,常用在从卷积层到全连接层的过渡。nn.Flatten 层,可以将每个 28x28 图像转换 784 (28×28=78428\times 28=78428×28=784)个像素值的连续数组(批量维度保持为3)。flatten = nn.Flatten() flat_image = flatten(input_image) #(3,28,28)转换为(3,784) print(flat_image.size()) nn.Linear 层nn.Linear 层,即线性层,是一个使用权重和偏差对输入数据作线性变换的模块。layer1 = nn.Linear(in_features=28*28, out_features=20) #输入(3,28*28) 输出(3,20) hidden1 = layer1(flat_image) print(hidden1.size()) nn.ReLU 层为了在模型的输入和输出之间创建复杂的非线性映射,需要使用非线性的激活函数。它们在线性变换后引入非线性,帮助神经网络学习各种各样的复杂映射。在这个模型中,我们在线性层之间使用 nn.ReLU,也可以使用其他激活函数来引入非线性。print(f"Before ReLU: {hidden1}\n\n") hidden1 = nn.ReLU()(hidden1) print(f"After ReLU: {hidden1}") nn.Sequential 层神经网络的最后一个线性层返回 logits,即值域区间在[−∞,∞][-\infty,\infty][−∞,∞]中的原始值。这些值传递给nn.Softmax模块后,logit被缩放为[0,1][0,1][0,1]区间中,表示模型对每个类的预测概率。dim参数表示每一维度进行运算的位置,运算结果相加为1。softmax = nn.Softmax(dim=1) pred_probab = softmax(logits) 输出模型结构神经网络中的许多层都是参数化的,即具有相关联的权重和偏差,这些参数在训练中被迭代优化。子类 nn.Module 自动跟踪模型对象内部定义的所有字段,并使用模型的 parameters() 或 named_parameters() 方法访问所有参数。我们可以通过模型迭代每个参数,并输出其尺寸和值。print("Model structure: ", model, "\n\n") for name, param in model.named_parameters(): print(f"Layer: {name} | Size: {param.size()} | Values : {param[:2]} \n") 最终输出结果可访问完整教程来源:掘金著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • [其他] 超越MobileNetV3!SkipNet:面向轻量级CNN的Bias Loss
    本文转载自:集智书童 Bias Loss for Mobile Neural Networks 论文:https://arxiv.org/abs/2107.11170简介近年来,Compact卷积神经网络(CNNs)的性能有了显著的提高。然而,在参数众多的情况下,它们仍然无法提供与普通CNN相同的预测能力。这些层捕获的多样且丰富的特征是这些CNN的一个重要特征。然而,大型CNN和小型CNN在这一特性上的差异很少被研究。在Compact CNN中,由于参数数量有限,不太可能获得丰富的特征,特征多样性成为本质特征。在模型推断期间,从数据点派生的激活映射中呈现的不同特征可能表明存在一组惟一描述符,这是区分不同类的对象所必需的。相比之下,特征多样性较低的数据点可能无法提供足够数量的描述符来进行有效预测;作者称之为随机预测。随机预测会对优化过程产生负面影响,并损害最终性能。本文提出通过重塑标准交叉熵来解决随机预测带来的问题,使其偏向具有有限数量独特描述特征的数据点。本文所提出的新型Bias Loss将训练重点放在一组有价值的数据点上,防止大量学习特征差的样本误导优化过程。此外,为了说明多样性的重要性,作者提出了一系列SkipNet模型,其体系结构增加了最后一层的唯一描述符的数量。实验表明,所提出的损失函数优于交叉熵损失。此外,与MobileNetV3 Large相比,Skipnet-M在相似的计算条件下,在ImageNet上分类准确率提高了1%。总结起来,本文的贡献有3个方面:设计了损失函数,以减少随机预测在Compact CNN优化中的误导;提出了一个有效的神经结构SkipNet模型,以增加数据点的数量与大量独特的描述特征;在资源受限的条件下,SkipNet模型在ImageNet分类任务上达到了最先进的性能。
  • [技术干货] 数据驱动算法在机器学习中的应用
    机器学习的概念分析机器学习作为一个概念,与提高计算机使用算法和神经网络模型学习的能力有关,并能更快更有效地执行各种任务。机器学习或ML通过使用数据或数据集来帮助建立模型来做出决策。它可用于精简组织的决策和执行绩效。这个词是1959年由美国人阿瑟·塞缪尔(ArthurSamuel)首创的,他精通人工智能和电脑游戏。从概念上讲,机器学习模拟了人类的脑细胞交互模式。在大脑活动中,当神经元相互交流时,这些神经元反过来使人类能够轻松地执行各种功能和任务,而不需要任何其他外部形式的支持。就像人类大脑中的神经元根据情况来解剖每个任务一样,在ML中,数据按照各种算法来预测、分类和表示,解决一个复杂问题并提出解决方案。机器学习中的神经网络模型也是基于DonaldHebb博士在TheOrganizationofBehavior中的理论。在制定机器学习概念方面的一些显着贡献是基于1950年代IBM的ArthurSamuel的进化工作的逐步实施,他开发了一个计算机程序。该计算机程序涉及alpha-beta剪枝,用于测量跳棋游戏中每一方获胜的机会。紧随其后的是由FrankRosenblatt于1957年开发的定制机器感知器,专为图像识别而构建,导致了MercelloPelillo于1967年开发的用于基本模式识别的最近邻算法。机器学习算法和模型机器学习是基于算法和模型的校准功能。简单地说,算法可以称为利用结构化或非结构化数据产生输出的简单过程。同时,机器学习模型表示程序和程序(算法)的结合,即使用程序来达到预期的结果,完成预期的任务。算法是一个公式,通过它可以做出预测;机器学习模型是实现算法后产生的输出的更广泛的方面。因此,在技术层面上,可以引用机器学习算法导致ML模型,而不是反之。为了理解ML算法的功能,让我们先看看机器学习中的模型。机器学习模型分为三大类: 监督学习:在监督学习中,在不确定的情况下,通过计算证据,从已知的数据集(输入)和已知的数据响应(输出)做出预测,以开发新的数据或数据集作为响应。监督学习进一步使用分类和回归等技术来提出其他机器学习模型。 无监督学习:无监督学习包括从输入数据中得出推论,而不从具有内在数据集或结构的隐藏模式中标记出响应。 强化学习:在机器学习的强化学习模型中,基于试错法,在复杂环境下做出一系列决策。根据所做决定的结果,奖励和惩罚有助于最终引出回应。现在为了详细说明机器算法做了什么,让我们以一个基于聚类的机器学习算法K-means为例。考虑了几个聚类,以k为变量。识别每个簇的中心或质心,并在其基础上定义一个数据点。在几次迭代中,数据点和集群被重新识别,一旦定义了所有中心,数据点将与每个集群对齐,并与集群中心相接近。该算法在训练数据上表现出色,有助于分类各种人工智能程序的音频检测和图像分割等复杂任务。使机器学习成为一个进步的领域,根据业务需求探索和发展的另一个方面是它对数据处理的需求。各种形式的训练数据是机器学习的基础。从检测用于安全目的的对象到预测业务趋势,高效和高性能的算法本质上是以数据为中心的;数据集越精确,算法产生的输出就越准确。机器学习中数据驱动的算法在物理世界中,人类互动的大部分方面都是基于与各种无形数据的动态关系,人类的大脑每天都会执行许多简单的数据驱动计算。类似地,计算是基于机器学习中的数据或标记训练数据,这有助于基于人工智能(AI)的程序工作来增加价值。与编写程序代码自动化处理过程或对大量数据进行深入调查相比,算法的使用要可靠得多,速度也快得多。机器学习算法是一种数学方法,在提供的数据的帮助下产生一组结果。因此,在机器学习的过程中,数据的重要性是至关重要的。由ML驱动的人工智能程序的效率取决于输入算法代码的训练数据的质量。不准确的数据集也会降低性能。对于一个ML算法产生高价值的输出,可用性的高质量的训练数据集是必须的。训练数据集是根据人工智能应用程序的目标开发的注释或说明数据。主要是两种类型的数据推动了机器学习算法的工作。1.手工数据标签2.自动数据标签3.人工智能辅助的数据标注在自动、手动和人工辅助数据标注方面有一些关键的区别。在手动数据标签,人群强制标签的原始数据按照共享的指导方针或技术定义附加标签。而在自动数据标注中,训练数据由程序标注,并在加载执行前检查其准确性。而且,人工智能辅助的数据标记需要自动程序和人工努力来产生高质量的训练数据。基于数据的算法在现实世界中的应用算法和技术适用于各行业和经济部门。在数字技术和数据驱动的生态系统时代,复杂的需求面临着高效数据创建和开发的挑战,在智慧城市、网络安全、智能医疗、社交媒体和商业等领域,ML也在不断实现数据结构化和可用数据处理,以更好地做出决策。提高绩效,增强业务可持续性。在卫生部门,人工智能程序正在执行由高度可用的训练数据驱动的任务。这些数据使诸如二十亿等健康应用程序通过检测对象、动作、属性、视听输入、语音输入、神经网络、语音输出、身体控制等来帮助客户跟踪他们的健康训练计划的进度。,正在帮助支持AI的应用程序解码复杂的任务,例如: 了解现场 理解口语 理解对象和动作 通过聊天机器人生成口语 控制助理的身体 理解人类的姿势 将视觉概念与文字等联系起来 行为在金融等领域,机器学习算法正在帮助企业发现未来的投资机会;同时,对于政府部门,ML算法通过简单地处理来自多个来源的复杂数据,帮助处理欺诈、身份盗窃和提高公共工程的效率。此外,随着数据量越来越大,机器学习(ML)正通过使用复杂的数据集来增加价值,帮助垂直企业应对未来的诸多挑战。尾注理想情况下,机器学习被用于处理涉及大量数据的复杂计算任务,而没有静态公式来得出结果。多年来,随着机器学习领域的不断研究和发展,医疗、能源生产、汽车、航空航天、制造业和金融等商业部门都从机器学习模式中获益。机器学习模型和算法正在帮助解决特定行业的问题,并通过对象检测、信用评分、交易预测、DNA测序和预测性维护提供未来的全行业解决方案。在未来几年,随着数据的持续增长和对可变数据的需求进一步攀升,我们可以希望看到许多其他任务使用由机器学习算法支持的人工智能程序来执行,这些程序的模型有助于阅读和处理数据,并为全球企业部门提供均衡的可持续性。
  • [问题求助] [问题求助-ModelZoo] Mask R-CNN 模型脚本编译报错
    【功能模块】【操作步骤&问题现象】1、运行Mask R-CNN模型 脚本模型的demo  运行至mxBase推理章节的编译工程时报错2、问题是编译mxBase推理工程时,提示缺少GetBuffer函数。已经确定环境变量是正确的,并且能找到头文件。3、问题定位为arm版的mxManufacture,安装后include/MxBase/PostProcessBases/PostProcessBase.h是没有GetBuffer这个函数的,但是X86架构的是有的https://www.hiascend.com/software/mindx-sdk/sdk-detailhttps://www.hiascend.com/zh/software/modelzoo/detail/C/5b5232e55ca04b81af264d9600cc8bd3【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [ModelZoo] Mask R-CNN 模型脚本编译报错
    【功能模块】【操作步骤&问题现象】1、运行Mask R-CNN模型 脚本模型的demo  运行至mxBase推理章节的编译工程时报错2、之前的章节都是成功的https://www.hiascend.com/zh/software/modelzoo/detail/C/5b5232e55ca04b81af264d9600cc8bd3【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [其他] 图神经网络的自适应迁移学习
    图神经网络(GNNs)被广泛用于学习一种强大的图结构数据表示。最近的研究表明,将知识从自监督任务迁移到下游任务可以进一步改善图的表示。然而,自监督任务与下游任务在优化目标和训练数据上存在内在的差距。传统的预训练方法可能对知识迁移不够有效,因为它们不能适应下游任务。为了解决这一问题,我们提出了一种新的迁移学习范式,该范式可以有效地将自监督任务作为辅助任务来帮助目标任务。在微调阶段,我们的方法将不同的辅助任务与目标任务进行自适应的选择和组合。我们设计了一个自适应辅助损失加权模型,通过量化辅助任务与目标任务之间的一致性来学习辅助任务的权重。此外,我们通过元学习来学习权重模型。我们的方法可以运用于各种迁移学习方法,它不仅在多任务学习中有很好的表现,而且在预训练和微调中也有很好的表现。在多个下游任务上的综合实验表明,所提出的方法能够有效地将辅助任务与目标任务相结合,与现有的方法相比,显著提高了性能。 https://www.zhuanzhi.ai/paper/852db932624d6feeb7bbd32e67772b27
  • [其他] 从DNN中解释和解分不同复杂度的特征分量
    在人工智能时代,深度学习已经在诸多方面有了广泛的应用,然而,神经网络黑盒本质使得人们难以理解这个复杂的系统。为了打开这一黑盒,目前,对神经网络的「解释」不仅需要在视觉概念的层面“实验观察”特征的语义,更需要“理论解释并建模”神经网络的表达能力,从而打通“直觉上的语义”与“数学建模表达能力”之间的壁垒。基于此,本项研究提出了一种对神经网络中层“特征复杂度”的通用量化指标,这一方法能够将神经网络中层特征拆分成不同阶次的复杂度分量。通过对不同复杂度特征分量的可视化,人们可以更清晰地分析不同复杂度分量的语义;同时,本研究也提出了数学指标以分析不同复杂度分量的可靠性、有效性、以及过拟合程度。作为一种通用指标,本项研究也可以为深度学习中的一些经典方法提供全新角度的解释。
  • [其他] 基于结构感知交互图神经网络的蛋白质-配体结合亲合性预测
    药物的发现往往依赖于对蛋白配体结合亲合性的成功预测。近年来,图神经网络(GNNs)通过学习蛋白质-配体配合物的表示来实现更好的亲合性预测具有广阔的应用前景。然而,现有的解决方案通常将蛋白质-配体配合物作为拓扑图数据处理,因此没有充分利用生物分子的结构信息。在GNN模型中也忽略了原子间基本的远距离相互作用。为此,我们提出了一种结构感知的交互式图神经网络(SIGN),它由两部分组成: 极性启发图注意力层(PGAL)和成对交互池(PiPool)。PGAL迭代执行节点边缘聚合过程,更新节点和边缘的嵌入,同时保留原子之间的距离和角度信息。然后,采用PiPool方法收集交互边,并进行后续的重构损失,以反映全局交互。在两个基准上进行了详尽的实验研究,验证了SIGN算法的优越性。https://www.zhuanzhi.ai/paper/92285a151920031182e24c0fced612de
  • [基础知识] 【MindSpore易点通】机器学习系列:神经网络的学习(上)
    危险,危险,危险——好久不见,等你在这里见面~在经过前两期关于神经网络的简单介绍后,今天小Mi将进一步介绍神经网络的代价函数、前向传播和反向传播,废话不多说,我们开干吧~1 代价函数首先引入一些便于稍后讨论的新标记方法:假设神经网络的训练样本有m个,每个包含一组输入x和一组输出信号y,L表示神经网络层数,表示每层的neuron个数(表示输出层神经元个数),代表最后一层中处理单元的个数。将神经网络的分类定义为两种情况:二类分类和多类分类,二类分类:,表示哪一类;K类分类:,表示分到第类; 小Mi带大家回顾一下,逻辑回归问题中的代价函数为:在逻辑回归中,我们只有一个输出变量,又称标量(scalar),也只有一个因变量y,但是在神经网络中,可以有很多输出变量,我们的是一个维度为K的向量,并且训练集中的因变量也是同样维度的一个向量,因此代价函数会比逻辑回归更加复杂一些,为:  这个看起来复杂很多的代价函数背后的思想还是一样的,我们希望通过代价函数来观察算法预测的结果与真实情况的误差有多大,唯一不同的是,对于每一行特征,都会给出K个预测,基本上可以利用循环对每一行特征都预测K个不同结果,然后在利用循环在K个预测中选择可能性最高的一个,将其与y中的实际数据进行比较。正则化的那一项只是排除了每一层后,每一层的矩阵的和。最里层的循环循环所有的行(由层的激活单元数决定),循环i则循环所有的列,由该层(层)的激活单元数所决定。即:与真实值之间的距离为每个样本-每个类输出的加和,对参数进行regularization的bias项处理所有参数的平方和。2 反向传播算法之前小Mi在计算神经网络预测结果的时候采用了一种正向传播方法,需要从第一层开始正向一层一层进行计算,直到最后一层的。现在,为了计算代价函数的偏导数,我们需要采用一种反向传播算法,也就是首先计算最后一层的误差,然后再一层一层反向求出各层的误差,直到倒数第二层。下面用一个例子来说明反向传播算法。假设我们的训练集只有一个样本,我们的神经网络是一个四层的神经网络,其中K=4,,L=4:前向传播算法:从最后一层的误差开始计算,误差是激活单元的预测与实际值之间的误差,,用来表示误差,则: 。利用这个误差值来计算前一层的误差:, 其中是S形函数的导数,。而则是权重导致的误差的和。下一步是继续计算第二层的误差: ,因为第一层是输入变量,不存在误差。我们有了所有的误差的表达式后,便可以计算代价函数的偏导数了,假设,即不做任何正则化处理时有: 值得注意的是,需要清楚地知道上面式子中上下标的含义:l代表目前所计算的是第几层。j 代表目前计算层中的激活单元的下标,也将是下一层的第j个输入变量的下标。i代表下一层中误差单元的下标,是受到权重矩阵中第i行影响的下一层中的误差单元的下标。如果我们考虑正则化处理,并且训练集是一个特征矩阵而非向量。在上面的特殊情况中,我们需要计算每一层的误差单元来计算代价函数的偏导数。在更为一般的情况中,我们同样需要计算每一层的误差单元,但是需要为整个训练集计算误差单元,此时的误差单元也是一个矩阵,可以用来表示这个误差矩阵。第l层的第i个激活单元受到第j个参数影响而导致的误差。我们的算法表示为:即首先用正向传播方法计算出每一层的激活单元,利用训练集的结果与神经网络预测的结果求出最后一层的误差,然后利用该误差运用反向传播法计算出直至第二层的所有误差。在求出了之后,便可以计算代价函数的偏导数了,计算方法如下:  3 反向传播算法的直观理解在上一节中,我们介绍了反向传播算法,对很多人来说,当第一次看到这种算法时,第一印象通常是,啊,这个算法看起来好难,需要那么多繁杂的步骤,简直是太复杂了!实在不知道这些步骤,到底应该如何合在一起使用。就好像一个黑箱,里面充满了复杂的步骤。如果你对反向传播算法也有这种感受的话,实际上是很正常的。相比于线性回归算法和逻辑回归算法而言,从数学的角度上讲,反向传播算法并不是一个简洁的算法,而且常常会让人感觉并不是很清楚反向传播算法究竟究竟在做什么。当然啦,小Mi始终认为,practice makes perfect!多做一些编程练习可以帮助我们将这些复杂的步骤梳理梳理,从而可以更深一步地理解反向传播算法具体是如何实现的,最终可以独立使用这个算法。下面小Mi会帮助大家巩固反向传播的一些固定步骤,使大家有一个更加全面直观的感受,理解这些步骤究竟是在做什么,同时也可以证明,它至少还是一个合理且合格的算法。当然啦,可能最终大家还是会觉得反向传播依然很复杂,依然像一个黑箱,包含了太多复杂的步骤,甚至有点神奇,这也OK。下面我们再来仔细研究一下前向传播的原理:为了更好地理解反向传播,我们先看研究下前向传播的过程,这是一个包含2个输入单元的神经网络结构(当然啦,我们并没有把偏置单元算进去),然后第二层有2个隐藏单元,再下一层也有2个,不过最后只有一个输出单元。为了更好地说明前向传播,可以用不同的颜色来表示这个网络。在进行前向传播时,可能会有一些特性的样本,比如,将其传到输入层中,因此可以把它们表示为,它们时我们为输入层设置的值,对其进行前向传播传播到第一个隐藏层时,然后计算出,它们是输入单元的加权和,然后我们将sigmoid逻辑函数,还有sigmoid激活函数应用到z值上得到这些激活值,也就是,然后继续向前传播,计算出,应用sigmoid逻辑函数和激活函数得到,就这样以此类推,最终得到,它是网络中最后的输出值。进一步研究下计算过程,比如紫红色表示的隐藏单元,将其权值表示出来,也就是,红色线这边的权值是,蓝色线的则是,因此计算的方法就是:,这就是前向传播。事实上,后面我们会发现反向传播的过程和前向传播非常相似,只是这两个算法计算的方向不一样而已,在反向传播算法中是从右往左进行运算: 首先我们先看看代价函数,这个代价函数一般应用于只有一个输出单元的情况,如果不止一个输出单元,只需对它们进行求和即可;但如果只有一个输出单元,代价函数就会是这样,我们同一组样本中,同时使用了前向传播和反向传播,可以择出一组单独的样本进行研究分析,,由于只有一个输出单元,就是一个实数,可以忽略正则化,即,所以最后这个正则化项就没有了,观察括号中的这个求和项,会发现代价函数对应第i个训练样本,即代价函数对应的训练样本,是由式子:给出。所以第i个样本的代价函数扮演了一个类似方差的角色,可以直接写成:,近似地当成是神经网络输出值与实际值的方差,就像逻辑回归中会偏向于选择比较复杂的带对数形式的代价函数,但是为了可以把这个代价函数看作是某种方差函数,因此表示了预测样本值的准确程度,也就是网络的输出值,和实际观测值的接近程度。现在再看看反向传播的过程,简单来说反向传播就是在计算项,其实看作在第层第个单元中得到的激活项的“误差”,更正式地说,项实际上代价函数关于的偏导数,也就是计算出的z项的加权和或者说代价函数关于z项的偏导数,具体来说这个代价函数是一个关于标签y和神经网络中的输出值的函数,如果分析网络的内部,稍微改动下项,就可以影响神经网络的这些值,最终将改变代价函数的值。另外,对于输出层而言,比如我们假设等于,当我们对样本做前向传播和反向传播的时候,设,这是一个误差值,也就是y的实际值与预测值的差,就可以算出的值,然后对这些值进行反向传播,最后可以计算出前一层的这些项,也就是和,然后继续进行传播,最后计算出和,反向传播的计算过程和前向传播非常地相似,只是方向翻过来了。可以看一下是如何计算出的值的,可以先标出权重,紫红色的权重为,红色的权重为,然后再来看是怎么计算的:再举一个例子,的计算方式就是:。顺带一提,这些值都只关于隐藏单元,并不包括偏置单元,这个包不包括取决于对于反向传播的定义以及实现算法的方式,所以也可以用其他方法来计算包含偏置单元的值。偏置单位的输出总是“+1”,由于它们并不影响偏导数的计算,所以可以最后计算。好啦,今天小Mi的分享就到这啦,希望今天大家能对反向传播这个复杂的函数有一个更加深入的理解,虽然有点复杂,但是好算法不怕多,对不对!下期的话小Mi还会针对神经网络的整体结构以及案例运用进行介绍,我们下期再见~(挥手十分钟!)PS:身在南京的小Mi也心系河南,一直在心中为大家默默祈祷!胡辣汤挺住,风雨面前盐水鸭和你们一起扛!!!
  • [基础知识] 【MindSpore易点通】网络实战系列之使用LeNet实现图像分类任务
    摘要家乡的大雨还在继续,大家一定要保护好自己。愿大雨早点停歇,所有人都平安,河南一定挺得住,加油本篇的主要内容是解析一下使用MindSpore深度学习框架训练LeNet网络对Mnist数据集进行分类。首先我给大家展示出本篇内容的一个示意图,帮助大家更直观的看到训练过程的一个重要步骤,如图所示,其中1、2、3…表示训练过程中的次序,下面我们也将从这些次序进行解析。训练导图数据集(Mnist)Mnist数据集来自**国家标准与技术研究所, National Institute of Standards and Technology (NIST). 训练集 (training set) 由来自 250 个不同人手写的数字构成,其中 50% 是高中学生,50% 来自人口普查局(the Census Bureau)的工作人员,测试集(test set)也是同样比例的手写数字数据。Mnist数据集结构它包含了以下四个部分,数据集中,训练样本:共60000个,其中55000个用于训练,另外5000个用于验证。测试样本:共10000个,验证数据比例相同。MNIST数据集下载页面:http://yann.lecun.com/exdb/mnist/。请按照图1中位置的关系进行存放。图1:数据集结构图Training set images: train-images-idx3-ubyte.gz (9.9 MB, 解压后 47 MB, 包含 60,000 个样本)Training set labels: train-labels-idx1-ubyte.gz (29 KB, 解压后 60 KB, 包含 60,000 个标签)Test set images: t10k-images-idx3-ubyte.gz (1.6 MB, 解压后 7.8 MB, 包含 10,000 个样本)Test set labels: t10k-labels-idx1-ubyte.gz (5KB, 解压后 10 KB, 包含 10,000 个标签)MNIST 数据集已经成为一个“典范”,很多教程都会选择从它下手。本次我们使用MindSpore深度学习框架进行加载。检查数据集在我们将Mnist数据集下载存放好之后,我们需要检查一下数据集的完整性和质量,使用MindSpore深度学习框架撸它,上代码:1.   import matplotlib.pyplot as plt  2.   import matplotlib  3.   import numpy as np  4.   import mindspore.dataset as ds  5.     6.   train_data_path = "./datasets/MNIST_Data/train"  7.   test_data_path = "./datasets/MNIST_Data/test"  8.   mnist_ds = ds.MnistDataset(train_data_path)  9.   print('The type of mnist_ds:', type(mnist_ds))  10.  print("Number of pictures contained in the mnist_ds:", mnist_ds.get_dataset_size())  11.    12.  dic_ds = mnist_ds.create_dict_iterator()  13.  item = next(dic_ds)  14.  img = item["image"].asnumpy()  15.  label = item["label"].asnumpy()  16.    17.  print("The item of mnist_ds:", item.keys())  18.  print("Tensor of image in item:", img.shape)  19.  print("The label of item:", label)  20.    21.  plt.imshow(np.squeeze(img))  22.  plt.title("number:%s"% item["label"].asnumpy())  23.  plt.show()  数据增强以上我们检查了数据集的正确性,但是想要这样使用还是不行的,我们还需要将数据集处理成可以喂入网络模型的规格,该过程也可以称为数据预处理,对应于训练导图中的步骤1。这里还可以再详细的分为:读入数据集;定义操作并作用到数据集;进行shuffle、batch操作。我们使用MindSpore深度学习框架撸它,上代码:1.   #首先导入MindSpore中mindspore.dataset和其他相应的模块。  2.   import mindspore.dataset as ds  3.   import mindspore.dataset.transforms.c_transforms as C  4.   import mindspore.dataset.vision.c_transforms as CV  5.   from mindspore.dataset.vision import Inter  6.   from mindspore import dtype as mstype  7.     8.     9.   #定义预处理操作  10.  def create_dataset(data_path, batch_size=32, repeat_size=1,  11.                     num_parallel_workers=1):  12.      # 定义数据集  13.      mnist_ds = ds.MnistDataset(data_path)  14.      resize_height, resize_width = 32, 32  15.      rescale = 1.0 / 255.0  16.      shift = 0.0  17.      rescale_nml = 1 / 0.3081  18.      shift_nml = -1 * 0.1307 / 0.3081  19.    20.      # 定义所需要操作的map映射  21.      resize_op = CV.Resize((resize_height, resize_width), interpolation=Inter.LINEAR)  22.      rescale_nml_op = CV.Rescale(rescale_nml, shift_nml)  23.      rescale_op = CV.Rescale(rescale, shift)  24.      hwc2chw_op = CV.HWC2CHW()  25.      type_cast_op = C.TypeCast(mstype.int32)  26.        27.      # 使用map映射函数,将数据操作应用到数据集  28.      mnist_ds = mnist_ds.map(operations=type_cast_op, input_columns="label", num_parallel_workers=num_parallel_workers)  29.      mnist_ds = mnist_ds.map(operations=resize_op, input_columns="image", num_parallel_workers=num_parallel_workers)  30.      mnist_ds = mnist_ds.map(operations=rescale_op, input_columns="image", num_parallel_workers=num_parallel_workers)  31.      mnist_ds = mnist_ds.map(operations=rescale_nml_op, input_columns="image", num_parallel_workers=num_parallel_workers)  32.      mnist_ds = mnist_ds.map(operations=hwc2chw_op, input_columns="image", num_parallel_workers=num_parallel_workers)  33.        34.      # 进行shuffle、batch操作  35.      buffer_size = 10000  36.      mnist_ds = mnist_ds.shuffle(buffer_size=buffer_size)  37.      mnist_ds = mnist_ds.batch(batch_size, drop_remainder=True)  38.    39.      return mnist_ds  通过运行上例代码就可以完成我们的第1步了,预备好我们的数据集,现在准备我们的主角LeNet网络。网络(LeNet5)LeNet 诞生于1994年,是最早的卷积神经网络之一,并且推动了深度学习领域的发展。自从1988年开始,在许多次成功的迭代后,这项由 Yann LeCun 完成的开拓性成果被命名为 LeNet5。LeNet5是一种用于手写体字符识别的非常高效的卷积神经网络,这与Mnist数据集正好匹配。LeNet5结构首先是最最具有代表性的LeNet5网络结构图,从图中我们可以看到每层之间的变换,包括卷积、池化和全连接三种变换方式。这里我们简单介绍下三种变换方式对图像的作用。卷积:首先卷积需要一个卷积核,卷积核的卷积计算过程就相当于一个滤波器,可以让图像的边缘更加明显。池化:通常图像中相邻的像素具有很大相似性,因此通过卷积后输出的像素值也依然有此特性,这意味着卷积输出的信息中存在冗余,池化可以做到减少图像中的信息冗余。全连接:全连接在整个卷积神经网络中起到分类器的作用,卷积和池化是将原始数据映射到隐层特征空间中,全连接层就是把学到的特征映射到样本空间中,以此实现分类。图2:LeNet5结构图介绍了不同变换方式,下面我们通过数值计算,看一下图像的变化。LeNet5的数值计算如图2中所示,是LeNet卷积网络的整体流程图,整体包含8个网络层,下面我们将了解每一层的计算。输入层:我们使用的数据集是MNIST数据集,该数据集中的样本数据都是规格为32×32的灰度图,我们以1个样本图片为例。那么我们输入的图片规格就是1×1×32×32,表示一个通道输入1个32×32的数组。C1层:C1层中数组规格为6×1×28×28,从1×1×32×32卷积得到。首先需要6个批次的卷积数组,每一个批次中都有1个规格为5×5的卷积数组,卷积步幅默认为1。即卷积数组规格为6×1×5×5。该卷积层共有6+1×5×5×6=156个参数,其中6个偏置参数。这一层网络**有6×1×28×28=4704个节点,每个节点和当前层5×5=25个节点相连,所以本层卷积层共有6×(1×28×28)×(1×5×5+1)=122304个全连接。S2层:S2层的数组规格为6×1×14×14,从1×1×28×28卷积得到。使用的是2×2,步幅为1的最大池化操作,所以并不改变批次数,只是将每一个输入数组从28×28降到14×14的输出数组。该池化层共有6×2=12个可训练参数,以及6×(1×14×14)×(2×2+1)=5880个全连接。C3层:C3层的数组规格为16×1×10×10,从6×1×14×14卷积得到。输出通道数数改变,所以卷积数组需要16批卷积数组,每一批中有6个卷积核与输入通道对应,每一个卷积数组规格都是5×5,步幅为1。即卷积数组规格为16×6×5×5。该卷积层共有16+1×5×5×16=2416个参数,其中16个偏置参数。这一层网络**有16×1×10×10=1600个节点,每个节点和当前层5×5=25个节点相连,所以本层卷积层共有16×(1×10×10)×(1×5×5+1)=41600个全连接。S4层:S4层的数组规格为16×1×5×5,这一层池化与S2层池化设置相同。所以输出数组只改变每一个数组的规格,不改变数量。该池化层共有16×2=32个可训练参数,以及16×(1×5×5)×(2×2+1)=2000个全连接。C5层:C5层是规格为120×1的一维向量,那么需要将S4层数组转换成一维向量,输入的数组规格是1×(16×1×5×)=1×400。使用全连接层将1×400转为1×120的向量。在全连接层中,每一个节点计算处结果后,都需要再经过激活函数计算,得出的值为输出的值。该连接层共有5×5×16=400个输入节点,参数个数为5×5×16×120+120=48120个,输出节点120个。F6层:F6层是规格为84×1的一维向量,与C5层计算相同,也是通过全连接层计算得到。为什么要转成84个神经元向量呢,如下图中所示,是所有字符标准格式,规格为12×7.所以有84个像素点,然后使用F6层的向量与这些标准图计算相似度。该连接层共有120个输入节点,参数个数为120×84+84=10164个,输出节点84个。图3:字符标准图输出层:该连接层共有84个输入节点,参数个数为84×10+10=850个,输出节点10个。输出层使用Softmax函数做多分类,在Softmax用于多分类过程中,它将多个神经元的输出,映射到(0,1)区间中,可以看作是每一个类别的概率值,从而实现多分类。Softmax从字面上来看,可以分成Soft和max两部分。Softmax的核心是Soft,对于图片分类来说,一张图片或多或少都会包含其它类别的信息,我们更期待得到图片对于每个类别的概率值,可以简单理解为每一个类别的可信度;max就是最大值的意思,选择概率值最大的当作分类的类别。LeNet5的创建上面我们通过图片和每层的计算解析了LeNet的结构和计算,下面我们开始用MindSpore撸它,上代码:1.   import mindspore.nn as nn  2.   from mindspore.common.initializer import Normal  3.     4.   class LeNet5(nn.Cell):  5.       """ 6.       Lenet网络结构 7.       """  8.       def __init__(self, num_class=10, num_channel=1):  9.           super(LeNet5, self).__init__()  10.          # 定义所需要的运算  11.          self.conv1 = nn.Conv2d(num_channel, 6, 5, pad_mode='valid')  12.          self.conv2 = nn.Conv2d(6, 16, 5, pad_mode='valid')  13.          self.fc1 = nn.Dense(16 * 5 * 5, 120, weight_init=Normal(0.02))  14.          self.fc2 = nn.Dense(120, 84, weight_init=Normal(0.02))  15.          self.fc3 = nn.Dense(84, num_class, weight_init=Normal(0.02))  16.          self.relu = nn.ReLU()  17.          self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2)  18.          self.flatten = nn.Flatten()  19.    20.      def construct(self, x):  21.          # 使用定义好的运算构建前向网络  22.          x = self.conv1(x)  23.          x = self.relu(x)  24.          x = self.max_pool2d(x)  25.          x = self.conv2(x)  26.          x = self.relu(x)  27.          x = self.max_pool2d(x)  28.          x = self.flatten(x)  29.          x = self.fc1(x)  30.          x = self.relu(x)  31.          x = self.fc2(x)  32.          x = self.relu(x)  33.          x = self.fc3(x)  34.          return x  35.    36.  # 实例化网络  37.  net = LeNet5()  通过运行上例代码就可以完成我们的第2步了,构建出了我们的模型,现在最主要的两大部件准备就绪,继续向下走。损失函数如果就此开始训练,也就是执行第3步,通过初始的模型分类之后会存在分类错误的情况,为了提升模型的分类能力,我们需要能够调整模型参数,那么损失函数就出现了,损失函数可以通过数值很直观的展示模型此刻的性能,损失值越大表示模型性能越差。损失函数原理损失函数也有很多,为什么是SoftmaxCrossEntropyWithLogits损失函数呢?我们再来了解一下本次项目的目的:图像分类。那么分类中的损失函数是怎么计算的,它是计算logits和标签之间的softmax交叉熵。使用交叉熵损失测量输入概率(使用softmax函数计算)与类别互斥(只有一个类别为正)的目标之间的分布误差,具体公式可以表示成图4。图4:SoftmaxCrossEntropyWithLogits表达式参数说明:logits (Tensor) - Tensor of shape (N, C). Data type must be float16 or float32.labels (Tensor) - Tensor of shape (N, ). If sparse is True, The type of labels is int32 or int64. Otherwise, the type of labels is the same as the type of logits.第一个参数logits:就是神经网络最后一层的输出,如果有batch的话,它的大小就是[batchsize,num_classes],单样本的话,大小就是num_classes;第二个参数labels:实际的标签,大小同上。损失函数的调用上面是解释了该类型损失函数的基本计算过程,但在我们需要使用进行调用的时候还是相当简便的,使用MindSpore撸它,上代码:1.   from mindspore import nn  2.   loss = nn.SoftmaxCrossEntropyWithLogits(sparse=True, reduction='mean')  这里参考官网API我们对做了如上的设置:选择使用稀疏格式为`True`,损失函数的减少类型选择为`mean`。优化器上面损失函数的作用是可以计算出模型的性能,我们也需要明确一点,Loss值是我们要最小化的值。那么如何才能够让Loss值最小化呢?就需要我们调整网络模型中的参数,让模型更适应所训练的数据集,这也是模型的训练过程,在其中调整参数的就是优化器。优化器原理本次训练中我们使用的是Momentum,也叫动量优化器。为什么是它?下面我们了解下它的工作原理,表达式如图5所示图5:Momentum表达式上面表达式中的grad、lr、p、v 和 u 分别表示梯度、learning_rate、参数、矩和动量。其中的梯度是通过损失函数求导得出的,在训练过程中得到的Loss是一个连续值,那么它就有梯度可求,并反向传播给每个参数。Momentum优化器的主要思想就是利用了类似移动指数加权平均的方法来对网络的参数进行平滑处理的,让梯度的摆动幅度变得更小。参数说明:params (Union [list [Parameter], list [dict]]) - 当params是一个dict列表时,“params”、“lr”、“weight_decay”和“order_params”是可以解析的键。lr:可选。如果键中有“lr”,将使用相应学习率的值。如果没有,将使用 API 中的learning_rate;weight_decay:可选。如果键中有“weight_decay”,将使用相应的权重衰减值。如果没有,将使用 API 中的weight_decay;order_params:可选。如果键中有“order_params”,则该值必须是参数的顺序,并且在优化器中将遵循该顺序。dict中没有其他键,并且 'order_params' 值中的参数必须在组参数之一中; grad_centralization:可选。“grad_centralization”的数据类型是 Bool。如果“grad_centralization”在键中,将使用设置的值。如果不是,则grad_centralization默认为 False。该参数仅适用于卷积层。learning_rate (Union [float, Tensor, Iterable, LearningRateSchedule ] ) – 学习率的值或图表。当 learning_rate 是一个 Iterable 或者一维的 Tensor 时,使用动态学习率,那么第 i 步将取第 i 个值作为学习率。当 learning_rate 为 LearningRateSchedule 时,使用动态学习率,训练过程中会根据 LearningRateSchedule 的公式计算第 i 个学习率。当 learning_rate 是零维的浮点数或张量时,使用固定学习率。不支持其他情况。浮点学习率必须等于或大于 0。如果类型learning_rate是 int,它将被转换为 float。动量(float) – float类型的超参数,表示移动平均线的动量。它必须至少为 0.0。weight_decay (int, float) – 权重衰减(L2 惩罚)。它必须等于或大于 0.0。默认值:0.0。loss_scale (float) – 损失比例的浮点值。它必须大于 0.0。一般情况下,使用默认值。仅当使用FixedLossScaleManager进行训练并且FixedLossScaleManager中的 drop_overflow_update设置为 False 时,该值需要与FixedLossScaleManager中的 loss_scale相同。默认值:1.0。use_nesterov (bool) - 图5中的2和3公式和参数use_nesterov相关,如果设置`use_nesterov = True`,则按照公式2计算,如果设置`use_nesterov = False`,则按照公式3计算。优化器的调用废话不多说,直接使用MindSpore撸它,上代码:1.   from mindspore import nn  2.   lr = 0.01  3.   momentum = 0.9  4.   net_opt = nn.Momentum(network.trainable_params(), lr, momentum)  参考以上的参数解析,我们对Momentum优化器的使用如上面代码。此时我们完成了首图中的`2->4->6`的训练过程,该过程就是重复网络分类图片、计算损失函数、梯度反向传播、参数调整的过程。精度虽然损失函数值可以衡量网络的性能,对于图片分类的任务,使用精度可以更加准确的表示最终的分类结果。精度表达式精度表达式比较简单,也好理解。分母是总样本数,分子是分类正确的样本总数,对应于首图中5。图6:Accuracy表达式 精度调用精度值也会随着训练过程实时更新,使用MindSpore撸他,上代码:1.   from mindspore import nn  2.   metrics = nn. Accuracy()3.   model = Model(net, net_loss, net_opt, metrics={"Accuracy": Accuracy()})  基于上面代码,可以使用Accuracy功能。Acc也是我们需要最大化的值。本篇内容中每一段代码为了展示不同接口的调用做了调整,完整的图像分类任务脚本可以参考:https://gitee.com/mindspore/docs/blob/master/docs/sample_code/lenet/lenet.py总结本次内容是以图像分类任务为例,对于任务首先要明白数据集的内容和结构,以及要完成的目标,然后根据目标选择基本网络、损失函数、优化器和精度这几部分,这些的选择和设置是非常重要的,会直接影响到模型的训练和最终的性能。其他任务也都可以基于本示例进行扩展升级,谢谢赏读。
  • [其他] 图灵奖得主Judea Pearl谈机器学习:不能只靠数据
    研究机器学习,既要数据拟合,也要能解释数据。在当前的人工智能研究社区,以数据为中心的方法占据了绝对的主导地位,并且这类方法也确实成就非凡,为语音识别、计算机视觉和自然语言处理等重要任务都带来了突破性的进展。即便如此,也一直有研究者在思考这类方法的不足之处以及其它方法的重要价值。近日,图灵奖获得者、著名计算机科学家和哲学家 Judea Pearl 发布了一篇短论文,从便利性、透明度、可解释性三个角度谈了他对激进经验主义和机器学习研究的思考。论文链接:https://ftp.cs.ucla.edu/pub/stat_ser/r502.pdf在这篇论文中,Judea Pearl 将沿便利性、透明度和可解释性三个维度对比用于数据科学的「数据拟合(data fitting)」与「数据解释(data interpreting)」方法。「数据拟合」方法的信念源自研究者相信理性决策就隐藏在数据本身之中。相较而言,数据解释学派却并不将数据视为唯一的知识来源,而是一种用于解读现实的辅助手段——这里的「现实」是指生成数据的过程。文章将在因果逻辑的指引下,探讨拟合与解释在任务方面的共生关系,以此让数据科学恢复平衡。  模拟进化与数据科学我最近参加了一个讲座,演讲者这样总结了机器学习的哲学思想:「所有知识均源自所观察到的数据,有些直接来自感官经验,有些则来自通过文化或基因方式传递给我们的非直接经验。」观众会觉得这样的称述是不证自明的,其也为该演讲奠定了基调,即可以如何通过检查数据中条件概率的模式来分析「知识」的本质。很自然,它没有涉及到「外部世界」、「理论」、「数据生成过程」、「因果」、「能动性」和「心智构造」等概念,因为从表面上看,如有需要,这些概念也能在数据中找到。换句话说,不管人类在解释数据时会用到什么概念,比如有关来源的文化、科学或基因上的概念,都可以追溯到让这些概念有存在价值的初始感觉经验并且还能从这些感官经验重新推衍出来。从人工智能的角度看,这种以数据为中心的哲学为机器学习研究提供了一种有吸引力的乃至极具诱惑力的研究前景:为了开发人类水平的智能机器,我们应该仅遵循我们祖先获得智能的方式,将我们可能收集到的所有数据用作输入,在数字机器上同时模拟基因进化和文化进化。在极端情况下,这样的前景可能激发出相当未来主义和雄心勃勃的情形:从一个类似原始生物(比如变形虫)的简单神经网络开始,让它与环境交互,变异并产生后代,给予其足够的时间,它最终就能获得爱因斯坦水平的智能。事实上,除了神圣的经文和神明的启示,如果没有自古以来一直冲击着人类种族的原始数据流(当然也包括人类之前那些更原始的生物获得的感官输入),爱因斯坦又能从其它什么地方获得他的知识、才能和智慧呢?   在问这样的前景有多现实之前,我们先在讨论之前看两个观察所知的情况:    模拟进化,不管是哪种具体形式,事实上都引领着当前大多数机器学习研究的主要范式,尤其是那些涉及到连接主义、深度学习和神经网络技术的范式。这些技术可以部署无模型的、基于统计学的学习策略。这些策略在计算机视觉、语音识别和自动驾驶汽车等应用中已经取得了亮眼的成功。这样的成功激发了对这些策略的充分性和无限潜力的希望,同时也削弱了人们对基于模型的方法的兴趣。    以数据为中心的发展方向的思想根基深深根植于西方哲学的经验主义分支。该哲学分支认为:感官体验是我们所有概念和知识的最终来源,而「先天观念」和「理性」在作为知识来源方面仅能发挥少许作用,乃至毫无作用。经验主义思想可以追溯到古代亚里士多德的著作,但将经验主义发扬光大的则是英国经验主义哲学家弗朗西斯 · 培根、约翰 · 洛克、乔治 · 贝克莱和大卫 · 休谟以及更近期的哲学家查尔斯 · 桑德斯 · 皮尔士(Charles Sanders Peirce)和威廉 · 詹姆斯(William James)。事实上,现代连接主义已被视为激进经验主义相对于理性主义的一大胜利。实际上,在数字机器上模拟知识习得过程的能力提供了非常灵活的测试平台,可让人通过在数字机器上执行实验来评估有关经验主义和天赋能力(innateness)之间平衡的理论。尽管测试哲学理论有其好处,但对于为机器学习研究遵循激进经验主义议程的思想,我有三个主要的保留意见。我将通过三个论点来说明为什么经验主义应该与基于模型的科学的原理保持平衡。而对于基于模型的科学,学习过程受两大信息来源指引:(a) 数据,(b) 人工设计的有关数据生成方式的模型。  我将这三个论点标记为:(1) 便利性、(2)透明度、(3)可解释性。将在下文逐一讨论它们:便利性进化是一个过于缓慢的过程,因为大多数突变都是无用乃至有害的,并且等待自然选择区分并从无用突变中过滤出有用突变往往也具有难以承受的成本。大量机器学习任务都需要对稀疏的新数据进行快速解读并快速响应,而这些新数据又实在过于稀疏,以至于无法通过随机突变来过滤。新冠疫情的爆发就是这一情况的完美例证:来自不可靠和各式各样来源的稀疏数据需要快速解读和快速行动,它们主要基于之前的流行病传播和数据生成模型。总体而言,机器学习技术有望利用大量已经存在的科学知识,结合可以收集到的数据,从而解决健康、教育、生态和经济等领域的关键社会问题。更重要的是,科学知识可通过主动引导数据和数据源的选择或过滤过程来加快进化速度。选择使用哪些数据或运行哪些实验前,需要从理论上假设性地考虑每种选择会得到怎样的结果以及它们在未来提升性能的可能性。举个例子,为了提供这样的预期,可使用因果模型,其既能预测假设性操作的结果,也能预测违反事实情况地撤销过去事件的后果。    透明度为了最终能使用世界知识(即便是自原始数据自发演化而来的世界知识),我们必须以某种机器形式对其进行编译和表征。编译知识的目的是将发现过程分摊到许多推理任务上,从而无需重复这个过程。然后,编译后的表征有助于高效地得到许多选择性决策问题的答案,包括有关如何收集额外数据的方式的问题。某些表征允许这样的推理,另一些则不允许。《为什么:关于因果关系的新科学》一书中提出的因果关系层级(adder of Causation)形式化地定义了用于回答有关假设性干预和 / 或解释以及反事实的问题所需的知识内容的类型。知识编译涉及到抽象和重新格式化。前者允许损失信息(正如图像模型归纳为数值方程的情况),而后者会保留信息内容,只是会将一些信息从隐式转变成显式的表征。举一个经典的例子:信号波形的频谱表示。从信息角度看,前者等价于后者,但频谱明确表示了信号的特定方面。这些需要考虑之处要求我们研究所编译的表征的数学性质、它们的内在局限性、它们支持的推理类型以及它们在得到它们期望得到的答案上的效果。用更具体的术语说,机器学习研究者也应该参与现在被称为「因果建模(causal modelling)」的研究,并使用因果科学的工具和原则来指导数据探索和数据解释过程。    可解释性不管积累、发现或存储因果知识的方式如何,由知识推动实现的推理都要交付给人类用户并让其获益。现如今,这些用途包括政策评估、个人决策、生成解释、分配功劳和责罚或广义地认知我们周围的世界。因此,所有推理都必须用一种与人们自身组织世界知识的方式相匹配的语言进行描述,也即因果的语言。因此,不管机器学习研究者为数据拟合采用了怎样的方法,他们都必须熟练掌握这种对用户友好的语言、其语法、其普遍规则以及人们解读或误读机器学习算法发现的功能的方式。结论将人类知识的内容与其感官数据来源等同起来是错误的。对于知识的特征描述而言,知识存储于心智(或计算机)中的格式及(尤其是)其隐式与显式组分的平衡是与其内容或来源一样重要的。尽管激进经验主义可能是进化过程的一个有效模型,但它对机器学习研究而言却是一个糟糕的策略。它让以数据为中心的思潮大行其道,而这一思潮当前主导了统计学和机器学习文化。这一思潮认为:理性决策的秘诀仅在于数据。「数据拟合」和「数据解释」平衡的混合策略能更好地让我们把握进化过程所需的知识编译的各个阶段。转发自:https://www.jiqizhixin.com/articles/2021-07-18-2
  • [其他] “深度学习将无所不能”
    神经网络的弱点:“神经网络在处理多参数少量数据时,表现不错,但是这方面,人类似乎做得更好。"杰夫·辛顿说:“深度学习将无所不能”人工智能领域的缺口:“必须有更多的概念上的突破,在规模上,还需要加大。"神经网络的弱点:“神经网络在处理多参数少量数据时,表现不错,但是这方面,人类似乎做得更好。"人脑如何工作:“大脑内部是参与神经活动的大向量。"现代人工智能革命始于一场默默无闻的研究竞赛:2012年,即第三届图像网络竞赛(ImageNetcompetition),挑战团队需要建立一个能识别1000个物体的计算机视觉系统,这1000个物体中包括动物、景观和人类。在前两年,即便是最好的参赛团队,准确率都不超过 75%。但是到了第三年,三位研究人员(一位教授和他的两个学生)突然打破了这个天花板,他们惊人地超出了10.8个百分点,赢得了比赛。那个教授便是杰弗里·辛顿,他们使用的技术叫做深度学习。自20世纪80年代以来,辛顿一直致力于深度学习的研究工作,由于缺乏数据和计算能力,其有效性受到了限制,一直到2012年才取得成果。辛顿对这项技术的坚定信念最终带来了巨大的回报:在第四年的图像网比赛(ImageNet competition)中,几乎所有参赛队都在使用深度学习,并获得了神奇的准确性。很快,深度学习便被应用于图像识别之外的任务。去年,由于他在这一领域的特殊贡献,辛顿与人工智能的先驱们YannLeCun和Yoshua Bengio一起被授予图灵奖。10月20日,我在麻省理工学院技术评论的年会“Em Tech MIT会议”上与他谈到了这个领域的现状,以及下一步的方向。我深信深度学习将无所不能,同时,我认为必须有相当多的概念上的突破。例如,2017年AshishVaswani等人,引入“transformer”“transformers”这个概念,它利用向量来表示词义,这是一个概念性的突破,目前几乎用于所有的自然语言处理模型。我们需要更多类似的突破。人工智能领域一直把人脑作为其最大的灵感来源,不同的人工智能方法源于认知科学中的不同理论。原文链接 https://www.jiqizhixin.com/articles/2020-11-18-3