干货 | 转型人工智能,你需要掌握的八大神经网络
为什么我们需要机器学习?
机器学习可以解决人类不能直接用编程来应对的复杂难题,因此,我们喂给机器学习算法大量的数据,以期得到想要的答案。
我们来看看这两个例子:
编写解决问题的程序是非常困难的,比如在杂乱的场景中,在新的照明条件下从新的角度来识别三维物体。我们不知道要如何通过代码来解决这个问题,因为这个识别过程在大脑中完成情况对我们来说还是未解之谜。 即使我们知道该怎么做,要编写的程序可能会非常复杂。
再比如,编写一个程序来预测信用卡交易欺诈发生的概率也是很难的,这可能也不存在任何简单而可靠的规则。因为欺诈是一个动态的目标,但程序需要不断变化。我们需要做的是结合大量的弱项规则来进行欺诈预测。
再者是机器学习方法。我们并不需要为每个特定的任务手动编写程序,而是收集大量的例子,为给定的输入指定正确的输出。然后,机器学习算法拿这些例子,并产生一个程序来完成这项工作。
学习算法产生的程序可能与典型的手写程序看起来非常不同。它可能包含数百万的数字。如果方法得当,该计划将适用于新案例以及我们训练的案例。如果数据改变,程序也可以通过对新数据进行训练来改变。你应该注意到,现在大量的计算比支付某人编写任务特定的程序来的更廉价。
鉴于此,机器学习能够很好地解决一些任务,包括:
模式识别
:真实场景中的对象,面部识别或面部表情,口语等;
异常情况识别
:信用卡交易的异常顺序,核电厂传感器读数的异常模式等;
预测
:未来的股票价格或货币汇率,一个人会喜欢的电影等。
什么是神经网络?
神经网络
是一般机器学习中的一类模型,它是一套特定的算法,受到生物神经网络的启发,彻底改变了机器学习的领域。目前所谓的深度神经网络的出现就已经证明它能够工作得非常好。
神经网络本身就是一般泛函数的逼近,这就是为什么它们几乎可以应用于任何机器学习问题,因为所有的机器学习都是学习从输入到输出空间的复杂映射。
以下是说服你学习神经计算的三个理由:
能够理解大脑是如何工作的
:这是非常大且复杂的问题,并且是个令人绞尽脑汁去思考的问题,因此我们需要使用计算机来模拟。
能够了解受神经元和自适应连接启发的并行计算风格
:这是一种与顺序计算非常不同的风格。
通过使用受大脑启发的新颖学习算法来解决实际问题
:即使这不是大脑实际工作的方式,但这样的学习算法也是非常有用的。
在这篇文章中,我想分享八种神经网络架构,这是每一位从事机器学习的研究人员都应该熟悉的。
?
一般来说,这些体系结构可以分为以下三类:
1 - 前馈神经网络
这是在实际应用中最常见的一种神经网络类型。第一层是输入,最后一层是输出。如果有多个隐藏层,我们称之为“深度”神经网络。它们计算出一系列改变案例之间相似性的转换。各层后紧接着的非线性函数用于各层神经元的激活。
2 -
在神经网络结构的连接图中决定了循环的方向。这意味着你有时可以按照箭头回到你开始的地方。循环神经网络的结构更接近生物的实际情况,其结构有很复杂的动态过程,这使得这种神经网络有时候难以训练。但是,目前已经有大量有趣的研究已经找到一些有效的方式来训练循环神经网络结构。
循环神经网络是一种非常自然地模拟连续数据的方式,类似每个时间片都具有一个隐藏层的深层神经网络。除了能在每个时间片上获得输入并使用相同的权重进行训练外,循环神经网络还能长时间地记住隐藏状态的信息。但目前还很难训练循环神经网络来使用这些隐藏的状态信息。
3 - 对称连接网络
对称连接网络是一种类似循环神经网络结构的神经网络,但是其单元之间的连接是对称的(它们在两个方向上具有相同的权重)。对称连接网络的结构比循环神经网络更容易分析,因为其遵循能量函数。
没有隐藏单元的对称连接网络被称为“Hopfield网络”。有隐藏单元的对称连接网络被称为“Boltzmann机”。
▌ 1.
感知器
感知器作为第一代神经网络,还只是单个神经元的计算模型。它们在二十世纪六十年代初被 Frank Rosenblatt 推广。1969年,Minsky和Papert出版了一本名为“感知器”的书,分析了这种神经网络模型可以做什么,并提到了它的局限性。许多人认为这些局限性限制了所有的神经网络模型。然而,目前感知器的学习过程仍然被广泛应用于具有包含数百万特征的巨大特征向量任务。
在统计与模式识别的标准样例中,我们首先将原始输入向量转换为特征的激活向量。然后,基于常识的手写程序,我们为其定义特征。接下来,我们学习如何对每个特征激活向量进行加权计算以获得单个标量值。
如果这个数值高于某个阈值,我们认为输入向量是属于目标类的一个正样本。标准的感知器体系结构遵循前馈神经网络模型,这意味着输入被馈送到神经元,被处理,并产生输出。
在下图中,可以看到网络自下而上读取:输入从底部输入,输出从顶部输出:
然而,感知器确实有局限性。如果你遵循手动选择特征的原则,并且使用了足够多的特征,则几乎可以做任何事情。对于二进制输入向量,我们可以为每个指数级的二进制向量分别设置一个特征单元,因此我们可以对二进制输入向量进行任何可能的区分。但是一旦确定了手工编码的特征,感知器所能学习的东西将会受到很多的限制。
这个结论对于感知器是毁灭性的,因为整个模式识别的重点是识别模式。Minsky and Papert 研究组提出的“群体不变定理”说明,一部分感知器的学习,如果转换形成一个群体,那么感知器将无法学习。为了处理这种转换,感知器需要使用多个特征单元来识别信息子模式的转换。所以模式识别的棘手部分必须由手工编码的特征检测器来解决,而不是学习过程。
没有隐藏单元的网络是非常受限的,因为它们只能学习输入到输出的映射。由于网络结构仍然是线性的,更多的线性单位层不会帮助也无法改善这个问题。固定输出的非线性也是不够的。因此,我们需要多层自适应非线性隐藏单元。
但是我们要如何训练这样的网络呢?
我们需要一种能够适应所有层权重的有效方式,而不仅仅是最后一层。这很难,因为学习隐藏单元的权重等同于学习特征,但没有人能直接告诉我们隐藏单元应该做什么。
▌ 2. 卷积神经网络
机器学习研究已经广泛地集中在目标检测问题上。在很多情况下识别目标是很困难的,如下:
分割
:真实的场景与其他对象混杂在一起。很难判断哪些作品是同一个对象的一部分。对象的部分也可以隐藏在其他对象的后面。
光照
:像素的强度由照明和目标物共同决定。
变形
:目标物可以以各种非仿射方式变形。例如,手写的形状可以是一个大的循环,也可以是一个尖头。
可用性
:对象类通常由它们的使用方式来定义。例如,椅子是为了能够坐在上面而设计的,因此它们具有各种各样的物理形状。
角度
:标准学习方法无法应对由视角变化而导致的图像变化,即输入维度(像素)之间的信息跳跃。
设想有一个医疗数据库,病人的年龄是输入维度是权重的编码。如果要用机器学习方法,我们首先要消除这个维度跳跃。
?
复制特征的方法是目前神经网络解决目标检测问题的主要方法
。它使用具有不同位置的相同特征,来为检测器提供许多不同副本。它也可以在规模和方向上进行复制,但这是棘手和昂贵的。复制时使用几种不同的特征类型,每种都有自己的复制映射图,但是会大大减少了学习时可用参数的数量。
复制也允许以各种方式来表示每个图像块。
那么复制这些特征检测器是如何实现的呢?
等效激活
:神经网络对复制的特征,具有翻译平移不变形。神经元的激活函数对特征复制的效果也是一样的 。
不变的知识
:如果一个特征训练期间在某些位置是有用的,那么在测试期间该特征的检测器将在所有位置都可用。
1998年,Yann LeCun和他的同事开发了一种名为LeNet的手写数字识别器。它在具有许多隐藏层的前馈网络中使用反向传播,在每层中复制许多单元的映射,并对附近复制单元的输出进行池化操作,即使重叠也能够同时处理几个字符。这是一种用聪明的方式训练出得完整系统,而不仅仅是一个识别器。后来人们正式地称之为“卷积神经网络”。
有趣的是,这种神经网络模型被用来读取北美地区约10%的支票。
卷积神经网络
可用于从手写数字到3D对象的所有与物体识别有关的工作。但是,从网络下载的彩色照片中识别真实的物体通常要比识别手写的数字复杂得多。对于三维场景的二维图像,有1000多个类别(1000 vs 10个),百倍像素值(256×256彩色图 vs 28×28灰度图),场景聚类需要应用图像分割技术,并得到每张图像中的多个目标。相同类型的卷积神经网络会起作用吗?
ILSVRC-2012 ImageNet竞赛,这是一个包含大约120万张高分辨率训练图像的数据集。测试图像将不会显示初始的注释 (没有分割或标签),算法将产生指定图像中存在对象的标签。一些最优秀的计算机视觉方法是由来自牛津,INRIA,XRCE等研究团队提出的。通常,计算机视觉系统使用复杂的多层次网络系统,在训练开始阶段会通过优化几个参数来进行手动调整。
?
2012年竞赛的获胜者Alex Krizhevsky(NIPS 2012) 继承了Yann LeCun的模型结构,开创性地提出一种非常深的卷积神经网络类型。其架构包括7个隐藏层,不包括一些最大池化层。网络结构由卷积层组成,而最后两层是全连接层。
在每个隐藏层中,激活函数使用修正线性单位函数。模型的训练比logistic units更快,特征表征更具有表现力。
除此之外,当附近的单位有更强的激活性时,模型还使用竞争性的正则化策略来抑制隐藏层激活。当图像强度变化时,这种策略将有助于模型对于特征的学习。还有一些训练技巧能够显著提高神经网络的泛化能力:
在 256 x 256 图像上随机截取 224 x 224 大小的图像以获取更多数据并使用图像的左右反射进行训练。在测试阶段,结合来自10个不同的图像块:四个 224 x 224 的图像角块加上中央的 224 x 224 图像块再加上这5个图像的反射块。
使用“
Dropout
”来调整全连接层(包含大部分模型参数)的权重。Dropout意味着对于每个训练样本来说,一层网络中的一半隐藏单元会被随机移除,这使得该层隐藏单位不再依赖其他层的隐藏单元。就硬件要求而言,AlexNet卷积神经网络在2个 Nvidia GTX 580 GPU (超过1000个快速小内核) 上得到了非常高效的实现。 GPU非常适合矩阵乘法,并且具有非常高的内存带宽。 这使得AlexNet模型可以在一周内训练网络,并能够在测试阶段快速地结合10个图像块的结果。
如果我们可以足够快地更新网络状态,那么就可以在很多内核上传播一个网络。随着内核越来越便宜,数据集越来越大,相比传统计算机视觉系统,大型神经网络模型的性能将提高得更快。
▌ 3. 循环神经网络
为了理解循环神经网络模型,我们需要对序列建模进行简要概述。当将机器学习应用于序列时,我们经常希望将输入序列转换为不同域中的输出序列。例如,将一系列的声压转换成一系列的单词。
当没有单独的目标序列时,我们可以通过尝试预测输入序列中的下一项来获得学习的信号。目标的输出序列是提前一步的输入序列,这似乎比尝试预测图像中其他像素的一个像素或图像其余部分的一个像素来的更自然。
预测序列中的下一个术语模糊了有监督学习和无监督学习之间的区别。它使用专为监督学习而设计的方法,但它不需要单独的学习信号。
无记忆模型
是这个任务的标准方法。具体而言,自回归模型可以从先前固定数量的术语中使用“延迟抽头”来预测序列下一项;而前馈神经网络是使用一层或多层非线性隐藏单元的广义自回归模型。
但是,如果我们给生成模型一些隐藏的状态,而这个隐藏的状态又有一个内部的动态,我们就会得到一个更有趣的模型:它可以长时间地将信息存储在隐藏状态。
如果动态是带噪声的,那么从隐藏状态产生输出的方式也是带噪声的,我们永远无法知道它的确切的隐藏状态。我们能够做的是推断隐藏状态矢量空间的概率分布。这种推断只适用于两种隐藏状态模型。
循环神经网络
是非常强大的,因为它们结合了两个属性:
1) 分布式隐藏状态:允许网络有效地存储大量有关过去的信息;
2) 非线性动态:允许模型能够以复杂的方式更新隐藏状态。
有了足够的神经元和时间,循环神经网络能够计算任何通过计算机可以计算出来的东西。
那么循环神经网络可以展现出什么样的行为呢?
它们可以摆动,可以定点吸引,还可以表现出混乱,而且它们还可以通过学习来实现大量的小程序,每个小程序能够捕获一小块知识并且并行运行,相互作用来产生非常复杂的效果。
然而,循环神经网络的计算能力使得这种网络结构很难训练,因为会有梯度爆炸或消失的问题。当我们通过多层次的反向传播时,如果权重很小,梯度将呈指数缩小。如果权重很大,梯度会呈指数增长。
典型的前馈神经网络可以应付这些梯度的指数效应,因为它们只有一些隐藏层。另一方面,在训练长序列的循环神经网络时,梯度很容易爆炸或消失。即使是具有良好的初始权重的网络模型,也很难检测到当前目标输出对来自多个时间步骤输入的依赖,因此循环神经网络难以处理远程依赖性。
基本上,有以下四种有效的方法来学习循环神经网络:
长短期记忆块
:使循环神经网络脱离长时间记忆值依赖的小模块。
Hessian Free Optimization
:通过使用优化器来处理消失梯度问题,该优化器可以检测具有微小梯度和更小曲率的方向。
回声状态网络
:初始化输入 ->隐藏层和隐藏层 ->隐藏层和输出 ->隐藏连接,可以通过输入选择性地驱动该振荡器,以便让隐藏状态具有巨大的弱耦合振荡器。
良好的动态初始化
:像回声状态网络一样初始化,然后使用动量来学习所有的连接。
▌ 4.
长短期记忆网络
Hochreiter & Schmidhuber (1997) 通过构建长短期记忆网络,解决了循环神经网络长时间记忆)(如数百步时间步骤内)的获取问题。他们使用具有乘法相互作用的逻辑和线性单元来设计存储器单元。
每当“写入”门打开时,信息就会进入单元。信息保持在单元中,只要其“保持”门打开。 信息可以通过打开“读取”门来从单元中读取。
阅读草书手写是循环神经网络处理一个常见任务。 输入是笔尖的 (x,y,p) 坐标序列,其中p表示笔是向上还是向下。输出是一个字符序列。 Graves & Schmidhuber (2009) 表明,带有长短期记忆的循环神经网络是目前处理草书阅读的最佳神经网络系统。 简而言之,他们使用一系列小图像作为输入而不是笔坐标。
?
▌ 5. Hopfield网络
具有非线性单元的周期性神经网络通常难以分析。它们可以以许多不同的方式呈现:由稳定到稳定的状态,中间有振荡,或者遵循不可预测的混沌轨迹。一个Hopfield网络由二元门限单元组成,它们之间有连续的连接。
1982年,Hopfield认识到,如果连接是对称的,就是一种全能量函数。整个网络的每个二进制“配置”都具有能量;而二进制阈值决策规则是导致网络是根据这个能量函数的最小值而定的。
利用这种类型进行计算的一种便捷方式是,使用记忆作为神经网络的能量最小值,使用能量最小值来表示可访问内容的内存。一个项目可以通过只知道其部分内容信息来访问。这对硬件的损损伤是巨大的。
每当我们对配置进行一次记忆,我们就希望创造一个新的能量最小值。但是,如果在中间位置附近有两个最小值呢?
这受限于Hopfield网络的容量。那么我们如何增加Hopfield网络的容量呢?物理学家喜欢用他们已经知道的数学知识来解释大脑是如何工作的。在物理学期刊上有许多对Hopfield网络及其存储容量方面进行研究的论文。
最终,Elizabeth Gardner发现存在一个更好的存储规则,就是使用权重的全部容量。它是通过多次循环训练集,而非一次性存储向量。并利用感知器的收敛过程来训练每个单元,使其具有正确的状态,并给定该向量中所有其他单元的状态。统计学家称这种技术为“伪可能性”。
Hopfield网络还有另一个计算角色,我们用它来构建感官的输入解释。“输入”用可见的单元表示,“解释”用隐藏单元的状态表示,解释的好坏情况用能量表示。
▌
6. 玻尔兹曼机网络
玻尔兹曼机
是一种随机性的循环神经网络。它可以被看作是Hopfield网络的随机生成产物。它是第一个能够学习内部表示的神经网络之一,能够表示和解决困难的组合问题。
?
作为机器学习算法的一种,玻尔兹曼机的学习目标是通过玻尔兹曼机分配给训练集中的二进制向量来最大化概率的乘积。
这相当于最大化玻尔兹曼机分配给训练向量的对数概率之和。也就是说,如果我们做了如下的事情,我们可以得到N个训练样本的最大化概率:
1) 让网络在没有外部输入的情况下,处于不同时间的稳定分布状态;
2) 每次采用可见的向量。
2012年,Salakhutdinov 和 Hinton 提出了玻尔兹曼机高效的小批量学习程序。
正相阶段
,首先将隐藏概率初始化为0.5,将数据向量固定在可见单元上,然后将所有隐藏单元进行并行更新,使用平均场更新策略直到最终收敛。在网络收敛之后,记录每个连接单元对的PiPj值,并在最小批量中对所有数据进行平均化。
负相阶段
:首先保留一组“幻想粒子”。每个粒子的值都是全局配置,然后依次更新每个幻想粒子中的所有单位,重复数次。对于每一个连接单位对,平均化所有“幻想粒子”的SiSj值。
对于普通的玻尔兹曼机而言,单元的随机更新是需要连续进行的。有一种特殊的体系结构允许波尔兹曼机交替地并行更新 (层内没有连接,没有跳层连接的结构)。这是高效的一种结构。
这种小批量程序使玻尔兹曼机器的更新更加并行化,也就是所谓的深玻尔兹曼机,而一个普通的玻尔兹曼机会有很多缺失的连接。
2014年,Salakhutdinov 和 Hinton 为他们的模型提出了另一个更新形式,称之为受限玻尔兹曼机。他们限制了玻尔兹曼机的连通性使得模型的推理和学习过程变得更容易 (隐藏单元只有一层,而隐藏单元之间没有连接)。在玻尔兹曼机中,当可见单元被固定时,只需要一步就能达到热平衡。
另一种有效的小批量玻尔兹曼机的学习程序是这样的:
对于正相阶段,首先在可见单元上固定一个数据向量,然后计算所有可见和隐藏单元对的 <ViHj> 的准确值。对于每个连接的单元对,平均化小批量中所有数据的 <ViHj> 值。
对于负相阶段,也要保留一组“幻想粒子”。然后通过交替式并行更新策略来更新每个幻想粒子,重复数次。对于每个连接的单位对,平均化所有幻想粒子的 <ViHj> 值。
▌ 7. 深度置信网络
反向传播被认为是人工神经网络中的一种标准方法,用于在处理完一批数据后,计算出每个神经元对误差的贡献值。
但是,反向传播存在一些问题。首先,它需要带标记的训练数据,但几乎所有的数据都是没有标签的。其次,学习时间的范围不够理想,这意味着隐藏层数量多的网络反向传播过程将变得很慢。第三,它可能会陷入局部最优值而无法达到全局最优状态。所以对于深度神经网络来说,这些是远远不够的。
为了克服反向传播的限制,研究人员已经考虑使用无监督的学习方法,它将有助于保证使用梯度方法来调整权重的效率和简单性,还可以用它来对感知输入的结构进行建模。特别是,权重的调整可以使得生成模型产生的感知输入的概率最大化。
问题在于,我们应该学习什么样的生成模型?可以建立像玻尔兹曼机器一样的能量模型吗?还是由理想化的神经元组成的因果模型?或者两者混合?
置信网络是一种由随机变量组成的有向无环图网络模型
。使用置信网络,我们可以观察到一些变量,我们想要解决2个问题:
1)
推理问题:推断未观测变量的状态;
2)
学习问题:调整变量之间的交互作用,使网络更有可能产生训练数据。
早期的图模型使用专家来定义图模型的结构和条件概率。那时,图模型是稀疏连接的,所以研究人员最初的研究重点是做出正确的推论,而不是学习。
对于神经网络来说,学习是重心,手写知识并不是最优的做法,因为知识可以通过学习训练数据得到。神经网络的目的不在于那些便于推理的可解释性或稀疏连接性。目前,深度置信网络可以来解决这些问题。
由随机的二元神经元组成的生成神经网络有两种类型:
1)基于能量的网络模型
,利用对称连接形式来连接二元随机神经元,得到玻尔兹曼机;
2)基于因果关系的网络模型
,其中我们连接一个有向无环图中的二进制随机神经元得到Sigmoid型的深度置信网络。
不过,这两种类型都超出了本文阐述的范围。
▌
8.
深度自动编码器
最后,我们来讨论深度自编码器。对于非线性降维,深度自编码器看起来是一种非常好的方式,主要是因为,它们提供了两种灵活的映射方式。训练样本的学习时间是线性的(或更好的形式)。最终的编码模型也相当紧凑和快速。
然而,使用反向传播来优化深度自编码器是非常困难的。在初始权重较小的情况下,反向传播过程中梯度将消失。优化办法就是,要么使用无监督的逐层预训练,要么像回声状态网络那样小心地初始权重。
对于预训练任务,实际上有三种不同类型的浅自动编码器:
用玻尔兹曼机作为自编码器
:当我们用对比发散来训练一个玻尔兹曼机时,它试图进行数据重建。它就像个自编码器一样,但是它通过使用隐藏层中的二进制激活来强化正则化过程。当运用最大可能性策略训练后,玻尔兹曼机则不像自编码器。我们可以用一堆浅自编码器来替换用于预训练的玻尔兹曼机堆栈;然而,如果浅自编码器通过惩罚平方权重项而被正则化,那么预训练就不是有效的。
去噪自编码器
:通过将其许多分量设置为0 (如dropout,但是用于输入),将噪声添加到输入向量。它们仍然需要重建这些组分,因此它们必须提取到输入之间相关性的特征。如果我们使用自编码器堆栈的话,那么预训练将会与玻尔兹曼机预训练一样好或者更好。评估预训练的过程也将更简单,因为我们可以很容易地计算目标函数的值。但是它缺乏的是使用玻尔兹曼机所能获得的好的变分边界,但这只是理论上的兴趣。
压缩自动编码器
:另一种正则化自编码器的方法是尝试使隐藏单元的激活对输入尽可能不敏感,但是自编码器不能忽视这些投入,因为他们必须重建这些输入。我们通过惩罚每个隐藏层的激活相对于输入的平方梯度来达到这个目的。在训练开始前,压缩自编码器工作得很好,而这种性质只倾向于那些对输入变化敏感的小部分隐藏单元。
简而言之,现在有很多不同的方法能够对特征进行逐层预训练。对于没有大量标记样本的数据集而言,预训练模型将有助于模型后续的判别式学习。对于非常大的标记数据集,使用无监督预训练对监督学习中使用的权重进行初始化并不是必须的,即使对于深度网络也是如此。预训练是初始化深网权重的第一个好方法,但是现在还有其他方法。但是,如果我们把网络变得更大,我们将需要再次进行预训练!
▌
最后的忠告
神经网络是有史以来最棒的编程范例之一。在传统的编程方法中,我们告诉计算机做什么,将大问题分解成精确定义的小问题,这样计算机可以轻松地执行。相比之下,在神经网络中,我们不告诉计算机如何解决问题,而让神经网络能够从观测数据中学习,找出手头问题的解决办法。
今天,深度神经网络和深度学习技术在计算机视觉,语音识别和自然语言处理等许多重要问题上取得了出色的表现,它们正在被Google,微软和Facebook等公司大规模部署。
如果想要了解更多,可以下载观看Geoffrey Hinton的课程!
作者 | James Le
原文链接:
http://medium.com/@james_aka_yale/the-8-neural-network-architectures-machine-learning-researchers-need-to-learn-2f5c4e61aeeb
翻译 | AI科技大本营(rgznai100)
参与 | 林椿眄
编辑 | Donna
转载声明
:本文转载自「AI科技大本营」,搜索「rgznai100」即可关注。
- 庄家做庄一只股票需要多少筹码,干货分享
- 郭广昌的跨年演讲,全是干货
- 远策投资张益驰:龙头集中、传统行业崛起 关注创新药、人工智能
- 【人物】张继科30岁生日,三十而立面临转型,将何去何从?
- 人工智能可以3D建模了?3D打印未来无需自己建模
- 一步天堂,一步地狱,一招干货教你躲过数字货币的泡沫
- 拼经济,促就业,谋转型南非总统拉马福萨国情咨文点燃新希望
- 新年干货 | 你想知道的春节英语词汇都在这里啦!
- 除夕送干货!买涨好还是买跌好?这是最靠谱的答案
- 干货,春节假期出行最强攻略!