SINet

开源代码的环境配置:源码要求torchvision的版本是0.2.1,pytorch版本最好是0.4.1

1. conda install cudatoolkit==9.0.0

2. conda install cudnn==7.1.2

3. 在https://download.pytorch.org/whl/cu90/torch_stable.html上下载pytorch0.4.1,再pip install ***whl

4. 在pypi上下载torchvision0.2.1,再pip install ***whl

摘要:设计一种轻量级、鲁棒性强的人像分割算法是一项重要的研究课题。然而,该问题被认为是目标分割问题的一个子集,在语义分割领域的研究较少。显然,人像分割有其独特的要求。首先,由于人像分割是在许多实际应用程序的整个过程中间进行的,因此需要非常轻量级的模型。其次,此域中没有任何公共数据集包含足够数量的具有无偏统计信息的图像。为了解决第一个问题,我们引入了一个新的非常轻量级的图像分割模型SINet,它包含一个信息块解码器(information blocking decoder)和空间压缩模块(spatial squeeze modules)。信息块解码器使用置信度估计来重新覆盖局部空间信息,而不破坏全局一致性。空间压缩模块使用多个感受野来处理图像中各种大小的一致性。为了解决第二个问题,我们提出了一种简单的方法来创建额外的人像分割数据,这可以提高EG1800数据集的准确性。在对EG1800数据集的定性和定量分析中,我们发现我们的方法优于现有的各种轻量级分割模型。我们的方法将参数的数量从2.1M减少到86.9K(大约减少95.9%),同时将精确度保持在与最新的人像分割方法相比的1%的范围内。我们还展示了我们的模型成功地在100.6fps的真实移动设备上运行。此外,我们还证明了我们的方法可以用于Cityscapes数据集的通用语义分割。代码和数据集在:https://github.com/HYOJINPARK/ExtPortraitSeg

https://github.com/clovaai/ext_portrait_segmentation

1. 引言

开发面向人脸数据的算法一直是计算机视觉领域的一项重要任务,许多相关的视觉算法包括检测、识别和关键点提取等都在积极研究中。其中,人像分割在现实生活中的应用非常普遍,如背景编辑、安全检查和人脸分辨率增强等[19,29],这就需要快速、鲁棒的分割模型。

分割任务的难点在于模型必须同时解决两个相互矛盾的问题:(1)处理长期依赖关系(long-range dependencies),或者说全局一致性;(2)保留局部的细节信息。图2所示是两个常见的分割错误。首先,图2(b)中的蓝色斑块被归类为前景,景观其很容易被识别成木材区域。造成该错误的原因是分割模型没有获得全局的上下文信息。其次,图2(b)中的红色斑块显示了模型未能准确分割细节。头发的边缘有待精细的分割,因为它比较小,且颜色与木材相似。由于缺乏头发的细节信息,模型无法产生清晰的分割图像。造成该问题的原因是卷积滑动步长(stride)或者池化层。卷积滑动步长和池化可以扩大感受野大小来捕获全局信息,但是局部的细节信息可能因此而被破坏。

图2.两种典型的分割错误。(b)中树木区域被错误地分割成前景,男孩的头发部分没有得到精细的分割。(d)是我们的结果,没有大计算量就解决了这两问题。

为了解决这些问题,研究人员已经开发了几种策略,第一种是为每一层产生多个感受野。这种多路径结构能够同时增强全局和本地信息,但由于零碎的并行操作而增加了延迟时间[10]。另一种策略是使用两个分支网络,其中一个更深的分支用来生成全局的上下文信息,一个更浅的分支通过保留高分辨率来保留局部的细节特征[16,17,27]。尽管浅分支的层数更少,但由于其高分辨率的特征映射,计算量很大。此外,此方法必须提取两次特征,每个分支一次。

人像分割问题带来了一系列额外的挑战。第一个是可用数据集规模太小。EG1800数据集[19]是一个可访问的公共人像分割数据集,仅包含约1300幅训练图像,在分布——例如种族、年龄和性别等方面——有较大的偏差。另一个挑战是,实际应用中,人像分割通常只是几个步骤中的一个。由于这些应用程序中的许多都运行在移动设备上,因此分割模型需要是轻量级的,以确保实时速度。研究人员已经开发了大量的轻量级分割方法,但大多数方法仍然不够轻量,无法实时地完成人像分割任务。例如,PotraitNet是EG1800数据集上最先进的模型,它的参数量是2.1M。通用轻量级分割模型的几个例子是参数为0.78M的ESPNetV2[11]和参数为0.47M的MobileNet V3[6]。

