【DL筆記5】用TensorFlow搭建神經(jīng)網(wǎng)絡(luò)——手寫數(shù)字識(shí)別

使用TensorFlow搭建神經(jīng)網(wǎng)絡(luò)——手寫數(shù)字識(shí)別

之前又有很長(zhǎng)一段時(shí)間在講理論讯壶,上次實(shí)踐還是用python實(shí)現(xiàn)Logistic regression料仗。那是一個(gè)很有意義的嘗試湾盗,雖然Logistic regression簡(jiǎn)單伏蚊,但是真的親手手動(dòng)實(shí)現(xiàn)并不容易(我指的是在沒有任何框架的加成下),但我們也深刻理解了內(nèi)部的原理格粪,而這么原理是模型再怎么復(fù)雜也不變的躏吊。
但是想構(gòu)建更加復(fù)雜的網(wǎng)絡(luò)氛改,用純python+numpy恐怕就很不容易了,主要是反向傳播比伏,涉及到大量的求導(dǎo)胜卤,十分麻煩。針對(duì)這種痛點(diǎn)赁项,各種深度學(xué)習(xí)框架出現(xiàn)了葛躏,他們基本上都是幫我們自動(dòng)地進(jìn)行反向傳播的過程,我們只用把正向傳播的“圖”構(gòu)建出來即可悠菜。
所以舰攒,今天,我會(huì)介紹如何用TensorFlow這個(gè)深度學(xué)習(xí)最有名的的框架(之一吧悔醋,免得被杠)摩窃,來實(shí)現(xiàn)一個(gè)3層的神經(jīng)網(wǎng)絡(luò),來對(duì)MNIST手寫數(shù)字進(jìn)行識(shí)別芬骄,并且達(dá)到95%以上的測(cè)試集正確率猾愿。

一、TensorFlow的運(yùn)行機(jī)制和基本用法

TensorFlow運(yùn)行機(jī)制:

剛開始接觸TensorFlow的同學(xué)可能會(huì)發(fā)現(xiàn)它有點(diǎn)奇怪账阻,跟我們一般的計(jì)算過程似乎不同蒂秘。

首先我們要明確TensorFlow中的幾個(gè)基本概念:

  • Tensor 張量,是向量宰僧、矩陣的延伸材彪,是tf中的運(yùn)算的基本對(duì)象
  • operation 操作,簡(jiǎn)稱op琴儿,即加減乘除等等對(duì)張量的操作
  • graph 圖段化,由tensor和tensor之間的操作(op)搭建而成
  • session 會(huì)話,用于啟動(dòng)圖造成,將數(shù)據(jù)feed到圖中显熏,然后運(yùn)算得到結(jié)果

其他的概念先放一邊,我們先搞清楚上面這幾個(gè)玩意兒的關(guān)系晒屎。

在TF中構(gòu)建一個(gè)神經(jīng)網(wǎng)絡(luò)并訓(xùn)練的過程喘蟆,是這樣的:
先用tensor和op來搭建我們的graph,也就是要定義神經(jīng)網(wǎng)絡(luò)的各個(gè)參數(shù)鼓鲁、變量蕴轨,并給出它們之間是什么運(yùn)算關(guān)系,這樣我們就搭建好了圖(graph)骇吭,可以想象是我們搭建好了一個(gè)管道橙弱。

定義參數(shù)、變量,搭建成管道

然后我們啟動(dòng)session(想象成一個(gè)水泵)棘脐,給參數(shù)斜筐、變量初始化,并把我們的訓(xùn)練集數(shù)據(jù)注入到上面構(gòu)建好的圖(graph)中蛀缝,讓我們的數(shù)據(jù)按照我們搭建好的管道去流動(dòng)(flow)顷链,并得到最終的結(jié)果。


開啟session屈梁,數(shù)據(jù)流動(dòng)嗤练、循環(huán)

一句話,先搭建數(shù)據(jù)流圖在讶,然后啟動(dòng)會(huì)話注入數(shù)據(jù)潭苞。TF自動(dòng)完成梯度下降及相應(yīng)的求導(dǎo)過程。

TensorFlow基本用法:
  1. 定義變量
    一般用下面兩種方法來定義:
w = tf.Variable(<initial-value>, name=<optional-name>)

或者用:

w = tf.get_variable(<name>, <shape>, <initializer>)

我更常用后一種方法真朗,因?yàn)榭梢灾苯又付╥nitializer來賦值此疹,比如我們常用的Xavier-initializer,就可以直接調(diào)用tf.contrib.layers.xavier_initializer(),不用我們自己去寫函數(shù)進(jìn)行初始化遮婶。

  1. placeholder
    我們一般給X蝗碎、Y定義成一個(gè)placeholder,即占位符旗扑。也就是在構(gòu)建圖的時(shí)候蹦骑,我們X、Y的殼子去構(gòu)建臀防,因?yàn)檫@個(gè)時(shí)候我們還沒有數(shù)據(jù)眠菇,但是X、Y是我們圖的開端袱衷,所以必須找一個(gè)什么來代替捎废。這個(gè)placeholder就是代替真實(shí)的X、Y來進(jìn)行圖的構(gòu)建的致燥,它擁有X登疗、Y一樣的形狀。
    等session開啟之后嫌蚤,我們就把真實(shí)的數(shù)據(jù)注入到這個(gè)placeholder中即可辐益。
    定義placeholder的方法:
X = tf.placeholder(<dtype>,<shape>,<name>)
  1. operation
    op就是上面定義的tensor的運(yùn)算。比如我們定義了W和b脱吱,并給X定義了一個(gè)placeholder智政,那么Z和A怎么計(jì)算呢:
Z = tf.matmul(X,W)+b
A = tf.nn.relu(Z)

上面兩個(gè)計(jì)算都屬于op,op的輸入為tensor箱蝠,輸出也為tensor续捂,因此Z猜年、A為兩個(gè)新的tensor。
同樣的疾忍,我們可以定義cost,然后可以定義一個(gè)optimizer來minimize這個(gè)cost(optimizer怎么去minimize cost不用我們操心了床三,我們不用去設(shè)計(jì)內(nèi)部的計(jì)算過程一罩,TF會(huì)幫我們計(jì)算,我們只用指定用什么優(yōu)化器撇簿,去干什么工作即可)聂渊。這里具體就留給今天的代碼實(shí)現(xiàn)了。

  1. session
    我們構(gòu)建了圖之后四瘫,就知道了cost是怎么計(jì)算的汉嗽,optimizer是如何工作的。
    然后我們需要啟動(dòng)圖找蜜,并注入數(shù)據(jù)饼暑。
    啟動(dòng)session有兩種形式,本質(zhì)上是一樣的:
sess = tf.Session()
sess.run(<tensor>,<feed_dic>)
...
sess.close()

或者:

with tf.Session() as sess:
    sess.run(<tensor>,<feed_dic>)
    ...

后者就是會(huì)自動(dòng)幫我們關(guān)閉session來釋放資源洗做,不用我們手動(dòng)sess.close()弓叛,因?yàn)檫@個(gè)經(jīng)常被我們忘記。

我們需要計(jì)算什么诚纸,就把相關(guān)的tensor寫進(jìn)<tensor>中去撰筷,計(jì)算圖中的placeholder需要什么數(shù)據(jù),我們就用feed_dic={X:...,Y:...}的方法來傳進(jìn)去畦徘。具體我們下面的代碼實(shí)現(xiàn)部分見毕籽!

上面就是最基本的TensorFlow的原理和用法了,我們下面開始搭建神經(jīng)網(wǎng)絡(luò)井辆!好戲現(xiàn)在開始~

二关筒、開始動(dòng)手,搭建神經(jīng)網(wǎng)絡(luò)杯缺,識(shí)別手寫數(shù)字

我們要面對(duì)的問題是啥呢平委?以前銀行收到支票呀,都要人工去看上面的金額夺谁、日期等等手寫數(shù)字廉赔,支票多了,工作量就很大了匾鸥,而且枯燥乏味蜡塌。那我們就想,能不能用機(jī)器是識(shí)別這些數(shù)字呢勿负?

