热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

更快更简单|飞桨PaddlePaddle单机训练速度优化最佳实践

导读:飞桨(PaddlePaddle)致力于让深度学习技术的创新与应用更简单。在单机训练速度方面,通过高并行、低开销的异步执

导读:飞桨(PaddlePaddle)致力于让深度学习技术的创新与应用更简单。在单机训练速度方面,通过高并行、低开销的异步执行策略和高效率的核心算子,优化静态图训练性能,在Paddle Fluid v1.5.0的基准测试中,在7个典型模型上进行了测试(图像领域5个,NLP领域2个),其中5个模型的速度显著优于对标框架(大于15%),2个模型与对标框架持平(5%之内)。如果想让单机训练速度更快,可以根据这篇文档的建议从网络构建、数据准备、模型训练三个方向了解飞桨单机训练中常用的优化方法。来一组测试数据先睹为快。

测试环境如下:

•   PaddlePaddle version:1.5.0

•   Tensorflow version:1.12.0

•   PyTorch version:1.1.0

•   MXNet version:1.4.1

•   GPU:Tesla V100-SXM2

•   CPU:Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz,38核

•   Nvida driver: 418.39

•   CUDNN VERSION:7.4.2.24

•   CUDA VERSION:9.0.176,单卡模式

1. 网络构建过程中的配置优化

减少模型中Layer的个数

为方便用户使用,飞桨提供一些不同粒度的Layer,其中有些Layer的组合可以通过单个Layer完成。比如:

(1)fluid.layers.softmax_with_cross_entropy,该操作其实是fluid.layers.softmax和fluid.layers.cross_entropy的组合,因此如果模型中有出现fluid.layers.softmax和fluid.layers.cross_entropy的组合,可以直接用fluid.layers.softmax_with_cross_entropy替换。

(2)如果模型中需要对数据进行标准化,可以直接使用fluid.layers.data_norm,而不用通过一系列layer组合出数据的标准化操作。

因此,建议在构建模型时优先使用飞桨提供的单个Layer完成所需操作,这样减少模型中Layer的个数,并因此加速模型训练。

2. 数据准备优化

数据准备通常分为两部分:第一部分是数据加载,即程序从磁盘中加载训练/预测数据;第二部分是数据预处理,程序对加载的数据进行预处理,比如图像任务通常需要进行数据增强、Shuffle等。这两部分需要用户根据自己的模型需要进行设置,只需要最后得到Data Reader接口即可。Data Reader返回iterable对象,可以每次返回一条样本或者一组样本。代码示例如下:

def data_reader (width, height):defreader():while True:
yield np.random.uniform(-1, 1,size=width*height), \np.random.randint(0,10)
return reader
train_data_reader = data_reader(32, 32)

飞桨提供了两种方式从Data Reader中读取数据:同步数据读取和异步数据读取。

2.1 同步数据读取

同步数据读取是一种简单并且直观的数据准备方式,代码示例如下:

Image = paddle.layer.data("image",...)
label = paddle.layer.data("label",...)
# 模型定义
# ……
prediction = fluid.layers.fc(input= image,size=10)
loss = fluid.layers.cross_entropy(input=prediction, label= label)
avg_loss = fluid.layers.mean(loss)
# ……
# 读取数据
# paddle.dataset.mnist.train()返回数据读取的Reader,每次可以从Reader中读取一条样本,batch_size为128
train_reader =paddle.batch(paddle.dataset.mnist.train(), 128)
end = time.time()
for batch_id, batch in enumerate(train_reader):data_time = time.time() - end# 训练网络executor.run(feed=[...], fetch_list=[...])batch_time = time.time() - endend= time.time()

用户首先需要通过fluid.layers.data定义模型的输入,然后根据输入构建模型,最后从事先自定义的Reader函数中获取一个batch的数据,并将数据传递给执行器。

 

