华为开源自研AI框架昇思MindSpore数据处理:性能优化

2023-05-16

目录

  • 一、环境准备
    • 1.进入ModelArts官网
    • 2.使用CodeLab体验Notebook实例
  • 二、下载数据集
  • 三、数据加载性能优化
  • 四、shuffle性能优化
  • 五、数据增强性能优化
  • 六、操作系统性能优化
  • 七、自动数据加速
  • 八、数据异构加速

数据是整个深度学习中最重要的一环,因为数据的好坏决定了最终结果的上限,模型的好坏只是去无限逼近这个上限,所以高质量的数据输入,会在整个深度神经网络中起到积极作用,数据在整个数据处理和数据增强的过程像经过pipeline管道的水一样,源源不断地流向训练系统,如图所示:

在这里插入图片描述

MindSpore为用户提供了数据处理以及数据增强的功能,在数据的整个pipeline过程中,其中的每一步骤,如果都能够进行合理的运用,那么数据的性能会得到很大的优化和提升。

本次体验将基于CIFAR-10数据集来为大家展示如何在数据加载、数据处理和数据增强的过程中进行性能的优化。

此外,操作系统的存储、架构和计算资源也会一定程度上影响数据处理的性能。

如果你对MindSpore感兴趣,可以关注昇思MindSpore社区

在这里插入图片描述

在这里插入图片描述

一、环境准备

1.进入ModelArts官网

云平台帮助用户快速创建和部署模型,管理全周期AI工作流,选择下面的云平台以开始使用昇思MindSpore,可以在昇思教程中进入ModelArts官网

在这里插入图片描述

选择下方CodeLab立即体验

在这里插入图片描述

等待环境搭建完成

在这里插入图片描述

2.使用CodeLab体验Notebook实例

下载NoteBook样例代码.ipynb为样例代码

在这里插入图片描述

选择ModelArts Upload Files上传.ipynb文件

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

选择Kernel环境

在这里插入图片描述

进入昇思MindSpore官网,点击上方的安装

在这里插入图片描述

获取安装命令

在这里插入图片描述

回到Notebook中,在第一块代码前加入三块命令
在这里插入图片描述

pip install --upgrade pip
conda install mindspore-gpu=1.9.0 cudatoolkit=10.1 -c mindspore -c conda-forge
pip install mindvision

依次运行即可

在这里插入图片描述

在这里插入图片描述

二、下载数据集

运行以下命令来获取数据集:

下载CIFAR-10二进制格式数据集,并将数据集文件解压到./datasets/目录下,数据加载的时候使用该数据集。


from mindvision import dataset
import os
import shutil

dl_path = "./datasets"
data_dir = "./datasets/cifar-10-batches-bin/"
dl_url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/cifar-10-binary.tar.gz"

dl = dataset.DownLoad()  # 下载CIFAR-10数据集
dl.download_and_extract_archive(url=dl_url, download_path=dl_path)
test_path = "./datasets/cifar-10-batches-bin/test"
train_path = "./datasets/cifar-10-batches-bin/train"
os.makedirs(test_path, exist_ok=True)
os.makedirs(train_path, exist_ok=True)
if not os.path.exists(os.path.join(test_path, "test_batch.bin")):
    shutil.move("./datasets/cifar-10-batches-bin/test_batch.bin", test_path)
[shutil.move("./datasets/cifar-10-batches-bin/"+i, train_path) for i in os.listdir("./datasets/cifar-10-batches-bin/") if os.path.isfile("./datasets/cifar-10-batches-bin/"+i) and not i.endswith(".html") and not os.path.exists(os.path.join(train_path, i))]

在这里插入图片描述

解压后的数据集文件的目录结构如下:

./datasets/cifar-10-batches-bin
├── readme.html
├── test
│ └── test_batch.bin
└── train
├── batches.meta.txt
├── data_batch_1.bin
├── data_batch_2.bin
├── data_batch_3.bin
├── data_batch_4.bin
└── data_batch_5.bin

三、数据加载性能优化

MindSpore支持加载计算机视觉、自然语言处理等领域的常用数据集、特定格式的数据集以及用户自定义的数据集。不同数据集加载接口的底层实现方式不同,性能也存在着差异,如下所示:

常用数据集用户自定义MindRecord
底层实现C++PythonC++
性能

性能优化方案

