人工神經(jīng)網(wǎng)絡(luò)實現(xiàn)醫(yī)療數(shù)據(jù)分類Python

進(jìn)半年孽水,大量學(xué)習(xí)和實踐深度學(xué)習(xí)方面的知識尊浪,因此希望把所學(xué)的知識進(jìn)行總結(jié)梳理十酣,幫助更多同路的人。在這里連載文章际长,希望得到更多的人的支持耸采。同時感謝港理工的佳佳博士與我一起完成這本書,一路過來,謝謝。

2.3 使用ANN對醫(yī)療數(shù)據(jù)分類

IBM在2015年5月宣布推出Watson Health服務(wù)池户,收集健康數(shù)據(jù)交給Watson超級計算機(jī)進(jìn)行分析央拖。目前IBM Waston Health最主要的應(yīng)用便是在癌癥的診療上普气,通過對醫(yī)學(xué)影像的分析和學(xué)習(xí)润讥,幫助醫(yī)生做出對癌癥患者的精準(zhǔn)診斷呛梆。另外一方面吟税,在每一個國家的醫(yī)療資源都是十分稀缺的搪泳,如何提高基層醫(yī)生的診療水平顯得至關(guān)重要稀轨。我們并不需要智能診療會取代醫(yī)生,因為醫(yī)療也并不是簡單的診斷岸军,醫(yī)生更重要的價值還在于對診斷結(jié)果的解釋奋刽、說明和信用背書,但讓智能診療系統(tǒng)輔助醫(yī)生診斷艰赞,則無疑會大大提高普通醫(yī)生的診斷水平和診斷效率佣谐,降低誤診率。

因此方妖,人工智能對于輔助醫(yī)生的工作來說狭魂,越顯得非常重要。例如:醫(yī)生可以根據(jù)人工智能給出女性最佳生育期的建議党觅,不再僅僅基于她們的年齡雌澄,而是基于一系列相關(guān)的個人身體指標(biāo)。

以現(xiàn)代醫(yī)療檢測報告為例杯瞻,很多時候我們?nèi)メt(yī)院抽血镐牺、檢查細(xì)胞病變等檢查之后,檢查室開出一張看不懂的表格如圖2.3.1又兵,上面有白細(xì)胞任柜、鏈球菌、血小板的參數(shù)沛厨,醫(yī)生通過檢查這些參數(shù)值得大小和變化宙地,可以預(yù)測判斷該病人是否患有某種病原體。

下面我們將把類似的醫(yī)療數(shù)據(jù)作為背景:首先給出對的醫(yī)療檢測數(shù)據(jù)進(jìn)行數(shù)學(xué)模型的轉(zhuǎn)換逆皮,然后通過構(gòu)建一個三層的人工神經(jīng)網(wǎng)絡(luò)ANN對已有的醫(yī)療數(shù)據(jù)進(jìn)行訓(xùn)練宅粥, 得到該醫(yī)療數(shù)據(jù)的分類模型,然后對新的數(shù)據(jù)進(jìn)行預(yù)測其所屬分類电谣,因為人工神經(jīng)網(wǎng)絡(luò)的隱層對數(shù)據(jù)的分類存在較大影響秽梅,因此最后探討隱層的神經(jīng)元節(jié)點(diǎn)數(shù)對實際的數(shù)據(jù)有如何的影響。

這里寫圖片描述

2.3.1 準(zhǔn)備數(shù)據(jù):從醫(yī)療數(shù)據(jù)到數(shù)學(xué)模型

假設(shè)本次血液檢測項目只有鏈球菌x1和葡萄球菌x2兩種剿牺,對于不同的球菌組合企垦,會出現(xiàn)不同的病原體(不同的病癥)。假設(shè)有兩個分類晒来,分別是病原體I和病原體II钞诡,病原體I、病原體II分別用用藍(lán)色、紅色表達(dá)荧降;x軸表示鏈球菌的值接箫,y軸表示葡萄球菌的值。在本例程這里的數(shù)據(jù)已經(jīng)歸一化處理過后朵诫,因此數(shù)據(jù)的分布集中在[-2, 2]之間(想要了解更多關(guān)于歸一化操作請參考機(jī)器學(xué)習(xí)實踐[1])辛友。