可以看出,采用同步数据读取方式时,用户可通过加入计时函数来统计数据准备部分和执行部分所占用的时间。由于数据准备和执行是顺序进行的,所以程序的执行速度可能较慢。如果用户想进行模型调试的话,同步数据读取是一个不错的选择。

 

更多同步数据读取的介绍请参考:

https://www.paddlepaddle.org.cn/documentation/docs/en/1.5/user_guides/howto/prepare_data/reader.html

2.2 异步数据读取

飞桨里面使用py_reader接口来实现异步数据读取,代码示例如下:

train_py_reader = fluid.layers.py_reader(capacity=10,shapes=((-1, 784), (-1, 1)),dtypes=('float32', 'int64'),name="train_reader",use_double_buffer=True)
# 使用 read_file() 方法从py_reader中获取模型的输入
image, label = fluid.layers.read_file(reader)
# 模型定义
# ……
prediction = fluid.layers.fc(input= image,size=10)
loss = fluid.layers.cross_entropy(input=prediction, label= label)
avg_loss = fluid.layers.mean(loss)
# ……
# 读取数据
train_reader =paddle.batch(paddle.dataset.mnist.train(), 128)
train_py_reader.decorate_paddle_reader(train_reader)
# 启动py_reader
train_py_reader.start()
try:end= time.time()while True:print("queue size: ", train_py_reader.queue.size())loss, = executor.run(fetch_list=[...])# ...batch_time = time.time() - endend = time.time()batch_id += 1
except fluid.core.EOFException:train_py_reader.reset()

用户首先需要通过fluid.layers.py_reader定义py_reader对象,并使用 read_file() 方法从py_reader中获取模型的输入,然后根据输入构建模型,再然后用decorate_paddle_reader将自定义的Reader与py_reader绑定。在训练开始之前,通过调用start()方法来启动数据读取。在数据读取结束之后,executor.run会抛出fluid.core.EOFException,表示训练已经遍历完Reader中的所有数据。

 

采用异步数据读取时,Python端和C++端共同维护一个数据队列,Python端启动一个线程,负责向队列中插入数据,C++端在训练/预测过程中,从数据队列中获取数据,并将该数据从对队列中移除。用户可以在程序运行过程中,监测数据队列是否为空,如果队列始终不为空,表明数据准备的速度比模型执行的速度快,这种情况下数据读取可能不是瓶颈。

 

另外,飞桨提供的一些FLAGS也能很好的帮助分析性能。如果用户希望评估一下在完全没有数据读取开销情况下模型的性能,可以设置一下环境变量:FLAGS_reader_queue_speed_test_mode,在该变量为True情况下,C++端从数据队列中获取数据之后,不会从数据队列中移除,这样能够保证数据队列始终不为空,从而避免了C++端读取数据时的等待开销。

 

需要特别注意的是,FLAGS_reader_queue_speed_test_mode只能在性能分析时打开,正常训练/预测模型时需要关闭。

 

为降低训练的整体时间,建议用户使用异步数据读取的方式,并开启 use_double_buffer=True 。用户可根据模型的实际情况设置数据队列的大小。如果数据准备的时间大于模型执行的时间,或者出现了数据队列为空的情况,就需要考虑对数据读取Reader进行加速。常用的方法是使用多进程准备数据,

可以参考:

https://github.com/PaddlePaddle/models/blob/develop/PaddleCV/yolov3/reader.py

 

更多异步数据读取的介绍请参考:

https://www.paddlepaddle.org.cn/documentation/docs/en/1.5/user_guides/howto/prepare_data/use_py_reader_en.html

3. 模型训练相关优化

3.1 飞桨的执行器介绍

目前Python API中,飞桨提供了fluid.compiler.CompiledProgram的概念,用户可以通过CompiledProgram将传入的program(飞桨中的网络模型)进行编译,如果希望采用数据并行模式训练,只需要将CompiledProgram返回的对象调用一下with_data_parallel即可,最后统一通过executor.run(…)执行compiled_program。

 

