《Learning to Compare: Relation Network for Few-Shot Learning》

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《Learning to Compare: Relation Network for Few-Shot Learning》相关的知识,希望对你有一定的参考价值。

参考技术A         深度学习模型在视觉识别任务中取得了巨大的成功。然而,这些监督学习模型需要大量的标记数据和许多迭代来训练它们大量的参数。由于标注成本的原因,这严重限制了它们对新类的可拓展性,但从根本上限制了它们对新出现的或是很少出现的类的适用性。在这些类别中,大量注释的图像可能根本不存在。相比之下,人类在几乎没有直接监督或根本没有监督的情况下却非常擅长识别物体,例如小样本学习或零样本学习。例如,孩子们可以毫不费力地从书中的一张图片中或者在听到它看起来像一匹条纹马的描述时可以归纳出“斑马”的概念。由于传统的深度学习方法在每一类上只有一个或几个样例都无法很好地发z挥作用,再加上人类对小样本学习和零样本学习的学习能力,最近人们对机器小样本学习和零样本学习的兴趣又重新燃起。

        小样本学习旨在从极少的标记例子中识别新的视觉类别。只有一个或很少几个例子的可用性挑战了深度学习中的标准的“微调”实践。在这种数据有限的情况下, 数据增强 和 正则化技术 可以缓解过拟合问题,但并不能解决这个问题。因此,当代的小样本学习方法常常将训练分解为一个辅助元学习阶段,在这个阶段中,可转移知识以良好的初始条件、嵌入(?)或优化策略的形式学习。目标小样本学习问题是通过微调与学习优化策略或计算前馈通过不更新网络权值来学习的。零样本学习也会受到相关挑战的影响。识别器是通过类描述形式的单个例子来训练的,这使得基于梯度学习的数据不足成为一个难题。

        尽管前景很好,但大多数现有的小样本学习方法要么需要复杂的推理机制,复杂的递归神经网络(RNN)架构,要么对目标问题进行微调。我们的方法与其他旨在训练一次性学习的有效度量标准的方法密切相关,其中这些方法专注于可转移嵌入的学习,并预先定义了一个固定的度量(例如,欧几里得距离),我们进一步的目标是学习一个可转移的深度度量来比较图像之间的关系(小样本学习),或图像和类描述之间的关系(零样本学习)。通过表达更深层次解决方案的归纳偏差(在嵌入和关联模块上的多个非线性学习阶段),我们可以更容易地学习到问题的可推广解决方案。

具体地说,我们提出了一个 双分支关系网络(RN) ,它通过学习比较查询图像和标记为小样本图像的样本来完成小样本的识别。首先, 嵌入模块 生成查询图像的表示并且训练图像。然后,使用 关系模块 对这些嵌入进行比较,确定它们是否来自匹配的类别。受[39,36]的启发,定义了episode-based策略,嵌入模块和关系模块是元学习、端到端的,以支持小样本学习。这可以被看作是扩展了[39,36]的策略,包括一个可学习的非线性比较器,而不是一个固定的线性比较器。我们的方法优于以前的方法,同时更简单(没有RNNs)和更快(没有微调)。我们提出的策略也直接推广到零样本学习。在这种情况下,样本分支嵌入一个单样本的类别描述,而不是一个单一的样本训练图像,并且关系模块学习比较查询图像和类别描述嵌入。

总的来说,我们的贡献是提供了一个显而易见的框架,包含了小样本学习和零样本学习。我们对四个基准测试的评估表明,它在整体上有比较引人注目的性能,同时比其他替代方案更简单、更快。

对零样本或小样本目标识别的研究一直是人们关注的焦点。早期关于小样本学习的工作往往涉及具有复杂迭代推理策略的生成模型[9,23]。随着有区别的深度学习方法在数据丰富的多样本学习环境中的成功,人们对将这种深度学习方法推广到小样本学习环境产生了浓厚的兴趣。这些方法使用元学习或学会学习策略在某种意义上,他们从一组辅助任务中提取一些可转换的知识(元学习,学会学习),然后帮助他们学习好目标域小样本问题没有遭受时可能的过度拟合应用深度模型数据稀疏问题。

