DeepLabv1: Semantic Image Segmentation with Deep CNNs and Fully Connected CRFs的論文閱讀與Pytorch實(shí)現(xiàn)

作 者: 心有寶寶人自圓

聲 明: 歡迎轉(zhuǎn)載本文中的圖片或文字产捞,請(qǐng)說明出處

寫在前面

自從FCN提出以來(lái),越來(lái)越多的語(yǔ)義分割任務(wù)開始采用采用全卷積網(wǎng)絡(luò)結(jié)構(gòu)利耍,隨著FCN結(jié)構(gòu)使用的增加笔刹,研究人員發(fā)先了其結(jié)構(gòu)天生的缺陷極大的限制了分割的準(zhǔn)確度:CNNs在high-level (large scale) tasks中取得了十分優(yōu)異的成績(jī)囱持,這得益于局部空間不變性(主要是池化層增大了感受野,也丟棄了部分細(xì)節(jié)信息)使得網(wǎng)絡(luò)能夠?qū)W習(xí)到層次化的抽象信息闲擦,但這卻恰恰不利于low-level (small scale) tasks

所以Deeplab的作者引入了如下結(jié)構(gòu)來(lái)對(duì)抗這種細(xì)節(jié)丟失的問題:

  • 帶洞的卷積慢味,atrous算法
  • Fully connected CRF的后處理過程

1. Introduction


CNNs在high-level vision tasks(如圖像分類、目標(biāo)檢測(cè)等)取得優(yōu)異得表現(xiàn)墅冷,這些工作都有共同的主題:end-to-end訓(xùn)練的方法比人工的特征工程方法更優(yōu)纯路。這得益于CNNs內(nèi)在的局部空間不變性,然而對(duì)應(yīng)low-level vision tasks(語(yǔ)義分割)來(lái)說寞忿,我們需要準(zhǔn)確的位置信息而非空間信息抽象后的層次化信息驰唬。

CNNs應(yīng)用于low-level vision tasks主要技術(shù)障礙是:

  • 信號(hào)的下采樣

  • 空間的局部不變性

    下采樣問題是池化層和striding的聯(lián)合影響產(chǎn)生,其目的是為了使較小的卷積核能夠去學(xué)習(xí)空間中有用的信息(因此需要增大感受野)腔彰,但這種下采樣必然造成信息的損失叫编。為了在不造成信息損失的情況下增大感受野,作者使用了帶洞的卷積(下均稱atrous方法)

該圖片來(lái)自:vdumoulin/conv_arithmetic

DILATED CONVOLUTIONS with kernel size 3x3, dilation=2

局部空間不變性是classifier獲得以對(duì)象為中心的決策的要求霹抛,主要還是由于池化層得作用只保留了局部空間中最重要的信息宵溅,作者使用Fully connected CRF(后稱DenseCRF)進(jìn)行全卷積網(wǎng)絡(luò)訓(xùn)練完成后的后處理,DenseCRF能夠在滿足長(zhǎng)程依賴性的同時(shí)捕獲細(xì)節(jié)邊緣信息

2. Related Work


遠(yuǎn)古時(shí)期上炎,分割主要基于信號(hào)系統(tǒng)恃逻,而后是概率模型占據(jù)主流

CNNs發(fā)展起來(lái)之后是two-stage的策略(提議區(qū)域+區(qū)域預(yù)測(cè))占據(jù)了主流,但提議區(qū)域會(huì)使得系統(tǒng)面臨前端分割系統(tǒng)的潛在錯(cuò)誤(提議區(qū)域的質(zhì)量直接能影響預(yù)測(cè)結(jié)果)

隨FCN提出后one-stage策略(直接基于像素預(yù)測(cè))占據(jù)主流

3.CNN NETWORKS FOR DENSE IMAGE LABELING


Deeplabv1就基本上是按照FCN的結(jié)構(gòu)來(lái)設(shè)計(jì)的藕施,只是部分結(jié)構(gòu)進(jìn)行了修改寇损。由于網(wǎng)絡(luò)使用了atrous算法,可以使作為encoder的CNN提取出比FCN更密集的final layer特征:FCN的encoder的final layer下采樣了32倍裳食,而Deeplabv1僅下采樣了8倍

本文和FCN一樣使用了預(yù)訓(xùn)練的VGG-16網(wǎng)絡(luò)

3.1 AGROUS算法