虽然统一通过executor.run(…)接口来执行,实际底层的执行策略有两种,对应C++部分的两个执行器,即Executor和ParallelExecutor,如果用户采用数据并行模式,C++部分使用的是ParallelExecutor,除此之外都是使用Executor。

 

这两个执行器的差别:

可以看出,Executor的内部逻辑非常简单,但性能可能会弱一些,因为Executor对于program中的操作是串行执行的。而ParallelExecutor首先会将program转变为计算图,并分析计算图中节点间的连接关系,对图中没有相互依赖的节点(OP),通过多线程并行执行。

 

因此,Executor是一个轻量级的执行器,目前主要用于参数初始化、模型保存、模型加载。ParallelExecutor是Executor的升级版本,目前ParallelExecutor主要用于模型训练,包括单机单卡、单机多卡以及多机多卡训练。

 

ParallelExecutor执行计算图之前,可以对计算图进行一些优化,比如使计算图中的一些操作是In-place的、将计算图中的参数更新操作进行融合等。用户还可以调整Parallel Executor执行过程中的一些配置,比如执行计算图的线程数等。这些配置分别是构建策略(BuildStrategy)和执行策略(ExecutionStrategy)参数来设置的。

一个简单的使用示例如下:

build_strategy = fluid.BuildStrategy()
build_strategy.enable_inplace = True
build_strategy.fuse_all_optimizer_ops=Trueexec_strategy = fluid.ExecutionStrategy()
exec_strategy.num_threads = 4train_program = fluid.compiler.CompiledProgram(main_program).with_data_parallel(loss_name=loss.name,build_strategy=build_strategy,exec_strategy=exec_strategy)place = fluid.CUDAPlace(0)
exe = Executor(place)
# 使用py_reader读取数据,因此执行时不需要feed
fetch_outs = exe.run(train_program, fetch_list=[loss.name],)

更多关于ParallelExecutor的介绍请参考:

https://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/api_guides/low_level/parallel_executor.html

更多关于CompiledProgram的介绍请参考:

https://www.paddlepaddle.org.cn/documentation/docs/zh/1.5/api_guides/low_level/compiled_program.html

3.2 构建策略(BuildStrategy)配置参数介绍

BuildStrategy中提供了一些关于计算图优化的策略,这些策略可以在不同程度上提升模型的训练速度,但是其中一些策略与模型的结构有关,比如fuse_all_optimizer_ops不支持sparse梯度,我们正在积极的完善这些策略,并在下一个版本将这些策略默认打开。

构建策略的详细介绍如下:

参数说明:

(1)关于 reduce_strategy , Parallel Executor 对于数据并行支持两种参数更新模式:AllReduce 和 Reduce 。在 AllReduce 模式下,各个节点上计算得到梯度之后,调用 AllReduce 操作,梯度在各个节点上聚合,然后各个节点分别进行参数更新。在 Reduce 模式下,参数的更新操作被均匀的分配到各个节点上,即各个节点计算得到梯度之后,将梯度在指定的节点上进行 Reduce ,然后在该节点上进行参数的更新,最后将更新之后的参数Broadcast到其他节点。

即:如果模型中有100个参数需要更新,训练使用的节点数为4,在 AllReduce 模式下,各个节点需要分别对这100个参数进行更新;在 Reduce 模式下,各个节点需要分别对这25个参数进行更新,最后将更新的参数Broadcast到其他节点。注意:如果是使用CPU进行数据并行训练,在Reduce模式下,不同CPUPlace 上的参数是共享的,所以在各个CPUPlace 上完成参数更新之后不用将更新后的参数Broadcast到其他CPUPlace。

(2)关于 enable_backward_optimizer_op_deps ,在多卡训练时,打开该选项可能会提升训练速度。

(3)关于 fuse_all_optimizer_ops ,目前只支持SGD、Adam和Momentum算法。注意:目前不支持sparse参数梯度。