Learning to Fine-T une. 成功的MAML方法旨在元学习一个初始条件(一组神经网络权值),这有利于微调小样本问题。这里的策略是搜索给定神经网络的权重配置,这样它就可以在几个梯度下降更新步骤内有效地微调到稀疏数据问题上。从一个多任务训练集中采样许多不同的目标问题;然后对基本神经网络模型进行微调,以解决每一个问题,并且在微调驱动后在基本模型中更新每一个目标问题——从而驱动一个易于微调的初始条件的产生。[29]的小样本优化方法在元学习方面更进一步,不仅是一个良好的初始条件,而且是一个基于LSTM的优化器,这个优化器经过训练可有效用于微调。然而,这两种方法都需要对目标问题进行微调。相反,我们的方法以完全前馈的方式解决目标问题,不需要模型更新,使其更方便用于低延迟或低功耗的应用。

RNN Memory based. 另一类方法利用带记忆的循环神经网络。这里的思想是,典型的RNN迭代给定问题的一个例子,并在其隐藏的激活或外部记忆中积累解决该问题所需的知识。新实例可以分类,例如通过将它们与存储在存储器中的历史信息进行比较。因此,在展开RNN的过程中,可以“学习”单一目标问题,而“学习中学习”意味着通过学习许多不同的问题来训练RNN的权值。虽然这些架构很吸引人,但它们面临的问题是如何确保可靠地存储所有可能是长期的、相关的历史信息而不被遗忘。在我们的方法中,我们避免了递归网络的复杂性,以及确保其内存充足所涉及的问题。相反,我们的“学会学习”的方法完全定义为简单而快速的前馈CNN。

Embedding and Metric Learning Approaches. 在学习目标小样本问题时,前面的方法有一定的复杂性。另一类方法的目的是学习一组投影函数,该函数从目标问题中提取查询图像和样本图像,并以前馈方式对其进行分类。一种方法是根据样本集来参数化前馈分类器的权重。这里的元学习训练辅助参数化网络,该网络学习如何参数化给定前馈小样本集的分类问题。基于度量学习的方法旨在学习一组投影函数,当在此嵌入空间表示时,图片很容易使用简单的最近邻或是线性分类器被识别到。在这种情况下,元学习到的可转移知识是投影函数,并且目标问题是一个简单的前馈计算。与我们最相关的方法是原型网络和暹罗网络。这些方法集中于学习一个嵌入空间,该嵌入空间转换数据,这样它可以被一个固定的最近邻或线性分类器识别。相比之下,我们的框架进一步定义了一个 关系分类器CNN ,与[20,36]相比,这可以被视为提供了一个可学习的而不是固定的度量,或非线性而不是线性分类器。与[20]相比,我们受益于从头开始的端到端的episodic training策略,与[32]相比,我们避免了集合到集合的RNN嵌入样本集的复杂性,并且仅仅依赖于pooling[33]。

Zero-shot Learning. 我们的方法是为小样本学习而设计的,但是通过修改样本分支输入单一的类别描述,而不是单一的训练图像可以使我们的方法跨越到零样本学习(ZSL)的空间。当应用到ZSL时,我们的架构与涉及到学习对齐图像和类别嵌入以及通过预测图像和类别嵌入对是否匹配来进行识别的方法有关。与之前基于度量的小样本方法类似,这些方法大多在结合图像和嵌入类别后,使用一个固定的人工定义的相似性度量或线性分类器。相比之下,我们再次受益于更深层次的端到端架构,包括以我们所学到的卷积关系网络形式的非线性度量;以及以episode为基础的训练策略。