本文提出了一种新的基于信息分块解码结构和空间压缩模块(S2模块)的轻量级图像分割模型SINet。此外,我们收集额外的人像分割数据,以克服上述数据集问题。提出的SINet有86.9K个参数,在iPhone XS中实现了100.6fps,无需任何低浮点运算或修剪方法。与基线模型(拥有2.1M个参数的PortraitNet)相比,在EG1800数据集上,准确度下降不到1%,如图1所示。

图1  在EG1800验证集上的Accuracy(mIoU) vs 模型复杂度(参数个数)。我们的SINet以较小的模型复杂度取得了较高的accuracy

本文的主要工作概括如下:(1)在解码器中引入信息阻塞机制(information blocking scheme)。它在低分辨率的特征图上测量置信度,并在高置信度的像素上屏蔽高分辨率的特征图的影响。这可以防止噪声信息破坏已经确定的区域,并关注模型关注具有高度不确定性的区域。结果表明,信息阻塞解码器对平移(translation)有较强的鲁棒性,可用于通用的分割任务。(2)我们提出了空间压缩模块(S2模块),这是一种高效地用于特征提取的多路径网络。现有的多路径结构通过控制接收多种感受野来处理不同大小的长程依赖关系(long-range dependencies)。然而,这增加了实际应用中的延迟时间,因为在核启动和同步方面有不合理的结构。为了缓解该问题,我们在每个特征图用平均池化压缩空间分辨率,结果表明这比使用多个感受野更有效。(3)与其它的分割数据集相比,公共的人像分割数据集的图像数量较少,且有很大的偏差。我们提出了一种简单有效的数据生成方法,用大量的图像来扩充EG1800数据集。

2. 相关工作

纵向应用:PortraitFCN+[19]从Flickr中建立了一个人像数据集,提出了一个基于FCN[9]的人像分割模型。之后,PortraitNet提出了一个实时的人像分割模型,分割精度高于PortraitFCN+。[13] 将Mask R-CNN和DensePose两种不同的分割方案进行融合,生成基于FCN的抠图细化算法。[5] 引入了对边界敏感的核来增强语义边界形状信息。虽然这些工作取得了很好的分割效果,但它们的模型对于嵌入式设备来说计算量太大。

全局一致性:全局一致性和长期依赖性是分割任务的关键因素,模型如果缺乏足够大的感受野就会出现错的分割。一种方法是使用大尺寸的核来创造大的感受野,然而这并不适用于轻量模型,因为模型参数多。另一种方法是用下采样来减小特征图的尺寸,但这会导致对细小狭窄的物体分割困难。

为了解决这个问题,扩张卷积(dilated convolutions )是一种有效的解决方案,在保留位置信息[28,2]的同时获得一个较大的感受野,同时和正常卷积的计算量相同。然而,随着扩张率的增加有效权重的数量会减少,最终退化为1×1卷积[3]。同时网格效应(棋盘格模式)会降低分割效果。另一种方法是用空间金字塔池化来获得获得更大的感受野。空间金字塔池化使用不同尺寸的池化核,并将每个输出的特征图拼接起来,以获得多尺度的感受野。类似地,扩张空间塔池化[4]用扩张卷积替换池化,以获得多尺度表示。为了获得多尺度表示,一些工作使用多路径结构进行特征提取[18,11,14]。每个模块划分输入的特征图,并用不同的扩张率转译(translate)特征图。此方法非常适用于轻量模型,但存在高延迟。最近,受非局部块[23](non-local block)和空间金字塔池化的启发,[30]提出了不对称非局部块。由于非局部块要计算所有像素对的依赖性,因此计算量很大。不对称非局部块用空间金子塔池化近似该计算,然而,计算量还是很大,无法满足轻量模型的需求。近年来,一些研究更多地使用平均池化来减小模型复杂度[21,7]。