(4)关于 fuse_all_reduce_ops ,多GPU训练时,可以对 AllReduce 操作进行融合,以减少 AllReduce 的调用次数。默认情况下会将同一layer中参数的梯度的 AllReduce 操作合并成一个,比如对于 fluid.layers.fc 中有Weight和Bias两个参数,打开该选项之后,原本需要两次 AllReduce 操作,现在只用一次 AllReduce 操作。此外,为支持更大粒度的参数梯度融合,飞桨提供了 FLAGS_fuse_parameter_memory_size 选项,用户可以指定融合AllReduce操作之后,每个 AllReduce 操作的梯度字节数,比如希望每次 AllReduce 调用传输64MB的梯度,export FLAGS_fuse_parameter_memory_size=64 。注意:目前不支持sparse参数梯度。

(5)关于 mkldnn_enabled_op_types ,目前飞桨的Op中可以使用mkldnn库计算的操作包括:transpose, sum, softmax,requantize, quantize, pool2d, lrn, gaussian_random, fc, dequantize,conv2d_transpose, conv2d, conv3d, concat, batch_norm, relu, tanh, sqrt, abs.

3.3 执行策略(ExecutionStrategy)配置参数介绍

ExecutionStrategy中提供了关于计算图执行时的一些配置,这些配置可能会影响模型的训练速度。同时,这些配置与模型的结构有关,如果用户希望模型训练速度更快,可以调整一下这些配置。在后续的优化中,我们会对这部分进行优化,根据输入模型结构动态调整这些设置。

ExecutionStrategy配置选项说明:

参数说明:

(1)关于 num_iteration_per_drop_scope ,框架在运行过程中会产生一些临时变量,通常每经过一个batch就要清理一下临时变量,但是由于GPU是异步设备,在清理之前需要对所有的GPU调用一次同步操作,因此耗费的时间较长。为此我们在 execution_strategy 中添加了 num_iteration_per_drop_scope 选项。用户可以指定经过多少次迭代之后清理一次。

(2)关于 num_threads ,ParallelExecutor 根据OP之间的依赖关系确定OP的执行顺序,即:当OP的输入都已经变为ready状态之后,该OP会被放到一个队列中,等待被执行。ParallelExecutor 内部有一个任务调度线程和一个线程池,任务调度线程从队列中取出所有Ready的OP,并将其放到线程队列中。num_threads 表示线程池的大小。根据以往的经验,对于CPU任务,num_threads=2*dev_count 时性能较好,对于GPU任务,num_threads=4*dev_count 时性能较好。注意:线程池不是越大越好。

4. 运行时FLAGS设置优化

Paddle Fluid中有一些FLAGS可以有助于性能优化:

(1)FLAGS_cudnn_exhaustive_search表示在调用cuDNN中的卷积操作时,根据输入数据的shape等信息,采取穷举搜索的策略从算法库中选取到更快的卷积算法,进而实现对模型中卷积操作的加速。需要注意的是:

a. 在搜索算法过程中需要使用较多的显存,如果用户的模型中卷积操作较多,或者GPU卡显存较小,可能会出现显存不足问题。

b. 通过穷举搜索选择好算法之后,该算法会进入Cache,以便下次运行时,如果输入数据的shape等信息不变,直接使用Cache中算法。

(2)FLAGS_enable_cublas_tensor_op_math表示是否使用TensorCore加速cuBLAS等NV提供的库中的操作。需要注意的是,这个环境变量只在Tesla V100以及更新的GPU上适用,且可能会带来一定的精度损失,通常该损失不会影响模型的收敛性。


5.最佳实践(Best Practise)

(1)尽可能的使用飞桨提供的单个layer实现所需操作。

(2)采用异步数据读取。

(3)模型训练相关优化:

 a. 使用ParallelExecutor作为底层执行器,代码示例:

compiled_prog = compiler.CompiledProgram(fluid.default_main_program()).with_data_parallel(loss_name=loss.name)

