元伪标签

https://arxiv.org/abs/2003.10580v4

我们提出了元伪标签,这是一种半监督学习方法,在ImageNet上实现了90.2%的最新top-1准确率,比现有的最新水平提高了1.6%。与伪标签一样,元伪标签有一个教师网络,用于在未标记的数据上生成伪标签,以教授学生网络。然而,与教师固定的伪标签不同,元伪标签中的教师不断地根据学生在标签数据集上的表现反馈进行调整。因此,教师可以生成更好的伪标签来教学生。代码在https://github.com/google-research/google-research/tree/master/meta_pseudo_labels

1.导言

伪标签或自训练方法[57、81、55、36]已成功应用于改进许多计算机视觉任务中的最新模型,如图像分类(如[79、77])、目标检测和语义分割(如[89、51])。伪标签方法通过一对网络工作,一个作为教师,一个作为学生。教师在未标记的图像上生成伪标签。然后将这些伪标记图像与标记图像结合起来训练学生。由于大量的伪标记数据以及数据增强等正则化方法的使用,学生学会了比老师更好[77]。

尽管伪标签方法的性能很好,但它们有一个主要缺点:如果伪标签不准确,学生将从不准确的数据中学习。因此,学生可能不会比老师取得显著的进步。这个缺点也被称为伪标记中的确认偏差问题[2]。

在本文中,我们设计了一个系统的机制,让教师通过观察其伪标签对学生的影响来纠正偏见。具体来说,我们提出了元伪标签,它利用学生的反馈来通知教师生成更好的伪标签。在我们的实现中,反馈信号是学生在标记数据集上的表现。此反馈信号用作奖励,在学生学习的整个过程中培训教师。总之,元伪标签的教师和学生是并行培训的:(1)学生从教师注释的伪标签数据的小批量中学习,(2)教师从奖励信号中学习学生在从标签数据集中提取的小批量中的表现。

我们使用元伪标签进行实验,使用ImageNet[56]数据集作为标记数据,使用JFT-300M数据集[26,60]作为未标记数据。我们使用元伪标签训练了一对高效的网络,一个是教师,一个是学生。由此产生的学生网络在ImageNet ILSVRC 2012验证集[56]上达到了90.2%的最高精度,比之前88.6%的记录[16]高出1.6%。该学生模型还推广到ImageNet ReaL测试集[6],如表1所示。在CIFAR10-4K、SVHN-1K和,ImageNet-10%还表明,元伪标签的性能优于最近提出的一系列其他方法,如FixMatch[58]和无监督数据增强[76]。

2.元伪标签

图1概述了伪标签和元伪标签之间的对比。主要区别在于,在元伪标签中,教师在标记的数据集上收到学生表现的反馈。

3.小规模实验

在本节中,我们将介绍我们在小尺度下对元伪标签的实证研究。我们首先研究了反馈在简单TwoMoon数据集上的元伪标签中的作用[7]。这项研究直观地说明了元伪标签的行为和好处。然后,我们在标准基准(如CIFAR-10-4K、SVHN-1K和ImageNet-10%)上将元伪标签与最先进的半监督学习方法进行比较。我们通过在标准ResNet-50体系结构上使用完整的ImageNet数据集进行实验来结束本节。

3.1. 双月实验

为了理解反馈在元伪标签中的作用,我们在简单和经典的TwoMoon数据集上进行了一个实验[7]。TwoMoon数据集的2D特性使我们能够可视化元伪标签相对于监督学习和伪标签的行为。

数据集。

在这个实验中,我们生成了我们自己版本的TwoMoon数据集。在我们的版本中,有2000个示例形成两个集群,每个集群有1000个示例。仅标记了6个示例,每个集群3个示例,而其余示例未标记。要求半监督学习算法使用这6个标记示例和聚类假设将两个聚类划分为正确的类。

培训细节。

我们的模型结构是一个前馈全连接神经网络,有两个隐藏层,每个层有8个单元。在每一层上都使用了sigmoid非线性。在元伪标签中,教师和学生都有这种结构,但有独立的权重。所有网络都使用SGD进行训练,使用0.1的恒定学习率。网络的权值初始化为-0.1和0.1之间的均匀分布。我们不应用任何正则化。

结果。