語(yǔ)義分割是一種dense prediction任務(wù)矛市,所以能夠使用CNN提取出更密集的feature是提升準(zhǔn)確率的關(guān)鍵,而基于密集feature評(píng)分成為Deeplabv1成功的關(guān)鍵诲祸。

為了獲得更密集的feature浊吏,作者跳過了最后兩個(gè)maxpooling層(maxpool4,5)的下采樣而昨,并在最后三個(gè)卷積層(conv5_1 - 3)和第一個(gè)全連接層(fc6)使用atrous算法

帶洞的原意是給卷積核中間插入0,而這樣的操作等同于給卷積層一個(gè)input_stride(普通的卷積默認(rèn)input_stride = 1)找田,這樣就可以使卷積計(jì)算后特征圖中同樣的像素具有更大的感受野(還需要調(diào)整padding = input_size *( kernel_size ) // 2才能保證特征圖保持輸入大小一致)歌憨。這樣不通過下采樣獲得的感受野增大不會(huì)缺失原有的信息,不像池化層那樣引入了近似

最后通過評(píng)分層輸出的class score maps 只需使用雙線性插值上采樣8倍即可

損失函數(shù)直接使用基于每個(gè)像素的Cross Entropy損失并相加墩衙,每個(gè)像素和每個(gè)類別的權(quán)重相同(大部分的類別為負(fù)類务嫡,即背景類,不會(huì)對(duì)最終分割效果產(chǎn)生影響)

3.2 控制感受野和加速計(jì)算

作者在這部分介紹的關(guān)于顯式控制感受野和加速密集計(jì)算的的方法主要涉及全連接層的轉(zhuǎn)換漆改。在我之前介紹FCN的文章中心铃,對(duì)于全連接層和卷積層之間的相互轉(zhuǎn)換有過講解。由于預(yù)訓(xùn)練模型都是針對(duì)大尺度目標(biāo)的分類任務(wù)的:例如VGG-16的fc6就是有4096個(gè)大小為7x7的核挫剑,而這么大的核通常又會(huì)帶來(lái)計(jì)算問題去扣。

作者使用了對(duì)卷積核進(jìn)行空間采樣的方法:simple decimation(在我之前的文章介紹SSD的2.2.2節(jié)有講解),這樣就可以顯式的降低感受野樊破,并且顯著的加快計(jì)算速度厅篓,節(jié)省存儲(chǔ)空間

4.恢復(fù)細(xì)節(jié)的邊界:全連接隨機(jī)條件場(chǎng)和多尺度預(yù)測(cè)


4.1 定位的挑戰(zhàn)

如圖2所示,CNN計(jì)算出的得分圖可以可靠地預(yù)測(cè)圖像中物體和大致位置捶码,但不能精確地指出它們的輪廓羽氮。CNN在分類準(zhǔn)確和定位準(zhǔn)確之間存在天然的trade-off:池化層提高了high-level tasks的效果,卻帶來(lái)了信息損失惫恼、大尺度的感受野和局部不變性档押,阻礙了low-level tasks的效果,因此為從得分圖推斷出原始空間的結(jié)果增加了難度祈纯。

在Deeplabv1提出前令宿,有兩種主流方法去解決定位的挑戰(zhàn):

  • 利用來(lái)自CNN多個(gè)層的信息(比如FCN的跳躍結(jié)構(gòu))

  • 采用超像素表示,本質(zhì)上是將定位任務(wù)委托給低級(jí)的分割方法

Deeplabv1提出了使用DenseCRF進(jìn)行后處理來(lái)解決定位的挑戰(zhàn)

4.2 使用DenseCRF進(jìn)行準(zhǔn)確定位

傳統(tǒng)上腕窥,CRFs模型是用來(lái)平滑分割圖上的噪聲粒没,尤其是這些模型包含連接鄰近節(jié)點(diǎn)的能量項(xiàng)(二元項(xiàng)),傾向于對(duì)空間近端像素進(jìn)行相同標(biāo)簽賦值簇爆。從定性的說癞松,這些短程CRFs(short-range CRFs)的主要功能是清除基于手工設(shè)計(jì)的局部特征構(gòu)建的弱分類器的錯(cuò)誤預(yù)測(cè)。

與弱分類器相比入蛆,Deeplab的CNN網(wǎng)絡(luò)是很強(qiáng)的分類器响蓉,圖2的結(jié)果也表明預(yù)測(cè)結(jié)果很平滑、有很強(qiáng)的同質(zhì)性哨毁。在這個(gè)背景下使用短程CRFs是有害的:因?yàn)槎坛藽RFs作用是平滑枫甲,而不是我們所期望的細(xì)化邊緣

