链接:http://arxiv.org/abs/2112.10021

简介

这是一篇在情感分类Sentiment Classification运用连续学习Continual Learning的paper,提出了KAN。
连续学习一般有两种setting:

  • Class continual learning (CCL):在CCL中,每个任务由一个或多个要学习的类组成。在这个阶段,所有的类都只建立了一个模型。在测试中,可以将来自任何类的测试实例呈现给模型,让它进行分类,而不给它任何训练中使用的任务信息。
  • Task continual learning (TCL):在TCL中,每个任务都是一个单独的分类问题(例如,一个任务对不同品种的狗进行分类,另一个任务对不同类型的鸟进行分类)。TCL在一个神经网络中构建一组分类模型(每个任务一个)。在测试中,系统知道每个测试实例属于哪个任务,只使用任务的模型对测试实例进行分类。

本文在TCL的情况下进行情感分析的连续学习任务,
通常,一家SA(情感分析)公司必须为许多客户工作,而每个客户都希望研究公众对其产品/服务的一个或多个类别及其竞争对手的产品/服务的看法。
对每一类产品/服务进行情感分析是一项任务。出于保密性,客户通常不允许SA公司与任何其他客户共享其数据或将其数据用于任何其他客户。因此,连续学习很适合这项工作。
在本例中,我们还希望在不违反机密性的情况下,随着时间的推移提高SA准确性。这就提出了两个关键的挑战:

  • (1)如何在不使用前一个任务数据的情况下,将从前一个任务中学到的知识转移到新的任务中,帮助新任务更好地学习;
  • (2)如何在不使用CF的情况下,对前一个任务的旧模型进行改进。在[15]中,作者发现CL有助于提高文档级情感分类(SC)的准确性,SC是SA[13]的子问题。

在本文中,我们提出了一个更好的模型,称为KAN (Knowledge Accessibility Network)。注意,这里的每个任务都是一个两类SC问题,也就是说,对一个产品的评论是正面的还是负面的进行分类。

我之前阅读的终身学习paper大多将重心放在抵抗遗忘catastrophic forgetting,但本文的重心在于知识迁移Knowledge Transfer:之前学过的任务能不能帮助解决以后学的任务;后学的任务能不能巩固增强之前学过的任务。
这是情感分析的特殊性导致的:情感分析是一个二分类问题,不同的任务之间相似度很大(电影评论和美食评论虽然是两个任务,但两者的情感词是基本一样的),也就是说不同任务之间有很多相通的知识,并不会产生较为严重的遗忘。所以工作的重心要放在知识迁移上。

为此,本文提出了KAN,包含两个部分:主要持续学习网络(main continual learning,MCL)和可访问性网络(accessibility,AC)。

  • MCL的主要组成部分是知识库(Knowledge Base,KB),用于存储从所有训练任务中学习到的知识。
  • 在学习每一个新任务时,AC网络决定过去的哪一部分知识对新任务有用并可以共享。
  • 也就是说,每学习一个新任务,共享知识就会被增强一次,从而使得知识既可以向前迁移,也可以向后迁移。

Related Work

在此之前,只有一个工作是将连续学习运用到情感分类:SRK。但是SRK在学习新任务的时候保护过去的知识,只能向前迁移不能向后迁移,并且他的向后迁移也很差。相比起来KAN就能前后迁移。
同时,SRK也指出:情感分类任务不怕遗忘,因为任务相似度太高了。

KAN

KAN受人脑的启发:我们的大脑会记录知识的可访问性。如果我们之前的一些知识对新任务有用(即,新任务和之前的一些任务之间的共享知识),我们的大脑将这些部分设置为可访问的,以实现前向知识转移。这也使落后的知识转移成为可能,因为它们现在是可访问的,我们有机会根据新的任务数据加强它们。对于以前的知识中那些无用的部分,它们被设置为不可访问,从而保护它们不被更改。
受到这个想法的启发,本文设计了一个内存和可访问性机制。

我们需要解决两个关键问题:

  • (1)如何决定知识的可访问性,即识别出之前的知识中对新任务有用的部分;
  • (2)如何利用识别出的有用/共享知识来帮助新任务学习,同时又保护其他部分。

KAN结构如图所示:

整体结构