在这里插入图片描述
数据加载性能优化建议如下:

对于已经提供加载接口的常用数据集,优先使用MindSpore提供的数据集加载接口进行加载,可以获得较好的加载性能,具体内容请参考内置加载算子,如果性能仍无法满足需求,则可采取多线程并发方案,请参考本文多线程优化。

不支持的数据集格式,推荐先将数据集转换为MindRecord数据格式后再使用MindDataset类进行加载(详细使用方法参考API),具体内容请参考将数据集转换为MindSpore数据格式,如果性能仍无法满足需求,则可采取多线程并发方案,请参考本文多线程优化。

不支持的数据集格式,算法快速验证场景,优选用户自定义GeneratorDataset类实现(详细使用方法参考API),如果性能仍无法满足需求,则可采取多进程并发方案,请参考本文多进程优化。

基于以上的数据加载性能优化建议,本次体验分别使用内置加载算子Cifar10Dataset类(详细使用方法参考API)、数据转换后使用MindDataset类、使用GeneratorDataset类进行数据加载,代码演示如下:

1.使用内置算子Cifar10Dataset类加载CIFAR-10数据集,这里使用的是CIFAR-10二进制格式的数据集,加载数据时采取多线程优化方案,开启了4个线程并发完成任务,最后对数据创建了字典迭代器,并通过迭代器读取了一条数据记录。


import mindspore.dataset as ds
cifar10_path = "./datasets/cifar-10-batches-bin/train"

# create Cifar10Dataset for reading data
cifar10_dataset = ds.Cifar10Dataset(cifar10_path, num_parallel_workers=4)
# create a dictionary iterator and read a data record through the iterator
print(next(cifar10_dataset.create_dict_iterator()))

在这里插入图片描述

2.使用Cifar10ToMR这个类将CIFAR-10数据集转换为MindSpore数据格式,这里使用的是CIFAR-10 python文件格式的数据集,然后使用MindDataset类加载MindSpore数据格式数据集,加载数据采取多线程优化方案,开启了4个线程并发完成任务,最后对数据创建了字典迭代器,并通过迭代器读取了一条数据记录。


from mindspore.mindrecord import Cifar10ToMR

trans_path = "./transform/"

if not os.path.exists(trans_path):
    os.mkdir(trans_path)

os.system("rm -f {}cifar10*".format(trans_path))

# download CIFAR-10 python
py_url = "https://mindspore-website.obs.cn-north-4.myhuaweicloud.com/notebook/datasets/cifar-10-python.tar.gz"
dl.download_and_extract_archive(url=py_url, download_path=dl_path)

cifar10_path = './datasets/cifar-10-batches-py'
cifar10_mindrecord_path = './transform/cifar10.record'

cifar10_transformer = Cifar10ToMR(cifar10_path, cifar10_mindrecord_path)
# execute transformation from CIFAR-10 to MindRecord
cifar10_transformer.transform(['label'])

# create MindDataset for reading data
cifar10_mind_dataset = ds.MindDataset(dataset_files=cifar10_mindrecord_path, num_parallel_workers=4)
# create a dictionary iterator and read a data record through the iterator
print(next(cifar10_mind_dataset.create_dict_iterator()))

{'data': Tensor(shape=[1289], dtype=UInt8, value= [255, 216, 255, 224,   0,  16,  74,  70,  73,  70,   0,   1,   1,   0,   0,   1,   0,   1,   0,   0, 255, 219,   0,  67,
   0,   2,   1,   1,   1,   1,   1,   2,   1,   1,   1,   2,   2,   2,   2,   2,   4,   3,   2,   2,   2,   2,   5,   4,
   4,   3,   4,   6,   5,   6,   6,   6,   5,   6,   6,   6,   7,   9,   8,   6,   7,   9,   7,   6,   6,   8,  11,   8,
   9,  10,  10,  10,  10,  10,   6,   8,  11,  12,  11,  10,  12,   9,  10,  10,  10, 255, 219,   0,  67,   1,   2,   2,
   ...
   ...
   ...
  39, 227, 206, 143, 241,  91, 196, 154, 230, 189, 125, 165, 105, 218,  94, 163, 124, 146,  11, 187,  29,  34, 217, 210,
  23, 186,  56,  14, 192,  19, 181,   1,  57,  36,  14,  51, 211, 173, 105,   9, 191, 100, 212, 174, 122,  25, 110,  39,
  11, 133, 193, 226, 169,  73,  36, 234,  69,  90, 222,  93,  31, 223, 115, 255, 217]), 'id': Tensor(shape=[], dtype=Int64, value= 46084), 'label': Tensor(shape=[], dtype=Int64, value= 5)}