為了克服短程CRFs的限制,作者使用了全連接CRF

DenseCRF模型采用能量函數(shù)

  • ?是分配給像素的標(biāo)簽

  • 其中一元項(xiàng)勢(shì)能\theta_i(x_i)=-logP(x_i),P(x_i)?表示給像素i處為該標(biāo)簽的概率,該項(xiàng)基于CNN預(yù)測(cè)分?jǐn)?shù)圖

  • 為二元項(xiàng)?\theta_{ij}(x_i,x_j)=\mu(x_i,x_j)\sum_{m=1}^Kw_m\cdot k^m(\boldsymbol f_i,\boldsymbol f_j)想幻,該項(xiàng)基于圖像本身粱栖,即考慮像素間的聯(lián)系

    其中?\begin{cases}\mu(x_i,x_j)=1,x_i \ne x_j\\\mu(x_i,x_j)=0,x_i=x_j\end{cases},由于是全連接脏毯,每?jī)蓚€(gè)像素之間都要連接

    ?w_m是由?決定的高斯核函數(shù)闹究,為:

?p是像素的位置,I是像素的顏色抄沮,\sigma_\alpha,\sigma_\beta,\sigma_\gamma均是高斯核的超參數(shù)

最后談一談關(guān)于DenseCRF的優(yōu)化目標(biāo)跋核,即為調(diào)整輸入\boldsymbol x(每個(gè)像素的label)使能量函數(shù)E(\boldsymbol x)最小化岖瑰。但由于是全連接叛买,直接計(jì)算的話計(jì)算量簡(jiǎn)直爆炸,所以采用平均場(chǎng)近似的方法進(jìn)行計(jì)算

對(duì)于DenseCRF具體內(nèi)容感興趣的可以看下有關(guān)論文蹋订,這里僅做感性的認(rèn)知率挣,并且僅使用有關(guān)pydensecrf庫(kù)。在后來(lái)的語(yǔ)義分割論文中很少看到DenseCRF的影子了露戒,因?yàn)閷?duì)于更強(qiáng)的網(wǎng)絡(luò)模型椒功,DenseCRF的提升效果不明顯,或甚至起到反作用智什。為什么不用DenseCRF了?

更多關(guān)于Dense的細(xì)節(jié)內(nèi)容和代碼中使用pydensecrf庫(kù)可參考:

4.2 MULTI-SCALE PREDICTION

作者也像FCN的跳躍結(jié)構(gòu)那樣結(jié)合了多尺度的得分圖证九,發(fā)現(xiàn)對(duì)于分割效果并沒很多提升删豺,更不如DenseCRF對(duì)于分割效果的提升明顯,并且?guī)?lái)了額外的計(jì)算消耗愧怜,因此只使用了最后一層得分圖

5. 實(shí)驗(yàn)和評(píng)價(jià)


  • Dataset:PASCAL VOC 2012 aug 數(shù)據(jù)集

  • Training:把CNN模型和CRF模型分開訓(xùn)練

    先f(wàn)ine-tuneCNN模型呀页,mini-batch = 20,learning rate = 0.001 (最后的分類層為0.01)拥坛,每迭代2000次lr變?yōu)樵瓉?lái)的0.1蓬蝶,momentum = 0.9 , weight decay = 0.0005

    CNN模型訓(xùn)練fine-tune完成后猜惋,開始為DenseCRF調(diào)參疾党,使用交叉驗(yàn)證的方法調(diào)參(val集里的100張圖片):預(yù)設(shè)?,尋找優(yōu)超參數(shù)?惨奕,平均場(chǎng)迭代次數(shù)固定為10

  • 不同的網(wǎng)絡(luò)設(shè)計(jì)

  • DeepLab:只使用了CNN

  • -CRF:使用了DenseCRF進(jìn)行后處理

  • -MSc:結(jié)合了多尺度的得分圖

  • -7x7:fc6使用的卷積核大小為7x7雪位,默認(rèn)為4x4

  • -LargeFOV:arbitrarily control the Field-of- View (FOV) of the models