KAN包含两部分:MCL网络(紫色)和AC网络(黄色)。MCL在持续学习和测试阶段都使用(AC在测试中不使用,除了从任务 t t t生成的掩码 a t a_t at)。
我们来看看MCL的结构:
首先最上面是情感分类头(Pos/Neg),每个任务特制一个;
下面是稠密层(dense layers);
在下面是知识库KB,因为本文用了RNN(内部是GRU),所有叫KB-RNN。注意:知识库包含所有的知识,分为任务特定的知识和共享的知识。

再来看AC的结构:
输入任务的id t t t,进入AC-EMB,得到任务的embedding。其中AC-EMB是一个随机初始化的embedding layer。
然后产生一个任务掩码 a t a_t at,来决定知识库中的哪一部分知识(或单元)可以被当前任务 t t t访问。

总结起来,KAN的输入是任务的id t t t和文档 d d d。它们被用于通过掩码 a t a_t at{ h i K B } \{h_i^{KB}\} {hiKB} (KB-RNN中的hidden state)链接训练这两个组件。

AC Training

在AC训练阶段,只有任务embedding(Task Embedding, AC- emb)、AC- RNN等黄色框中的内容是可训练的。
假设知识库已经保留了从任务 0 … t − 1 0…t-1 0t1中学习到的知识。当新的任务 t t t到达时,我们首先训练AC部分,来生成一个二进制的任务掩码 a t a_t at(一个与KB { h i K B } \{h_i^{KB}\} {hiKB}大小相同的矩阵),以指示KB- RNN中的哪些单元可以被新的/当前的任务 t t t访问。
由于掩码是基于新的任务数据进行训练的,KB-RNN中之前的知识是固定的,所以那些没有被屏蔽的KB-RNN单元(意味着它们对新任务是有用的)就是条目在 a t a_t at中为1的可访问单元(未屏蔽)。其他单元是不可访问的,它们的条目在 a t a_t at中为0(屏蔽)。

MCL Training

AC训练结束后,我们开始MCL训练。在这个阶段,只有KB-RNN和紫色框中的其他部分是可训练的。训练后的二进制的任务掩码 a t a_t at以元素为单位乘以KB-RNN的输出向量。这个操作保护了那些不可访问的单位,因为没有梯度流穿过它们,同时允许那些可访问的单位被更新,因为掩码不会停止它们的梯度。

Continual Learning in KAN

在算法1中给出了KAN中持续学习的算法。
对于每个新任务,首先进行AC训练,然后进行MCL训练。
一个例外是在第一个任务(算法1的3-4行),一开始KB没有知识,AC没有什么可以使用的,所以我们在AC之前训练MCL(和KB)先获得一些知识。但是,在第一个任务之后,对于每个新任务,AC总是在MCL(和KB)之前训练(第6-7行)。

Details of Accessibility Training


AC训练的目的是检测在给定新的任务数据的情况下,知识库中保留知识的可访问性。
如图1和算法2所示,它以训练示例 d d d和训练后的知识库KB-RNN W t − 1 K B − R N N W^{KB-RNN}_{t-1} Wt1KBRNN作为输入,因为AC总是在之前的任务训练KB (KB-RNN)之后进行训练。
为了生成一个二进制矩阵 a t a_t at,使其在MCL(和KB)和AC训练阶段都能作为一个掩码,我们借用了hard attention的思想,即attention矩阵中的值是二进制的,而不是像soft attention那样是一个概率分布。

Hard Attention Training

由于我们可以在训练和测试中访问任务id,一个自然的想法是利用任务embedding来计算Hard Attention。
具体来说,对于任务id t t t,我们首先通过将任务id输入到AC-EMB来计算任务嵌入 e t e_t et,其中1-hot i d id id向量乘以一个随机初始化的参数矩阵。利用得到的任务嵌入 e t e_t et,我们应用一个门函数 σ ( x ) ∈ [ 0 , 1 ] σ(x)∈[0,1] σ(x)[0,1]和一个正尺度参数 s s s来计算Algorithm 2中第1行和第2行所示的二进制attention。
直观上,它使用一个单位阶跃函数作为激活函数 σ ( x ) σ(x) σ(x),但由于它是不可微的,没法训练。因此,本文使用sigmoid函数来替代阶跃函数。
尺度参数 s s s用于控制 σ ( x ) σ(x) σ(x)的极化和输出 a t a_t at。我们的策略是在训练过程中退火s,诱导一个梯度流,在测试过程中设置 s = s m a x s = s_{max} s=smax。这是因为使用超参数 s m a x ≫ 1 s_{max}≫1 smax1,我们可以使我们的sigmoid函数近似于单位阶跃函数。
同时,当 s → ∞ s→∞ s时,得到 a t → { 0 , 1 } a_t→\{0,1\} at{0,1},当 s → 0 s→0 s0时,得到 a t → 0.5 a_t→0.5 at0.5
我们在开始训练阶段时,通过使用后一种方法让所有单位都具有同等的活跃度,并在这个阶段中逐渐极化它们。具体来说,我们退火如下:

其中 b = 1 , … B b = 1,…B b=1,B是batch索引, B B B是一个epoch内的batch总数。

为了更好地理解硬注意力训练,回想一下,我们生成的掩码 a t a_t at是二进制的,这样它就可以在两个阶段中用于阻断/解除某些单元的训练。任务id用于控制掩码以调节KB。为了实现这一点,我们需要确保任务id的embedding是可训练的,为此我们采用sigmoid作为伪gate函数。训练过程是退火,初始 s → 0 ( s = 1 s m a x ) s→0 (s = \frac{1}{s_{max}}) s0(s=smax1),掩码仍然是soft attention。
某些batch后, s s s变大, σ ( s ⊗ e t ) σ(s⊗e_t) σ(set)变得非常类似于门函数。训练完成后,那些条目为1的单元可访问任务 t t t,而其他单元则不可访问。
训练hard attention的另一个优点是,我们可以很容易地在训练后检索基于二进制任务的 a t a_t at:我们简单地采用 s m a x s_{max} smax作为 s s s,并应用 σ ( s m a x ⊗ e t ) σ(s_{max}⊗e_t) σ(smaxet)

Apply Hard Attention to the Network

固定的KB-RNN以训练样例 d d d作为输入,并生成一个输出向量序列 { h i K B } \{h^{KB}_i\} {hiKB},这样就包含了之前的知识(Algorithm 2的第3行)。 i i i表示RNN的第 i i i个步骤或输入的第 i i i个词的representation,范围是:0到 s t e p step step(步长的大小)。
随后, { h i K B } \{h^{KB}_i\} {hiKB}a t a_t at执行逐元素乘法,以获得先前知识 { h i K B ; A c c e s s } \{h^{KB;Access}_i\} {hiKB;Access}的可访问性表示(第4行)。
回想一下, e t e_t et是一个任务id的embedding向量, e t ∈ R d i m e_t∈R^{dim} etRdim,其中dim是维度大小,因此 a t ∈ R d i m ( a t = σ ( s ⊗ e t ) ) a_t∈R^{dim}(a_t = σ(s⊗e_t)) atRdim(at=σ(set))。换句话说,我们展开向量 a t a_t at(重复向量的步长)以匹配 { h i K B } \{h^{KB}_i\} {hiKB}的大小,然后执行逐元素乘法。这种可访问性representation对以前任务中的有用知识进行编码。我们首先将这个representation喂给AC-RNN来学习一些新任务知识(第5行)。
设AC-RNN的输出向量序列为 { h i A C } \{h^{AC}_i\} {hiAC},我们取序列的最后一step: h s t e p A C h^{AC}_{step} hstepAC,将其通过稠密层减少向量的维度,最后计算基于交叉熵的损失(第6行)。

Details of Main Continual Learning Training

MCL训练将当前任务知识学习到知识库(KB-RNN)中,并将之前任务中学习到的知识保护起来。
如Algorithm 3和图1所示,取相应数据集 D t D_t Dt中的一个输入训练示例 d d d,通过KB-RNN编码 d d d(第1行),得到一个向量序列 { h i K B } \{h^{KB}_i\} {hiKB}
按照我们的训练方案,即对于一个新任务 t t t, AC-RNN和AC-EMB总是在KB之前训练(第一个除外),在讨论KB时,我们已经有了训练好的AC-EMB W t A C − E M B W^{AC-EMB}_t WtACEMB。因此,我们可以从 W t A C − E M B W^{AC-EMB}_t WtACEMB(第5-6行)计算掩码。
注意,我们将 a t a_t at展开为一个二进制矩阵, a t ∈ R s t e p × d i m a_t∈R^{step×dim} atRstep×dim,其中step为KB-RNN的步长,dim为任务embedding向量的维数。对于第一个任务(即 t = 0 t = 0 t=0),我们简单地假设 a 0 a_0 a0为一个1的矩阵(第3行)。