在这里插入图片描述
3.使用GeneratorDataset类加载自定义数据集,并且采取多进程优化方案,开启了4个进程并发完成任务,最后对数据创建了字典迭代器,并通过迭代器读取了一条数据记录。


import numpy as np
def generator_func(num):
    for i in range(num):
        yield (np.array([i]),)

# create GeneratorDataset for reading data
dataset = ds.GeneratorDataset(source=generator_func(5), column_names=["data"], num_parallel_workers=4)

# create a dictionary iterator and read a data record through the iterator
print(next(dataset.create_dict_iterator()))

在这里插入图片描述

四、shuffle性能优化

shuffle操作主要是对有序的数据集或者进行过repeat的数据集进行混洗,MindSpore专门为用户提供了shuffle函数,其中设定的buffer_size参数越大,混洗程度越大,但时间、计算资源消耗也会大。该接口支持用户在整个pipeline的任何时候都可以对数据进行混洗,具体内容请参考shuffle处理。但是因为底层的实现方式不同,该方式的性能不如直接在内置加载算子中设置shuffle参数直接对数据进行混洗。

性能优化方案
在这里插入图片描述

shuffle性能优化建议如下:

  • 直接使用内置加载算子的shuffle参数进行数据的混洗。
  • 如果使用的是shuffle函数,当性能仍无法满足需求,可通过调大buffer_size参数的值来优化提升性能。

基于以上的shuffle性能优化建议,本次体验分别使用内置加载算子Cifar10Dataset类的shuffle参数和Shuffle函数进行数据的混洗,代码演示如下:

1.使用内置算子Cifar10Dataset类加载CIFAR-10数据集,这里使用的是CIFAR-10二进制格式的数据集,并且设置shuffle参数为True来进行数据混洗,最后对数据创建了字典迭代器,并通过迭代器读取了一条数据记录。


cifar10_path = "./datasets/cifar-10-batches-bin/train"

# create Cifar10Dataset for reading data
cifar10_dataset = ds.Cifar10Dataset(cifar10_path, shuffle=True)
# create a dictionary iterator and read a data record through the iterator
print(next(cifar10_dataset.create_dict_iterator()))

在这里插入图片描述
2.使用shuffle函数进行数据混洗,参数buffer_size设置为3,数据采用GeneratorDataset类自定义生成。


def generator_func():
    for i in range(5):
        yield (np.array([i, i+1, i+2, i+3, i+4]),)

ds1 = ds.GeneratorDataset(source=generator_func, column_names=["data"])
print("before shuffle:")
for data in ds1.create_dict_iterator():
    print(data["data"])

ds2 = ds1.shuffle(buffer_size=3)
print("after shuffle:")
for data in ds2.create_dict_iterator():
    print(data["data"])

在这里插入图片描述

五、数据增强性能优化

在图片分类的训练中,尤其是当数据集比较小的时候,用户可以使用数据增强的方法来预处理图片,达到丰富数据集的目的。MindSpore为用户提供了多种数据增强操作,其中包括:

  • 使用C++代码实现(主要基于OpenCV)的数据增强操作。
  • 使用Python代码实现(主要基于Pillow)的数据增强操作。
  • 用户可根据特定的需求,自定义Python数据增强函数。

具体的内容请参考数据增强。由于底层的实现方式不同,各个版本的数据增强操作的性能存在一定差异,具体如下所示:

编程语言三方库说明
C++OpenCV使用C++代码实现,性能较高
PythonPillow使用Python代码实现,更加灵活

性能优化方案
在这里插入图片描述

数据增强性能优化建议如下:

  • 优先使用实现在C++层的数据增强操作,能获得更好的性能,如果性能仍无法满足需求,可采取多线程优化、Compose优化方案或者算子融合优化。
  • 如果使用了实现在Python层的数据增强操作,当性能无法满足需求时,可采取多线程优化方案、多进程优化、compose优化或者算子融合优化。
  • 如果用户使用自定义Python函数进行数据增强,当性能仍无法满足需求,可采取多线程优化或者多进程优化,如果还是无法提升性能,就需要对自定义的Python代码进行优化。