我们随机生成TwoMoon数据集几次,并重复三种方法:监督学习、伪标签和元伪标签。我们观察到,元伪标签比监督学习和伪标签具有更高的找到正确分类器的成功率。图2展示了我们实验的典型结果,其中红色和绿色区域对应于分类器的决策。从图中可以看出,监督学习发现了一个错误的分类器,该分类器对标记的实例进行了正确分类,但未能利用聚类假设来分离两个“卫星”。伪标签使用监督学习中的坏分类器,因此在未标记的数据上接收不正确的伪标签。因此,伪标签会找到一个分类器,该分类器会对一半的数据(包括一些标记的实例)进行错误分类。另一方面,元伪标签则使用学生模型在标记实例上丢失的反馈来调整教师以生成更好的伪标签。因此,元伪标签为这个数据集找到了一个好的分类器。换句话说,在本实验中,元伪标签可以解决伪标签的确认偏差问题[2]。

3.2. CIFAR-10-4K、SVHN-1K和ImageNet-10%实验

数据集。

我们考虑了三个标准基准:CIOFE-10-4K、SvHN-1K和IMANETET-10%,它们在文献中被广泛使用,以相当基准半监督学习算法。这些基准是通过将训练集的一小部分保留为标记数据,而将其余部分用作未标记数据而创建的。对于CIFAR-10[34],4000个标记的示例保留为标记数据,而41000个示例用作未标记数据。CIFAR-10的测试集是标准的,由10000个示例组成。对于SVHN[46],1000个示例用作标记数据,而大约603000个示例用作未标记数据。SVHN的测试集也是标准的,有26032个示例。最后,对于ImageNet[56],128000个示例用作标记数据,约占整个ImageNet训练集的10%,而剩余的128万个示例用作未标记数据。ImageNet的测试集是具有50000个示例的标准ILSVRC 2012版本。对于CIFAR-10和SVHN,我们使用32x32的图像分辨率,对于ImageNet,我们使用224x224的图像分辨率。

培训细节。

在我们的实验中,我们的老师和学生共享相同的架构,但有独立的权重。对于CIFAR-10-4K和SVHN-1K,我们使用了WideResNet-28-2[84],它有145万个参数。对于ImageNet,我们使用一个ResNet-50[24],它有2550万个参数。这些体系结构也被该领域以前的工作所普遍使用。在培训教师和学生的元伪标签培训阶段,我们对所有模型使用先前工作中的默认超参数,但RandAugment[13]中的一些修改除外,我们在附录C.2中对此进行了详细说明。附录C.4中报告了所有超参数。在使用元伪标签对教师和学生进行培训之后,我们在标记的数据集上对学生进行微调。对于这个微调阶段,我们使用固定学习率为10的SGD−5,批量大小为512,针对ImageNet-10%运行2000个步骤,针对CIFAR-10和SVHN运行1000个步骤。由于所有三个数据集的标记示例数量有限,因此我们不使用任何heldout验证集。相反,我们在最后一个检查点返回模型。

基线。

为了确保公平比较,我们仅将元伪标签与使用相同体系结构的方法进行比较,而不与使用更大体系结构的方法进行比较,例如,对于CIFAR-10和SVHN[5,4,72,76],使用更大的体系结构的方法,如Biger-WideResNet-28-2和PyramidNet+ShakeDrop;对于ImageNet-10%[25, 23, 10, 8, 9]. 我们也不会将元伪标签与培训程序进行比较,培训程序包括自我蒸馏或从更大的老师那里蒸馏[8,9]。我们在基线上实施这些限制,因为众所周知,更大的体系结构和蒸馏可以改进任何方法,可能包括元伪标签。

我们直接将元伪标签与两个基线进行比较:全数据集监督学习和无监督数据增强(UDA[76])。完整数据集的监督学习代表了净空,因为它不公平地使用了所有标记的数据(例如,对于CIFAR10,它使用了所有50000个标记的示例)。我们还与UDA进行比较,因为我们的元伪标签实现在培训教师时使用了UDA。这两个基线使用相同的实验协议,因此确保公平比较。我们遵循[48]的train/eval/test拆分,并使用相同数量的资源来调整基线和元伪标签的超参数。更多详情见附录C。

其他基线。

除了这两个基线外,我们还将一系列其他半监督基线分为两类:标签传播和自监督。由于这些方法不共享相同的受控环境,因此与它们的比较不是直接的,应该按照[48]的建议进行语境化。比较元伪标签和其他基线的更多受控实验见附录D。

结果。