我们考虑了小样本分类器的学习任务。正式地来说,我们有三个数据集:一个训练集,一个支持集,和一个测试集。支持集和测试集共享相同的标签空间,但训练集都有自己的标签空间与支持集或测试集不相交。如果支持集在每个独特的C个类中包含K个标记样本,那么目标小样本问题就被叫做 C-way K-shot 。

仅在支持集上,原则上我们可以在测试集中为每一个 训练一个分类器分配一个类标签 。然而,由于支持集中缺少标签样本,这样一个分类器的性能通常是不能令人满意的。因此,我们的目标是在训练集上进行元学习,以提取可转移知识,使我们在支持集上进行更好的小样本学习,从而更成功地对测试集进行分类。

利用训练集的一种有效方法是通过基于episode的训练来模拟小样本学习的设置。在每一次训练的迭代中,一个episode是由从训练集中随机抽取C个类,每个类中有K个标记样本,作为样本集S( )及查询集Q( )(其余C类示例的一部分而构成的)。这个查询集分割为支持集/测试集。如果需要,从样本集/查询集训练出来的模型可以使用支持集进一步进行微调。在这项工作中,我们采用了这样一种基于episode的训练策略。在我们的小样本实验(见4.1节)中,我们考虑了单个样本(K = 1,图1)和五个样本的(K = 5)设置。我们还将处理K = 0零样本学习案例,如3.3节中所解释的。

one-shot. 我们的关系网络(RN)包括两个模块:一个嵌入模块 和关系模块 ,如图1所示。查询集Q中的样本 ,和样本集S中的样本 输入到嵌入模块 ,产生特征图 和 。特征图 和 通过operator结合起来 。在这项工作中,我们假设 是深度特征图的连接,尽管也可能有其他选择。将支持集和查询集的组合特征图输入关系模块 ,最终产生一个在0 - 1范围的表示 和 相似度的标量,称为关系得分。因此,在C-way one-shot设置中,我们生成了查询输入 和支持集样本 间对应的C个关系得分 :

K-shot. 对于K-shot,其中K >1,我们对每个训练类的所有样本的嵌入模块输出按元素求和,形成该类的特征图。这个合并的特征图与上面的查询图像特征映射结合在一起。因此,在one-shot或few-shot设置中,一个查询图的关系分数总是C个。

Objective function. 我们使用均方误差(MSE)损失(Eq.(2))来训练我们的模型,regressing the relation score to the ground truth: 匹配的对相似度为1,不匹配的对相似度为0。MSE的选择有些不标准。我们的问题似乎是一个标签空间0,1的分类问题。然而,我们在概念上预测的是关系得分,这可以被认为是一个回归问题,尽管对于ground-truth,我们只能自动生成0,1目标。

Zero-shot learning类似于one-shot learning,即给出一个数据来定义要识别的每个类。然而,它并没有为每个C训练类提供一张图片的支持集,而是为每个C训练类包含一个语义类嵌入向量 。修改我们的框架来处理zero-shot问题很简单:作为一个不同的形态语义向量用于支持集(例如,属性向量而不是图片),我们使用第二个异构嵌入模块 除了嵌入模块 用于图像查询集。然后关系网络 还是用之前的。因此,每个查询输入 的关系得分为:

Zero-shot Learning的目标函数与Few-shot Learning的一样。

由于大多数小样本学习模型使用四个卷积块来嵌入模块,为了公平比较,我们遵循相同的架构设置,见图2。更具体地说,每个卷积块分别包含一个64个filter ,大小为3×3、一个BN和一个ReLU非线性层。前两个块还包含一个2×2的最大池化层,而后两个没有。我们这样做是因为我们需要输出特征图,为了关系模块中的卷积层。关系模块由两个卷积块和两个全连通层组成。每个卷积块是一个3×3的卷积,包含64个滤波器,然后是批处理归一化、ReLU非线性和2×2最大池化层。对于数据集Omniglot来说,最后一个最大池化层的输出大小为H = 64,对于数据集miniImageNet来说,H = 64∗3∗3 = 576。这两个完全连接的层分别是8维和1维。除了输出层为Sigmoid外,所有全连通层均为ReLU,以便为我们所有版本的网络架构生成一个合理范围内的关系分数。zero-shot学习架构如图3所示。在这种体系结构中,DNN子网是一个在ImageNet上预先训练好的现有网络(例如,Inception或ResNet)。