MindSpore也支持用户同时使用实现在C++层的和实现在Python层的数据增强操作,但由于两者底层实现不同,过度地混用将增加资源开销,降低处理性能。推荐用户只使用其中的一种,或者先集中使用其中一种,再集中使用另外一种。不要在两种不同实现的数据增强操作中频繁地进行切换。

基于以上的数据增强性能优化建议,本次体验分别使用实现在C++层的数据增强操作和自定义Python函数进行数据增强,演示代码如下所示:

1.使用实现在C++层的数据增强操作,采用多线程优化方案,开启了4个线程并发完成任务,并且采用了算子融合优化方案,使用RandomResizedCrop融合类替代RandomResize类和RandomCrop类。


import mindspore.dataset.vision as vision
import matplotlib.pyplot as plt

cifar10_path = "./datasets/cifar-10-batches-bin/train"

# create Cifar10Dataset for reading data
cifar10_dataset = ds.Cifar10Dataset(cifar10_path, num_parallel_workers=4)
transforms = vision.RandomResizedCrop((800, 800))
# apply the transform to the dataset through dataset.map()
cifar10_dataset = cifar10_dataset.map(operations=transforms, input_columns="image", num_parallel_workers=4)

data = next(cifar10_dataset.create_dict_iterator())
plt.imshow(data["image"].asnumpy())
plt.show()

在这里插入图片描述
2.使用自定义Python函数进行数据增强,数据增强时采用多进程优化方案,开启了4个进程并发完成任务。


def generator_func():
    for i in range(5):
        yield (np.array([i, i+1, i+2, i+3, i+4]),)

ds3 = ds.GeneratorDataset(source=generator_func, column_names=["data"])
print("before map:")
for data in ds3.create_dict_iterator():
    print(data["data"])

func = lambda x: x**2
ds4 = ds3.map(operations=func, input_columns="data", python_multiprocessing=True, num_parallel_workers=4)
print("after map:")
for data in ds4.create_dict_iterator():
    print(data["data"])

在这里插入图片描述

六、操作系统性能优化

由于MindSpore的数据处理主要在Host端进行,运行环境的配置也会对处理性能产生影响,主要体现在存储设备、NUMA架构和CPU计算资源等方面。

1.存储设备

数据的加载过程涉及频繁的磁盘操作,磁盘读写的性能直接影响了数据加载的速度。当数据集较大时,推荐使用固态硬盘进行数据存储,固态硬盘的读写速度普遍较普通磁盘高,能够减少I/O操作对数据处理性能的影响。

一般地,加载后的数据将会被缓存到操作系统的页面缓存中,在一定程度上降低了后续读取的开销,加速了后续Epoch的数据加载速度。用户也可以通过MindSpore提供的单节点缓存技术,手动缓存加载增强后的数据,避免了重复的数据加载和数据增强。

2.NUMA架构

NUMA的全称为Non-Uniform Memory Access,即非一致性内存访问,是为了解决传统的对称多处理器(SMP)架构中的可扩展性问题而诞生的一种内存架构。在传统架构中,多个处理器共用一条内存总线,容易产生带宽不足、内存冲突等问题。

而在NUMA架构中,处理器和内存被划分为多个组,每个组称为一个节点(Node),各个节点拥有独立的集成内存控制器(IMC)总线,用于节点内通信,不同节点间则通过快速路径互连(QPI)进行通信。对于某一节点来说,处在同节点内的内存被称为本


numactl --cpubind=0 --membind=0 python train.py

在这里插入图片描述

3.CPU计算资源

尽管可以通过多线程并行技术加快数据处理的速度,但是实际运行时并不能保证CPU计算资源完全被利用起来。如果能够人为地事先完成计算资源配置的设定,将能在一定程度上提高CPU计算资源的利用率。

  • 计算资源的分配

在分布式训练中,同一设备上可能开启多个训练进程。默认情况下,各个进程的资源分配与抢占将会遵循操作系统本身的策略进行,当进程较多时,频繁的资源竞争可能会导致数据处理性能的下降。如果能够事先设定各个进程的计算资源分配,就能避免这种资源竞争带来的开销。


numactl --cpubind=0 python train.py

在这里插入图片描述

  • CPU频率设置

