How to train your Deep Neural Network(如何训练你的深度神经网络)

Distilling the Knowledge in a Neural Network 神经网络中的知识蒸馏 提高几乎任何机器学习算法性能的一种非常简单的方法是,在相同数据上训练许多不同的模型,然后对它们的预测结果取平均值[3]。遗憾的是,使用整个模型集成进行预测较为繁琐,并目计算成本可能过高,难以部署给大量用户,尤其是在各个模型都是大型神经网络时。Caruana及其合作者[1]已表明,可以将一个集成中的知识压缩到单个模型中,从而使其更易于部署;我们使用一种不同的压缩技术进一步发展了这种方法。 阅读详情

There are certain practices in Deep Learning that are highly recommended, in order to efficiently train Deep Neural Networks. In this post, I will be covering a few of these most commonly used practices, ranging from importance of quality training data, choice of hyperparameters to more general tips for faster prototyping of DNNs. Most of these practices, are validated by the research in academia and industry and are presented with mathematical and experimental proofs in research papers like Efficient BackProp(Yann LeCun et al.) and Practical Recommendations for Deep Architectures(Yoshua Bengio).
As you’ll notice, I haven’t mentioned any mathematical proofs in this post. All the points suggested here, should be taken more of a summarization of the best practices for training DNNs. For more in-depth understanding, I highly recommend you to go through the above mentioned research papers and references provided at the end.