Block the Inaccessible and Unblock the Accessible Units

当然,我们希望“移除”那些不可访问的单元,以便只有可访问的单元才能对KB-RNN的训练做出贡献。一种有效的方法是简单地将KB { h i K B } \{h^{KB}_i\} {hiKB}的输出乘以 a t a_t at(第7行)。由于 a t a_t at是一个二进制掩码,只有那些掩码为1的KB才能通过向后传播更新。这相当于用掩码 a t a_t at修改梯度 g g g

得到的向量可以被看作是可访问知识的表示。
最后,我们把最后一步得到的可访问知识向量 { h i K B ; A c c e s s } \{h^{KB; Access}_i\} {hiKB;Access}放入全连接层进行分类(第8行)。注意,我们采用多头配置(上部组件在知识库培训阶段在图1)这意味着每个任务有一个独有的稠密层。这些稠密层被映射到类数的维数 c ( c = 2 ) c (c=2) c(c=2),这样我们就可以根据不同的任务id使用不同的稠密层进行分类。

实验

数据集

数据集在亚马逊上收集了24种不同产品的评论,它们构成了24个任务。每个任务有2500个正面评价(4星或5星)和2500个负面评价(1星或2星)。训练、测试、验证的比例是8:1:1。

Baseline

  • One task learning (ONE):给每个任务单独一个模型,模型之间没有知识共享。本文将KAN的AC部分去掉,只保留MCL部分。
  • Elastic Weight Consolidation (EWC):目前最主流的终身学习方法之一,在学习新任务时保护就任务的知识。
  • Hard Attention to Task (HAT):也是一种主流终身学习方法。使用给定的任务id在给定的基础网络中学习路径(因此任务增量)。然后,这些路径被用来获取特定于任务的网络。它是当前最先进的任务持续学习模型,用于避免灾难性遗忘(CF)。
  • Orthogonal Weights Modification (OWM):一种先进的类持续学习(CCL)方法。由于OWM是一种CCL方法,但我们需要一种TCL方法,因此我们将其用于TCL。具体来说,我们在训练时只对特定任务id的对应头部进行训练,在测试时只考虑对应头部的预测。
  • Sentiment Classification by Retained Knowledge (SRK):之前唯一的情感分析终身学习方法。他的弊端在前文讲过了。
  • Lifelong Learning for Sentiment Classification (LSC):一种基于朴素贝叶斯(Naive Bayes)的情感分类终身学习方法,它是一种正向迁移而非持续学习的终身学习方法,因此不存在CF问题。这种传统方法的主要目标只是提高新任务的性能。
  • Naive continual learning (N-CL):朴素地训练一系列SC任务,而不处理CF。请注意,这相当于去除AC和掩码后的KAN,即使用与ONE相同的网络。

网络和训练

除非另有说明,我们一般使用300维的embedding来表示输入文本。300维的GRU用于AC-RNN和KB-RNN。采用Glove 300d作为预训练的单词嵌入,并在KAN训练过程中对其进行修正。最后一层为具有softmax输出的全连接层,并伴有分类交叉熵损失。
在KAN训练过程中,我们将batch处理中每个元素的hidden state初始化为0。
s s s退火算法中设置 s m a x s_{max} smax为140;在MCL和AC训练阶段,在嵌入层和GRU层之间的dropout为0.5。
梯度下降用的是Adam,学习率设为0.001。
如果连续5个阶段验证准确性没有提高时,我们停止训练(早停法,patience=5)。batch大小设置为64。、在测试期间,我们只使用MCL来评估最终的性能。AC不参与测试(除了在训练期间用任务id t t t生成的掩码)。
对于SRK、HAT、OWM和EWC,我们使用它们的作者提供的代码(如果需要,为文本定制),并采用它们的原始参数。

结果

平均结果

我们首先报告所有比较模型的平均结果,以显示提出的KAN的有效性。