出于节约能效的考虑,操作系统会根据需要适时调整CPU的运行频率,但更低的功耗意味着计算性能的下降,会减慢数据处理的速度。要想充分发挥CPU的最大算力,需要手动设置CPU的运行频率。如果发现操作系统的CPU运行模式为平衡模式或者节能模式,可以通过将其调整为性能模式,提升数据处理的性能。


cpupower frequency-set -g performance

在这里插入图片描述

七、自动数据加速

MindSpore提供了一种自动数据调优的工具——Dataset AutoTune,用于在训练过程中根据环境资源的情况自动调整数据处理管道的并行度,最大化利用系统资源加速数据处理管道的处理速度。详细用法请参考自动数据加速。

在整个训练的过程中,Dataset
AutoTune模块会持续检测当前训练性能瓶颈处于数据侧还是网络侧。如果检测到瓶颈在数据侧,则将进一步对数据处理管道中的各个算子(如GeneratorDataset、map、batch此类数据算子)进行参数调整,目前可调整的参数包括算子的工作线程数(num_parallel_workers),算子的内部队列深度(prefetch_size)。
在这里插入图片描述

启动AutoTune后,MindSpore会根据一定的时间间隔,对数据处理管道的资源情况进行采样统计。

当Dataset AutoTune收集到足够的信息时,它会基于这些信息分析当前的性能瓶颈是否在数据侧。 如果是,Dataset
AutoTune将调整数据处理管道的并行度,并加速数据集管道的运算。 如果不是,Dataset
AutoTune也会尝试减少数据管道的内存使用量,为CPU释放一些可用内存。

启动自动数据加速(不保存调优后的推荐配置):


import mindspore.dataset as ds
ds.config.set_enable_autotune(True)

启动自动数据加速并设定调优结果的保存路径:


import mindspore.dataset as ds
ds.config.set_enable_autotune(True, "/path/to/autotune_out")

八、数据异构加速

MindSpore提供了一种运算负载均衡的技术,可以将MindSpore的算子计算分配到不同的异构硬件上,一方面均衡不同硬件之间的运算开销,另一方面利用异构硬件的优势对算子的运算进行加速。详细用法请参考数据异构加速。

目前该异构硬件加速技术仅支持将数据算子均衡到网络侧,均衡数据处理管道与网络运算的计算开销。具体来说,目前数据处理管道的算子均在CPU侧运算,该功能将部分数据操作从CPU侧“移动”到网络端,利用昇腾Ascend或GPU的计算资源对数据数据处理的算子进行加速。

该功能仅支持将作用于特定数据输入列末端的数据增强操作移至异构侧进行加速,输入列末端指的是作用于该数据的map算子所持有的位于末端且连续的数据增强操作。

下图显示了给定数据处理管道使用异构加速的典型计算过程。

在这里插入图片描述

异构加速功能对两个API进行了相关更新以允许用户启用此功能:

  • map数据算子新增offload输入参数,
  • 数据集全局配置mindspore.dataset.config中新增set_auto_offload接口。

如需检查数据增强算子是否移动至加速器,用户可以保存并检查计算图IR文件。在异构加速功能被启动后,相关计算算子会被写入IR文件中。异构加速功能同时适用于数据集下沉模式(dataset_sink_mode=True)和数据集非下沉模式(dataset_sink_mode=False)。

使用全局配置设置自动异构加速。在这种情况下,所有map数据处理算子的offload参数将设置为True(默认为None)。值得注意的是,如果用户指定特定map操作算子的offload为False,该map算子将直接应用该配置而不是全局配置。


import mindspore.dataset as ds
ds.config.set_auto_offload(True)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

