视觉项目必须知道的 8 个深度学习工具

本文详细介绍了深度学习工具的重要性,涵盖了TensorFlow、PyTorch、OpenCV、CUDA、CVAT、OpenVino和WeightsandBiases等工具,阐述了它们在计算机视觉和机器学习中的应用和优势,以及它们在MLOps中的角色。
摘要由CSDN通过智能技术生成

在这里插入图片描述

介绍

深度学习工具广泛用于大多数行业的视觉应用,从移动设备上的面部识别到特斯拉的自动驾驶汽车。但是,在处理这些应用程序时,使用正确的工具至关重要,因为它需要深入的知识和专业知识。

阅读本文后,您将了解什么是深度学习工具,为什么使用它们,并探索您可以在项目和应用程序中使用的最常见类型。

什么是深度学习工具?

通常,深度学习模型是在数百甚至数千个图像、视频或其他数字媒体上训练的。但是,这些数据可能是大量和非结构化的。为了以结构化的方式对这些复杂的数据进行排序,我们使用了深度学习工具。
这些工具在分析和处理视觉数据以及从中获取有意义的信息方面发挥着关键作用。这些深度学习工具的核心是使用来自机器学习、人工智能、模式识别和数字信号处理的复杂算法。计算能力的进步、算法和神经网络架构的优化以及大型数据集的可用性推动了对深度学习工具的需求。

必须知道的深度学习工具

有几种工具可用于处理计算机视觉中的图像和视频。在本节中,我们将讨论一些最常见的深度学习工具。它们的复杂性和应用领域各不相同。它们可以是用于执行基本图像处理操作的简单库,也可以是用于识别对象、理解场景或识别面部识别的更高级系统。

TensorFlow (张量流)

TensorFlow 是一个用于数值计算、统计和预测分析以及大规模深度学习的开源库。它由 Google 于 2015 年在 Apache 2.0 许可下发布。DistBelief 是一个闭源的 Google 框架,是 TensorFlow 的前身。它为深度学习实现提供了一个测试平台。Google 的一些应用程序和在线服务由 TensorFlow 及其第一个 TPU(张量处理单元)提供支持。在撰写本文时,TensorFlow 2.15 是最新版本,于 2024 年发布。
顶级深度学习工具 TensorFlow

它是深度学习项目最流行的框架之一。与其他用于深度学习的数值库不同,TensorFlow 专为研究和开发而设计。

借助 TensorFlow,开发人员可以创建数据流图。这些结构描述了数据如何在图形或一系列节点中移动。每个节点代表一个数学运算,两个节点之间的连接是一个多维数据数组或张量。Tensor 可以定义为可用于存储、表示或更改数据的容器。

附带说明:由于张量是框架的一个组成部分,因此 Google 的框架称为 TensorFlow。

TensorFlow 可以训练和运行深度神经网络,用于图像识别、单词嵌入、手写数字分类、图像分割、对象检测等任务。尽管 TensorFlow 使用 Python 作为前端 API 来构建应用程序,但与 OpenCV 非常相似,我们可以在 C++ 或 Java 等不同语言中使用该框架。因此,无论使用何种语言或平台,都可以快速训练和部署深度学习模型。

TensorFlow 包括高级和低级 API。Google 建议使用低级 API 来调试应用程序,而高级 API 则有利于简化数据管道开发和应用程序编程。
TensorFlow 在数据科学和机器学习市场中占有最高份额,为 37.28%,其次是 OpenCV。有近 22,000 个品牌在使用 TensorFlow,我们可以说它是最常用的深度学习工具之一,掌握它对于在计算机视觉领域保持相关性至关重要。

PyTorch

PyTorch 是深度学习框架领域的另一个大牌。它是一个开源的深度学习库,用于开发和训练基于神经网络的模型。早在 2002 年,它就由少数人正式推出,是最早的框架之一,后来被 Facebook 的研究实验室采纳,并于 2016 年以 PyTorch 的形式推出。它主要是为了以更准确和高效的方式训练和实现深度学习模型而开发的。PyTorch 于 2018 年与另一个 Python 框架 Caffe2 合并。
PyTorch,深度学习工具

PyTorch 使用 Python API 在 C++ 中开发,更易于理解,这意味着开发人员可以使用此框架比其他深度学习框架更舒服。由于它与 Python 的深度集成,我们还可以使用各种 Python 调试工具。此外,PyTorch 的文档井井有条,对新手来说很方便。这使得它适合学术和研究目的。