表2显示了我们使用元伪标签与其他方法进行比较的结果。结果表明,在严格公平比较的情况下(如[48]所述),元伪标签显著优于UDA。有趣的是,在CIFAR-10-4K上,元伪标签甚至超过了整个数据集上的净空监督学习。在ImageNet-10%上,元伪标签在前1名的准确率方面比UDA教师高出5%以上,从68.07%提高到73.89%。对于ImageNet来说,这样的相对改进非常重要。

与现有最先进的方法相比。

与以往文献报道的结果相比,元伪标签在所有三个数据集(CIFAR-10-4K、SVHN-1K和ImageNet-10%)的相同模型体系结构中取得了最好的精度。在CIFAR-10-4K和SVHN-1K上,与最高报告基线相比,元伪标签导致了近10%的相对误差降低[58]。在ImageNet-10%上,元伪标签比SimCLR[8,9]的精度高出2.19%。

虽然在这些数据集上存在更好的结果,但据我们所知,这些结果都是通过更大的模型、更强的正则化技术或额外的蒸馏程序获得的。例如,CIFAR10-4K的最佳报告精度为97.3%[76],但该精度是通过一个金字塔网实现的,该金字塔网的参数比我们的WideResNet-28-2多17倍,并使用复杂的振动降正则化[80]。另一方面,通过SimCLRv2[9]使用自蒸馏训练阶段和ResNet-152×3(其参数比我们的ResNet-50多32倍),ImageNet-10%的最高报告精度为80.9%,蒸馏也可以应用于元伪标记,以进一步改进我们的结果。

3.3. ResNet-50实验

先前的实验表明,在CIFAR-10-4K、SVHN-1K和ImageNet-10%上,元伪标签优于其他半监督学习方法。在本实验中,我们对整个ImageNet数据集上的元伪标签以及来自JFT数据集的未标记图像进行基准测试。本实验的目的是在我们对EfficientNet进行更大规模的实验之前,验证元伪标签在广泛使用的ResNet-50体系结构[24]上是否工作良好(第4节)。

数据集。

如前所述,我们使用来自ImageNet数据集的所有标记示例进行实验。我们从ImageNet数据集中保留25000个示例,用于超参数调整和模型选择。我们的测试集是ILSVRC 2012验证集。此外,我们从JFT数据集中获取了1280万张未标记的图像。为了获得这1280万张未标记的图像,我们首先在整个ImageNet训练集上训练一个ResNet-50,然后使用得到的ResNet-50为JFT数据集中的图像分配类别概率。然后,我们为1000类ImageNet中的每一类选择12800张概率最高的图像。这一选择产生了1280万张图像。我们还确保使用的1280万张图像中没有一张与ImageNet的ILSVRC 2012验证集重叠。UDA[76]和嘈杂的学生[77]使用了过滤额外未标记数据的程序。

实施细节。

我们实现了与第3.2节相同的元伪标签,但我们使用了更大的批量和更多的训练步骤,因为本实验的数据集要大得多。具体来说,对于学生和教师,我们对标记图像使用4096的批量大小,对未标记图像使用32768的批量大小。我们在未标记的数据集上训练500000个步骤,相当于大约160个纪元。在ImageNet+JFT上训练元伪标签阶段后,我们在ImageNet上微调生成的学生10000 SGD步骤,使用10的固定学习率−4.使用512 TPUv2核,我们的培训过程大约需要2天。

基线。

我们将元伪标签与两组基线进行比较。第一组包含有监督学习方法和数据增强或正则化方法,如AutoAugment[12]、DropBlock[18]和CutMix[83]。这些基线代表了ResNet-50上最先进的监督学习方法。第二组基线包括三种最新的半监督学习方法,它们利用来自ImageNet的标记训练图像和其他地方的未标记图像。具体而言,十亿规模的半监督学习[79]使用来自YFCC100数据集的未标记数据[65],而UDA[76]和嘈杂学生[77]都使用JFT作为未标记数据,如元伪标签。与第3.2节类似,我们仅将Meta伪标签与使用ResNet-50和未经蒸馏获得的结果进行比较。

结果。

表3给出了结果。从表中可以看出,元伪标签将ResNet-50的顶级精度从76.9%提高到83.2%,这对于ImageNet来说是一个很大的改进空间,优于UDA和Noised Student。元伪标签在顶级精度方面也优于十亿规模的SSL[68,79]。这尤其令人印象深刻,因为数十亿规模的SSL在Instagram的弱监督图像上预先训练他们的ResNet-50。