settings. 在小样本学习的所有实验中使用Adam,初始学习率为 ,每10万episode退火一半。我们所有的模型都是端到端,从头到尾训练的没有额外的数据集。

baselines. 我们比较了各种现有的先进的小样本识别基线,包括神经统计,有无微调的匹配网络,MANN,有记忆的暹罗网络,卷积暹罗网络,MAML,元网络,原型网络和元学习器LSTM 。

dataset. Omniglot包含来自50种不同字母的1623个字符(类)。每个类别包含20个不同人抽取的样本。在[32,39,36]之后,我们通过对现有数据进行90°,180°和270°的旋转来扩充新的类,并使用1200个原始类加上轮次来进行训练,剩余的423个类加上轮次来进行测试。所有输入图像都被调整到28 × 28。

training. 除了K个样本图像之外,5-way 1-shot包含19个查询图像,5-way 5-shot具有15个查询图像,20-way 1-shot具有10个查询图像,20-way 5-shot对于每个训练集的每个C个样本类具有5个查询图像。这意味着,例如,对于5路单镜头实验,在一个训练集/小批量中有19 × 5 + 1 × 5 = 100个图像。

results. 根据[36],我们在Omniglot上通过对测试集随机生成的1000多集进行平均来计算少镜头分类的准确性。对于1-shot和5-shot实验,我们在测试过程中分别为每个类批处理一个和五个查询图像进行评估。结果如表1所示。在所有实验设置下,我们都获得了最高的性能,平均精度更高,标准偏差更低,除了5-way 5-shot,我们的模型精度比[10]低0.1%。尽管许多替代方案有明显更复杂的机制[27,8],或对目标问题进行微调[10,39],但我们没有。

dataset. miniImagenet数据集最初由[39]提出,由60,000幅彩色图像组成,有100个类别,每个类别有600个例子。我们遵循了[29]中介绍的分割方法,分别为64、16和20节课进行训练、验证和测试。16个验证类仅用于监控概括性能。

training. 遵循大多数现有的少镜头学习工作所采用的标准设置,我们进行了5-way 1-shot和5-shot的分类。除了K个样本图像之外,5-way 1-shot包含15个查询图像,5-way 5-shot在每个训练集对于C个样本类中的每一个都有10个查询图像。这意味着,例如,对于5-way 1-shot实验,在一个训练集/小片段中有15×5+1×5 = 80个图像。我们将输入图像调整到84 × 84。我们的模型是端到端的,从头到尾训练的,随机初始化,没有额外的训练集。

results. 在[36]之后,我们在每集每类中批处理15个查询图像,以在1-shot和5-shot场景中进行评估,并且通过对测试集中随机生成的600多集进行平均来计算小样本分类精度。从表2中,我们可以看到,我们的模型在5-way 1-shot设置上实现了一流的性能,在5-way 5-shot设置上实现了竞争结果。然而,由原型网络[36]报告的1-shot结果要求在每个训练集上训练30-way 15个查询,而5-shot结果在每个训练集上训练20-way 15个查询。当每集训练用5-way15 query训练时,[36]一次评价只得到46.14±0.77%,明显弱于我们。相比之下,我们所有的模型都是在5-way上训练的,每个训练集有1个1-shot查询和5个5-shot查询,训练查询比[36]少得多。