与利用计算图的 TensorFlow 等同类产品不同,PyTorch 使用动态计算,从而在构建复杂架构时具有更大的灵活性。这意味着可以在运行时更改特征,并且梯度计算也会随之动态变化。它使用反向模式自动微分。简单地说,它是磁带录音机的一种形式,记录所有操作,然后向后重放以计算梯度。这使得调试和适应某些应用变得容易,使其在原型设计中很受欢迎。PyTorch 位居榜首,TensorFlow 和 OpenCV 以 21.39% 的份额位居第三。近 13,000 个品牌都在使用 PyTorch,它是他们武器库中必须拥有的另一个重要的深度学习工具。

OpenCV

深度学习工具列表中的下一个是 OpenCV,它是最大的开源计算机视觉库之一。OpenCV 于 1999 年正式推出,最初是英特尔研究院的一部分,用于高级 CPU 密集型应用程序。它的一些主要目标包括为

  1. 开发人员提供通用基础架构,使其具有更易于阅读和可转移的代码
  2. 不仅为基础视觉基础设施提供开放代码,还提供优化代码
  3. 为基于视觉的高级商业应用提供免费的性能优化代码

OpenCV最初是用C++编写的,作为其主要接口。包装器库有多种语言版本,以鼓励更广泛的受众使用它们,最常见的是 Python Wrapper,通常称为 OpenCV-Python。
在这里插入图片描述

它拥有超过 2,500 种优化算法,包括经典和最先进的计算机视觉和机器学习算法。这些算法可用于广泛的任务,如物体识别和检测、人脸检测或跟踪相机运动。谷歌、Microsoft、英特尔和雅虎等科技巨头广泛使用 OpenCV 库。

它支持 Windows、Linux、Mac OS 和 Android,并提供 C++、Python、Java 和 MATLAB 接口。
超过 13,000 个品牌将 OpenCV 用作数据科学和机器学习工具,下载量超过 1800 万次,它是最常用的深度学习工具之一,在数据科学和机器学习市场占有 21.68% 的市场份额。

CUDA

计算统一设备架构 (CUDA) 是一种高级语言,用于编写在 NVIDIA GPU 上并行运行的代码。CUDA 增强了图形处理单元或 GPU,并基于 C/C++。我们可以使用带有 CUDA 的 GPU 编写和执行代码。NVIDIA 于 2006 年推出了 CUDA,作为并行计算平台,并作为增强 NVIDIA GPU 中已有的并行计算引擎的模型。与 CPU 相比,它能更有效地解决复杂的计算挑战。这是因为 GPU 的 ALU(算术逻辑单元)比 CPU 小,使它们能够同时处理多个并行计算,而不是一个。
最佳深度学习工具,NVIDIA CUDA

此外,CUDA 还提供 C、C++ 和 Fortran 版本,因此开发人员可以更轻松地实现并行编程。我们需要做的就是为这些语言添加一些基本关键字,以访问 GPU 的虚拟指令集和并行计算元素。

2003 年,斯坦福大学的一组研究人员最初将 CUDA 开发为通用编程平台。NVIDIA 当时资助了 CUDA,首席研究员随后转到 NVIDIA 开发 CUDA 作为基于 GPU 的商业并行计算项目。

但是,深度学习对CUDA的需求是什么?

众所周知,在训练和构建深度学习模型方面,GPU 是最重要的硬件之一。GPU 专为高速并行计算而设计。为了将这些快速计算付诸实践,GPU 需要 CUDA。

CUDA 是免费的,易于使用,可用于各种操作系统,如 Windows 和 Linux。它还提供了广泛的并行计算库,并且比 OpenCL 等竞争产品快得多.CUDA 拥有超过 4000 万的下载量和超过 400 万的开发人员,是计算机视觉和深度学习中 GPU 加速的首选平台,也是计算机视觉工程师必须知道的深度学习工具。

CVAT系列

计算机视觉注释工具(CVAT)是一个免费的开源平台,用于为机器学习和深度学习项目注释图像和视频。它支持不同的注释,如多边形、关键点和边界框。理想情况下,CVAT部署在大型项目的云平台上,并本地安装用于个人或小型项目。

CVAT

CVAT 最初由英特尔于 2017 年推出,专为内部使用而开发,旨在为数千张图像的大规模图像注释提供更好的方法。CVAT现在是一个位于美国加利福尼亚州的独立品牌。

视觉工程师和数据科学家严重依赖大量注释数据来训练深度神经网络。但是要获得这些带注释的图像,需要数千小时。

CVAT 加快了此注释过程,并减少了耗时。它提供自动标记和半自动图像注释,以加快注释过程并加快注释服务。

大型企业利用 CVAT 进行图像注释,并将其与用于 DevOps、应用程序开发或运营的工具相结合。

使用 CVAT 非常简单