4.大规模实验:突破ImageNet精度极限

在本节中,我们将扩展元伪标签,以便在大型模型和大型数据集上进行训练,以提高ImageNet精度的极限。具体来说,我们使用EfficientNet-L2体系结构,因为它比Resnet具有更高的容量。EfficientNet-L2也被嘈杂的学生使用[77],在ImageNet上实现了88.4%的顶级精度。

数据集。

在本实验中,我们使用整个ImageNet训练集作为标记数据,并使用JFT数据集作为未标记数据。JFT数据集有3亿张图像,然后由有噪声的学生使用置信阈值和上采样将图像过滤到1.3亿张[77]。我们使用的是和吵闹的学生一样的1.3亿张图片。

模型架构。

我们使用EfficientNetL2进行实验,因为它在ImageNet[77]上具有最先进的性能,没有额外的标记数据。除了使用512x512而不是475x475的训练图像分辨率外,我们对有噪声的学生使用相同的超参数。我们增加了输入图像的分辨率,以与我们在下一段中讨论的模型并行实现兼容。除了EfficientNet-L2之外,我们还使用了一个较小的模型进行实验,该模型的深度与EfficientNet-B6[63]相同,但宽度因子从2.1增加到了5.0。该模型称为EfficientNet-B6-Wide,具有3.9亿个参数。对于EfficientNet-B6-Wide,我们采用EfficientNet-L2的所有超参数。我们发现EfficientNet-B6-Wide的性能几乎与EfficientNet-L2相同,但编译和训练速度更快。

模型并行性。

由于我们网络的内存占用,为教师和学生保留两个这样的网络内存将大大超过我们加速器的可用内存。因此,我们设计了一个混合的modeldata并行框架来运行元伪标签。具体而言,我们的培训过程在2048个TPUv3核心集群上运行。我们将这些核心划分为128个相同的副本,以标准的数据并行性和同步的梯度运行。在2048/128=16核上运行的每个副本中,我们实现了两种类型的模型并行性。首先,将每个分辨率为512x512的输入图像沿宽度维度分割为16块大小相等的512x32块,并分配到16个核进行处理。请注意,我们选择输入分辨率为512x512,因为512与Noised Student使用的分辨率475x475接近,并且512将网络中间输出的维度保持为16整除。其次,每个权重张量也被平均分割为16个部分,分配给16个核。我们在XLA分片框架中实现了我们的混合数据模型并行性[37]。通过这种并行性,我们可以将2048个标记图像和16384个未标记图像的批量大小放入每个训练步骤中。我们总共对模型进行100万步的训练,对于EfficientNet-L2大约需要11天,对于EfficientNet-B6-Wide大约需要10天。在完成元伪标签训练阶段后,我们对标记数据集上的模型进行了20000个步骤的微调。详细的微调程序见附录C.4。

结果。

我们的结果如表4所示。从表中可以看出,元伪标签在ImageNet上达到了90.2%的top-1精度,这是该数据集的最新技术。这一结果比使用嘈杂的学生[77]和FixRes[69,70]训练的相同效率的ET-L2体系结构要好1.8%。元伪标签的性能也优于BiT-L[33]的最新结果和Vision Transformer[14]的先前状态。这里重要的对比是,Bit-L和Vision TRANSFORM都对来自JFT的3亿个标记图像进行预训练,而我们的方法只使用来自该数据集的未标记图像。在这种精度水平下,与最近的收益相比,我们在[16]上的收益为1.6%,这是一个非常显著的改进幅度。例如,视觉转换器[14]在嘈杂的学生+定影器上的增益仅为0.05%,而定影器在嘈杂的学生上的增益仅为0.1%。

最后,为了验证我们的模型并不是简单地过度适合ImageNet ILSVRC 2012验证集,我们在ImageNet ReaL测试集上对其进行了测试[6]。在这个测试集上,我们的模型也运行良好,达到91.02%Precision@1这比视觉变压器[14]好0.4%。这一差距也比视觉转换器和吵闹学生之间的差距大,后者仅为0.17%。

元伪标签的精简版本。