局部细节信息:恢复局部细节信息是生成清晰分割图的关键。常用方法是使用基于转置卷积的编码-解码结构[9,12]。通过拼接高分辨率的特征图,模型可以逐步地恢复原始分辨率。此外,另一些公祖使用全局注意力来上采样。特征金字塔注意力[8]使用全局池化从低分辨率的特征图来增强高分辨率特征图。然而,由于全局池化,注意力向量不能很好地反映局部信息。近年来,为了更好的分割,人们提出了两分支分割法。ContextNet[16]和FastSCNN[17]设计了一个双路径网络,每个分支分别用于全局上下文和细节信息。BiSeNet[27]还提出了一种类似的双路径网络,用于保存空间信息以及获取足够大的感受野。但是,它需要计算两次特征,每个分支一次。

3. 方法

这一节将介绍我们的SINet结构,它由一个空间压缩模块和一个信息阻塞解码器组成。空间压缩模块(S2模块)使用多感受野机制来处理全局一致性,压缩特征分辨率以降低多路径结构的高延迟。信息阻塞模块利用低分辨率特征图的置信度,只提取高分辨率特征图中所需的信息。解码器中的信息阻塞机制对于提高转译的鲁棒性很重要(3.1节),S2模块可以处理全局一致性而不需大量计算(3.2节)。我们还介绍一个简单的数据生成框架,以解决两种情况下的数据缺乏问题:1)具有人像分割的真值;2)仅具有原始图像(第3.4节)。

3.1 信息阻塞解码器

编码-器解码器结构是最常用的分割结构。编码器根据图像的语义信息提取图像的语义特征,解码器恢复局部细节信息和特征图的分辨率。为了设计解码器,通常使用双线性上采样或转置卷积上采样块来扩展编码器输出的低分辨率特征图。此外,最近的工作[18,14,6,4]重复利用编码器的额外的高分辨率特征图,以获得更精确的分割结果。

据我们所知,大多数研究都是通过级联、元素求和或根据注意力向量用低分辨率特征图来增强高分辨率特征图。然而,使用高分辨率的特征图意味着引入了形成干扰的、原本已被编码器消除的局部信息。因此,我们不得不采取必要的线索,避免特征噪声的影响。

这里,我们引入了一个新的概念,即使用信息阻塞机制的解码器。在低分辨率特征图中测量置信度得分,在解码器分割得较为成功的高置信度区域,阻塞高分辨率特征图的信息流向该区域。信息阻塞机制去除了图像中的干扰信息,使得高分辨率特征图只关注低置信度区域。

图3所示是SINet的总体架构和信息阻塞解码器的详细过程。模型通过逐点卷积将编码器的最后一组特征图投影到类别数的大小,并使用双线性上采样使其分辨率与高分辨率的真值分割图相同。模式使用softmax函数计算每个像素属于每个类的概率,像素属于每个类的概率中的最大值记为该像素的置信度c。最后,通过计算1-c来生成信息阻塞图(map)。将信息阻塞图和高分辨率特征图执行按元素相乘。这确保了低置信度区域从高分辨率特征图中获取更多信息,而高置信度区域在随后的按元素加法操作中保持其原始值。

图3 SINet的架构。S2模块是SINet的bottleneck。信息阻塞模块使模型分割效果好。DSConv+SE等效于带有压缩-解压块的深度可分离卷积

图4(b)是信息阻塞图的一个例子,(c)是模型输出的置信图。如图4(b)所示,边界和衣服具有很高的不确定性,而前景和背景的内部部分已经具有很高的置信度。这说明高不确定性区域需要更详细的局部信息来减少不确定性。但是,人脸的内部部分,如胡须和鼻子,不需要获取更多的局部信息来生成分割图。如果嵌入局部信息,可能会由于噪声等干扰信息而影响全局一致性。在模型的最终置信图(图4(c))中,边界的不确定性区域收缩,内部区域的置信度提高。

图4 从左到右,(a)输入图像,(b)信息阻塞图,(c)模型的最后个模块输出的置信度图,(d)本文方法的分割结果。信息阻塞模块有利于阻止特征中干扰信息的流入,使模型更关注高度不确定性的区域。

3.2 空间压缩模块