Training data
A lot of ML practitioners are habitual of throwing raw training data in any Deep Neural Net(DNN). And why not, any DNN would(presumably) still give good results, right? But, it’s not completely old school to say that - “given the right type of data, a fairly simple model will provide better and faster results than a complex DNN”(although, this might have exceptions). So, whether you are working with Computer Vision, Natural Language Processing, Statistical Modelling, etc. try to preprocess your raw data. A few measures one can take to get better training data:
Get your hands on as large a dataset as possible(DNNs are quite data-hungry: more is better)
Remove any training sample with corrupted data(short texts, highly distorted images, spurious output labels, features with lots of null values, etc.)
Data Augmentation - create new examples(in case of images - rescale, add noise, etc.)
Choose appropriate activation functions
One of the vital components of any Neural Net are activation functions. Activations introduces the much desired non-linearity into the model. For years, sigmoid activation functions have been the preferable choice. But, a sigmoid function is inherently cursed by these two drawbacks - 1. Saturation of sigmoids at tails(further causing vanishing gradient problem). 2. sigmoids are not zero-centered.
A better alternative is a tanh function - mathematically, tanh is just a rescaled and shifted sigmoid, tanh(x) = 2*sigmoid(x) - 1. Although tanh can still suffer from the vanishing gradient problem, but the good news is - tanh is zero-centered. Hence, using tanh as activation function will result into faster convergence. I have found that using tanh as activations generally works better than sigmoid.
You can further explore other alternatives like ReLU, SoftSign, etc. depending on the specific task, which have shown to ameliorate some of these issues.
Number of Hidden Units and Layers
Keeping a larger number of hidden units than the optimal number, is generally a safe bet. Since, any regularization method will take care of superfluous units, at least to some extent. On the other hand, while keeping smaller numbers of hidden units(than the optimal number), there are higher chances of underfitting the model.
Also, while employing unsupervised pre-trained representations(describe in later sections), the optimal number of hidden units are generally kept even larger. Since, pre-trained representation might contain a lot of irrelevant information in these representations(for the specific supervised task). By increasing the number of hidden units, model will have the required flexibility to filter out the most appropriate information out of these pre-trained representations.
Selecting the optimal number of layers is relatively straight forward. As @Yoshua-Bengio mentioned on Quora - “You just keep on adding layers, until the test error doesn’t improve anymore”. ;)
Weight Initialization
Always initialize the weights with small random numbers to break the symmetry between different units. But how small should weights be? What’s the recommended upper limit? What probability distribution to use for generating random numbers? Furthermore, while using sigmoid activation functions, if weights are initialized to very large numbers, then the sigmoid will saturate(tail regions), resulting into dead neurons. If weights are very small, then gradients will also be small. Therefore, it’s preferable to choose weights in an intermediate range, such that these are distributed evenly around a mean value.
Thankfully, there has been lot of research regarding the appropriate values of initial weights, which is really important for an efficient convergence. To initialize the weights that are evenly distributed, a uniform distribution is probably one of the best choice. Furthermore, as shown in the paper(Glorot and Bengio, 2010), units with more incoming connections(fan_in) should have relatively smaller weights.
Thanks to all these thorough experiments, now we have a tested formula that we can directly use for weight initialization; i.e. - weights drawn from ~ Uniform(-r, r) where r=sqrt(6/(fan_in+fan_out)) for tanh activations, and r=4*(sqrt(6/fan_in+fan_out)) for sigmoid activations, where fan_in is the size of the previous layer and fan_out is the size of next layer.
Learning Rates
This is probably one of the most important hyperparameter, governing the learning process. Set the learning rate too small and your model might take ages to converge, make it too large and within initial few training examples, your loss might shoot up to sky. Generally, a learning rate of 0.01 is a safe bet, but this shouldn’t be taken as a stringent rule; since the optimal learning rate should be in accordance to the specific task.
In contrast to, a fixed learning rate, gradually decreasing the learning rate, after each epoch or after a few thousand examples is another option. Although this might help in faster training, but requires another manual decision about the new learning rates. Generally, learning rate can be halved after each epoch - these kinds of strategies were quite common a few years back.
Fortunately, now we have better momentum based methods to change the learning rate, based on the curvature of the error function. It might also help to set different learning rates for individual parameters in the model; since, some parameters might be learning at a relatively slower or faster rate.
Lately, there has been a good amount of research on optimization methods, resulting into adaptive learning rates. At this moment, we have numerous options starting from good old Momentum Method to Adagrad, Adam(personal favourite ;)), RMSProp etc. Methods like Adagrad or Adam, effectively save us from manually choosing an initial learning rate, and given the right amount of time, the model will start to converge quite smoothly(of course, still selecting a good initial rate will further help).
Hyperparameter Tuning: Shun Grid Search - Embrace Random Search
Grid Search has been prevalent in classical machine learning. But, Grid Search is not at all efficient in finding optimal hyperparameters for DNNs. Primarily, because of the time taken by a DNN in trying out different hyperparameter combinations. As the number of hyperparameters keeps on increasing, computation required for Grid Search also increases exponentially.
There are two ways to go about it:
Based on your prior experience, you can manually tune some common hyperparameters like learning rate, number of layers, etc.
Instead of Grid Search, use Random Search/Random Sampling for choosing optimal hyperparameters. A combination of hyperparameters is generally choosen from a uniform distribution within the desired range. It is also possible to add some prior knowledge to further decrease the search space(like learning rate shouldn’t be too large or too small). Random Search has been found to be way more efficient compared to Grid Search.
Learning Methods
Good old Stochastic Gradient Descent might not be as efficient for DNNs(again, not a stringent rule), lately there have been a lot of research to develop more flexible optimization algorithms. For e.g.: Adagrad, Adam, AdaDelta, RMSProp, etc. In addition to providing adaptive learning rates, these sophisticated methods also use different rates for different model parameters and this generally results into a smoother convergence. It’s good to consider these as hyper-parameters and one should always try out a few of these on a subset of training data.
Keep dimensions of weights in the exponential power of 2
Even, when dealing with state-of-the-art Deep Learning Models with latest hardware resources, memory management is still done at the byte level; So, it’s always good to keep the size of your parameters as 64, 128, 512, 1024(all powers of 2). This might help in sharding the matrices, weights, etc. resulting into slight boost in learning efficiency. This becomes even more significant when dealing with GPUs.
Unsupervised Pretraining
Doesn’t matter whether you are working with NLP, Computer Vision, Speech Recognition, etc. Unsupervised Pretraining always help the training of your supervised or other unsupervised models. Word Vectors in NLP are ubiquitous; you can use ImageNet dataset to pretrain your model in an unsupervised manner, for a 2-class supervised classification; or audio samples from a much larger domain to further use that information for a speaker disambiguation model.
Mini-Batch vs. Stochastic Learning
Major objective of training a model is to learn appropriate parameters, that results into an optimal mapping from inputs to outputs. These parameters are tuned with each training sample, irrespective of your decision to use batch, mini-batch or stochastic learning. While employing a stochastic learning approach, gradients of weights are tuned after each training sample, introducing noise into gradients(hence the word ‘stochastic’). This has a very desirable effect; i.e. - with the introduction of noise during the training, the model becomes less prone to overfitting.
However, going through the stochastic learning approach might be relatively less efficient; since now a days machines have far more computation power. Stochastic learning might effectively waste a large portion of this. If we are capable of computing Matrix-Matrix multiplication, then why should we limit ourselves, to iterate through the multiplications of individual pairs of Vectors? Therefore, for greater throughput/faster learning, it’s recommended to use mini-batches instead of stochastic learning.
But, selecting an appropriate batch size is equally important; so that we can still retain some noise(by not using a huge batch) and simultaneously use the computation power of machines more effectively. Commonly, a batch of 16 to 128 examples is a good choice(exponential of 2). Usually, batch size is selected, once you have already found more important hyperparameters(by manual search or random search). Nevertheless, there are scenarios when the model is getting the training data as a stream(online learning), then resorting to Stochastic Learning is a good option.
Shuffling training examples
This comes from Information Theory - “Learning that an unlikely event has occurred is more informative than learning that a likely event has occurred”. Similarly, randomizing the order of training examples(in different epochs, or mini-batches) will result in faster convergence. A slight boost is always noticed when the model doesn’t see a lot of examples in the same order.
Dropout for Regularization
Considering, millions of parameters to be learned, regularization becomes an imperative requisite to prevent overfitting in DNNs. You can keep on using L1/L2 regularization as well, but Dropout is preferable to check overfitting in DNNs. Dropout is trivial to implement and generally results into faster learning. A default value of 0.5 is a good choice, although this depends on the specific task,. If the model is less complex, then a dropout of 0.2 might also suffice.
Dropout should be turned off, during the test phase, and weights should be scaled accordingly, as done in the original paper. Just allow a model with Dropout regularization, a little bit more training time; and the error will surely go down.
Number of Epochs/Training Iterations
“Training a Deep Learning Model for multiple epochs will result in a better model” - we have heard it a couple of times, but how do we quantify “many”? Turns out, there is a simple strategy for this - Just keep on training your model for a fixed amount of examples/epochs, let’s say 20,000 examples or 1 epoch. After each set of these examples compare the test error with train error, if the gap is decreasing, then keep on training. In addition to this, after each such set, save a copy of your model parameters(so that you can choose from multiple models once it is trained).
Visualize
There are a thousand ways in which the training of a deep learning model might go wrong. I guess we have all been there, when the model is being trained for hours or days and only after the training is finished, we realize something went wrong. In order to save yourself from bouts of hysteria, in such situations(which might be quite justified ;)) - always visualize the training process. Most obvious step you can take is to print/save logs of loss values, train error or test error, etc.
In addition to this, another good practice is to use a visualization library to plot histograms of weights after few training examples or between epochs. This might help in keeping track of some of the common problems in Deep Learning Models like Vanishing Gradient, Exploding Gradient etc.
Multi-Core machines, GPUs
Advent of GPUs, libraries that provide vectorized operations, machines with more computation power, are probably some of the most significant factors in the success of Deep Learning. If you think, you are patient as a stone, you might try running a DNN on your laptop(which can’t even open 10 tabs in your Chrome browser) and wait for ages to get your results. Or you can play smart(and expensively :z) and get a descent hardware with at least multiple CPU cores and a few hundred GPU cores. GPUs have revolutionized the Deep Learning research(no wonder Nvidia’s stocks are shooting up ;)), primarily because of their ability to perform Matrix Operations at a larger scale.
So, instead of taking weeks on a normal machine, these parallelization techniques, will bring down the training time to days, if not hours.
Use libraries with GPU and Automatic Differentiation Support
Thankfully, for rapid prototyping we have some really descent libraries like Theano, Tensorflow, Keras, etc. Almost all of these DL libraries provide support for GPU computation and Automatic Differentiation. So, you don’t have to dive into core GPU programming(unless you want to - it’s definitely fun :)); nor you have to write your own differentiation code, which might get a little bit taxing in really complex models(although you should be able to do that, if required). Tensorflow further provides support for training your models on a distributed architecture(if you can afford it).
This is not at all an exhaustive list of practices, to train a DNN. In order to include just the most common practices, I have tried to exclude a few concepts like Normalization of inputs, Batch/Layer Normalization, Gradient Check, etc. Although feel free to add anything in the comment section and I’ll be more than happy to update it in the post. :)
References:
Efficient BackProp(Yann LeCun et al.)
Practical Recommendations for Deep Architectures(Yoshua Bengio)
Understanding the difficulty of training deep feedforward neural networks(Glorot and Bengio, 2010)
Dropout: A Simple Way to Prevent Neural Networks from Overfitting
Andrej Karpathy - Yes you should understand backprop(Medium)

