吴恩达人工智能课总结

神经网络综述

1. 神经网络概述

need supplement…

  1. 激活函数的必要性
  2. 深层网络必要性
  3. 吴恩达使用的logistic lost function
  4. 为什么relu不会导致线性函数带来的问题
  5. 计算图的应用

1.1 模型构建

模拟人体神经网络建立神经网络。通过不同结构组织神经网络节点,构建不同结构的神经网络。学习过程即调整神经网络节点权重的过程,最终能够使用神经网络很好的拟合实际问题。

神经网络模型可以看作一个高维矩阵。对于全连接层,k-1层有m个节点,k层有n个节点。则全连接层之间的关系可以使用size为 m × n m\times n m×n 进行表示。对于卷积层,卷积层本身是一个三维矩阵 ( c h a n n e l × h e i g h t × w i d t h ) (channel\times height\times width) (channel×height×width),通过卷积核 ( n × c h a n n e l s × f i l t e r h × f i l t e r w ) (n\times channels\times filter_h\times filter_w) (n×channels×filterh×filterw)生成固定大小的新的卷积层. 通过调整卷积核的参数进行拟合。

1.2 学习

神经网络学习即训练过程是不断调整参数的过程。将每次训练过程称为一个epoch.一个epoch的流程包括:1. 初始化 2.forward 3.计算lost 4.计算梯度 4, backward and refresh. 不断重复epoch中的步骤,直到达到设定的精度要求停止训练,保存模型。

  1. 初始化

    1. 随机初始化

      对于对称的神经网络结构来说,如果初始化为相同的参数,相当于只有一般的神经原有效。同时,在初始化过程中需要考虑梯度大小的问题,如sigmoid作为激活函数,如果初始化参数过大,会导致梯度过小,学习效率低。

    2. Xavier 初始化

      为了防止过早出现梯度消失或梯度爆炸,采用Xavier初始化,将权重的方差固定为1。

  2. forward

    forward过程可以表达为公式(1)
    y = a c t i v i t e ( w x + b ) y = activite(wx+b) y=activite(wx+b)
    其中,activate function有多种选择,以下为一些常用选择:

    1. sigmoid
      σ ( z ) = 1 1 + e z \sigma(z) = \frac 1 {1+e^z} σ(z)=1+ez1

    2. relu:
      σ ( z ) = { z z > 0 0 z < 0 \sigma(z) = \begin{cases} &z \quad z>0 \\&0 \quad z<0 \end{cases} σ(z)={zz>00z<0

    3. leakyrelu
      σ ( z ) = { z z > 0 0.1 z z < 0 \sigma(z) = \begin{cases} z \quad &z>0\\ 0.1z \quad &z<0 \end{cases} σ(z)={z0.1zz>0z<0

    如果不使用非线性激活函数,对于全连接神经网络等价于只有两层网络,而中间层失效。

  3. lost函数

    lost函数代表预测值和真实值之间的差异,我们的训练目标就是最小化lost值。对

    从最优化角度来说,lost函数一定为一个凸函数,否则无存在局部最优解,无法直接通过来梯度求导得到最优解。对于非凸的Lost函数,为了避免局部最优,可以采用如下方法:1. 增加eopch,2.多次随机初始化,3. 调整学习率,前期采用较大的学习率,后期逐渐减少学习率。4. 调整lost函数,调整activate 函数。

    简单的拟合,分类问题中,常用的Lost函数有:

    1. softmax。softmax用于多分类任务中,采用one-hot编码格式表示分类结果。
      e z i ∑ j = 1 n e j \frac{e^{z_i}}{\sum_{j=1}^n{e^j}} j=1nejezi

    2. logistic
      − y ^ l o g ( y ) − ( 1 − y ^ ) l o g ( 1 − y ) -\hat ylog(y) - (1-\hat y)log(1- y) y^log(y)(1y^)log(1y)

  4. 梯度计算

    采用链式法则进行计算,实际应用过程中,在多轮次训练过程中,可能出现梯度消失或梯度爆炸等问题。

    当神经网络中间层过多时,中间的隐藏层的矩阵非单位矩阵。经过多层迭代,在初始化时,可能导致最终的结果过大,或者过小。即中间结果以指数形式增大或减小。

    1. 梯度消失:
    2. 梯度爆炸
  5. backward
    { w = w − γ d w b = b − γ d b \begin{cases} w&= w - \gamma dw\\ b& = b - \gamma d b\end{cases} {wb=wγdw=bγdb
    于一组训练数据,数据个数为m,需要计算整体损失cost 后采用链式法则更新权重。 1 m ∑ i = 1 n l o s t ( x i ) \frac 1 m \sum_{i=1}^{n}lost(x_i) m1i=1nlost(xi)

    j = 0
    dw = 0
    db = 0
    for i in range(n):
      dj = lost(x_i)
      for j in range(m):
      	dw_i += (dj/dw_i)/n
      	db_i += (dj/db_i)/n
       j += lost/n
    

    由于上述实现过程中,需要显示的使用 两个for 循环,在分量较多(m较大)时,回导致代码效率不高。因此,在代码实现过程中采用numpy向量化代替for循环。通过采用向量化加速训练过程。

1.3 模型评价

我们需要对一个训练好的神经网络进行评估是否适用。

首先,我们需要定义一些量化的评价指标。

  1. 偏差(Error rate)和方差: 偏差评价模型是否欠拟合, 方差评价是否过拟合。
  1. 高偏差模型: 增加训练次数,调整模型结构。

  2. 高方差模型:

    1. 增加训练数据,数据增强

    2. 正则化: (Regulation) 在原损失函数的基础上,增加一项权值正则项,目的是为了防止权值过大,能够简化模型。

      regulation could divide into L1 & L2

      L1 regulation define as l o s t + ∑ i = 1 n ∣ θ i ∣ lost + \sum_{i=1}^n{\vert \theta_i\vert} lost+i=1nθi , in such formula, θ i \theta_i θi is the hyper paremeter vector aka weight vector. And L1 regulation is the sum of original lost function and L1 norm of hyperparameter vector. We believe L1 is robust to the oulier and could 减少数据量,将无用的参数归零。

      L2 regulation is define as l o s t + ∑ λ ∥ θ ∥ 2 m lost + \sum{ \lambda \frac {\|\theta\|^2 }{m}} lost+λmθ2 λ \lambda λ is the rate of regualtion. m is the count of data. we try to use L2 norm function to reduce overfit. L2 is not robust .

      need supplement

      1. why l2 can’t make vector to 0
      2. why l2 is sensitive
      3. the relation between l2 and gaus

    1. Dropout:随机使得中间层某些节点失活

      need supplement …

      1. why not use drpoout and bn at the same time

      2. what is the different between dropout and regulation

    2. batch normalization

      对于中间层输出进行normalize,保证不会因为feature变换对下一层造成的影响。通常,normalize的对象为z.
      B N : z n o r m = z − μ σ 2 + ϵ z ^ = γ z n o r m + β γ , β 是需要学习的参数, z ^ 是最后激活函数的输入 BN:\\ z_{norm} = \frac{ z - \mu}{\sqrt{\sigma^2+\epsilon}}\\ \hat z = \gamma z_{norm} + \beta \\ \gamma, \beta 是需要学习的参数,\hat z是最后激活函数的输入 BN:znorm=σ2+ϵ zμz^=γznorm+βγ,β是需要学习的参数,z^是最后激活函数的输入

训练技巧

模型优化策略
  1. 正交化:单次调节单个参数
  2. 训练集 ----验证集-----测试集-----实际表现,依次进行评估,确定优化迭代策略。
  3. 使用单个指标对模型进行评价。如 accuracy,recall 两个指标进行调和平均得到 F1 Score指标,能够更好的评价模型。
  4. 各个数据集的分布相差不应该过大,保持优化目标不变。
  5. 将人类的表现近似看作最优化指标,通过和人类表现进行比较,确定优化策略。
模型改进策略
  1. Erro analyze:查看不同的错误类型,找到优化的方向。

  2. Correcting incorrect dev/test,

  3. 对于训练数据和测试数据数据分布不一致,并且测试数据代表的数据分布数量很少时,,将打算用于测试的数据进行拆分,分别用于train,dev,test.对于原始的训练数据全部用于训练。

  4. 如果train和test数据分布不一致时,无法判断模型是否发生过拟合或偏差是否合适。此时,需要对训练数据集进行重新分割,选取一部分作为train/dev子集,用于评估模型是否过拟合。依然使用测试集误差评价模型偏差。

  5. 训练过程中,实际采集的数据训练效果好于模拟数据。

  6. Transfer Learning: A,B是两个具有一定相似性的数据分布。如果A数据集数据量足够训练一个完美的模型,而B的数据量不够时,可以使用A数据集训练好的模型作为B数据集的预训练模型。通常可以只修改最后1-2层的参数,或新加新的神经网络层或其他的分类器。如果B的数据量不是非常小,可以考虑对预训练模型整体进行重新训练(Fine-tuning).

  7. Multi-Task: 多任务类型训练即使用多个不同的数据分布同时训练一个神经网络模型。使用多任务的前提包括:

    1. 不同数据中间具有一定的相似性。
    2. 单个数据分布数据量较小,
    3. 如果性能不如单任务训练的神经网络可以考虑增加神经网络的规模。
  8. end-end:端到端模型,在数据充足的情况下可以考虑构建端到端的模型。

各类神经网络

基础卷积神经网络

卷积神经网络框架在计算机视觉领域是最基本最常用的方法。深度学习中的卷积是一种互相关计算,通过卷积核遍历图像,得到结果。

我们一般称输入为image,中间的卷积结果为feature map.中间卷积层中的元素称为feature.

卷积网络的超参数包括:填充,步长,卷积核尺寸,卷积核个数。

最基础的卷积网络架构为:image -> (conv1+pool1)----> (conv2+pool2)–>(cov-n+pook-n) —>flatten --> FC —> output

(conv+pool)的结构构成卷积网络中的一个layer,

track:

  1. 卷积网络具有参数共享,参数稀疏的特点,有利于防止过拟合。

  2. 池化层多选用最大池化。

  3. feature map计算公式:

  4. n o u t = n i n + 2 p − f s − 1 n_{out} = \frac{n_{in}+2p-f}{s}-1 nout=snin+2pf1

感受野(Receptive filed)

感受野是卷积网络中的一个重要的概念。感受野定义为:feature map中feature对应Image的范围大小。需要关注的是感受野的大小和中心位置。

l层的feature经过卷积得到l+1层的feature,依次递归,向上采样。由于Image中每个pixel被计算的次数不一样,因此对feature的贡献也不一样。越是靠近中心的pixel的贡献成指数级递增(靠近中心的pixel对应的feature越多,被乘的次数越多)感受野最终的目的是能够区分提取的feature对应的Image范围。

研究过程中,有两种方法能够很好的可视化感受野提取过程。

  1. 金字塔模型,层层堆叠。
  2. 中心点对应模型,feature同样的尺寸对应到感受野的中心位置。

感受野计算公式:
j o u t = j i n ∗ s j_{out} = j_{in}*s jout=jins

r o u t = r i n + ( k − 1 ) ∗ j i n r_{out} = r_{in}+(k-1)*j_{in} rout=rin+(k1)jin

s t a r t o u t = s t a r t i n t + ( f − 1 2 − p ) × j i n start_{out} = start_{int}+(\frac{f-1}{2}-p)\times j_{in} startout=startint+(2f1p)×jin

track:

j表示两个feature 在Image坐标下的距离

r 表示 feature对应的image范围大小

start表示左上角feature对应的image坐标下的位置

以上计算基于两个假设:1. fild,image为正方形,对称。

时序神经网络

时序神经网络拓展了神经网络的维度,在NLP(自然语言处理)中有广泛的应用,对于计算机视觉中涉及到时序frame的问题同样可以加以应用。

循环序列模型(Recurent neural network)RNN

循环序列模型可以用于处理带有序列意义的输入值,如一个句子。

  1. 输入: RNN的输入需要固定大小,因此使用one-hot编码建立一个词语字典,使得每次输入大小固定。其中,特殊元素包括表示结尾,表示字典中不存在的词语。
  2. RNN存在的问题:1. 没有记忆性,t时刻之和t时刻附件的节点有关;2. 梯度消失
  1. 设时刻t,数据输入 x < t > , a p r e y < t − 1 > x^{<t>}, a_{prey}^{<t-1>} x<t>aprey<t1>
  2. 输出: t a n h ( w a a ∗ a < t − 1 > + w a x ∗ x < t > + b ) tanh(w_{aa}*a^{<t-1>}+ w_{ax}*x^{<t>} + b) tanh(waaa<t1>+waxx<t>+b) track:激活函数可以使用relu代替,但可能出现梯度消失或者梯度爆炸的问题。
  3. 无记忆性: 激活函数tanh范围 [-1, 1]。上一时间点所带来的信息非常小,经过几个时间后,对后来的时间点所带来的影响会越变越小。存疑?
  4. 可能梯度消失:如果输入过多的话,会导致最终的结果在激活函数求导的无效范围内经行求导,导致梯度消失。(需要重新理解)存疑?
  1. GRU&LSTM
    为解决上述问题,引入门的概念(gate) γ \gamma γ。通过调节门对应值的大小来调节当前时间点输入所带来的影响和过去时间点输出所带来的影响。
    c ~ < t > = t a n h ( W c [ c < t − 1 > , x < t > ] + b ) γ u < t > = σ ( W u [ c < t − 1 > , x < t > ] ) γ f < t > = σ ( W f [ c < t − 1 > , x < t > ] ) γ o < t > = σ ( W o [ c < t − 1 > , x < t > ] ) c < t > = γ u c ~ + γ f c < t − 1 > a < t > = γ o t a n h ( c < t > ) y < t > = s o f t m a x ( a < t > ) \widetilde{c}^{<t>} = tanh(W_c[c^{<t-1>},x^{<t>}] + b)\\ \gamma_u^{<t>} = \sigma(W_u[c^{<t-1>},x^{<t>}] ) \\ \gamma_f^{<t>} = \sigma(W_f[c^{<t-1>},x^{<t>}] ) \\ \gamma_o^{<t>} = \sigma(W_o[c^{<t-1>},x^{<t>}] )\\ c^{<t>} = \gamma_u \widetilde{c} + \gamma_f c^{<t-1>}\\ a^{<t>} = \gamma_o tanh(c^{<t>})\\ y^{<t>} = softmax(a^{<t>}) c <t>=tanh(Wc[c<t1>,x<t>]+b)γu<t>=σ(Wu[c<t1>,x<t>])γf<t>=σ(Wf[c<t1>,x<t>])γo<t>=σ(Wo[c<t1>,x<t>])c<t>=γuc +γfc<t1>a<t>=γotanh(c<t>)y<t>=softmax(a<t>)
    可以将 c ~ < t > \widetilde{c}^{<t>} c <t> 看作原始RNN-CELL的 a < t > a^{<t>} a<t>,通过设置门调节了t时刻所带来的影响,并且使用变量c记忆t时刻之前的所有信息。
  2. 深度RNN和双向RNN
    。。。

神经网络在计算机视觉的应用

深层卷积网络模型

  1. le-net , alex-net,vgg.

    在基础的卷积网络基础上增加层数。alex-net 采用relu激活函数,多gpu进行训练。 vgg,结构整齐,有一定规律,问题在于参数过多,不容易学习

  2. resnet:为了解决深度(层数)增加精确率上升的问题

    1. residual block or skip connection:
    2. idea:交叉进行skpi connection。增加更多的residual block.
  3. 1 × 1 1\times1 1×1fileter :用于压缩channle,可以用于构建bottle neck,减少计算量。

  4. inception net :同时使用多个size的fielter(include pool layer),将不同的卷积结果进行叠加。

  5. 卷积神经网络训练技巧

    1. transformer:迁移学习,使用已经训练好的神经网络进行训练,用于训练数据较少的情况。可以冻结(freeze)部分层的参数,只训练末尾部分的神经网络。freeze的规模和数据量有关,数据量越多,可以学习的部分越大。

    ideal:freeeze全部神经网络,在末尾添加svm进行训练.

    1. 数据增强(data argumentation):1. mirro 2. crop 3.color shifting

    last: 1. ensembing 可以使用多个神经网络的输出平均提高精度, mult-crop ?

目标检测算法

Sliding window algorithm

特征点:用于实现特征检测,如人脸的眼角等部分。用于人脸识别,姿态检测

sliding window(滑窗):用于目标检测。

  1. train:选取目标图片,训练网络识别特定目标。
  2. predict: 选取不同尺寸的silde window,以互相关(卷积核)的方法遍历图片,实现目标检测。tips:每次滑动一个窗口都需要进行一次完整的forward。
  3. pros & cons: 计算成本高;为了提高成本采用细粒度的sliding window 进一步提高成本,采用粗粒度的sliding window会降低精度。

为了解决上述计算成本的问题,采用share convolution的方法。直接对图片整体进行卷积,为了解决分类器中FC层尺寸匹配的问题,使用1*1卷积代替全连接层。tips:与感受野相似,最后的卷积结果反应对应感受野的结果。

YOLO V1 (the best object recognization algorithm)
  1. 基本架构:一个类似VGG的模型,只有主干网络,没有其他分支网络。

    经过卷积得到一个 S ∗ S ∗ ( B ∗ 5 + C ) S*S*(B*5+C) SSB5+C) 的feature, 每个feature对应的感受野即一个CELL。最终得到的feature map 中每个feature 仅仅能预测一个目标。

  2. forward 过程:?

  1. Bounding box

    Bounding box是yolo网络forward的结果,共有 S ∗ S ∗ B S*S*B SSB个。可以把最后的结果看作一个feture map,每个bounding box对应的感受野就是原始图片中的一个cell.

  2. anchor

  3. forward

    yolov1经过一个类似vgg结构的网络得到一个feature map. 结果为 S ∗ S ∗ ( B ∗ 5 + C ) S*S*(B*5+C) SSB5+C) 每个tensor对应原图一块感受野,包括了对应区域内的目标目标置信度,x,y,w,h 和 classes。

  4. loss funcion

    见论文。

  5. predict

    预测过程:

    1. forward 得到feature map
    2. 根据每个feature 中 class 的score最高的类作为该feature预测的类别
    3. 使用上述挑选的score multiple 每个bounding box 的pr值, 过滤掉所有小于预设 threshold的bounding box 。过滤掉的bounding box表示不包含目标。
    4. 对于未过滤的bounding box,按照类别得分进行降序排列,对于每个类别分别进行NMS.
    5. 最后剩余的bounding box作为预测结果。
  6. train

    1. forward 得到feature map
    2. 对于target cell之外的cell产生的feature作为不包含目标处理
    3. 对于target cell内的bounding box, 计算 bounding box和target tensor的IOU,选择较大的IOU的bounding box作为给目标的预测框。
    4. 将上述所选的参数作为lost函数参数进行计算。
  7. object recognization

  8. classify: 最后的feature 中的class 表示条件概率 P ( c l s ∣ o b j ) P(cls|obj) P(clsobj) , 分类中的 类别分数为: P ( c l s ∣ o b j ) ∗ P ( o b j ) ∗ I O U P(cls|obj)*P(obj)*IOU P(clsobj)P(obj)IOU , 预测中的 class 分数为: P ( o b j ) ∗ c l a s s s c o r e P(obj)*class score P(obj)classscore

**RCNN **(anothe way to recognize )

人脸认证

rec: facenet

基本思路是通过一个预训练的卷积神经网络提取人脸图片的特征,与数据库中的图片所提取出的特征进行比较,如果差值小于某个阈值 α \alpha α 则验证成功。最终,该问题转很为一个二元分类问题。
i f d ( i m g 1 , i m g 2 ) < τ y e s e l s e n o if \quad d(img1, img2) < \tau \quad yes\\ else\quad no ifd(img1,img2)<τyeselseno
对于最后的图片特征差值计算可以直接计算或使用二元分类器计算。

风格迁移

point 不更新神经网络参数,只更新输入的像素值。使用同一个神经网络提取内容和风格特征。其中,内容可以提取中间的某层,是超参数;风格可以结合多层的激活函数值加权求和。

基本思路为:随机生成一张图片,然后分别从内容和风格两部分修改生成图片。
G = G − α d ( J ( G ) ) d ( G ) G = G-\alpha \frac {d(J(G))}{d(G)} G=Gαd(G)d(J(G))
Content:设置一个内容呢lost 函数 ,第l层的特征值尽可能相似。
J c o n t e n t ( G , C ) = α ∣ ∣ a [ l ( C ) ] − a [ l ( G ) ] ∣ ∣ J_{content}(G,C) = \alpha ||a^{[l(C)]}-a^{[l(G)]}|| Jcontent(G,C)=α∣∣a[l(C)]a[l(G)]∣∣
Style: 卷积层中不同的通道代表所提取的不同特征,因此,通道间的关系可以用来衡量图片的风格。

Gram matrix(style matrix) :
G k k ′ [ l ] = ∑ i ∑ j a i j k × a i j k ′ G_{kk^{\prime}} ^{[l]} = \sum_{i}\sum_j a_{ijk}\times a_{ijk\prime} Gkk[l]=ijaijk×aijk
G 组成一个 N C ∗ N C N_C*N_C NCNC 的矩阵。分别对Style image和Generate image 构造Gram matrix .计算差值。

风格损失函数:
J ( S , G ) = ∑ l 1 ( 2 n H l n W l n C l ) 2 ∑ k ∑ k ′ ( G k k ′ ( l ) [ S ] − G k k ′ ( l ) [ G ] ) J(S,G) = \sum_l \frac 1 {(2n_H^l n_W^ln_C^l)^2}\sum_k \sum_{k\prime}(G_{kk\prime}^{(l)[S]}-G_{kk\prime}^{(l)[G]}) J(S,G)=l(2nHlnWlnCl)21kk(Gkk(l)[S]Gkk(l)[G])

J ( G , S , C ) = α J c o n t e n t ( G , C ) + β J S t y l e ( G , S ) J(G,S,C) = \alpha J_{content}(G,C) + \beta J_{Style}(G,S) J(G,S,C)=αJcontent(G,C)+βJStyle(G,S)

自然语言处理

词嵌入

建立一个词汇库,对库中的每个单词进行编码,编码方式可以采用one-hot方式,表示单词。但是,one-hot编码会丢失词语本身的特征信息,不能使用神经网络进行处理,因此采用词汇特征进行编码,使用t-SNE编码方式将高维向量映射到低维,对低维向量进行的各种处理称为词嵌入。其中,最主要的词嵌入为更具上下文(context)预测单词(target/content)。
对于使用特征向量表示的词语,可以计算不同词汇特征之间的距离确定两个词语之间的关系,如man,woman; king, queen两组词之间的特征距离相近,表示两组词之间的关系类似。可以使用sim函数对特征向量之间的关系进行计算。
s i m ( u , v ) = u , v T ∣ u ∣ . ∣ v ∣ sim(u, v) = \frac {u,v^T} {|u|.|v|} sim(u,v)=u∣.∣vu,vT ,sim函数值越小,代表两个词语之间的特征差异越小。

序列模型和注意力机制

seq2seq 和 image2seq模型通常为:RNN (神经网络模型提取特征) + Decoder,其中RNN用于提取目标的特征,Decoder用于生成序列结果。
其中Decoder使用beam search算法。

Beam search

beam search 算法每次取B(width)个最优值,直到产生结束标志( < EOS > )总体来说,beam search过程可以看作条件概率模型:
p ( y t ∣ x , y 1 , . . . y t − 1 ) = π i = 1 t − 1 p ( y i ∣ x , y 1 , . . . y i − 1 ) p(y^{t}|x,y^{1},...y^{t-1}) = \pi_{i=1}^{t-1} p(y^{i}|x,y^{1},...y^{i-1}) p(ytx,y1,...yt1)=πi=1t1p(yix,y1,...yi1)
使得条件概率最大的前B个值即为每次生成的结果,然后在每次生成的结果上不断迭代即可。argmax p
为了避免算法为了增加P,而降低长度的趋势,我们采用Log,
1 T y α ∑ t = 1 T y l o g ( p ) , α ∈ [ 0 , 1 ] \frac 1 {T_y ^{\alpha}} \sum_{t=1}^{T_y} log(p), \alpha \in [0,1] Tyα1t=1Tylog(p),α[0,1]

错误判断

对于最后生成的结果中的错误判断其来源是 rnn 还是 decoder 。
y*为人工结果, y ^ \hat y y^ 表示模型计算结果。
如果 p ( y ∗ ∣ x ) > p ( y ^ ∣ x ) p(y*|x) > p(\hat y |x) p(yx)>p(y^x), 表示 beam search 没有检索到最优值,应该优化B,增加width。
否则,应该尝试优化RNN模型,更好的提取特征。

结构化神经网络模型

硬件结合

未来展望

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值