深度學(xué)習(xí)領(lǐng)域的大佬Yann LeCun(CNN的發(fā)明者)提供了一個(gè)手寫數(shù)字?jǐn)?shù)據(jù)集MNIST馏艾,可以說是深度學(xué)習(xí)的hello world了劳曹。數(shù)字長(zhǎng)這樣:


MNIST手寫數(shù)字

其中每個(gè)圖片的大小是 28×28,我們的 數(shù)據(jù)集已經(jīng)將圖片給扁平化了琅摩,即由28×28铁孵,壓扁成了784,也就是輸入數(shù)據(jù)X的維度為784.

我們今天就設(shè)計(jì)一個(gè)簡(jiǎn)單的 3-layer-NN房资,讓識(shí)別率達(dá)到95%以上蜕劝。
假設(shè)我們的網(wǎng)絡(luò)結(jié)構(gòu)是這樣的:
第一層 128個(gè)神經(jīng)元,第二層 64個(gè)神經(jīng)元轰异,第三層是 Softmax輸出層岖沛,有 10個(gè)神經(jīng)元,因?yàn)槲覀円R(shí)別的數(shù)組為0~9搭独,共10個(gè)婴削。網(wǎng)絡(luò)結(jié)構(gòu)如下(數(shù)字代表維度):

3-layer-NN

好了,我們下面一步步地實(shí)現(xiàn):

(1)加載數(shù)據(jù)牙肝,引入相關(guān)的包

import tensorflow as tf
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
# 下面這一行代碼就可以直接從官網(wǎng)下載數(shù)據(jù)唉俗,下載完之后,你應(yīng)該可以在目錄中發(fā)現(xiàn)一個(gè)新文件夾“MNIST_data”
from tensorflow.examples.tutorials.mnist import input_data 
mnist = input_data.read_data_sets("MNIST_data/", one_hot=True)

下面我們從數(shù)據(jù)集中配椭,把我們的訓(xùn)練集互躬、測(cè)試集都導(dǎo)出:

X_train,Y_train = mnist.train.images,mnist.train.labels
X_test,Y_test = mnist.test.images,mnist.test.labels
# 不妨看看它們的形狀:
print(X_train.shape)  # (55000, 784)
print(Y_train.shape)  # (55000, 10)
print(X_test.shape)   # (10000, 784)
print(Y_test.shape)   # (10000, 10)

可以看出,我們的訓(xùn)練樣本有55000個(gè)颂郎,測(cè)試集有10000個(gè)吼渡。

(2)根據(jù)網(wǎng)絡(luò)結(jié)構(gòu),定義各參數(shù)乓序、變量寺酪,并搭建圖(graph)

tf.reset_default_graph() # 這個(gè)可以不用細(xì)究,是為了防止重復(fù)定義報(bào)錯(cuò)

# 給X替劈、Y定義placeholder寄雀,要指定數(shù)據(jù)類型、形狀:
X = tf.placeholder(dtype=tf.float32,shape=[None,784],name='X')
Y = tf.placeholder(dtype=tf.float32,shape=[None,10],name='Y')

# 定義各個(gè)參數(shù):
W1 = tf.get_variable('W1',[784,128],initializer=tf.contrib.layers.xavier_initializer())
b1 = tf.get_variable('b1',[128],initializer=tf.zeros_initializer())
W2 = tf.get_variable('W2',[128,64],initializer=tf.contrib.layers.xavier_initializer())
b2 = tf.get_variable('b2',[64],initializer=tf.zeros_initializer())
W3 = tf.get_variable('W3',[64,10],initializer=tf.contrib.layers.xavier_initializer())
b3 = tf.get_variable('b3',[10],initializer=tf.zeros_initializer())