datasets and settings. 我们遵循两个ZSL设置:旧设置和[42]为训练/测试劈叉提供的新GBU设置。在[42]之前的大多数现有ZSL作品所采用的旧设置下,一些测试类也出现在ImageNet 1000类中,这些测试类已经用于对图像嵌入网络进行预处理,从而违反了零镜头假设。相比之下,新的GBU设置确保没有数据集的测试类出现在ImageNet 1000类中。在这两种设置下,测试集只能包含未看到的类别样本(常规测试集设置)或看到的和未看到的类别样本的混合。后者被称为广义零样本学习,在实践中更为现实。两个广泛使用的ZSL基准被选择用于旧的设置:AwA(具有属性的动物)由50类动物的30,745幅图像组成。它有一个固定的评估部分,有40个训练类别和10个测试类别。CUB(Calech-UCSD Birds-200-2011) 包含200种鸟类的11788幅图像,其中有150个可见类和50个不相交的不可见类。选择三个数据集用于GBU设置:AwA1、AwA2和CUB。新发布的AwA2 由50个级别的37322幅图像组成,是AwA的扩展,而AwA1与AwA相同,但在GBU环境下。

Semantic representation. 对于AwA,我们使用来自[24]的连续85维类级属性向量,所有最近的工作都使用了这个向量。对于CUB,使用连续的312维类级属性向量。

Implementation details .在零样本学习中,两种不同的嵌入模块用于两种输入模式。除非另有说明,否则我们使用InceOptionv2[38,17]作为在旧的常规设置中嵌入DNN的查询图像,而使用ResNet101 [16]作为GBU和通用设置,分别将顶部池单元作为维度为D = 1024和2048的图像嵌入。这个DNN是预先训练的ILSVRC 2012 1K分类,没有微调,如最近的深度ZSL工作[25,30,45]。MLP网络用于嵌入语义属性向量。对于AwA和CUB,隐藏层FC1(图3)的大小分别设置为1024和1200,输出大小FC2设置为与两个数据集的图像嵌入相同的维度。对于关系模块,图像和语义嵌入在被馈送到分别具有400和1200 AWa和CUB的隐藏层FC3尺寸的MLPs之前被连接。

我们在FC1和FC2中增加了权重衰减(L2正则化),因为在ZSL的跨模态映射中存在一个中心问题[45],这个问题可以通过将语义特征向量映射到具有正则化的视觉特征空间来最好地解决。之后,使用FC3 & 4(关系模块)计算语义表示(在视觉特征空间中)和视觉表示之间的关系。由于在这一步中不存在傲慢问题,因此不需要L2正则化/重量衰减。所有ZSL模型都是在嵌入网络中用权重衰减105来训练的。用亚当[19]将学习速率初始化为10-5,然后每200,000次迭代退火一半。

Results under the old setting. 对ZSL的常规评估,以及随后的大部分前期工作,是假设测试数据都来自于看不见的类。我们首先评估这个设置。我们在表3中比较了15种替代方法。仅使用属性向量作为样本类嵌入,我们的模型在AwA上获得了有竞争力的结果,在更具挑战性的CUB数据集上获得了最先进的性能,远远超过了最相关的替代原型网络[36]。注意,只考虑归纳法。最近的一些方法[48,12,13]是无效的,因为它们同时使用所有的测试数据进行模型训练,这给了它们很大的优势,但代价是做出了在实际应用中可能无法满足的非常强的假设,因此我们在此不做比较。

Results under the GBU setting. 我们遵循[42]的评估设置。我们将我们的模型与表4中的11个备选ZSL模型进行了比较。10个浅层模型的结果来自[42],最先进的方法DEM [45]的结果来自作者的GitHub第1页。我们可以看到,在AwA2和CUB上,我们的模型在使用调和平均度量测量的更现实的GZSL设置下特别强。而在AwA1上,我们的方法仅优于DEM [45]。