将图片或视频上传到平台
选择我们想要注释的图像或视频
选择我们希望使用的工具,比如关键点
将注释精确地应用于感兴趣的对象
保存注释并对剩余数据重复上述步骤
有兴趣探索CVAT吗?在 YouTube 上查看完整的 CVAT 视频系列。
CVAT 是一种安全、维护良好的数据注释工具,具有频繁的更新和积极的社区支持。它是一款功能强大且用途广泛的图像注释工具,提供各种注释类型和灵活性。这是一个很好的深度学习工具,可以简化 AI 数据标记项目或优化图像注释。

OpenVino

OpenVino 由英特尔于 2018 年开发,是一款开源工具包,旨在优化神经网络推理,加速跨英特尔硬件(如 CPU 和 GPU)部署深度学习应用程序。它支持各种开箱即用的深度学习模型,并为使用计算机视觉、自然语言处理 (NLP) 或语音识别的应用程序提供功能。通过利用 Fusion 和 Frozen 等高级优化技术,OpenVINO 增强了 AI 工作负载,包括音频和推荐系统,使模型更小、更快。深度学习工具,英特尔 OpenVino

该工具包简化了模型优化,以确保最佳执行,解决了在计算机视觉算法中实现高精度的挑战,这需要硬件和计算方法的调整。OpenVINO 的预定函数库和预先优化的内核,以及简化的中间表示,通过在不同的处理器和加速器之间有效地分配工作负载来加速 AI 工作负载和上市时间。

开发人员可以使用与应用程序逻辑集成的高级 C++ 推理引擎 API 部署预训练的深度学习模型,从而实现 AI 工作负载的无缝定制和扩展到云。OpenVINO 还有助于深度学习模型层的定制和不同加速器的并行编程,而无需通过 OpenCL 内核等工具增加框架开销,从而将自定义代码直接集成到工作负载管道中。

借助深度学习部署工具包,OpenVINO 不仅可以在计算机视觉之外运行深度学习模型,还可以从不同的框架导入和优化模型,从而在不同的硬件上实现视觉推理。这种全面的方法确保了提高性能,并为开发人员提供了一条简化的途径,使他们能够更有效地将 AI 驱动的应用程序推向市场。

OpenVINO 提供了一个强大的工具包,用于跨多个硬件平台优化和加速深度学习模型,帮助开发人员更快、更高效地部署 AI 应用程序。除了支持广泛的 AI 工作负载外,它还具有可定制性,使其成为推进人工智能的有效解决方案。

TensorRT

TensorRT 是一个机器学习框架,用于在硬件上运行推理。它由 NVIDIA 开发,基于 CUDA 并行编程模型构建,推理速度比基线模型快约 5 倍。
英伟达 Tensorrt
TensroRT 基于从深度学习系统或知识库中学到的算法进行推理。TensorRT 中的推理引擎负责编译和运行时。
在这里插入图片描述

编译是指将模型优化并转换为 TensorRT 引擎的过程。这是通过模型解析、层和张量融合或精度校准等过程完成的。

运行时正在执行优化的 TensorRT 引擎来执行推理。这包括加载模型、分配 GPU、执行快速预测和收集输出。

TensorRT 通过一系列复杂的过程来优化深度学习模型。在初始阶段,TensorRT 解析来自各种框架(如 TensorFlow、PyTorch 和 ONNX)的训练模型。优化用于 GPU 的表示涉及几种关键技术。

层和张量融合

通过将操作和层相结合,TensorRT 可以减少操作之间的内存访问需求,从而减少延迟并提高吞吐量。

精密校准

在 TensorRT 中,支持混合精度计算,这意味着可以使用较低精度的算术进行计算(FP16 或 INT8),而不会显着影响模型的准确性。精密校准用于通过仔细选择每个操作的精度来实现这一点,以最大限度地减少内存消耗和计算需求,同时保持整体模型精度。

内核自动调优

使用 TensorRT 的内核自动调优功能,TensorRT 根据模型的具体架构和 GPU 硬件目标,基于对各种实现进行基准测试,确定最快的执行路径。

TensorRT GPU 可以在多个 GPU 之间分配工作负载,也可以在单个 GPU 内的多个流之间分配工作负载,以用于需要同时处理多个数据流的应用程序。由于这种并行执行功能,大规模部署可以从可扩展的性能改进中受益。

TensorRT 还提供了用于分析和分析模型性能的综合工具。工程师可以深入了解模型中每个层或操作的执行时间、内存使用情况和吞吐量。这种级别的分析对于识别瓶颈和进一步优化模型性能非常宝贵。

Weights and Biases