How to Train Your Deep Neural Network——深度神经网络训练详解 作者:禅与计算机程序设计艺术 1.简介 首先,介绍一下自己。我是一名资深的机器学习工程师、数据科学家以及高级技术顾问,目前负责公司的AI产品研发工作。本文从基本概念到具体细节地讲述了深度学习相关的一些知识。通过阅读本文,读者能够了解到如何用最少的计算资源构建一个准确而有效的深度学习模型,并在实际业务场景 阅读详情

相关推荐

How to Train a Deep Neural Network: Architecture and Tr

作者:禅与计算机程序设计艺术 1.简介 最近有不少人都在谈论深度学习领域的最新技术,那么深度学习的前世今生、理论基础、应用场景、实践经验等知识是否能够从头到尾完整地呈现给读者呢?本文将详细介绍深度神经网络(DNN)的发展历史及其理论基础、算法原理,并结合训练策略及实际案例展示如何快速建立起一个有效的深度

AI天才研究院 1607

How to train your neural network?(如何训练你的神经网络)

How To train a Neural Network: 原始文章地址 Gradient check your implementation with a small batch of data and be aware of the pitfalls. As a sanity check, make sure your initial loss is reasonable, and that you can achieve 100% training accuracy on a very small

weixin_43874070的博客 448