我們的目標(biāo)是通過訓(xùn)練一個三層的人工神經(jīng)網(wǎng)絡(luò)ANN模型,對給出不同血液檢測項目(x1剪返、x2)的數(shù)據(jù)進(jìn)行分類废累。值得注意的是,因為很多時候醫(yī)療數(shù)據(jù)是線性不可分的随夸,因此我們并不能夠簡單地使用一條直線對數(shù)據(jù)進(jìn)行劃分九默。這意味著不能夠用線性分類器來分類震放,例如Logistic分類器宾毒、貝葉斯分類器等,否則分類的數(shù)據(jù)精度和回召率過低殿遂,會對真實的醫(yī)療診斷結(jié)果造成巨大的影響诈铛。

使用神經(jīng)網(wǎng)絡(luò)的好處就是不需要去擔(dān)心特征工程問題,隱層會自動地去尋找特征墨礁。

from sklearn import linear_model
from sklearn import datasets
import sklearn
import numpy as np
import matplotlib.pyplot as plt
# 在notebook內(nèi)顯示plt圖
%matplotlib inline
def plot_decision_boundary(pred_func, data, labels):
    '''繪制分類邊界圖'''
    # 設(shè)置最大值和最小值并增加0.5的邊界(0.5 padding)
    x_min, x_max = data[:, 0].min() - 0.5, data[:, 0].max() + 0.5
    y_min, y_max = data[:, 1].min() - 0.5, data[:, 1].max() + 0.5
    h = 0.01

    # 生成一個點(diǎn)陣網(wǎng)格幢竹,點(diǎn)陣間距離為h
    xx, yy = np.meshgrid(np.arange(x_min, x_max, h),
                         np.arange(y_min, y_max, h))

    # 預(yù)測整個網(wǎng)格當(dāng)中的函數(shù)值
    z = pred_func(np.c_[xx.ravel(), yy.ravel()])
    z = z.reshape(xx.shape)

    # 繪制輪廓和訓(xùn)練樣本
    plt.contourf(xx, yy, z, cmap=plt.cm.Spectral)
    plt.scatter(data[:, 0], data[:, 1], s=40, c=labels, cmap=plt.cm.Spectral)
np.random.seed(0)
X, y = datasets.make_moons(300, noise=0.25)  # 300個數(shù)據(jù)點(diǎn),噪聲設(shè)定0.3
plt.scatter(X[:,0], X[:,1], s = 50,  c = y, cmap=plt.cm.Spectral, edgecolors="Black")
plt.title('Data Example')
plt.show()
這里寫圖片描述

邏輯回歸結(jié)果

下圖顯示了我們邏輯回歸分類器的分類結(jié)果恩静,邏輯回歸算法直接用直線將數(shù)據(jù)分隔開兩類焕毫,明顯這樣的分類結(jié)果是遠(yuǎn)遠(yuǎn)不能滿足真實情況的。

# 使用scikit-learn的線性回歸分類器
clf = sklearn.linear_model.LogisticRegressionCV() 
clf.fit(X, y)

# 顯示分類結(jié)果
plot_decision_boundary(lambda x: clf.predict(x), X, y)
plt.title("Logistic Regression")
<matplotlib.text.Text at 0x10d0de190>
這里寫圖片描述

2.3.2 建立人工神經(jīng)網(wǎng)絡(luò)模型

為了解決現(xiàn)實情況更多線性不可分的數(shù)據(jù)驶乾,我們需要建立一個三層神經(jīng)網(wǎng)絡(luò)邑飒,輸入層、隱層级乐、輸出層疙咸。

其中輸入層(第一層)中的神經(jīng)節(jié)點(diǎn)數(shù)目由輸入數(shù)據(jù)的維數(shù)決定,例子有鏈球菌x1和葡萄球菌x2风科,因此數(shù)據(jù)維度是2撒轮,輸入有兩個神經(jīng)元節(jié)點(diǎn)。同理贼穆,輸出層(第三層)中的節(jié)點(diǎn)數(shù)目由我們的分類數(shù)決定题山,例子里為病原體I(0)和病原體II(1),因此輸出層有兩個神經(jīng)元故痊。該神經(jīng)網(wǎng)絡(luò)如圖2.3.4所示顶瞳。