Weights and Biases 是一种 MLOps 开发人员工具,可从头到尾简化机器学习工作流。如果需要,可以在框架、环境或工作流中使用权重和偏差,以帮助开发人员优化、可视化或标准化他们的模型。

提供了多种功能,包括交互式数据可视化、超参数优化和实验跟踪,以及实时 CPU 和 GPU 监控,可实时可视化数据集、日志和过程统计信息。

权重和偏差,顶级深度学习工具
该平台可免费用于个人或学术目的。使用托管笔记本,只需 30 秒即可运行第一个实验。

它广泛用于深度学习领域,用于几个关键目的。

实验跟踪

权重和偏差使用户能够记录超参数和输出指标,以便他们可以在运行之间比较他们的模型。这有助于确定哪些更改提高了模型性能并一致地重现实验。

可视化

借助该平台,您可以可视化训练周期中的损失和准确率曲线等指标,这对于诊断模型性能至关重要。除了混淆矩阵和 ROC 曲线外,它还支持用于分析模型输出的原始图像。

数据版本控制

此功能有助于跟踪用于训练特定模型的数据版本,确保可重复性,对于数据随时间变化的机器学习工作流非常重要。

模型保存和共享

W&B 允许用户将其模型检查点直接保存到应用程序中。这允许来自不同位置的团队成员进行协作和共享。

超参数优化

W&B提供的超参数优化工具允许用户自动搜索最佳模型配置,从而在手动调整参数时节省时间和资源。

与深度学习框架集成

权重和偏差允许开发人员以对现有代码库进行最小的更改来跟踪他们的实验,因为 W&B 与框架无关,与流行的深度学习框架(如 TensorFlow、PyTorch、Keras 等)集成。

协作和报告

该平台允许团队成员轻松分享结果和见解,从而促进他们之间的协作。它还使利益相关者能够生成可与其他利益相关者共享的报告。
权重和偏差是很好的深度学习工具,允许开发人员逐步构建和简化深度学习工作流程,并提高整体生产力。

结论

我们探索了什么是深度学习工具,阐明了基础知识,并检查了该领域最常用的一些工具,例如最大的开源计算机视觉库 OpenCV 和图像注释工具 CVAT。