如果是单卡训练,也可以调用with_data_parallel方法。

b. 如果模型中参数的梯度都是非sparse的,可以打开fuse_all_optimizer_ops选项,将多个参数更新操作融合为一个。

c. 如果是多卡训练,可以打开enable_backward_optimizer_op_deps、fuse_all_reduce_ops选项。如果想指定每次每次AllReduce操作的数据大小,可以设置FLAGS_fuse_parameter_memory_size,比如 export FLAGS_fuse_parameter_memory_size=1,表示每次 AllReduce 调用传输1MB的梯度。

d. 使用CPU做数据并行训练时,推荐使用Reduce模型,因为在使用CPU进行数据并行训练时,在Reduce模式下,不同CPUPlace 上的参数是共享的,所以在各个CPUPlace 上完成参数更新之后不用将更新后的参数Broadcast到其他CPUPlace上,这对提升速度也有很大帮助。

e. 如果是Reduce模式,可打开fuse_broadcast_ops选项。

f. 如果用户的模型较小,比如mnist、language_model等,可以将num_threads设为1。

g. 在显存足够的前提下,建议将 exec_strategy.num_iteration_per_drop_scope 设置成一个较大的值,比如设置为100 ,这样可以避免反复地申请和释放内存。

 

目前我们正在推进这些配置自动化的工作:即根据输入的模型结构自动配置这些选项,争取在下一个版本中实现,敬请期待。

(4)FLAGS设置

FLAGS_cudnn_exhaustive_search = TrueFLAGS_enable_cublas_tensor_op_math = True 


6.典型案例

不同的模型计算特征不同,最优运行时配置也就不尽相同。大体来说,主要是两种情况,第一种情况:模型组网OP数量少、OP的计算量大,常见的如ResNet、VGG模型,通过设置合适的batch_size,这类模型很容易就可以将最大限度的利用GPU计算资源,因此设置不同的执行器参数对总体速度影响可能不是很明显。第二种情况:模型由大量的计算量很小的OP组成,比如RNN模型,这类模型则需要用户通过实验来选择运行时参数的最佳配置。因此,我们以典型的语言模型(language model)为例,了解一下上述优化策略的实际效果。

 

6.1 LSTM language model原理介绍

飞桨提供了论文《Recurrent Neural Network Regularization》中基于LSTM循环神经网络(RNN)的language model的开源实现。相比于传统的语言模型方法,基于循环神经网络的语言模型方法能够更好地解决稀疏词的问题。

 

该模型的目的是给定一个输入的词序列,预测下一个词出现的概率。

 

模型中采用了序列任务常用的RNN网络,实现了一个两层的LSTM网络,然后使用LSTM的结果去预测下一个词出现的概率。由于数据的特殊性,每一个batch的last hidden和lastcell会作为下一个batch的init hidden和init cell。

6.2 language_model单GPU训练性能优化效果

language_model中提供了4种RNN运行模式,分别为:static、padding、cudnn和lstm_basic。本案例中测试的为static模式。language_model中同样提供了small、medium、large三种模型配置,主要差别在于隐层的大小、RNN的步数、dropout比例上。我们对这个案例在模型配置、执行选项和数据读取三个方面都进行了优化,我们依次测试了如下优化版本的结果:

 

(1)Baseline版本

(2)设置exec_strategy.num_threads = device_count

(3)设置exec_strategy.num_iteration_per_drop_scope = 100

(4)设置build_strategy.enable_inplace = True,build_strategy.memory_optimize = False

(5)设置build_strategy.fuse_all_optimizer_ops = True

(6)使用py_reader进行异步数据读取

(7)配置优化

  •  reshape中设置inplace=True

  • 使用split操作代替多次slice

优化前:

for index in range(len):
input = layers.slice(input_embedding, axes=[1], starts=[index],ends=[index + 1])

优化后:

sliced_inputs = layers.split(input_embedding,num_or_ps=len, dim=1)
for index in range(len):
input = sliced_inputs[index]

  • 减少reshape的次数

优化前:

for index in range(len):…
res.append(layers.reshape(input, shape=[1, -1,hidden_size]))real_res = layers.concat(res, 0)real_res = layers.transpose(x=real_res, perm=[1, 0, 2])
优化后:
for index in range(len):…
res.append(input)real_res = layers.concat(res, 0)real_res = layers.reshape(real_res, shape=[len, -1, hidden_size],inplace=True)real_res = layers.transpose(x=real_res,perm=[1, 0, 2])

经过7个版本的优化,small和large模型最终分别获得了1.64x和1.35x的加速。从实验结果可以看出,即使是类似的网络结构,调整运行参数产生加速效果也不同,如设置exec_strategy.num_threads = device_count,small模型获得了4.9%的加速,large模型只获得0.8%的加速。另外,异步数据读取对该模型总体训练时间的减少也不明显,主要是因为这个模型的所使用的PTB数据集很小,可以提前将所有数据读取到内存里,因此训练时,数据准备部分对整体时延的影响较小。

 

如果有兴趣的同学,可以加入官方QQ群,您将遇上大批志同道合的深度学习同学。官方QQ群:432676488。

如果您想详细了解更多飞桨PaddlePaddle的相关内容,请点击阅读原文或参阅以下文档。

官网地址:https://www.paddlepaddle.org.cn?fr=gzh

本文提到的项目地址:

  • DeepLabV3+:

    https://github.com/PaddlePaddle/models/tree/v1.5/PaddleCV/deeplabv3%2B

  • YOLOv3:

    https://github.com/PaddlePaddle/models/tree/v1.5/PaddleCV/yolov3

  • BERT:

    https://github.com/PaddlePaddle/ERNIE

  • Mask-RCNN:

    https://github.com/PaddlePaddle/models/tree/v1.5/PaddleCV/rcnn

  • CycleGAN:

    https://github.com/PaddlePaddle/models/tree/v1.5/PaddleCV/PaddleGAN/cycle_gan

  • SE-ResNeXt50:

    https://github.com/PaddlePaddle/models/tree/v1.5/PaddleCV/image_classification

  • Transformer:

    https://github.com/PaddlePaddle/models/tree/v1.5/PaddleNLP/models/neural_machine_translation/transformer

最后给大家推荐一个GPU福利 - Tesla V100免费算力!配合PaddleHub能让模型原地起飞~ 扫码下方二维码申请~