多路径结构具有高精度和较少参数的优点[21,20,20,25],但它的延迟与子路径的数量成正比[10]。我们提出的空间压缩模块(S2模块)解决了这个问题。图5所示是S2模块的结构。我们用平均池化来调整感受野大小和减少延迟。

图5 (a)输入特征图被N×N的平均池化层压缩,池化层之后是深度卷积层。然后,使用双线性上采样将特征图分辨率恢复到原始输入特征图的分辨率。(b)S2模块通过使用不同的卷积核组合和S2块的池化,具有多感受野结构

S2模块还采用了一种split-transform-merge方案,类似于[18,11,14],用2个空间压缩块来覆盖多个感受野。首先,我们用逐点卷积将特征图的数量减半。为了进一步减小计算量,我们使用带通道打乱(channel shuffle)的组逐点卷积(group pointwise convolution)。缩小后的特征图通过每个S2块,并将输出拼接起来。我们在输入特征图和拼接后的特征图之间使用残差连接。最后,使用PReLU激活函数。

对于S2块,我们选择平均池化而不是扩张卷积来形成多感受野,有两个原因。首先,延迟受扩张率的影响,如表1所示,而扩张卷积不能摆脱网格效应的问题[14,22]。其次,多路径结构对GPU并行计算不友好[10]。因此,我们压缩每个特征图的分辨率,以避免延迟过大。S2块通过平均池化压缩特征图的分辨率,池化核大小是4。然后,使用核尺寸为3或5的深度可分离卷积。在深度卷积和逐点卷积之间,使用PReLU激活函数。经验上,将逐点卷积放在双线性上采样之前或之后对精度没什么影响。因此,我们将逐点卷积放在双线性上采样之前,以进一步减少计算量。在深度卷积和双线性上采样之后,我们还插入了一个批量归一化层。

表1 在iPhone XS上,深度可分离扩张卷积在不同的扩张率下的延迟时间。输入的尺寸是128×120×120。其它尺寸的实验见补充材料。

3.3 SINet的网络设计

这部分介绍SINet的总体结构。SINet使用S2模块作为bottleneck,并使用步长为2的深度可分离卷积(ds-conv)来降低特征图的分辨率。实验表明,在相同的输出尺寸条件下,采用步长为2的S2模块进行下采样可以提高精度,但我们发现它比步长为1的S2模块具有更长的延迟时间。因此,对于下采样,我们使用带压缩和激励块(Squeeze-and-Excite blocks)的深度可分离卷积,而不是步长为2的S2模块。对于第一个bottleneck,我们使用两个串联的S2模块;对于第二个bottleneck,我们使用八个。S2模块的详细设置如表2所示。我们为每个bottleneck添加一个残差连接,将bottleneck输入与其输出连接起来。采用3×3卷积进行分类,最后采用双线性上采样恢复原始输入分辨率。

表2 SINet编码器的详细设置。k表示深度卷积的核尺寸,p表示S2块的平均池化的核尺寸。

我们发现,边界部分的加权辅助损失有助于提高精度。最终损失如下:

B=(f\oplus y^\ast  )-(f\ominus  y^\ast  )

Loss=CE_{i\in P} (y_{i}^\ast ,\hat{y}  )+\lambda CE_{j\in B} (y_{j}^\ast ,\hat{y}_{j}   )    (1)

这里,f是一个15×15的滤波器,用于形态扩张\oplus 和腐蚀\ominus P表示真值的所有像素。B表示由形态学操作定义的边界区域中的像素。y^\ast 表示二元真值取值,\hat{y} 表示分割模型预测标签。\lambda 是控制损失项之间平衡的超参数。

3.4 数据生成

标注数据的成本通常很高,每个实例的注释时间因任务类型而异。例如,PASCAL VOC的每个样本,分类任务的标注耗时估计为20.0秒,分割任务为239.7秒,这是在[1]中提到的数量级差异。

为了降低人像分割的标注成本,我们考虑了两种可能的情况:1)有全身分割真值的图像,2)只有原始图像的。我们使用复杂的人脸检测模型(情况1)或分割模型(情况2)来生成每种情况下的伪真值。