相关的先前少量工作使用固定的预先指定的距离度量,例如欧几里德或余弦距离来执行分类[39,36]。这些研究可以被视为距离度量学习,但是所有的学习都发生在特征嵌入中,并且给定所学习的嵌入,使用固定的度量。同样相关的是传统的度量学习方法[26,7],其集中于学习固定特征表示的浅(线性)马氏度量。与先前工作的固定度量或固定特征和浅学习度量相比,关系网络可以被视为既学习深度嵌入又学习深度非线性度量(相似性函数)2。这些都是端到端的相互调整,在很少的短期学习中相互支持。为什么这可能特别有用?通过使用灵活的函数逼近器来学习相似性,我们可以以数据驱动的方式学习良好的度量,而不必手动选择正确的度量(欧几里德、余弦、马氏)。像[39,36]这样的固定度量标准假设特征仅在元素方面进行比较,而最相关的[36]假设嵌入后的线性可分性。因此,这些严重依赖于学习的嵌入网络的效率,并因此受到嵌入网络产生不充分的区别性表示的程度的限制。相比之下,通过深入学习与嵌入相结合的非线性相似性,关系网络可以更好地识别匹配/不匹配对。

为了说明前面关于学习输入嵌入的充分性的观点,我们展示了一个综合的例子,其中现有的方法肯定会失败,并且我们的关系网络可以由于使用深度关系模块而成功。假设2D查询和样本输入嵌入到关系模块,图4(a)示出了固定2D查询输入的2D样本输入的空间。每个样本输入(像素)根据其是否匹配固定查询而被着色。这表示嵌入模块的输出对于查询和样本集之间的普通(欧几里德神经网络)比较而言不够有区别的情况。在图4(c)中,我们试图通过马氏度量学习关系模块来学习匹配,并且我们可以看到结果是不充分的。在图4(d)中,我们进一步学习了查询和样本输入的2-隐藏层MLP嵌入以及后续的马哈拉诺比斯度量,这也是不够的。只有通过学习相似性的全深度关系模块,我们才能在图4(b)中解决这个问题。

在一个真实的问题中,比较嵌入的困难可能没有这么极端,但它仍然具有挑战性。我们定性地说明了匹配两个Omniglot示例查询图像(投影到2D的嵌入,图5(左))的挑战,方法是显示一个由匹配(青色)或不匹配(洋红色)着色的真实样本图像与两个示例查询(黄色)的类似图。在标准假设[39,36,26,7]下,青色匹配样本应该是具有某种度量(欧几里德、余弦、马氏)的黄色查询图像的最近邻居。但是我们可以看到,匹配关系比这个更复杂。在图5(右)中,我们根据每个查询样本对的2D主成分分析表示绘制了相同的两个示例查询,如关系模块的倒数第二层所示。我们可以看到,关系网络已经将数据映射到一个空间中,在这个空间中,(误)匹配对是线性可分的。

我们提出了一个简单的方法,称为小样本和零样本学习的关系网络。关系网络学习一个用于比较查询和样本项的嵌入和深度非线性距离度量。使用episode训练对网络进行端到端训练,调整嵌入和距离度量,以实现有效的小样本学习。这种方法比最近的小样本元学习方法简单有效得多,并且产生了最先进的结果。它进一步证明了在传统和一般的零样本设置都有效。

How to compare dates in Java

How to compare dates in Java
By mkyong | January 18, 2010 | Updated : November 15, 2016 | Viewed : 930,987 | +4,252 pv/w
Few examples show you how to compare two dates in Java. Updated with Java 8 examples.

1. Date.compareTo()
A classic method to compare two java.util.Date in Java.

Return value is 0 if both dates are equal.
Return value is greater than 0 , if Date is after the date argument.
Return value is less than 0, if Date is before the date argument.
TestDate.java

package com.mkyong.date;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class TestDate {

public static void main(String[] args) throws ParseException {

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date1 = sdf.parse("2009-12-31");
Date date2 = sdf.parse("2010-01-31");

System.out.println("date1 : " + sdf.format(date1));
System.out.println("date2 : " + sdf.format(date2));

if (date1.compareTo(date2) > 0) {
System.out.println("Date1 is after Date2");
} else if (date1.compareTo(date2) < 0) {
System.out.println("Date1 is before Date2");
} else if (date1.compareTo(date2) == 0) {
System.out.println("Date1 is equal to Date2");
} else {
System.out.println("How to get here?");
}

}

}
Output