推荐阅读
  • 本文提供了PyTorch框架中常用的预训练模型的下载链接及详细使用指南,涵盖ResNet、Inception、DenseNet、AlexNet、VGGNet等六大分类模型。每种模型的预训练参数均经过精心调优,适用于多种计算机视觉任务。文章不仅介绍了模型的下载方式,还详细说明了如何在实际项目中高效地加载和使用这些模型,为开发者提供全面的技术支持。 ... [详细]
  • 在Windows系统中安装TensorFlow GPU版的详细指南与常见问题解决
    在Windows系统中安装TensorFlow GPU版是许多深度学习初学者面临的挑战。本文详细介绍了安装过程中的每一个步骤,并针对常见的问题提供了有效的解决方案。通过本文的指导,读者可以顺利地完成安装并避免常见的陷阱。 ... [详细]
  • TensorFlow基础知识深化讲解
    批标准化批标准化(batchnormalization,BN)是为了克服神经网络层数加深导致难以训练而诞生的。深度神经网络随着深度加深,收 ... [详细]
  • 中文分词_中文分词技术小结几大分词引擎的介绍与比较
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了中文分词技术小结几大分词引擎的介绍与比较相关的知识,希望对你有一定的参考价值。笔者想说:觉得英文与中文分词有很大的区别, ... [详细]
  • CCF 100w+奖池大赛启动!百度高级工程师带你玩转NLP 、CV赛题!
    2021年大数据与AI领域年度盛事——第九届CCF大数据与计算智能大赛已开赛近一个月,你的队伍是否已荣登top榜!百度发布NLP领域“千言-问题匹配鲁棒 ... [详细]
  • 最详尽的4K技术科普
    什么是4K?4K是一个分辨率的范畴,即40962160的像素分辨率,一般用于专业设备居多,目前家庭用的设备,如 ... [详细]
  • 在Conda环境中高效配置并安装PyTorch和TensorFlow GPU版的方法如下:首先,创建一个新的Conda环境以避免与基础环境发生冲突,例如使用 `conda create -n pytorch_gpu python=3.7` 命令。接着,激活该环境,确保所有依赖项都正确安装。此外,建议在安装过程中指定CUDA版本,以确保与GPU兼容性。通过这些步骤,可以确保PyTorch和TensorFlow GPU版的顺利安装和运行。 ... [详细]
  • 【图像分类实战】利用DenseNet在PyTorch中实现秃头识别
    本文详细介绍了如何使用DenseNet模型在PyTorch框架下实现秃头识别。首先,文章概述了项目所需的库和全局参数设置。接着,对图像进行预处理并读取数据集。随后,构建并配置DenseNet模型,设置训练和验证流程。最后,通过测试阶段验证模型性能,并提供了完整的代码实现。本文不仅涵盖了技术细节,还提供了实用的操作指南,适合初学者和有经验的研究人员参考。 ... [详细]
  • 在过去,我曾使用过自建MySQL服务器中的MyISAM和InnoDB存储引擎(也曾尝试过Memory引擎)。今年初,我开始转向阿里云的关系型数据库服务,并深入研究了其高效的压缩存储引擎TokuDB。TokuDB在数据压缩和处理大规模数据集方面表现出色,显著提升了存储效率和查询性能。通过实际应用,我发现TokuDB不仅能够有效减少存储成本,还能显著提高数据处理速度,特别适用于高并发和大数据量的场景。 ... [详细]
  • 深入解析经典卷积神经网络及其实现代码
    深入解析经典卷积神经网络及其实现代码 ... [详细]
  • 本文深入探讨了数据库性能优化与管理策略,通过实例分析和理论研究,详细阐述了如何有效提升数据库系统的响应速度和处理能力。文章首先介绍了数据库性能优化的基本原则和常用技术,包括索引优化、查询优化和存储管理等。接着,结合实际应用场景,讨论了如何利用容器化技术(如Docker)来部署和管理数据库,以提高系统的可扩展性和稳定性。最后,文章还提供了具体的配置示例和最佳实践,帮助读者在实际工作中更好地应用这些策略。 ... [详细]
  • 利用PaddleSharp模块在C#中实现图像文字识别功能测试
    PaddleSharp 是 PaddleInferenceCAPI 的 C# 封装库,适用于 Windows (x64)、NVIDIA GPU 和 Linux (Ubuntu 20.04) 等平台。本文详细介绍了如何使用 PaddleSharp 在 C# 环境中实现图像文字识别功能,并进行了全面的功能测试,验证了其在多种硬件配置下的稳定性和准确性。 ... [详细]
  • TensorFlow中文社区—下载与安装 转自:http:www.tensorfly.cntfdocget_startedos_setup.html下载与安装你可以使用我们提供的二 ... [详细]
  • 如何在jieba分词中加自定义词典_常见中文分词包比较
    1jiebajieba.cut方法接受三个输入参数:需要分词的字符串;cut_all参数用来控制是否采用全模式;HMM参数用来控制是否使用HMM模型ji ... [详细]
  • 快加入「我的最爱」吧 Python 开发者不容错过的30 个Github 开源专案(上)
    愈来愈多人使用Python来进行不同的功能,例如进行机器学习等。如果想透过Python使用这些功能,可以在GitHub上找开源专题。以下介绍在GitHu ... [详细]
author-avatar
Linda--林琳
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有