這里需要說明的有幾點(diǎn)呢:

  1. 最好給每個(gè)tensor 都取個(gè)名字(name屬性)陨献,這樣報(bào)錯(cuò)的時(shí)候盒犹,我們可以方便地知道是哪個(gè)
  2. 形狀的定義要一致,比如這里的W的形狀眨业,我們之前在講解某些原理的時(shí)候急膀,使用的是(當(dāng)前層維度,上一層維度),但是 這里我們采用的是(上一層維度龄捡,當(dāng)前層維度),所以分別是(784,128),(128,64),(64,10). 另外卓嫂,X、Y的維度中的None聘殖,是樣本數(shù)晨雳,由于我們同一個(gè)模型不同時(shí)候傳進(jìn)去的樣本數(shù)可能不同行瑞,所以這里可以寫 None,代表可變的餐禁。
  3. W的初始化血久,可以直接用tf自帶的initializer,但是注意不能用0給W初始化帮非,這個(gè)問題我在之前的“參數(shù)初始化”的文章里面講過氧吐。b可以用0初始化。

接著喜鼓,我們根據(jù)上面的變量,來 計(jì)算網(wǎng)絡(luò)中間的logits(就是我們常用的Z)衔肢、激活值

A1 = tf.nn.relu(tf.matmul(X,W1)+b1,name='A1')
A2 = tf.nn.relu(tf.matmul(A1,W2)+b2,name='A2')
Z3 = tf.matmul(A2,W3)+b3

為什么我們只用算到Z3就行了呢庄岖,因?yàn)門ensorFlow中,計(jì)算損失有專門的函數(shù)角骤,一般都是直接用Z的值和標(biāo)簽Y的值來計(jì)算隅忿,比如

對(duì)于sigmoid函數(shù),我們有:
tf.nn.sigmoid_cross_entropy_with_logits(logits=,labels=)來計(jì)算邦尊,

對(duì)于Softmax背桐,我們有:
tf.nn.softmax_cross_entropy_with_logits(logits=,labels=)來計(jì)算。
這個(gè)logits蝉揍,就是未經(jīng)激活的Z链峭;labels,就是我們的Y標(biāo)簽又沾。

因此我們?nèi)绾?定義我們的cost呢:

cost = tf.reduce_mean(tf.nn.softmax_cross_entropy_with_logits(logits=Z3,labels=Y))

注意弊仪,為什么要用 reduce_mean()函數(shù)呢?因?yàn)榻?jīng)過softmax_cross_entropy_with_logits計(jì)算出來是杖刷,是所有樣本的cost拼成的一個(gè)向量励饵,有m個(gè)樣本,它就是m維滑燃,因此我們需要去平均值來獲得一個(gè)整體的cost役听。

定義好了cost,我們就可以 定義optimizer來minimize cost了:

trainer = tf.train.AdamOptimizer().minimize(cost)

也是一句話的事兒表窘,賊簡(jiǎn)單了典予。這里我們采用Adam優(yōu)化器,用它來minimize cost乐严。當(dāng)然熙参,我們可以在AdamOptimizer()中設(shè)置一些超參數(shù),比如leaning_rate麦备,但是這里我直接采用它的默認(rèn)值了孽椰,一般效果也不錯(cuò)昭娩。

至此,我們的整個(gè)計(jì)算圖黍匾,就搭建好了栏渺,從X怎么一步步的加上各種參數(shù),并計(jì)算cost锐涯,以及optimizer怎么優(yōu)化cost磕诊,都以及明確了。接下來纹腌,我們就可以啟動(dòng)session霎终,放水了!

(3)啟動(dòng)圖升薯,注入數(shù)據(jù)莱褒,進(jìn)行迭代

廢話不多說,直接上代碼:

with tf.Session() as sess:
    # 首先給所有的變量都初始化(不用管什么意思涎劈,反正是一句必須的話):
    sess.run(tf.global_variables_initializer())

    # 定義一個(gè)costs列表广凸,來裝迭代過程中的cost,從而好畫圖分析模型訓(xùn)練進(jìn)展
    costs = []
    
    # 指定迭代次數(shù):
    for it in range(1000):
        # 這里我們可以使用mnist自帶的一個(gè)函數(shù)train.next_batch蛛枚,可以方便地取出一個(gè)個(gè)地小數(shù)據(jù)集谅海,從而可以加快我們的訓(xùn)練:
        X_batch,Y_batch = mnist.train.next_batch(batch_size=64)

        # 我們最終需要的是trainer跑起來,并獲得cost蹦浦,所以我們r(jià)un trainer和cost扭吁,同時(shí)要把X、Y給feed進(jìn)去:
        _,batch_cost = sess.run([trainer,cost],feed_dict={X:X_batch,Y:Y_batch})
        costs.append(batch_cost)

        # 每100個(gè)迭代就打印一次cost:
        if it%100 == 0:
            print('iteration%d ,batch_cost: '%it,batch_cost)

    # 訓(xùn)練完成盲镶,我們來分別看看來訓(xùn)練集和測(cè)試集上的準(zhǔn)確率:
    predictions = tf.equal(tf.argmax(tf.transpose(Z3)),tf.argmax(tf.transpose(Y)))
    accuracy = tf.reduce_mean(tf.cast(predictions,'float'))
    print("Training set accuracy: ",sess.run(accuracy,feed_dict={X:X_train,Y:Y_train}))
    print("Test set accuracy:",sess.run(accuracy,feed_dict={X:X_test,Y:Y_test}))