华为开源自研AI框架昇思MindSpore数据处理:性能优化 的相关文章

  • 5:SpringBoot-Actuator-Java Spring

    目录 5 1 SpringBoot Actuator介绍5 2 Endpoints 介绍5 3 Actuator原理5 4 Actuator依赖引入 5 1 SpringBoot Actuator介绍 Actuator是Spring Boo
  • Ubuntu 20.04 VNC 安装与设置

    原链接 VNC是一个远程桌面协议 按照本文的说明进行操作可以实现用VNC对Ubuntu 20 04进行远程控制 一般的VNC安装方式在主机没有插显示器的时候是无法使用的 下面的操作可以在主机有显示器和没有显示器时都能够正常工作 首先安装x1
  • 6:RestFul API-Java Spring

    目录 6 1 RestFul API介绍6 2 URL构成6 3 RestFul API原理6 4 RestFul API映射注解6 5 RestFul API操作 6 1 RestFul API介绍 Rest表示性状态转移 xff08 R
  • 7:JSON-Java Spring

    目录 7 1 JSON介绍7 2 JSON和XML的区别7 3 JSON的构成7 4 JSON的语法7 5 JSON parse 7 6 JSON stringify 7 1 JSON介绍 JSON即JavaScript 对象标记法 xff
  • 8:Spring MVC-Java Spring

    目录 8 1 WEB开发模式一8 2 WEB开发模式二8 3 Spring MVC介绍8 4 Spring MVC主要组件8 5 Spring MVC处理流程8 6 Spring MVC的HTTP请求方法 在Web开发中有两种主要的结构 x
  • 9:参数校验-Java Spring

    目录 9 1 参数校验介绍9 2 JSR3039 3 Hibernate Validator9 4 参数校验依赖引入 9 1 参数校验介绍 参数校验即保证数据的合法性 xff0c JCP组织定义了一个标准来规范化这个任务操作 xff0c 即
  • 江服校园导游咨询系统-数据结构课程设计

    目录 1 需求分析1 1 问题描述1 2 系统简介1 3 系统模块功能要求介绍1 4 系统开发环境及开发人员1 5 校园平面图 2 概要设计2 1 算法设计及存储结构说明2 2 系统功能设计 3 详细设计3 1 定义符号变量3 2 主程序模
  • 基于STM32的光敏传感器数据采集系统-嵌入式系统与设计课程设计

    目录 1 项目概述1 1 项目介绍1 2 项目开发环境1 3 小组人员及分工 2 需求分析2 1 系统需求分析2 2 可行性分析2 3 项目实施安排 3 系统硬件设计3 1 系统整体硬件电路设计3 2 STM32 最小系统电路设计3 3 传
  • QX-A51智能小车实现-物联网应用系统设计项目开发

    目录 介绍说明展示 介绍 STC89C52系列单片机是STC推出的新一代高速 低功耗 超强抗干扰 超低价的单片机 xff0c 指令代码完全兼容传统8051单片机 xff0c 12时钟每机器周期和6时钟每机器周期可以任意选择 QX A51智能
  • 11:跨域访问-Java Spring

    目录 11 1 跨域访问11 2 同源策略11 3 跨域解决方案 11 1 跨域访问 跨域指的是浏览器不能执行其他网站的脚本 xff0c 当一个请求url的协议 域名 端口三者有任意一个不同即为跨域 无法跨域是由浏览器的同源策略造成的 xf
  • 10:@Validated和@Valid-Java Spring

    目录 10 1 64 Valid10 2 64 Validated10 2 区别10 2 Controller参数校验 10 1 64 Valid 64 Valid 是 Hibernate validation 提供的注解 xff0c 表示
  • 12:CORS跨域设置-Java Spring

    目录 12 1 CORS介绍12 2 CORS原理12 3 CORS实现 12 1 CORS介绍 CORS跨域资源共享 xff08 Cross origin resource sharing xff09 是指在服务器端定义跨域请求规则 xf
  • Ubuntu虚拟机可以上网,可以ping网络,但是无法update和install,显示不能连接或者无网络

    此方法为我找遍了网上全部解决方案之后还没有解决掉 xff0c 自己琢磨出来的其中一种方法 错误情况 xff1a 可以上浏览器看视频 xff0c 但是不能apt install vim或者gcc 解决方案 1 打开文件夹 2 输入 或者进入
  • 13:SpringBoot跨域解决方案-Java Spring

    目录 13 1 CorsFilter13 2 64 CrossOrigin13 3 WebMvcConfigurer 13 1 CorsFilter SpringBoot设置CORS的的本质都是通过设置响应头信息来告诉前端该请求是否支持跨域
  • 14:Servlet并发机制-Java Spring

    目录 14 1 并发14 2 Servlet并发机制14 3 Tomcat并发特点14 4 Tomcat线程模型 14 1 并发 并发 xff08 Concurrent xff09 是指多个任务交替执行的现象 xff0c 把CPU运行时间划
  • 手写字体识别实验-Python课程设计

    安装python 打开手写识别文件夹中的安装包文件夹 xff0c 双击python3 7 1可执行文件 xff0c 进行安装 弹出窗口 第一步 xff0c 勾选第二个复选框 Add Python 3 7 to PATH xff0c 然后点击
  • 生产企业原材料订购与运输的研究-数据处理课程设计

    目录 摘要1 引言2 规划问题说明3 问题重述3 1 问题分析3 2 数据说明3 3 模型假设3 4 符号说明 4 实验及分析4 1 问题一模型的建立与求解4 2 问题二模型的建立与求解 5 总结5 1 模型的优点5 2 模型的缺点 参考文
  • 信号发生器-电路与电子技术课程设计

    目录 1 设计任务与要求1 1 设计任务1 2 设计要求 2 方案设计与论证2 1 方案设计2 2 论证 3 信号发生器设计与计算3 1 信号发生器设计3 2 方波振荡电路图3 3 三角波振荡电路图3 4 参数计算 4 总原理图及元器件清单
  • 增益可控放大电路-电路与电子技术课程设计

    目录 1 设计任务与要求1 1 设计任务1 2 设计要求 2 方案设计与论证2 1 方案设计2 2 论证 3 放大电路设计与计算3 1 放大电路设计3 2 电子开关切换电路设计3 3 六档控制电路3 4 参数计算 4 总原理图及元器件清单4
  • 超声波测距实验-传感器原理及应用实验

    目录 一 实验实训主要内容二 实验实训方法 过程步骤三 实验实训结果与分析四 讨论小结 一 实验实训主要内容 学习超声波测距传感器的使用方法 xff0c 了解超声波测距传感器的原理和电路及实际应用 xff0c 了解超声波测距传感器的基本操作