date1 : 2009-12-31
date2 : 2010-01-31
Date1 is before Date2


2. Date.before(), Date.after() and Date.equals()
A more user friendly method to compare two java.util.Date

TestDate2.java

package com.mkyong.date;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class TestDate2 {

public static void main(String[] args) throws ParseException {

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date1 = sdf.parse("2009-12-31");
Date date2 = sdf.parse("2010-01-31");

System.out.println("date1 : " + sdf.format(date1));
System.out.println("date2 : " + sdf.format(date2));

if (date1.after(date2)) {
System.out.println("Date1 is after Date2");
}

if (date1.before(date2)) {
System.out.println("Date1 is before Date2");
}

if (date1.equals(date2)) {
System.out.println("Date1 is equal Date2");
}

}

}
Output


date1 : 2009-12-31
date2 : 2010-01-31
Date1 is before Date2


3. Calender.before(), Calender.after() and Calender.equals()
Example to compare two java.util.Calendar

TestDate3.java

package com.mkyong.date;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class TestDate3 {

public static void main(String[] args) throws ParseException {

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date1 = sdf.parse("2009-12-31");
Date date2 = sdf.parse("2010-01-31");

System.out.println("date1 : " + sdf.format(date1));
System.out.println("date2 : " + sdf.format(date2));

Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal1.setTime(date1);
cal2.setTime(date2);

if (cal1.after(cal2)) {
System.out.println("Date1 is after Date2");
}

if (cal1.before(cal2)) {
System.out.println("Date1 is before Date2");
}

if (cal1.equals(cal2)) {
System.out.println("Date1 is equal Date2");
}
}

}
Output


date1 : 2009-12-31
date2 : 2010-01-31
Date1 is before Date2
4. Java 8
In Java 8, you can use the new isBefore(), isAfter(), isEqual() and compareTo() to compare LocalDate, LocalTime and LocalDateTime.

Review the following example to compare two java.time.LocalDate

TestDate4.java

package com.mkyong.date;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;

public class TestDate4 {

public static void main(String[] args) {

DateTimeFormatter sdf = DateTimeFormatter.ofPattern("yyyy-MM-dd");
LocalDate date1 = LocalDate.of(2009, 12, 31);
LocalDate date2 = LocalDate.of(2010, 01, 31);

System.out.println("date1 : " + sdf.format(date1));
System.out.println("date2 : " + sdf.format(date2));

System.out.println("Is...");
if (date1.isAfter(date2)) {
System.out.println("Date1 is after Date2");
}

if (date1.isBefore(date2)) {
System.out.println("Date1 is before Date2");
}

if (date1.isEqual(date2)) {
System.out.println("Date1 is equal Date2");
}

System.out.println("CompareTo...");
if (date1.compareTo(date2) > 0) {

System.out.println("Date1 is after Date2");

} else if (date1.compareTo(date2) < 0) {

System.out.println("Date1 is before Date2");

} else if (date1.compareTo(date2) == 0) {

System.out.println("Date1 is equal to Date2");

} else {

System.out.println("How to get here?");

}
}

}
Output


date1 : 2009-12-31
date2 : 2010-01-31
Is...
Date1 is before Date2
CompareTo...
Date1 is before Date2

http://www.mkyong.com/java/how-to-compare-dates-in-java/
http://www.mkyong.com/tutorials/java-date-time-tutorials/
























































































以上是关于《Learning to Compare: Relation Network for Few-Shot Learning》的主要内容,如果未能解决你的问题,请参考以下文章

compare用法

How to compare dates in Java

Java 里的Comparator接口里的compare方法怎么确定升降序的?

Introduction to Learning to Trade with Reinforcement Learning

How does Circus stack compare to a classical stack?

How to Compare Means (均值比较)