deepMOT:如何训练您的深度多对象跟踪器的官方实施

CVPR2020:如何训练您的深度多对象跟踪器 新闻:我们发布了用于训练和测试DeepMOT-Tracktor的代码以及用于训练DHN的代码。 请访问: : 如何训练您的深度多对象跟踪器, ,, , , [] 比比克斯 如果您认为此代码有用,请给项目加注星标并考虑引用: @inproceedings{xu2020train, title={How To Train Your Deep Multi-Object Tracker}, author={Xu, Yihong and Osep, Aljosa and Ban, Yutong and Horaud, Radu and Leal-Taix{\'e}, Laura and Alameda-Pineda, Xavier}, booktitle={Proceedings of the IEEE/CVF Confe

[cv231n] Lecture 6 | Training Neural Networks I (activations)

Lecture 6 | Training Neural Networks I Quick intro It is possible to introduce neural networks without appealing to brain analogies. In the section on linear classification, we computed scores for d...

gdtop的个人笔记 1109

orangepi 5 plus ubuntu24.04上安装redroid

OrangePi 5 Plus运行reDroid云手机方案总结 在RK3588+Ubuntu 24.04上部署reDroid(Android容器化方案)的关键步骤: 内核要求:确保启用binderfs(无需ashmem,新版reDroid使用memfd替代); 安装流程: 安装Docker并配置代理加速镜像拉取; 拉取reDroid镜像(推荐Android 12/13 ARM64版本); 通过挂载binderfs启动容器,指定分辨率与DPI参数; 多实例管理: 脚本化创建多个容器(如8个实例),分配独立端口

babytiger的专栏 2292

STM32L433使用DSP库配置过程

STM32L433中有FPU,在使用中为了使用其中的部分函数,需要对其进行配置。     配置成功后做些总结,留待后续复习备忘,同时也希望有朋友像我一样使用DSP库配置时少走弯路,留作交流。

在在在的博客 4550

一个可微的轨迹训练方法:How To Train Your Deep Multi-Object Tracker

目前的MOT的训练时,大对子模型进行单独使用损失函数训练,并没有关联到评价指标例如MOTA,MOTP,一个主要原因还是这些指标不可微分。这里作者提出了一个MOTA和MOTP的微分代理,组合进损失函数中,实现端到端训练MOT模型。提出了深度匈牙利网络(DHN)模型来代替匈牙利匹配算法,实现目标轨迹和GT目标之间的MOTA和MOTP的代理微分计算。

1737

Openharmony 命令行工具hdc的获取与安装

OpenHarmony实战:命令行工具hdc安装应用指南_hdc工具-优快云博客t=N7T8。

Devlin_的博客 1万+

深度学习简介

资料来源:台大 李宏毅 2020机器学习深度学习课程 文章目录Ups and downs of deep learning Ups and downs of deep learning 1958: Perceptron感知机 (linear model) 和逻辑回归相似,没有sigmoid的部分 1969:Perceptron has limitation ...

yuemo3353009的博客 416

从零开始:在CentOS服务器上部署R Shiny应用的完整指南

本文提供了一份在CentOS服务器上部署R Shiny应用的完整实战指南。内容涵盖从创建专用用户、安装R语言环境、配置Shiny Server,到最终部署应用并配置防火墙的全过程。针对部署过程中常见的权限、端口及依赖问题,给出了详细的解决方案,旨在帮助数据分析师和开发者将本地Shiny应用稳定、安全地发布至生产环境。

weixin_29079743的博客 135

STC单片机使用FatFs文件系统读取SD卡指定文件内容

STC单片机使用FatFs文件系统读取SD卡指定文件内容

perseverance51博客 2745

how to train your deep multi-object tracker 论文简单解读

写在前面: “how to train your deep multi-object tracker”是论文“DeepMOT-A Differentiable Framework for Training Multiple Object Trackers”的改进版本,前者比后者多了一些实验。 主要工作: 提出了一个端对端的多目标跟踪方法的训练框架,能够针对多目标跟踪的评估指标进行训练。 主要贡献:...

yjmlaile的博客 2559

基于YOLOv8的应急通道占用监测系统设计与实现

通过详细的数据集选择、模型训练、代码实现等内容,本博客为您提供完整的系统搭建过程,帮助您构建高效的监测系统。然而,在一些建筑物和公共场所中,应急通道经常被不当占用,导致紧急情况下无法及时使用,严重影响人员的疏散效率。YOLOv8是YOLO系列中的最新版本,它通过引入深度学习的优化和改进,在保证检测速度的同时,显著提升了检测精度。同时,随着深度学习技术的不断发展,检测精度与速度的提升将使得该系统在更广泛的场景中应用。:如果已有监控设备,可以采集应急通道的实时视频,并进行标注,生成占用监测数据集。

YOLO 797

How to train your Deep Neural Network

转自:http://rishy.github.io//ml/2017/01/05/how-to-train-your-dnn/ There are certain practices in Deep Learning that are highly recommended, in order to efficiently train Deep Neural Networks. In this

Don't worry,be happy 574

Qlib:微软开源的AI量化投资平台 极简入门快速上手教程:使用 Qlib 进行中芯国际股价回测和预测

Qlib是由微软开源的面向AI量化投资的工具包。它提供了构建量化投资模型所需的基础设施,旨在帮助研究者和从业人员更高效地进行量化研究和策略开发。

AI天才研究院 5414

DISM进行系统修复,进度条卡在63.2%的解决方法

一时用不了软件,安装修复的时候也出现问题 DISM一直卡在63.2%,等了好久时间,直接强制退出寻找最终的解决方案

码农研究僧的博客 1万+

第一课:Neural Networks and Deep Learning 第四周:编程作业 Building your Deep Neural Network: Step by Step

第一课:Neural Networks and Deep Learning 第四周:编程作业 Building your Deep Neural Network: Step by Step 本周课程笔记见:第4周:深层神经网络(Deep Neural Networks) Building your Deep Neural Network: Step by Step Welcome to your ...

肖泽的博客 896

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

推荐系统算法学习(二)——DNN与FM DeepFM

1.FM 与 DNN和embedding的关系 先来复习一下FM 对FM模型进行求解后,对于每一个特征xi都能够得到对应的隐向量vi,那么这个vi到底是什么呢? 想一想Google提出的word2vec,word2vec是word embedding方法的一种,word embedding的意思就是,给出一个文档,文档就是一个单词序列,比如 “A B A C B F G”, 希望对文...

qq_23269761的博客 1万+

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

推荐系统算法总结(三)——FM与DNN DeepFM

来源:https://blog.csdn.net/qq_23269761/article/details/81366939,如有不妥,请随时联系沟通,谢谢~ 0.疯狂安利一个博客 FM的前世今生: https://tracholar.github.io/machine-learning/2017/03/10/factorization-machine.html#%E7%BB%BC%E8%BF%...

hellozhxy的博客 2616

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Distilling the Knowledge in a Neural Network

提高几乎任何机器学习算法性能的一种非常简单的方法是,在相同数据上训练许多不同的模型,然后对它们的预测结果取平均值[3]。遗憾的是,使用整个模型集成进行预测较为繁琐,并目计算成本可能过高,难以部署给大量用户,尤其是在各个模型都是大型神经网络时。Caruana及其合作者[1]已表明,可以将一个集成中的知识压缩到单个模型中,从而使其更易于部署;我们使用一种不同的压缩技术进一步发展了这种方法。

u013250861的博客 46

吴恩达 深度学习 1-4 课后作业2 Deep Neural Network for Image Classification: Application

Deep Neural Network for Image Classification: Application When you finish this, you will have finished the last programming assignment of Week 4, and also the last programming assignment of this co

xiayuanma的专栏 397

终极指南:Deep-Compression-AlexNet的核心原理与实现步骤详解

Deep-Compression-AlexNet是一个基于Deep Compression技术的模型压缩项目,它能够将AlexNet模型从233MB压缩到8.9MB,同时保持精度不损失。该项目展示了如何通过剪枝、量化和霍夫曼编码等技术实现深度神经网络的高效压缩,为模型部署在资源受限设备上提供了可行方案。 ## 什么是Deep Compression技术? Deep Compression是一种

gitblog_00157的博客 730

Must Know Tips/Tricks in Deep Neural Networks

Must Know Tips/Tricks in Deep Neural Networks (by Xiu-Shen Wei)   Deep Neural Networks, especially Convolutional Neural Networks (CNN), allows computational models that are composed of m

zr459927180的博客 1327

NVIDIA Profile Inspector 免费解锁 200+ 驱动隐藏设置实操指南

NVIDIA Profile Inspector 是一款免费的 Windows 桌面工具,它通过 NVIDIA 官方驱动 API 直接读写驱动内部的游戏配置文件,把控制面板里藏起来的帧率限制、同步模式、纹理过滤、DLSS 覆盖等参数暴露出来,让你按每款游戏单独调。下面按"跑起来→改对→存住"的真实顺序带你走一遍。 [![NVIDIA Profile Inspector 配置界面:按功能分组的全部

gitblog_00766的博客 785

Neural Networks and Deep Learning CH6

Introducing convolutional networks Local receptive fields Shared weights and biases Pooling layers Put it all together Convolutional neural networks in practice The code for our convolutional networks

渐近自由 904

2026年李宏毅机器学习-homework1(新冠预测)

对美国各州进行one-hot编码,选用MSE(Mean Square error)下载 Google Drive 上 ID 为的文件,并。下载 ID 为的文件,并。

2403_87910151的博客 301
上一篇: JNI/NDK开发指南(十一)——JNI异常处理
下一篇: 人工智能、机器学习和数据挖掘三者之间的关系
class_brick
博客等级 码龄12年 223粉丝 76原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值