考虑到元伪标签昂贵的训练成本,我们设计了一个精简版的元伪标签,称为精简元伪标签。我们在附录E中描述了此lite版本,在附录E中,我们使用EfficientNet-B7在ImageNet ILSRVC 2012验证集上实现了86.9%的top-1精度。为了避免使用JFT等专有数据,我们使用ImageNet训练集作为标记数据,使用YFCC100M数据集[65]作为未标记数据。减少元伪标签使我们能够实现元伪标签的反馈机制,同时避免在内存中保留两个网络。

5.有关工程

伪标签。

伪标签方法也称为自训练,是一种简单的半监督学习(SSL)方法,已成功应用于改善许多任务的最新技术,如:图像分类[79,77]、对象检测、语义分割[89]、机器翻译[22]和语音识别[31,49]。传统的伪标签方法在学生学习过程中让经过预培训的教师保持固定,当伪标签不准确时,会导致确认偏差[2]。与普通的伪标签不同,元伪标签继续调整教师,以提高学生在标记数据集上的表现。这种额外的调整允许教师生成更好的伪标签来教学生,如我们的实验所示。

其他SSL方法。

其他典型的SSL方法通常通过优化目标函数来训练单个模型,该目标函数结合了标记数据的监督损失和未标记数据的无监督损失。监督损失通常是在标记数据上计算的交叉熵。同时,无监督损失通常是自监督损失或标签传播损失。自我监督损失通常会鼓励模型建立关于图像的常识,例如绘画[50],解决拼图[47],预测旋转角度[19],对比预测[25,10,8,9,38],或引导潜在空间[21]。另一方面,标签传播损失通常强制要求模型对数据的某些转换保持不变,例如数据增强、对抗性攻击或潜在空间中的接近[35、64、44、5、76、30、71、58、32、51、20]。元伪标签与前面提到的SSL方法有两个显著的区别。首先,使用元伪标签的学生从不直接从标签数据学习,这有助于避免过度拟合,特别是在标签数据有限的情况下。其次,元伪标签中的教师从学生在标签数据上的表现中接收到的信号是利用标签数据的一种新方法。

知识提炼和标签平滑。

元伪标签中的教师使用其对未标记数据的softmax预测来教导学生。这些softmax预测通常被称为软标签,已在知识提炼文献中广泛使用[26、17、86]。在蒸馏工作范围之外,人工设计的软标签(如标签平滑[45]和温度锐化或阻尼[76,77])也被证明可以提高模型的泛化能力。这两种方法都可以看作是调整训练示例的标签,以改进优化和泛化。与其他SSL方法类似,这些调整不会收到本文中提出的学生表现的任何反馈。附录D.2中给出了比较元伪标签和标签平滑的实验。

双层优化算法。

我们在方法名称中使用元,因为我们从学生反馈中得出教师更新规则的技术是基于元学习文献中经常出现的双层优化问题。已经提出了类似的双层优化问题来优化模型的学习过程,例如学习学习速率计划[3],设计架构[40],纠正错误的训练标签[88],生成训练示例[59],以及重新加权训练数据[73,74,54,53]。元伪标签在这项工作中使用相同的双层优化技术,从学生的反馈中得出教师的梯度。元伪标签与这些方法的区别在于,元伪标签采用双层优化技术来改进教师模型生成的伪标签。

6.结论

在本文中,我们提出了半监督学习的元伪标签方法。元伪标签的关键是教师从学生的反馈中学习,以最有助于学生学习的方式生成伪标签。元伪标签中的学习过程包括两个主要更新:基于教师生成的伪标签数据更新学生和基于学生表现更新教师。在标准低资源基准(如CIFAR-10-4K、SVHN-1K和ImageNet-10%)上的实验表明,元伪标签优于许多现有的半监督学习方法。Meta伪标签也可以很好地扩展到大型问题,在ImageNet上达到90.2%的top-1精度,这比以前的最先进技术[16]要好1.6%。一致的收益证实了学生对教师反馈的好处。

致谢

作者希望感谢Rohan Anil、Frank Chen和Wang Tao在运行我们的实验过程中对许多技术问题的帮助。我们还感谢David Berthelot、Nicholas Carlini、Sylvain Gelly、Geoff Hinton、Mohammad Norouzi和Colin Raffel对论文早期草稿的评论,以及Google Brain团队中的其他人在整个漫长项目中的支持。Jaime Carbonell还建议我们消除Resnet模型ImageNet的数据加载瓶颈。当我们没有足够的备用TPU用于我们的ResNet工作时,他的建议帮助很大。他将被深深记住。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容