運(yùn)行智末,查看輸出結(jié)果:

iteration0 ,batch_cost:  2.3507476
iteration100 ,batch_cost:  0.32707167
iteration200 ,batch_cost:  0.571893
iteration300 ,batch_cost:  0.2989539
iteration400 ,batch_cost:  0.1347334
iteration500 ,batch_cost:  0.24421218
iteration600 ,batch_cost:  0.13563904
iteration700 ,batch_cost:  0.26415896
iteration800 ,batch_cost:  0.1695988
iteration900 ,batch_cost:  0.17325541
Training set accuracy:  0.9624182
Test set accuracy:  0.9571

嚯,感覺不錯(cuò)徒河!訓(xùn)練很快系馆,不到5秒,已經(jīng)達(dá)到我們的要求了顽照,而且我們僅僅是迭代了1000次啊由蘑。

我們不妨將結(jié)果可視化一下,隨機(jī)抽查一些圖片代兵,然后輸出對(duì)應(yīng)的預(yù)測(cè):
將下列代碼放到上面的session中(不能放在session外部尼酿,否則沒法取出相應(yīng)的值),重新運(yùn)行:

    # 這里改了一點(diǎn)上面的預(yù)測(cè)集準(zhǔn)確率的代碼植影,因?yàn)槲覀冃枰李A(yù)測(cè)結(jié)果裳擎,所以這里我們單獨(dú)把Z3的值給取出來,這樣通過分析Z3思币,即可知道預(yù)測(cè)值是什么了鹿响。
    z3,acc = sess.run([Z3,accuracy],feed_dict={X:X_test,Y:Y_test})
    print("Test set accuracy:",acc)
    
    # 隨機(jī)從測(cè)試集中抽一些圖片(比如第i*10+j張圖片)羡微,然后取出對(duì)應(yīng)的預(yù)測(cè)(即z3[i*10+j]):
    fig,ax = plt.subplots(4,4,figsize=(15,15))
    fig.subplots_adjust(wspace=0.1, hspace=0.7)
    for i in range(4):
        for j in range(4):
            ax[i,j].imshow(X_test[i*10+j].reshape(28,28))
            # 用argmax函數(shù)取出z3中最大的數(shù)的序號(hào),即為預(yù)測(cè)結(jié)果:
            predicted_num  = np.argmax(z3[i*10+j])        
            # 這里不能用tf.argmax惶我,因?yàn)樗械膖f操作都是在圖中妈倔,沒法直接取出來
            ax[i,j].set_title('Predict:'+str(predicted_num))
            ax[i,j].axis('off')

得到結(jié)果:


圖片和預(yù)測(cè)結(jié)果

可見,我們的模型是真的訓(xùn)練出來了绸贡,而且效果不錯(cuò)盯蝴。這個(gè)圖中,右下角的那個(gè)奇怪的“4”都給識(shí)別出來了听怕。唯一有爭(zhēng)議的是第三排第三個(gè)的那個(gè)數(shù)字捧挺,我感覺是4,不過也確實(shí)有點(diǎn)像6尿瞭,結(jié)果模式識(shí)別它為6闽烙。

總的來說還是很棒的,接下來我覺得增大迭代次數(shù)筷厘,迭代它個(gè)10000次鸣峭!然后看更多的圖片(100張圖片)宏所。效果如下:

準(zhǔn)確率和cost曲線

可見酥艳,準(zhǔn)確率提高到了97%以上!
再展示一下圖片:
手寫數(shù)字預(yù)測(cè)

至此爬骤,我們的實(shí)驗(yàn)就完成了充石。我們成功地利用TensorFlow搭建了一個(gè)三層神經(jīng)網(wǎng)絡(luò),并對(duì)手寫數(shù)字進(jìn)行了出色的識(shí)別霞玄!


對(duì)于TensorFlow更豐富更相信的使用骤铃,大家可以去TensorFlow中文社區(qū)或者TensorFlow官網(wǎng)了解。這里也推薦大家試試TensorFlow的高度封裝的api——Keras坷剧,也是一個(gè)深度學(xué)習(xí)框架惰爬,它可以更加輕松地搭建一個(gè)網(wǎng)絡(luò)。之后的文章我也會(huì)介紹keras的使用惫企。

歡迎關(guān)注我的專欄:
【DeepLearning學(xué)習(xí)筆記】
和我一起一步步學(xué)習(xí)深度學(xué)習(xí)撕瞧。
專欄其他文章:
【DL筆記1】Logistic回歸:最基礎(chǔ)的神經(jīng)網(wǎng)絡(luò)
【DL筆記2】神經(jīng)網(wǎng)絡(luò)編程原則&Logistic Regression的算法解析
【DL筆記3】一步步親手用python實(shí)現(xiàn)Logistic Regression
【DL筆記4】神經(jīng)網(wǎng)絡(luò)詳解,正向傳播和反向傳播
【DL碎片1】神經(jīng)網(wǎng)絡(luò)參數(shù)初始化的學(xué)問
【DL碎片2】神經(jīng)網(wǎng)絡(luò)中的優(yōu)化算法
【DL碎片3】神經(jīng)網(wǎng)絡(luò)中的激活(Activation)函數(shù)及其對(duì)比
【DL碎片4】深度學(xué)習(xí)中的的超參數(shù)調(diào)節(jié)
【DL碎片5】深度學(xué)習(xí)中的正則化(Regularization))

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末狞尔,一起剝皮案震驚了整個(gè)濱河市丛版,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌偏序,老刑警劉巖页畦,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異研儒,居然都是意外死亡豫缨,警方通過查閱死者的電腦和手機(jī)独令,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來州胳,“玉大人记焊,你說我怎么就攤上這事∷ㄗ玻” “怎么了遍膜?”我有些...
    開封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)瓤湘。 經(jīng)常有香客問我瓢颅,道長(zhǎng),這世上最難降的妖魔是什么弛说? 我笑而不...
    開封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任挽懦,我火速辦了婚禮,結(jié)果婚禮上木人,老公的妹妹穿的比我還像新娘信柿。我一直安慰自己,他們只是感情好醒第,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開白布渔嚷。 她就那樣靜靜地躺著,像睡著了一般稠曼。 火紅的嫁衣襯著肌膚如雪形病。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天霞幅,我揣著相機(jī)與錄音漠吻,去河邊找鬼。 笑死司恳,一個(gè)胖子當(dāng)著我的面吹牛途乃,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扔傅,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼耍共,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了铅鲤?” 一聲冷哼從身側(cè)響起划提,我...
    開封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎邢享,沒想到半個(gè)月后鹏往,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體菌赖,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡畜晰,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片卦停。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡油猫,死狀恐怖隆夯,靈堂內(nèi)的尸體忽然破棺而出噪沙,到底是詐尸還是另有隱情,我是刑警寧澤哄辣,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布请梢,位于F島的核電站,受9級(jí)特大地震影響力穗,放射性物質(zhì)發(fā)生泄漏毅弧。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一当窗、第九天 我趴在偏房一處隱蔽的房頂上張望够坐。 院中可真熱鬧,春花似錦崖面、人聲如沸元咙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽庶香。三九已至,卻和暖如春疏遏,著一層夾襖步出監(jiān)牢的瞬間脉课,已是汗流浹背救军。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工财异, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人唱遭。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓戳寸,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親拷泽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子疫鹊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353