深度学习工具包 Deprecation notice. ----- This toolbox is outdated and no longer maintained. There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/) I would suggest you use one of the tools mentioned above rather than use this toolbox. Best, Rasmus. DeepLearnToolbox ================ A Matlab toolbox for Deep Learning. Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data. It is inspired by the human brain's apparent deep (layered, hierarchical) architecture. A good overview of the theory of Deep Learning theory is [Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf) For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng. * [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007) * [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010) * [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011) If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284) ``` @MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012", } ``` Contact: rasmusbergpalm at gmail dot com Directories included in the toolbox ----------------------------------- `NN/` - A library for Feedforward Backpropagation Neural Networks `CNN/` - A library for Convolutional Neural Networks `DBN/` - A library for Deep Belief Networks `SAE/` - A library for Stacked Auto-Encoders `CAE/` - A library for Convolutional Auto-Encoders `util/` - Utility functions used by the libraries `data/` - Data used by the examples `tests/` - unit tests to verify toolbox is working For references on each library check REFS.md Setup ----- 1. Download. 2. addpath(genpath('DeepLearnToolbox')); Example: Deep Belief Network --------------------- ```matlab function test_example_DBN load mnist_uint8; train_x = double(train_x) / 255; test_x = double(test_x) / 255; train_y = double(train_y); test_y = double(test_y); %% ex1 train a 100 hidden unit RBM and visualize its weights rand('state',0) dbn.sizes = [100]; opts.numepochs = 1; opts.batchsize = 100; opts.momentum = 0; opts.alpha = 1; dbn = dbnsetup(dbn, train_x, opts); dbn = dbntrain(dbn, train_x, opts); figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights %% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NN rand('state',0) %train dbn dbn.sizes = [100 100]; opts.numepochs = 1; opts.batchsize = 100; opts.momentum = 0; opts.alpha = 1; dbn = dbnsetup(dbn, train_x, opts); dbn = dbntrain(dbn, train_x, opts); %unfold dbn to nn nn = dbnunfoldtonn(dbn, 10); nn.activation_function = 'sigm'; %train nn opts.numepochs = 1; opts.batchsize = 100; nn = nntrain(nn, train_x, train_y, opts); [er, bad] = nntest(nn, test_x, test_y); assert(er < 0.10, 'Too big error'); ``` Example: Stacked Auto-Encoders --------------------- ```matlab function test_example_SAE load mnist_uint8; train_x = double(train_x)/255; test_x = double(test_x)/255; train_y = double(train_y); test_y = double(test_y); %% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN % Setup and train a stacked denoising autoencoder (SDAE) rand('state',0) sae = saesetup([784 100]); sae.ae{1}.activation_function = 'sigm'; sae.ae{1}.learningRate = 1; sae.ae{1}.inputZeroMaskedFraction = 0.5; opts.numepochs = 1; opts.batchsize = 100; sae = saetrain(sae, train_x, opts); visualize(sae.ae{1}.W{1}(:,2:end)') % Use the SDAE to initialize a FFNN nn = nnsetup([784 100 10]); nn.activation_function = 'sigm'; nn.learningRate = 1; nn.W{1} = sae.ae{1}.W{1}; % Train the FFNN opts.numepochs = 1; opts.batchsize = 100; nn = nntrain(nn, train_x, train_y, opts); [er, bad] = nntest(nn, test_x, test_y); assert(er < 0.16, 'Too big error'); ``` Example: Convolutional Neural Nets --------------------- ```matlab function test_example_CNN load mnist_uint8; train_x = double(reshape(train_x',28,28,60000))/255; test_x = double(reshape(test_x',28,28,10000))/255; train_y = double(train_y'); test_y = double(test_y'); %% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% error rand('state',0) cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer }; cnn = cnnsetup(cnn, train_x, train_y); opts.alpha = 1; opts.batchsize = 50; opts.numepochs = 1; cnn = cnntrain(cnn, train_x, train_y, opts); [er, bad] = cnntest(cnn, test_x, test_y); %plot mean squared error figure; plot(cnn.rL); assert(er<0.12, 'Too big error'); ``` Example: Neural Networks --------------------- ```matlab function test_example_NN load mnist_uint8; train_x = double(train_x) / 255; test_x = double(test_x) / 255; train_y = double(train_y); test_y = double(test_y); % normalize [train_x, mu, sigma] = zscore(train_x); test_x = normalize(test_x, mu, sigma); %% ex1 vanilla neural net rand('state',0) nn = nnsetup([784 100 10]); opts.numepochs = 1; % Number of full sweeps through data opts.batchsize = 100; % Take a mean gradient step over this many samples [nn, L] = nntrain(nn, train_x, train_y, opts); [er, bad] = nntest(nn, test_x, test_y); assert(er < 0.08, 'Too big error'); %% ex2 neural net with L2 weight decay rand('state',0) nn = nnsetup([784 100 10]); nn.weightPenaltyL2 = 1e-4; % L2 weight decay opts.numepochs = 1; % Number of full sweeps through data opts.batchsize = 100; % Take a mean gradient step over this many samples nn = nntrain(nn, train_x, train_y, opts); [er, bad] = nntest(nn, test_x, test_y); assert(er < 0.1, 'Too big error'); %% ex3 neural net with dropout rand('state',0) nn = nnsetup([784 100 10]); nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through data opts.batchsize = 100; % Take a mean gradient step over this many samples nn = nntrain(nn, train_x, train_y, opts); [er, bad] = nntest(nn, test_x, test_y); assert(er < 0.1, 'Too big error'); %% ex4 neural net with sigmoid activation function rand('state',0) nn = nnsetup([784 100 10]); nn.activation_function = 'sigm'; % Sigmoid activation function nn.learningRate = 1; % Sigm require a lower learning rate opts.numepochs = 1; % Number of full sweeps through data opts.batchsize = 100; % Take a mean gradient step over this many samples nn = nntrain(nn, train_x, train_y, opts); [er, bad] = nntest(nn, test_x, test_y); assert(er < 0.1, 'Too big error'); %% ex5 plotting functionality rand('state',0) nn = nnsetup([784 20 10]); opts.numepochs = 5; % Number of full sweeps through data nn.output = 'softmax'; % use softmax output opts.batchsize = 1000; % Take a mean gradient step over this many samples opts.plot = 1; % enable plotting nn = nntrain(nn, train_x, train_y, opts); [er, bad] = nntest(nn, test_x, test_y); assert(er < 0.1, 'Too big error'); %% ex6 neural net with sigmoid activation and plotting of validation and training error % split training data into training and validation data vx = train_x(1:10000,:); tx = train_x(10001:end,:); vy = train_y(1:10000,:); ty = train_y(10001:end,:); rand('state',0) nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax output opts.numepochs = 5; % Number of full sweeps through data opts.batchsize = 1000; % Take a mean gradient step over this many samples opts.plot = 1; % enable plotting nn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally) [er, bad] = nntest(nn, test_x, test_y); assert(er < 0.1, 'Too big error'); ``` [![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值