由于任务的顺序可能会影响CL的最终结果,我们随机选择并运行10个序列,并对其结果进行平均。我们还确保10个序列中的最后一个任务是不同的。
表1给出了所有系统的平均精度。列2给出了学习完所有任务后,每个模型超过24个任务的平均结果。第3列给出了每个模型的最后一个任务的精度结果。
请注意,Last Tasks和All Tasks没有可比性,因为每个Last Tasks结果是10个随机任务序列中最后10个任务的平均值,而每个All Tasks结果是所有24个任务的平均值。
第4列给出了显著性检验的p值,表明KAN优于所有基线(稍后详细讨论)。
第5列给出了每个模型的参数数。注意,ONE和LSC不是持续学习(CL)系统,没有CF问题。其余的是持续学习系统。

KAN的结果明显优于所有基线。由于传统的终身学习方法LSC主要是为了提高最后一个任务的绩效,所以在All Tasks栏中,我们给出了其最好的结果,即将24个任务中的每一个作为最后一个任务。即使在这种有利的环境下,其结果也远不如KAN。

有趣的是,与ONE相比,即使没有处理CF(遗忘)的机制,朴素CL (N-CL)的准确性平均也没有下降。N-CL实际上比ONE要好得多(它们使用完全相同的网络)。正如前面提到的,这是因为情感分析任务彼此相似,可以互相帮助。也就是说,CF在情感分析的CL中不是一个主要问题。
事实上,N-CL在所有任务上也优于SRK。这或许是因为SRK的知识不能向后迁移,毕竟SRK的主要目标是提高最后一个任务的性能,而不是所有任务的性能。

对于持续学习(CL)其他baselin:EWC、OWM和HAT,它们的表现很差,甚至比ONE还要差,这并不奇怪,因为它们的网络主要是为了保存之前每个任务所学习的知识而设计的。这使得他们很难利用知识共享来改进所有的任务。

显著性测试

为了证明KAN的结果明显优于基线的结果,我们进行了配对t检验。我们根据10个随机序列中的所有任务的结果,在每个基线上测试KAN。所有的p值均远低于0.05(见表1),说明KAN明显优于各baseline。

表1还包括每个神经模型的参数数量(列4)。KAN的参数的很大一部分是由于每个任务的掩码。

消融实验

KAN有两个组件,AC和MCL。为了评估AC的有效性,我们可以去除AC来测试KAN,去掉之后就是N-CL,KAN显著优于N-CL,见表1。
MCL是进行持续学习的主要模块,不可移除。

单项任务结果

为了进行更多的分析,我们在表2中报告了所有持续学习基线和KAN的个体任务结果。我们还包括一个比较。注意,模型的每个任务结果都是10个随机序列(ONE除外)结果的平均值。

表2显示,在24个任务中,KAN在21个任务中给出了最好的准确性。即便是在没有取得第一的任务,KAN依旧名列前茅。因此,我们可以得出这样的结论:KAN具有较高的准确性和鲁棒性。

对于SRK,它只在2个任务中表现最好。然而,这两个任务的结果仅略好于KAN。这些明显表明SRK比KAN弱。对于其他的持续学习基线:HAT、OWM和EWC,它们的表现一直比ONE还要差。这是意料之中的,因为他们的目标是保护每一个ONE的结果,这样的保护并不是完美的,因此仍然可能导致一些CF(遗忘)。

前向和后向知识转移的有效性

从表1和表2中,我们可以看到KAN能够利用共享的知识来提高相似任务的学习。在这里,我们想要展示的是正向知识转移和逆向知识转移是否确实有效。

表3显示了每学习6个任务后的准确率结果。在第二行中,我们给出了连续学习6个任务后的结果。向前列中的每个精度结果的总体平均6任务当每个人都是第一次学习的10个随机运行,标明正向传递有效性,因为从第二个任务,系统已经可以开始利用前面的知识来帮助学习新任务。通过与ONE和N-CL的相应结果对比,可以看出KAN的正向转移确实有效。N-CL也有正向转移作用,但KAN效果更好。后向列中的每个结果显示了学习完所有6个任务(超过10次随机运行)后的平均测试准确度。通过与前向列对应的结果对比,我们可以看到KAN的后向迁移也是有效的,这意味着学习后面的任务可以自动帮助提高前面的任务。对于N-CL也是如此,尽管KAN做得更好。第3、4和5行分别显示了学习了12、18和24个任务后的相应结果。