当我们有全身图像和真值时,我们需要在人像区域周围有一个边界框。我们从百度数据集[24]中获取图像,其中包含5382个人体全身分割图像,涵盖各种姿势、时尚和背景。为了得到边界框和人像区域,我们使用面部检测器[26]检测图像的面部位置。由于人脸检测器只覆盖脸部区域,因此在裁剪图像和分割真值时,我们增加边界框的大小,以包含上半身和背景的部分。

我们还创建了第二个数据增扩:使用从网上scrape下来的人像图像,用一个计算量更大的分割模型来生成伪真值掩膜。该分割模型包含DeepLabv3+ [4]的架构,以SE-ResNeXt-50 [25]为主干。该模型在ImageNet上进行了预训练,并在包含约2500个精细分割的全身图像的专有数据集上进行了微调。该模型训练用于通用的全身分割,而不是用于特定的人像分割。

最后,标注人员只需要检查每个伪真值图像的质量,去除明显的失败样本。该方法通过将分割任务转化为二分类任务,将每个样本的标注工作量从几分钟减少到1.25秒。

4. 实验

我们在公共数据集EG1800[19]上评估了该方法,该数据集收集了Flickr中带有手动注释标签的图像。该数据集共有1800个图像,分为1500个训练图像和300个验证图像。然而,我们只能访问1309张训练图像和270张验证图片,因为有些url已经失效。我们使用第3.4节中提到的数据生成方法生成了另外10448幅图像。

我们使用ADAM优化器训练我们的模型,初始学习率为7.5e-3,权重衰减为2e-4,总共训练600个epoch。采用文献[29]中的数据增强方法,得到224×224幅图像。我们使用两阶段的训练方法;对于前300个epoch,我们只训练编码器,batchsize设置为36。然后,在另外的300个epoch,我们用第一阶段训练出来的最佳参数初始化编码器,并训练整个SINet,batchsize设定为24。我们用多个消融实验评估我们的模型,使用平均交并比(mIoU)和边界部分的F1分数作为评估指标,并且与最先进的人像分割模型对比,包括那些轻量级分割模型。为了确定边界区域,我们用一个15×15的核从扩张的真值中减去腐蚀的真值。在第4.2节中,我们在EG1800验证集上证明了信息阻塞解码器对随机旋转的鲁棒性,以及多感受野结构的重要性。另外,我们证明了我们的方法可用于通用的分割任务,并且在Cityscapes数据集上评估。

4.1 EG1800数据集的评估结果

我们将所提出的模型与PortraitNet[29]进行了比较,后者在人像分割领域达到最先进水平。由于EG1800数据集中的一些样本url失效,我们按照论文中的原始方法,使用EG1800数据集中剩余样本的官方代码对PortraitNet进行了训练。PortraitNet将他们的模型与BiSeNet和ENet进行了比较。因此,我们还按照PortraitNet的方法对BiSeNet和ENet进行了重新训练,以便进行公平的比较。如表3所示,由于训练数据集的减小,重新训练的模型的精度略有降低。我们使用LG gram笔记本电脑上的PyTorch框架,在英特尔酷睿i5-7200U CPU环境中测量了延迟时间。

在比较的方法中,DS-ESPNet与ESPNet具有相同的结构,只需将模型的标准扩展卷积变换为深度可分离扩展卷积。对于ESP NetV2(2.0)和ESP NetV2(1.5),为了减小模型大小,我们按照官方源码改变了卷积层的通道数。我们还将DS-ESPNet(0.5)中卷积的通道数减半,使其小于0.1M的参数量和0.2G的FLOPs。原始的ContextNet用了4个金字塔池化,但是由于特征图尺寸太小,我们只用了3个。

从表3可以看出,我们的方法在参数较少、FLOPs较小、FPS较高的情况下,取得了与其他模型相当或更好的性能。SOTA模型PortraitNet在所有的实验结果中显示出最高的精度,而且比计算量更大的BiSeNet的性能更好。然而,PortraitNet参数多,不适用于较小设备。在保证精度的前提下,与PortraitNet相比,SINet的参数量减少了95%,FLOPs减少了80%。ESPNet和ESPNet V2具有相似的精度,但在参数数量和FLOPs数量之间显示出一种折衷。ESPNet V2比ESPNet参数更多,FLOPs更少。Enet比这两种模型的性能更高,但FLOPs也更多。我们的模型参数少、FLOPs少,仍然取得比ESPNet和ESPNet V2更好的精度。特别是,我们的SINet在极轻量化的模型中具有最高的精度。图6显示了我们的模型的质量优于其他极轻量级的模型。