随机推荐

  • 光敏传感器实验-传感器原理及应用实验

    目录 一 实验实训主要内容二 实验实训方法 过程步骤三 实验实训结果与分析四 讨论小结 一 实验实训主要内容 学习光敏传感器的使用方法 xff0c 了解光敏传感器的基本实验原理和实际应用 xff0c 熟练掌握光敏传感器实验的操作步骤 xff
  • 红外反射传感器实验-传感器原理及应用实验

    目录 一 实验实训主要内容二 实验实训方法 过程步骤三 实验实训结果与分析四 讨论小结 一 实验实训主要内容 学习红外反射传感器的使用方式 xff0c 了解红外反射传感器的实验原理和实际应用 xff0c 学习并理解Modbus数据格式所代表
  • 酒精传感器实验-传感器原理及应用实验

    目录 一 实验实训主要内容二 实验实训方法 过程步骤三 实验实训结果与分析四 讨论小结 一 实验实训主要内容 学习酒精传感器MQ 3的使用方法 xff0c 了解酒精传感器的实验原理和实际应用 xff0c 了解酒精传感器的基本操作模式 xff
  • hdoj 1575 Tr A (矩阵快速幂)

    Tr A Time Limit 1000 1000 MS Java Others Memory Limit 32768 32768 K Java Others Total Submission s 4549 Accepted Submiss
  • MapReduce排序过程

    排序是MapReduce框架中最重要的操作之一 MapTask和ReduceTask均会对数据按照key 进行排序 该操作属于Hadoop 的默认行为 xff0c 任何应用程序中的数据均会被排序 xff0c 而不管逻辑上是否需要 默认排序是
  • 温湿度传感器实验-传感器原理及应用实验

    目录 一 实验实训主要内容二 实验实训方法 过程步骤三 实验实训结果与分析四 讨论小结 一 实验实训主要内容 学习温湿度传感器的使用方法 xff0c 了解温湿度传感器的基本实验原理和实际应用 xff0c 熟练掌握温湿度传感器的基本步骤 xf
  • 烟雾检测传感器实验-传感器原理及应用实验

    目录 一 实验实训主要内容二 实验实训方法 过程步骤三 实验实训结果与分析四 讨论小结 一 实验实训主要内容 学习烟雾检测传感器的原理及检测方式 xff0c 了解烟雾检测传感器的实验原理和技术指标 xff0c 熟练掌握烟雾检测传感器的工作步
  • 4:Servlet-Java Web

    目录 4 1 Servlet简介4 2 HTTP协议4 3 Servlet与JSP4 4 Servlet处理的基本流程4 5 Servlet 容器4 6 Servlet程序实现 4 1 Servlet简介 Servlet是用Java语言编写
  • 5:Servlet程序-Java Web

    目录 5 1 Servlet要求5 2 创建Servlet5 3 第一个Servlet5 4 Servlet编译5 5 Servlet配置 5 1 Servlet要求 如果要开发一个可以处理HTTP请求的Servlet程序 xff0c 首先
  • 6:部署Servlet-Java Web

    目录 6 1 部署Servlet6 2 请求Servlet6 3 找不到servlet包6 4 Servlet映射的细节 6 1 部署Servlet 部署就是把Servlet的字节码文件放在适当的地方 为了在浏览器上访问Servlet xf
  • 7:Servlet表单-Java Web

    目录 7 1 Servlet响应7 2 Servlet获取客户端参数7 3 Servlet接受表单数据 7 1 Servlet响应 通过response对象对用户进行响应 创建输出流对象 PrintWriter out 61 respons
  • 8:Servlet生命周期-Java Web

    目录 8 1 Servlet生命周期8 2 Servlet生命周期对应的方法8 3 Servlet的多线程机制 8 1 Servlet生命周期 Servlet程序是运行在服务器端的一段Java程序 xff0c 其生命周期将受到Web容器的控
  • 9:中文乱码处理-Java Web

    目录 9 1 常见字符集9 2 乱码原因9 3 解决乱码 9 1 常见字符集 ASCII 最原始的一套编码 xff0c 所有编码都是由一个字节的二进制数对应 xff0c 尽管包含8位 xff0c 但是第一位始终是0 xff0c 也就是128
  • 华为云平台零代码搭建物联网可视化大屏体验:疫情防控数据大屏

    目录 一 介绍二 准备三 搭建1 创建疫情防控大屏应用2 组件放置3 组件配置4 应用打包 一 介绍 零代码搭建物联网可视化大屏 xff1a 自定义物联网场景 xff0c 根据个人理解实现基于华为云IoT以及可视化大屏DLV搭建物联网大屏
  • 华为开源自研AI框架昇思MindSpore入门体验:手写数字识别

    目录 一 环境安装1 进入MindSpore官网2 选择安装版本3 确保为Windows系统4 安装MindSpore5 验证安装6 安装依赖 二 模型训练1 下载并处理数据集2 创建模型 本教程是在CPU Ubuntu上安装MindSpo
  • 转型“系统集成商+大数据运营和服务商”,航天信息看好你哟

    毫无疑问 xff0c 人工智能今天已经是一个 风口 抓住这一契机 xff0c 迎风起舞 xff0c 可能是所有厂商的想法 但是每一个新的趋势出现时 xff0c 一定是机遇与挑战并存 对于厂商来说 xff0c 是处变不惊 xff0c 还是急速
  • 华为开源自研AI框架昇思MindSpore应用实践:DCGAN生成漫画头像

    目录 一 原理说明1 GAN基础原理2 DCGAN原理 二 环境准备1 进入ModelArts官网2 使用CodeLab体验Notebook实例 三 数据准备与处理1 数据处理 四 创建网络1 生成器2 判别器3 损失和优化器4 优化器 五
  • 我的创作纪念日-从写作到阿里云专家博主的故事

    目录 在创作之路上追寻自我首先是我为什么会埋下创作的种子种子的萌发通过这些经历 xff0c 此时创作的种子正在长成一棵小树创作的小树茁壮成长大树终将结出丰硕的果实 在创作之路上追寻自我 在创作之路上追寻自我 xff0c 与大家分享我从写作到
  • 华为开源自研AI框架昇思MindSpore应用实践:RNN实现情感分类

    目录 一 环境准备1 进入ModelArts官网2 使用CodeLab体验Notebook实例 二 数据准备1 数据下载模块2 加载IMDB数据集2 加载预训练词向量 三 数据集预处理四 模型构建1 Embedding2 RNN 循环神经网
  • 华为开源自研AI框架昇思MindSpore数据处理:性能优化

    目录 一 环境准备1 进入ModelArts官网2 使用CodeLab体验Notebook实例 二 下载数据集三 数据加载性能优化四 shuffle性能优化五 数据增强性能优化六 操作系统性能优化七 自动数据加速八 数据异构加速 数据是整个