這里寫圖片描述

根據(jù)實際情況我們可以增加隱層數(shù)和每一隱層的節(jié)點(diǎn)數(shù),當(dāng)隱層越多、隱層節(jié)點(diǎn)越多浊仆,能夠處理更加復(fù)雜數(shù)據(jù)模型客峭,但是伴隨著是更大的開銷:

1.更多隱層意味著我們的網(wǎng)絡(luò)模型越大,引入更多的權(quán)值參數(shù)抡柿,占用更多GPU顯存;

2.參數(shù)數(shù)量越多舔琅,數(shù)據(jù)過度擬合的可能性就越大,網(wǎng)絡(luò)就有可能不穩(wěn)定洲劣,預(yù)測效果反而下降备蚓;

那么如何選擇適當(dāng)?shù)碾[層數(shù)呢?每層隱藏層的神經(jīng)元數(shù)應(yīng)該設(shè)置多少呢囱稽?這是一個工程問題郊尝,不同的數(shù)據(jù)會有不一樣的結(jié)果,所以作者覺得神經(jīng)網(wǎng)絡(luò)的設(shè)計是一種工程藝術(shù)战惊,我們需要去嘗試流昏、訓(xùn)練、預(yù)測吞获、評估况凉,才能最終決定整個網(wǎng)絡(luò)模型的形態(tài),感受深度學(xué)習(xí)的魅力所在各拷。

在隱層我們需要一個激活函數(shù)刁绒,激活函數(shù)把輸出層轉(zhuǎn)換成為下一層的輸入層。非線性的激活函數(shù)能夠讓我們?nèi)ヌ幚矸蔷€性的問題烤黍。常用的有tanh函數(shù)知市、sigmoid函數(shù)或者ReLUs函數(shù)。例子里我們選擇使用tanh函數(shù)速蕊,你也可以嘗試把tanh函數(shù)換成其他函數(shù)查看輸出嫂丙。

最后通過softmax分類器把激活函數(shù)的輸出分?jǐn)?shù)轉(zhuǎn)換成為概率。

Softmax分類器

預(yù)測網(wǎng)絡(luò)

人工神經(jīng)網(wǎng)絡(luò)的預(yù)測使用向前反饋操作互例,我們可以理解為激活函數(shù)和矩陣乘法的操作奢入。假設(shè)輸入x是二維,我們可以根據(jù)計算公式得到輸出分類結(jié)果$\hat{y}$:

$z_1=xW_1+b_1$

$a_1=tanh(Z_1)$

$z2=a_1W_2+b_2$

$a_2=\hat{y}=softmax(Z_2)$

$z_i$是第$i$層的輸入媳叨,$a_i$是第$i$層激活函數(shù)處理后的輸出腥光。$W_1,b_1,W_2,b_2$是神經(jīng)網(wǎng)絡(luò)的參數(shù),用來學(xué)習(xí)和訓(xùn)練用的數(shù)據(jù)糊秆,這里可以把它們當(dāng)做在網(wǎng)絡(luò)中的的矩陣武福。圖2.3.5是圖2.3.4的展開。如果在隱層中使用100個神經(jīng)元節(jié)點(diǎn)痘番,那么有$W_1\in\mathbb{R}^{2100}, b_1\in\mathbb{R}{100},W_2\in\mathbb{R}{1002}, b_2\in\mathbb{R}^{2}$捉片,從上面的公式可以看出來增加隱層的節(jié)點(diǎn)數(shù)會大量的增加網(wǎng)絡(luò)
的參數(shù)平痰。

這里寫圖片描述

參數(shù)學(xué)習(xí)

學(xué)習(xí)參數(shù)意味著需要找$W_1,b_1,W_2,b_2$,使得我們的數(shù)據(jù)誤差最小伍纫。那么如何定義誤差宗雇?我們稱這個檢測誤差的函數(shù)叫做損失函數(shù)(loss function)。這里我們使用較為常用交叉熵?fù)p失函數(shù)(也叫做負(fù)對數(shù)似然函數(shù))莹规。如果我們有N個訓(xùn)練樣本和對應(yīng)C個分類赔蒲,那么預(yù)測值$\hat{y}$與實際值y的損失是:

$$L(y,\hat{y})=-\frac{1}{N}\sum_{n\in N}\sum_{i\in C}y_{n,i}{log\hat{y}_{n,i}}$$

當(dāng)實際值$y$與預(yù)測值$\hat{y}$之間的概率分布差別越大,損失就越大良漱。因此通過尋找好的權(quán)重參數(shù)舞虱,最大限度地減少損失,提高數(shù)據(jù)分類的準(zhǔn)確性母市。

例子里我們使用梯度下降算法去找損失函數(shù)的最小值矾兜,使用一個固定的學(xué)習(xí)速率實現(xiàn)批量梯度下降算法(在實際工程當(dāng)中通常是使用隨機(jī)梯度下降或minibatch梯度下降算法的)。

梯度下降首先需要對神經(jīng)網(wǎng)絡(luò)模型用到的參數(shù)進(jìn)行求導(dǎo):$\frac{\partial L}{\partial W_1},\frac{\partial L}{\partial b_1},\frac{\partial L}{\partial W_2},\frac{\partial L}{\partial b_2}$患久。而求得這些梯度則使用著名的BP算法椅寺,在這里不在給出推導(dǎo)過程,而是直接使用推導(dǎo)后的公式:

$\delta _3=\hat{y}-y$

$\delta _2=(1-tanh2z_1)*\delta_3W_2T$

$\frac{\delta L}{\delta W_2}=\alpha _1^T \delta_3$

$\frac{\delta L}{\delta b_2}=\delta _3$

$\frac{\delta L}{\delta w_1}=x^T\delta _2$

$\frac{\delta L}{\delta b_1}=\delta _2$

2.3.3 Python實現(xiàn)ANN

首先定義一些梯度下降的時候用到的一些變量:

class Config:
    input_dim = 2  # 輸入的維度
    output_dim = 2  # 輸出的分類數(shù)

    epsilon = 0.01  # 梯度下降學(xué)習(xí)速度
    reg_lambda = 0.01  # 正則化強(qiáng)度

下面的損失函數(shù)的實現(xiàn)墙杯,通過這個函數(shù)我們觀察模型訓(xùn)練的效果:

def calculate_loss(model, X, y):
    '''
    損失函數(shù)
    '''
    num_examples = len(X)  # 訓(xùn)練集大小
    W1, b1, W2, b2 = model['W1'], model['b1'], model['W2'], model['b2']
    # 正向傳播計算預(yù)測值
    z1 = X.dot(W1) + b1
    a1 = np.tanh(z1)
    z2 = a1.dot(W2) + b2
    exp_scores = np.exp(z2)
    probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
    # 計算損失值
    corect_logprobs = -np.log(probs[range(num_examples), y])
    data_loss = np.sum(corect_logprobs)
    # 對損失值進(jìn)行歸一化(可以不加)
    data_loss += Config.reg_lambda / 2 * \
        (np.sum(np.square(W1)) + np.sum(np.square(W2)))
    return 1. / num_examples * data_loss

接下來實現(xiàn)預(yù)測函數(shù)配并,預(yù)測的時候只需要對模型進(jìn)行一次向前傳播括荡,然后返回分類結(jié)果中概率最大的一項:

def predict(model, x):
    '''
    預(yù)測函數(shù)
    '''
    W1, b1, W2, b2 = model['W1'], model['b1'], model['W2'], model['b2']
    # 向前傳播
    z1 = x.dot(W1) + b1
    a1 = np.tanh(z1)
    z2 = a1.dot(W2) + b2
    exp_scores = np.exp(z2)
    probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)
    return np.argmax(probs, axis=1)

接下是整個人工神經(jīng)網(wǎng)絡(luò)模型的函數(shù)高镐,這個函數(shù)實現(xiàn)了使用向后傳播算法來計算批量梯度下降,使用了2.3.2中參數(shù)學(xué)習(xí)的公式:

def ANN_model(X, y, nn_hdim, num_passes=20000, print_loss=False):
    '''
    網(wǎng)絡(luò)學(xué)習(xí)函數(shù)畸冲,并返回網(wǎng)絡(luò)
    - nn_hdim: 隱層的神經(jīng)元節(jié)點(diǎn)(隱層的數(shù)目)
    - num_passes: 梯度下降迭代次數(shù)
    - print_loss: 是否顯示損失函數(shù)值
    '''
    num_examples = len(X)  # 訓(xùn)練的數(shù)據(jù)集
    model = {}  # 模型存儲定義

    # 隨機(jī)初始化參數(shù)
    np.random.seed(0)
    W1 = np.random.randn(Config.input_dim, nn_hdim) / np.sqrt(Config.input_dim)
    b1 = np.zeros((1, nn_hdim))
    W2 = np.random.randn(nn_hdim, Config.output_dim) / np.sqrt(nn_hdim)
    b2 = np.zeros((1, Config.output_dim))
    # display_model({'W1': W1, 'b1': b1, 'W2': W2, 'b2': b2})

    # 批量梯度下降
    for i in xrange(0, num_passes + 1):
        # 向前傳播
        z1 = X.dot(W1) + b1  # M_200*2 .* M_2*3 --> M_200*3
        a1 = np.tanh(z1)
        z2 = a1.dot(W2) + b2  # M_200*3 .* M_3*2 --> M_200*2
        exp_scores = np.exp(z2)
        probs = exp_scores / np.sum(exp_scores, axis=1, keepdims=True)

        # 向后傳播
        delta3 = probs  # 得到的預(yù)測值
        delta3[range(num_examples), y] -= 1  # 預(yù)測值減去實際值
        delta2 = delta3.dot(W2.T) * (1 - np.power(a1, 2))
        dW2 = (a1.T).dot(delta3)  # W2的導(dǎo)數(shù)
        db2 = np.sum(delta3, axis=0, keepdims=True)  # b2的導(dǎo)數(shù)
        dW1 = np.dot(X.T, delta2)  # W1的導(dǎo)數(shù)
        db1 = np.sum(delta2, axis=0)  # b1的導(dǎo)數(shù)

        # 添加正則化項
        dW1 += Config.reg_lambda * W1
        dW2 += Config.reg_lambda * W2

        # 根據(jù)梯度下降值更新權(quán)重
        W1 += -Config.epsilon * dW1
        b1 += -Config.epsilon * db1
        W2 += -Config.epsilon * dW2
        b2 += -Config.epsilon * db2

        # 把新的參數(shù)加入模型當(dāng)中
        model = {'W1': W1, 'b1': b1, 'W2': W2, 'b2': b2}

        if print_loss and i % 1000 == 0:
            print("Loss after iteration %i: %f" %
                  (i, calculate_loss(model, X, y)))

    return model

下面我們來看一下訓(xùn)練的網(wǎng)絡(luò)只有隱層節(jié)點(diǎn)數(shù)只有三個的時候訓(xùn)練的結(jié)果:

model = ANN_model(X, y, 3, print_loss=True)  # 建立三個神經(jīng)元的隱層
plot_decision_boundary(lambda x: predict(model, x), X, y)
plt.title("Hidden Layer size 3")
Loss after iteration 0: 0.389105
Loss after iteration 1000: 0.120831
Loss after iteration 2000: 0.116688
Loss after iteration 3000: 0.115724
Loss after iteration 4000: 0.115322
Loss after iteration 5000: 0.115115
Loss after iteration 6000: 0.114996
Loss after iteration 7000: 0.114923
Loss after iteration 8000: 0.114876
Loss after iteration 9000: 0.114845
Loss after iteration 10000: 0.114825
Loss after iteration 11000: 0.114811
Loss after iteration 12000: 0.114801
Loss after iteration 13000: 0.114794
Loss after iteration 14000: 0.114789
Loss after iteration 15000: 0.114786
Loss after iteration 16000: 0.114784
Loss after iteration 17000: 0.114782
Loss after iteration 18000: 0.114781
Loss after iteration 19000: 0.114780
Loss after iteration 20000: 0.114779
這里寫圖片描述

2.3.4 隱層節(jié)點(diǎn)數(shù)對模型的影響

從上圖可以看出人工神經(jīng)網(wǎng)絡(luò)模型的訓(xùn)練效果比Logistic回歸的效果好很多嫉髓,但是依然可以看出有個別數(shù)據(jù)的分類是錯誤的。接下來通過實際工程測試去深入了解隱層節(jié)點(diǎn)對模型的影響:

plt.figure(figsize=(16, 32))
hidden_layer_dimensions = [1, 2, 3, 4, 5, 15, 30, 50]
for i, nn_hdim in enumerate(hidden_layer_dimensions):
    plt.subplot(5, 2, i+1)
    plt.title('Hidden Layer size %d' % nn_hdim)
    model = ANN_model(X, y, nn_hdim)
    plot_decision_boundary(lambda x: predict(model, x), X, y)
plt.show()
這里寫圖片描述

通過上圖我們可以看到邑闲,隱層數(shù)在低維(4算行、5)的時候能夠很好地表達(dá)數(shù)據(jù)的分類屬性,隱層節(jié)點(diǎn)數(shù)越高苫耸,會造成過度擬合(如隱層數(shù)為50時)州邢。造成這種原因是因為隱層數(shù)較低的時候會有更好的歸一化表現(xiàn),當(dāng)隱層數(shù)正價的時候褪子,歸一化過度造成過度擬合量淌。如果想要更好地評估這個醫(yī)療數(shù)據(jù)分類模型,更建議把數(shù)據(jù)分為訓(xùn)練集和測試集嫌褪,然后檢測測試集的效果呀枢。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市笼痛,隨后出現(xiàn)的幾起案子裙秋,更是在濱河造成了極大的恐慌琅拌,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,509評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件摘刑,死亡現(xiàn)場離奇詭異进宝,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)枷恕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,806評論 3 394
  • 文/潘曉璐 我一進(jìn)店門即彪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人活尊,你說我怎么就攤上這事隶校。” “怎么了蛹锰?”我有些...
    開封第一講書人閱讀 163,875評論 0 354
  • 文/不壞的土叔 我叫張陵深胳,是天一觀的道長。 經(jīng)常有香客問我铜犬,道長舞终,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,441評論 1 293
  • 正文 為了忘掉前任癣猾,我火速辦了婚禮敛劝,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘纷宇。我一直安慰自己夸盟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,488評論 6 392
  • 文/花漫 我一把揭開白布像捶。 她就那樣靜靜地躺著上陕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拓春。 梳的紋絲不亂的頭發(fā)上释簿,一...
    開封第一講書人閱讀 51,365評論 1 302
  • 那天,我揣著相機(jī)與錄音硼莽,去河邊找鬼庶溶。 笑死,一個胖子當(dāng)著我的面吹牛懂鸵,可吹牛的內(nèi)容都是我干的偏螺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,190評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼矾瑰,長吁一口氣:“原來是場噩夢啊……” “哼砖茸!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起殴穴,我...
    開封第一講書人閱讀 39,062評論 0 276
  • 序言:老撾萬榮一對情侶失蹤凉夯,失蹤者是張志新(化名)和其女友劉穎货葬,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體劲够,經(jīng)...
    沈念sama閱讀 45,500評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡震桶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,706評論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了征绎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蹲姐。...
    茶點(diǎn)故事閱讀 39,834評論 1 347
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖人柿,靈堂內(nèi)的尸體忽然破棺而出柴墩,到底是詐尸還是另有隱情,我是刑警寧澤凫岖,帶...
    沈念sama閱讀 35,559評論 5 345
  • 正文 年R本政府宣布江咳,位于F島的核電站,受9級特大地震影響哥放,放射性物質(zhì)發(fā)生泄漏歼指。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,167評論 3 328
  • 文/蒙蒙 一甥雕、第九天 我趴在偏房一處隱蔽的房頂上張望踩身。 院中可真熱鬧,春花似錦社露、人聲如沸挟阻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,779評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽赁濒。三九已至,卻和暖如春孟害,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背挪拟。 一陣腳步聲響...
    開封第一講書人閱讀 32,912評論 1 269
  • 我被黑心中介騙來泰國打工挨务, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人玉组。 一個月前我還...
    沈念sama閱讀 47,958評論 2 370
  • 正文 我出身青樓谎柄,卻偏偏與公主長得像,于是被迫代替她去往敵國和親惯雳。 傳聞我的和親對象是個殘疾皇子朝巫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,779評論 2 354

推薦閱讀更多精彩內(nèi)容