表3 在EG1800验证集上的对比。DS表示深度可分离卷积。我们在Intel Core15-7200CPU上,以224×224为输入,测量FPS。最后一列的结果是来自PortraitNet[29]的论文。SINet+表示使用了3.4节的数据增扩
图6 在EG1800验证集上的定性对比

我们使用CoreML框架在iPhone XS上比较了我们的模型与SOTA分割模型MobileNet V3的执行速度。MobileNet V3每秒60.7帧,SINet每秒100.6帧。MobileNet V3和SINet中的FLOPs是相似的,但是SINet比mobilenetv3快得多。我们推测SE块和h-swish激活函数是MobileNet V3延迟增加的主要原因。综上所述,在各种分割模型中,提出的SINet在精度和速度上都表现出了优异的性能。

4.2 消融研究

信息阻塞解码器:表4显示了信息阻塞模块(IB)对准确性的提升。我们随机旋转验证集的图像,并在整张图像上评估mIOU。Reverse IB表示我们将高分辨率特征图与置信度c相乘,而不是1-c,从而增强低分辨率特征图的高置信度像素而不是低置信度像素。Remove IB是指没有使用任何信息阻塞,即在编码器的中间层将低分辨率特征图和高分辨率特征图按元素求和。GAU在元素求和之前,使用全局池化用低分辨率特征图来增强高分辨率特征图。GAU的性能比Reverse IB和Remove IB的要好,但仍然不能得到一个紧边界,在图像平移中也比IB要差。从结果可以看出,与其他方法相比,信息阻塞解码器表现出了优异的性能。定性地说,它防止了背景区域的分割误差,如图7所示。

表4 使用随机旋转后的mIoU。Org表示原始的验证集,没有任何的变换(translation)。IB表示使用信息阻塞映射。Reverse IB表示加强高置信度区域而不是低置信度区域。
图7 模型的最后个特征的置信度图,以及从不同解码方法得到的分割结果。

多感受野:表5所示是不同的多感受野结构的性能。SINet使用不同大小的核的组合来卷积和池化。不同的内核大小组合进行卷积和池。我们重新设计了S2模块,使其在S2块中分别对所有卷积层和池化层使用相同的核大小。如表5所示,我们的SINet的mIOU和F1得分高于其他模型。因此,多感受野结构比单一感受野结构在准确性方面具有优势。

表5 S2块的消融实验。我们的多感受野结构表现得更好。

4.3 通用分割数据集

通过在Cityscapes数据集上对模型进行测试,证明该方法不仅适用于二值分割问题,而且适用于一般的分割问题。与二值分割任务相比,我们稍微增加了层和通道的数量以应对任务复杂性的增加,并且我们将S2块中的深度卷积分解以减少参数的数量。在这里,SINet只有0.12M的参数,2048×512的输入只有1.2GFLOPs,但是我们的模型显示出比除了MobileNet V3和MobileNet V2之外的任何其他轻量级分段模型更好的精度。SINet的精度比MobileNet V3降低了2.9%,但其参数和FLOPs的数目远低于MobileNet V3。表7是Cityscapes分割编码器模型的详细设置。

表7 SINet编码器的详细设置。k表示深度可分离卷积的核尺寸,p表示S2块的平均池化的核尺寸。

5. 结论

本文提出了一种由信息阻塞解码器和空间压缩模块组成的轻量级图像分割模型SINet。SINet在100.6FPS的移动设备上运行良好,精度高达95.29。信息分块译码器避免了高分辨率特征带来的干扰信息,使模型更集中于高不确定性区域。空间挤压模块具有多个接收场来处理图像中各种大小的全局一致性。我们还提出了一个简单的数据生成框架,包括两种情况:1)具有人类分割的基本事实2)仅具有原始图像。与已有的轻量级分割模型相比,该模型不仅在特定的人像数据集上,而且在一般的分割数据集上都取得了优异的性能。在城市景观数据集上,该方法仅需0.12M个参数和1.2G的浮点运算,准确率为66.5%。

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

推荐阅读更多精彩内容