我们还观察到,正向迁移比反向迁移更有效。这是意料中的,因为正向转移首先利用了之前的知识,而向后转移只有在正向转移有了显著的改进后才能改进。此外,向后转移还可能导致前一个任务的一些遗忘,因为前一个任务的数据不再可用来防止它。

【Lifelong learning】Continual Learning with Knowledge Transfer for Sentiment Classification相关推荐

  1. 【论文阅读】Cross-X Learning for Fine-Grained Visual Categorization

    [论文阅读]Cross-X Learning for Fine-Grained Visual Categorization 摘要 具体实现 OSME模块 跨类别跨语义正则化(C3SC^{3} SC3S ...

  2. 【深度学习】Deep Learning必备之必背十大网络结构

    深度学习网络结构: [深度学习]Deep Learning必备之必背十大网络结构 (从公众号转发过来发现图片不能引用,直接点上面链接吧) 昨天的文章介绍了在学习Deep Learning过程中必须背熟 ...

  3. 【读论文】An Object-Based Approach for Urban Land Cover Classification(2013)

    [读论文]An Object-Based Approach for Urban Land Cover Classification: Integrating LiDAR Height and Inte ...

  4. 【论文翻译】PLOP: Learning without Forgetting for Continual Semantic Segmentation

    论文地址:http://​https://arxiv.org/abs/2011.11390​ 代码地址:GitHub - arthurdouillard/CVPR2021_PLOP: Official ...

  5. 【机器学习实战】Machine Learning in Action 代码 视频 项目案例

    MachineLearning 欢迎任何人参与和完善:一个人可以走的很快,但是一群人却可以走的更远 ApacheCN - 学习机器学习群[629470233] Machine Learning in ...

  6. 【论文阅读】Federated Learning应用扩展合集

    2020-MM-Performance Optimization for Federated Person Re-identification via Benchmark Analysis 动机:联邦 ...

  7. 【综述翻译】Deep Learning for Video Game Playing

    深度强化学习实验室 原文来源:https://arxiv.org/pdf/1708.07902.pdf 翻译作者:梁天新博士 编辑:DeepRL 在本文中,我们将回顾最近的Deep Learning在 ...

  8. 【新功能】SAP Learning Hub部分电子书支持下载啦

    体验升级! 部分SAP Learning Hub电子书支持下载,可保存电子版本了! 随时查阅更方便,学习无障碍! 还没有SAP Learning Hub? 私信我们,即刻订阅,立享SAP最新培训资源. ...

  9. 【论文翻译】Machine learning: Trends,perspectives, and prospects

    论文题目:Machine learning: Trends, perspectives, and prospects 论文来源:Machine learning: Trends, perspectiv ...

最新文章

  1. keepalived介绍
  2. 大家买PDA干什么,来看SPB的调查
  3. 5.Xilinx RapidIO核例子工程源码分析
  4. opencv bug 合集
  5. OpenCV SURF FLANN匹配单应性的实例(附完整代码)
  6. linux非阻塞的socket EAGAIN的错误处理【转】
  7. python元组取值_Python基础之元组
  8. 1.4编程基础之逻辑表达式与条件分支_16三角形判断(9分)
  9. php之time的用法,php中time()与$_SERVER[REQUEST_TIME]用法区别
  10. Docker存储卷基本操作
  11. 【MySQL】MySQL的帮助文档
  12. SBI旗下交易所SBI VC Trade推出比特币借贷服务
  13. 基于台达PLC的步进电机控制
  14. 6-5 统计二叉树叶子结点个数 (10 分)(C语言版)
  15. mysql数据库默认管理员是_数据库管理员密码的设置
  16. c# tcpclient 连接超时的设置
  17. 配置计算机能不能关机,详细教你电脑自动关机怎么设置
  18. powerBI使用概览
  19. 基于 DirectShow 实现 SourceFilter 常见问题分析
  20. Windows11任务栏无法透明化解决办法

热门文章

  1. matplotlib之hist详解
  2. CSS高度自适应 height:100%;
  3. 中国化工发展的新态势
  4. css设置宽高相等,高度自适应
  5. 自动获取IP发生IP冲突的问题
  6. python中虚拟环境的创建virtualenv workon
  7. PyCharm安装QT界面设计器
  8. IM即时通讯-2-如何做技术方案设计
  9. jQuery for 循环图片列表
  10. 将应用程序添加到鼠标右键