最后選擇的最優(yōu)組合:DeepLab-CRF-LargeFOV,同時(shí)把最后兩個(gè)classifier層的通道數(shù)從4096變?yōu)?024

我實(shí)現(xiàn)的代碼也是按照這個(gè)來(lái)進(jìn)行的

6. My code


這里主要列出網(wǎng)絡(luò)結(jié)構(gòu)和DenseCRF部分梨撞,其余部分(如Dataset雹洗,數(shù)據(jù)增廣處理香罐,訓(xùn)練、驗(yàn)證)都比較通用可用自己慣用的方法时肿,也可參考我寫的FCN主要代碼SSD主要代碼

我使用了PASCAL VOC 2012數(shù)據(jù)集庇茫,而沒有使用aug版,所以效果比使用aug版的差螃成,mIOU才達(dá)到51.92%

  • 網(wǎng)絡(luò)結(jié)構(gòu):主要由兩部分組成旦签,一部分是VGG的Base結(jié)構(gòu),第二部分是更改VGG的全連接層為L(zhǎng)argeFOV全卷積層
import torch
  from torch import nn
  from torchvision import models
  
  class VggBase(nn.Module):
      def __init__(self):
          super(VggBase, self).__init__()
          self.conv1_1 = nn.Conv2d(3, 64, kernel_size=3, padding=1)
          self.conv1_2 = nn.Conv2d(64, 64, kernel_size=3, padding=1)
          self.pool1 = nn.MaxPool2d(2, 2)
  
          self.conv2_1 = nn.Conv2d(64, 128, kernel_size=3, padding=1)
          self.conv2_2 = nn.Conv2d(128, 128, kernel_size=3, padding=1)
          self.pool2 = nn.MaxPool2d(2, 2)
  
          self.conv3_1 = nn.Conv2d(128, 256, kernel_size=3, padding=1)
          self.conv3_2 = nn.Conv2d(256, 256, kernel_size=3, padding=1)
          self.conv3_3 = nn.Conv2d(256, 256, kernel_size=3, padding=1)
          self.pool3 = nn.MaxPool2d(2, 2)
  
          self.conv4_1 = nn.Conv2d(256, 512, kernel_size=3, padding=1)
          self.conv4_2 = nn.Conv2d(512, 512, kernel_size=3, padding=1)
          self.conv4_3 = nn.Conv2d(512, 512, kernel_size=3, padding=1)
          self.relu4 = nn.ReLU(inplace=True)
          # 如文中所述:skip subsampling after the last two max-pooling layers in the network
          # 2×inthe last three convolutional layers and 4×in the first fully connected layer
          self.pool4 = nn.MaxPool2d(3, 1, 1)
  
          self.conv5_1 = nn.Conv2d(512, 512, kernel_size=3, padding=2, dilation=2)
          self.conv5_2 = nn.Conv2d(512, 512, kernel_size=3, padding=2, dilation=2)
          self.conv5_3 = nn.Conv2d(512, 512, kernel_size=3, padding=2, dilation=2)
          self.pool5 = nn.MaxPool2d(3, 1, 1)
  
          self.load_pretrained_layers()
  
      def load_pretrained_layers(self):
          pretrained_net = models.vgg16(pretrained=True)
          state_dict = self.state_dict()
          for c, pc in zip(state_dict.keys(), pretrained_net.features.state_dict().values()):
              assert state_dict[c].size() == pc.size()
              state_dict[c] = pc
          self.load_state_dict(state_dict)
  
      def forward(self, x):
          out = torch.relu(self.conv1_1(x))
          out = torch.relu(self.conv1_2(out))
          out = self.pool1(out)
  
          out = torch.relu(self.conv2_1(out))
          out = torch.relu(self.conv2_2(out))
          out = self.pool2(out)
  
          out = torch.relu(self.conv3_1(out))
          out = torch.relu(self.conv3_2(out))
          out = torch.relu(self.conv3_3(out))
          out = self.pool3(out)
  
          out = torch.relu(self.conv4_1(out))
          out = torch.relu(self.conv4_2(out))
          out = torch.relu(self.conv4_3(out))
          out = self.pool4(out)
  
          out = torch.relu(self.conv5_1(out))
          out = torch.relu(self.conv5_2(out))
          out = torch.relu(self.conv5_3(out))
          out = self.pool5(out)
  
          return out
  
  
  class AtrousConv(nn.Module):
      def __init__(self, n_classes, out_channels=1024, decimation=3, rate=12):
          # 按文中所述:employ kernel size 3×3 and input stride = 12,
          # and further change the filter sizes from 4096 to 1024 for the last two layers
          super(AtrousConv, self).__init__()
          self.decimation = [4096 // out_channels, None, decimation, decimation]
          self.atrous = nn.Conv2d(512, out_channels, kernel_size=decimation, padding=rate * (decimation - 1) // 2,
                                  dilation=rate)
          self.relu1 = nn.ReLU(inplace=True)
          self.fc1 = nn.Conv2d(out_channels, out_channels, kernel_size=1)
          self.relu2 = nn.ReLU(inplace=True)
          self.fc2 = nn.Conv2d(out_channels, n_classes, kernel_size=1)
  
          self.init_param()
  
      def decimate(self, param: torch.Tensor, decimation):
          assert param.dim() == len(decimation)
          for d in range(param.dim()):
              if decimation[d] is not None:
                  param = param.index_select(dim=d,
                                             index=torch.arange(start=0, end=param.size(d),
                                                                step=decimation[d]).long())
          return param
  
      def init_param(self):
          pretrained_dict = models.vgg16(pretrained=True).state_dict()
          self.atrous.weight.data = self.decimate(pretrained_dict['classifier.0.weight'].view(4096, 512, 7, 7),
                                                  self.decimation)
          self.atrous.bias.data = self.decimate(pretrained_dict['classifier.0.bias'].view(4096), self.decimation[:1])
  
          self.fc1.weight.data = self.decimate(pretrained_dict['classifier.3.weight'].view(4096, 4096, 1, 1),
                                               [self.decimation[0], self.decimation[0], None, None])
          self.fc1.bias.data = self.decimate(pretrained_dict['classifier.3.bias'].view(4096), self.decimation[:1])
  
          nn.init.xavier_normal_(self.fc2.weight)
          nn.init.constant_(self.fc2.bias, 0)
  
      def forward(self, x):
          for blk in self.children():
              x = blk(x)
          return x
  
  
  class DeepLabv1(nn.Module):
      def __init__(self, n_classes=21):
          super(DeepLabv1, self).__init__()
          self.base = VggBase()
          self.atrous = AtrousConv(n_classes)
  
      def forward(self, x):
          x = self.base(x)
          x = self.atrous(x)
          # https://zhuanlan.zhihu.com/p/87572724?from_voters_page=true 介紹關(guān)于align_corners的內(nèi)容
          # 為了和下采樣(transform寸宏,PIL)時(shí)圖像保持一致宁炫,使用align_corners=Fasle
          # 上面的博文認(rèn)為align_corners=True對(duì)語(yǔ)義分割任務(wù)可能更好,有機(jī)會(huì)可以試一下
          # also see:https://discuss.pytorch.org/t/what-we-should-use-align-corners-false/22663/9
          x = nn.functional.interpolate(x, scale_factor=8, mode='bilinear', align_corners=False)
          return x
  • 損失函數(shù):等權(quán)重的Cross Entropy Loss
    class NLLLoss2d(nn.Module):
        def __init__(self):
            super(NLLLoss2d, self).__init__()
            self.loss = nn.NLLLoss()
    
        def forward(self, pred, true):
            pred = nn.functional.log_softmax(pred, dim=1)
            return self.loss(pred, true)
  • DenseCRF:我是在Linux完成安裝pydensecrf的氮凝,windows實(shí)在裝不上...
    import numpy as np
    import pydensecrf.densecrf as dcrf
    import pydensecrf.utils as utils
    
    class DenseCRF(object):
        def __init__(self, max_epochs=5, delta_aphla=80, delta_beta=3, w1=10, delta_gamma=3, w2=3):
            self.max_epochs = max_epochs
            self.delta_gamma = delta_gamma
            self.delta_alpha = delta_aphla
            self.delta_beta = delta_beta
            self.w1 = w1
            self.w2 = w2
    
        def __call__(self, image, probmap):
            c, h, w = probmap.shape
    
            U = utils.unary_from_softmax(probmap)
            U = np.ascontiguousarray(U)
    
            image = np.ascontiguousarray(image)
    
            d = dcrf.DenseCRF2D(w, h, c)
            d.setUnaryEnergy(U)
    
            d.addPairwiseGaussian(sxy=self.delta_gamma, compat=self.w2)
            d.addPairwiseBilateral(sxy=self.delta_alpha, srgb=self.delta_beta, rgbim=image, compat=self.w1)
    
            Q = d.inference(self.max_epochs)
            Q = np.array(Q).reshape((c, h, w))
    
            return Q
  • 看一下DenseCRF的使用:
    import models # 寫Class DenseCRF的文件
    import numpy as np
    
    
    def crf(self, img, prob):
        """
            :param img: a PIL image
            :param prob: 網(wǎng)絡(luò)輸出score map, in shape of (21 , height, width)
            :return: new prob map
            """  
        crf = models.DenseCRF()
        prob = torch.softmax(prob, dim=1)[0].numpy()
        res = crf(np.array(image, dtype=np.uint8), prob)                        
    
        return res.argmax(axis=0)

注意:在進(jìn)行數(shù)據(jù)增廣時(shí)(resize)羔巢,插值的方法一定要選擇NEAREAST而不是默認(rèn)的Bilinear,否則會(huì)對(duì)true label image的pixel進(jìn)行誤標(biāo)罩阵,導(dǎo)致問題的出現(xiàn)

一些衡量的Metrics見:wkentaro/pytorch-fcn竿秆,它的算法方法非常巧妙

  • 分割結(jié)果





    看來(lái)自行車的準(zhǔn)確率不高啊??

Reference


[1] Chen, L. C. , Papandreou, G. , Kokkinos, I. , Murphy, K. , & Yuille, A. L. . (2014). Semantic image segmentation with deep convolutional nets and fully connected crfs. Computer Science.

[2] kazuto1011/ deeplab-pytorch

[3] doiken23/DeepLab_pytorch

[4] 【圖像后處理】python實(shí)現(xiàn)全連接CRFs后處理

轉(zhuǎn)載請(qǐng)說明出處。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末稿壁,一起剝皮案震驚了整個(gè)濱河市幽钢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌傅是,老刑警劉巖匪燕,帶你破解...
    沈念sama閱讀 212,383評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異落午,居然都是意外死亡谎懦,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,522評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門溃斋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)界拦,“玉大人,你說我怎么就攤上這事梗劫∠淼椋” “怎么了?”我有些...
    開封第一講書人閱讀 157,852評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵梳侨,是天一觀的道長(zhǎng)蛉威。 經(jīng)常有香客問我,道長(zhǎng)走哺,這世上最難降的妖魔是什么蚯嫌? 我笑而不...
    開封第一講書人閱讀 56,621評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上择示,老公的妹妹穿的比我還像新娘束凑。我一直安慰自己,他們只是感情好栅盲,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,741評(píng)論 6 386
  • 文/花漫 我一把揭開白布汪诉。 她就那樣靜靜地躺著,像睡著了一般谈秫。 火紅的嫁衣襯著肌膚如雪扒寄。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,929評(píng)論 1 290
  • 那天拟烫,我揣著相機(jī)與錄音该编,去河邊找鬼。 笑死构灸,一個(gè)胖子當(dāng)著我的面吹牛上渴,可吹牛的內(nèi)容都是我干的岸梨。 我是一名探鬼主播喜颁,決...
    沈念sama閱讀 39,076評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼曹阔!你這毒婦竟也來(lái)了半开?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,803評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤赃份,失蹤者是張志新(化名)和其女友劉穎寂拆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體抓韩,經(jīng)...
    沈念sama閱讀 44,265評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡纠永,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,582評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了谒拴。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片尝江。...
    茶點(diǎn)故事閱讀 38,716評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡控硼,死狀恐怖岳枷,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情徙鱼,我是刑警寧澤苍日,帶...
    沈念sama閱讀 34,395評(píng)論 4 333
  • 正文 年R本政府宣布惭聂,位于F島的核電站,受9級(jí)特大地震影響相恃,放射性物質(zhì)發(fā)生泄漏辜纲。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,039評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望耕腾。 院中可真熱鬧屋摇,春花似錦、人聲如沸幽邓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,798評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)牵舵。三九已至柒啤,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間畸颅,已是汗流浹背担巩。 一陣腳步聲響...
    開封第一講書人閱讀 32,027評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留没炒,地道東北人涛癌。 一個(gè)月前我還...
    沈念sama閱讀 46,488評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像送火,于是被迫代替她去往敵國(guó)和親拳话。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,612評(píng)論 2 350