論文共讀筆記(2)理解Transformer的三層境界--Attention is all you need

[TOC]
@author by xubing

0x00是鬼、先導知識

0.1 Seq2Seq

0.2 Attention


0x01.第一層境界

高屋建瓴端考,會當凌絕頂


  • 文章題目:《Attention is all you need》
  • 發(fā)表時間:2017.06
  • 作者:Google(幾位作者全部是一作)
論文基本信息
  • 傳統的編碼器解碼器一般使用RNN,這也是在機器翻譯中最經典的模型罐盔。但RNN難以處理長序列的句子但绕,無法實現并行,并且面臨對齊問題。
  • Attention模型就是在Encoder和Decoder之間增加了Attention層捏顺,解決了長距離依賴的問題六孵。

(長距離依賴信息”可以這么來理解:[1]一個詞其實是一個可以表達多樣性語義信息的符號(歧義問題)。[2]一個詞的語義確定幅骄,要依賴其所在的上下文環(huán)境劫窒。(根據上下文消岐)[3]有的詞可能需要一個范圍較小的上下文環(huán)境就能確定其語義(短距離依賴現象),有的詞可能需要一個范圍較大的上下文環(huán)境才能確定其語義(長距離依賴現象)昌执。)

  • 而本文提出的Transformer拋棄了傳統的CNN和RNN烛亦,只使用Attention 機制。
  • 并且在Attention的基礎增加了位置向量懂拾,保留了單詞序列信息煤禽。
  • 還提出了兩個新的Attention機制,Sacled Dot-Product Attention和Multi-head Attention岖赋。
  • Attention是Seq2Seq的升級版檬果,Transformer是Attention的升級版。

總結

  • 本文的創(chuàng)新點:拋棄了之前傳統的Encoder-Decoder模型必須結合CNN或RNN的固有模式唐断,只用了Attention选脊。提出了兩個新的attention 機制,分別叫做Scaled Dot-Product Attention和Multi-head Attention脸甘。
  • 與之前的模型的對比: 減少了計算量恳啥、提高了并行效率、任務效果提升丹诀。
  • 模型的應用:機器翻譯钝的、文檔摘要、對話系統...

0x02铆遭、第二層境界

由淺入深硝桩,由表及里,漸入佳境


宏觀視角(A High-Level Look)

我們先把Transformer想象成一個黑盒子枚荣,在機器翻譯的領域中碗脊,這個黑盒子的功能就是輸入一種語言然后將它翻譯成其他語言。如下圖:


blackbox.png

打開這個黑盒子橄妆,可以看到衙伶,這個黑盒子由兩個部分組成:Encoders和Decoders。(注意結尾加s)


blackboxopen.png

再進行進一步的剖析害碾,可以看到Encoders由6個Encoder組成痕支,Decoders由6個Decoder組成。
blackbox_opendeep.png

打破砂鍋拆到底蛮原,每一個Encoder由兩部分組成卧须,每一個Decoder由三部分組成。


one_encoder_decoder.png

還可以再細分嗎? - 可以花嘶,不過這里我們先解釋一下每個層的功能笋籽。
  • 每個Encoder的輸入首先會通過一個self-attention層,通過self-attention層幫助Endcoder在編碼單詞的過程中查看輸入序列中的其他單詞椭员。
  • Self-attention的輸出會被傳入一個全連接的前饋神經網絡车海,每個encoder的前饋神經網絡參數個數都是相同的,但是他們的作用是獨立的隘击。
  • 每個Decoder也同樣具有這樣的層級結構侍芝,但是在這之間有一個Attention層,幫助Decoder專注于與輸入句子中對應的那個單詞(類似與seq2seq models的結構)

將張量引入圖片(Bringing The Tensors Into The Picture)

用一個具體的例子來解釋埋同,觀察從輸入到輸出的過程中這些數據在各個網絡結構中的流動州叠。
首先,進行embedding


Each word is embedded into a vector of size 512. We'll represent those vectors with these simple boxes.

每個單詞被映射到一個512維的向量凶赁。詞嵌入(embedding)的過程只發(fā)生在最底層的一個Encoder咧栗。


image.png

在每個單詞進入Self-Attention層后都會有一個對應的輸出。Self-Attention層中的輸入和輸出是存在依賴關系的虱肄,而前饋層則沒有依賴致板,所以在前饋層,我們可以用到并行化來提升速率咏窿。(重點:并行在前饋層

開始“編碼”(Now We’re Encoding! )

image.png

如上圖所示斟或,每個位置的單詞首先會經過一個self attention層,然后每個單詞都通過一個獨立的前饋神經網絡(這些神經網絡結構完全相同)集嵌。

從宏觀視角看自注意力機制(Self-Attention at a High Level)

Self Attention是本文提出的新的概念缕粹,假設下面的句子就是我們需要翻譯的輸入句:
The animal didn't cross the street because it was too tired.

  • 這句話中的"it"指的是什么?它指的是“animal”還是“street”纸淮?對于人來說,這其實是一個很簡單的問題亚享,但是對于一個算法來說咽块,處理這個問題其實并不容易。self attention的出現就是為了解決這個問題欺税,通過self attention侈沪,我們能將 “it” 與 “animal” 聯系起來。
  • 當模型處理單詞的時候晚凿,self attention層可以通過當前單詞去查看其輸入序列中的其他單詞亭罪,以此來尋找編碼這個單詞更好的線索.
  • self-attention正是transformer中設計的一種通過其上下文來理解當前詞的一種辦法。你會很容易發(fā)現...相較于RNNs歼秽,transformer具有更好的并行性应役。


    image.png

    如上圖,是我們第五層Encoder針對單詞'it'的圖示,可以發(fā)現箩祥,我們的Encoder在編碼單詞‘it’時院崇,部分注意力機制集中在了‘animl’上,這部分的注意力會通過權值傳遞的方式影響到'it'的編碼袍祖。

從微觀視角看自注意力機制(Self-Attention in Detail)

計算self attention的第一步是從每個Encoder的輸入向量上創(chuàng)建3個向量(在這個情況下底瓣,對每個單詞做詞嵌入)。所以蕉陋,對于每個單詞捐凭,我們創(chuàng)建一個Query向量,一個Key向量和一個Value向量凳鬓。
如何產生QKV:這些向量是通過詞嵌入乘以我們訓練過程中創(chuàng)建的3個訓練矩陣而產生的茁肠。(矩陣最開始是隨機的)
以下是兩個詞的演示:

image.png

  • 第1步:為每個單詞生成qkv
    q_1 = X_1 * W^Q,q_2 = X_2 * W^Q,
    k_1 = X_1 * W^K,q_2 = X_2 * W^K,
    v_1 = X_1 * W^V,q_2 = X_2 * W^V,
  • 第2步:計算得分。將 query向量與每個key向量進行點乘,如下圖村视。
    image.png
  • 第3步:將第二步的得分除以\sqrt{d_k},(論文中使用key向量的維度是64維官套,其平方根=8,這樣可以使得訓練過程中具有更穩(wěn)定的梯度蚁孔。這個并不是唯一值奶赔,經驗所得)。
  • 第4步:將得到的輸出通過softmax函數標準化杠氢,使得最后的列表和為1站刑。


    image.png

    這個softmax的分數決定了當前單詞在每個句子中每個單詞位置的表示程度。很明顯鼻百,當前單詞對應句子中此單詞所在位置的softmax的分數最高绞旅,但是,有時候attention機制也能關注到此單詞外的其他單詞温艇,這很有用因悲。

  • 第5步:將每個Value向量乘以softmax后的得分。這里實際上的意義在于保存對當前詞的關注度不變的情況下勺爱,降低對不相關詞的關注晃琳。
  • 第6步:累加加權值的向量。 這會在此位置產生self-attention層的輸出(對于第一個單詞)琐鲁。


    image.png

    總結self-attention的計算過程(單詞級別)卫旱,就是得到一個我們可以放到前饋神經網絡的矢量。 然而在實際的實現過程中围段,該計算會以矩陣的形式完成顾翼,以便更快地處理。下面我們來看看Self-Attention的矩陣計算方式奈泪。

通過矩陣運算實現自注意力機制(Matrix Calculation of Self-Attention)

第一步是去計算Query适贸,Key和Value矩陣灸芳。我們將詞嵌入轉化成矩陣X中,并將其乘以我們訓練的權值矩陣W^Q,W^K,W^V

image.png

X矩陣中的每一行對應于輸入句子中的一個單詞取逾。 我們看到的X每一行的方框數實際上是詞嵌入的維度耗绿,圖中所示的和論文中是有差距的。X(圖中的4個方框論文中為512個)和q / k / v向量(圖中的3個方框論文中為64個)
最后砾隅,由于我們正在處理矩陣误阻,我們可以在一個公式中濃縮前面步驟2到6來計算self attention層的輸出。
image.png

“多頭怪”(The Beast With Many Heads)

本文通過使用“Multi-headed”的機制來進一步完善self attention層晴埂【糠矗“Multi-headed”主要通過下面兩種方式改善了attention層的性能:

  • 1、它擴展了模型專注于不同位置的能力儒洛。在上面的例子中精耐,雖然每個編碼都在z_1中有或多或少的體現,但是它可能被實際的單詞本身所支配琅锻。如果我們翻譯一個句子卦停,比如“The animal didn’t cross the street because it was too tired”,我們會想知道“it”指的是哪個詞恼蓬,這時模型的“多頭”注意機制會起到作用惊完。

  • 2、它給出了注意力層的多個“表示子空間”(representation subspaces)处硬。接下來我們將看到小槐,對于“多頭”注意機制,我們有多個查詢/鍵/值權重矩陣集(Transformer使用八個注意力頭荷辕,因此我們對于每個編碼器/解碼器有八個矩陣集合)凿跳。這些集合中的每一個都是隨機初始化的,在訓練之后疮方,每個集合都被用來將輸入詞嵌入(或來自較低編碼器/解碼器的向量)投影到不同的表示子空間中控嗜。

image.png

通過multi-headed attention,我們?yōu)槊總€“header”都獨立維護一套Q/K/V的權值矩陣骡显。然后我們還是如之前單詞級別的計算過程一樣處理這些數據疆栏。
如果對上面的例子做同樣的self attention計算,而因為我們有8頭attention蟆盐,所以我們會在八個時間點去計算這些不同的權值矩陣,但最后結束時遭殉,我們會得到8個不同的矩陣石挂。如下圖:
image.png

我們知道在self-attention后面緊跟著的是前饋神經網絡,而前饋神經網絡接受的是單個矩陣向量险污,而不是8個矩陣痹愚。所以我們需要一種辦法富岳,把這8個矩陣壓縮成一個矩陣。我們將這8個矩陣連接在一起然后再與一個矩陣W^O相乘拯腮。步驟如下圖所示:

image.png

這樣multi-headed self attention的全部內容就介紹完了窖式。之前可能都是一些過程的圖解,現在我將這些過程連接在一起动壤,用一個整體的框圖來表示一下計算的過程萝喘,希望可以加深理解。
image.png

現在我們已經觸及了attention的header琼懊,讓我們重新審視我們之前的例子阁簸,看看例句中的“it”這個單詞在不同的attention header情況下會有怎樣不同的關注點。
image.png

如圖:當我們對“it”這個詞進行編碼時哼丈,一個注意力的焦點主要集中在“animal”上启妹,而另一個注意力集中在“tired”,如果我們將所有注意力添加到圖片中醉旦,那么事情可能更難理解:
image.png

使用位置編碼表示序列的順序( Representing The Order of The Sequence Using Positional Encoding)

考慮輸入序列中單詞順序饶米。

  • 為了解決這個問題吏垮,transformer為每個輸入單詞的詞嵌入上添加了一個新向量-位置向量喻频。
  • 變換器為每個輸入嵌入添加了一個向量评疗。這些位置編碼向量有固定的生成方式寻拂,所以獲取他們是很方便的征字,但是這些信息確是很有用的防症,他們能捕捉到每個單詞的位置赌结,或者序列中不同單詞之間的距離吃环。將這些信息也添加到詞嵌入中羹饰,然后與Q/K/V向量進行點積伊滋,獲得的attention就有了距離的信息了。


    image.png

    為了讓模型捕捉到單詞的順序信息队秩,我們添加位置編碼向量信息(POSITIONAL ENCODING)-位置編碼向量不需要訓練笑旺,它有一個規(guī)則的產生方式。

如果我們的嵌入維度為4馍资,那么實際上的位置編碼就如下圖所示:


image.png

那么生成位置向量需要遵循怎樣的規(guī)則呢筒主?

觀察下面的圖形,每一行都代表著對一個矢量的位置編碼鸟蟹。因此第一行就是我們輸入序列中第一個字的嵌入向量乌妙,每行都包含512個值,每個值介于1和-1之間建钥。我們用顏色來表示1藤韵,-1之間的值,這樣方便可視化的方式表現出來:

image.png

這是一個20個字(行)的(512)列位置編碼示例熊经。你會發(fā)現它從中心位置被分為了2半泽艘,這是因為左半部分的值是一由一個正弦函數生成的欲险,而右半部分是由另一個函數(余弦)生成。然后將它們連接起來形成每個位置編碼矢量匹涮。
位置編碼的公式在論文(3.5節(jié))中有描述天试。你也可以在中查看用于生成位置編碼的代碼 get_timing_signal_1d().這不是位置編碼的唯一可能方法。然而然低,它具有能夠擴展到看不見的序列長度的優(yōu)點(例如喜每,如果我們訓練的模型被要求翻譯的句子比我們訓練集中的任何句子都長)。

殘差模塊 (The Residuals)

這一節(jié)介紹的是encoder過程中的每個self-attention層的左右連接情況脚翘,我們稱這個為:layer-normalization 步驟灼卢。如下圖所示:

image.png

再進一步探索其內部的計算方式,可以得到下圖:
image.png

Decoder的子層也是同樣的来农,如果我們想做堆疊了2個Encoder和2個Decoder的Transformer鞋真,那么它可視化就會如下圖所示:


image.png

解碼側(The Decoder Side)

Decoder 和 Encoder基本上差不多,不過還是需要仔細探討一下Decoder的數據計算原理沃于。
編碼器通過處理輸入序列開啟工作涩咖。頂端編碼器的輸出之后會變轉化為一個包含向量K(鍵向量)和V(值向量)的注意力向量集 。這些向量將被每個解碼器用于自身的“編碼-解碼注意力層”繁莹,而這些層可以幫助解碼器關注輸入序列哪些位置合適:


image.gif

在完成編碼階段后檩互,則開始解碼階段。解碼階段的每個步驟都會輸出一個輸出序列(在這個例子里咨演,是英語翻譯的句子)的元素

接下來的步驟重復了這個過程闸昨,直到到達一個特殊的終止符號,它表示transformer的解碼器已經完成了它的輸出薄风。每個步驟的輸出在下一個時間步被提供給底端解碼器饵较,并且就像編碼器之前做的那樣,這些解碼器會輸出它們的解碼結果 遭赂。另外循诉,就像我們對編碼器的輸入所做的那樣,我們會嵌入并添加位置編碼給那些解碼器撇他,來表示每個單詞的位置茄猫。

transformer_decoding_2.gif

而那些解碼器中的自注意力層表現的模式與編碼器不同:在解碼器中,自注意力層只被允許處理輸出序列中更靠前的那些位置困肩。在softmax步驟前划纽,它會把后面的位置給隱去(把它們設為-inf)。

這個“編碼-解碼注意力層”工作方式基本就像多頭自注意力層一樣锌畸,只不過它是通過在它下面的層來創(chuàng)造查詢矩陣勇劣,并且從編碼器的輸出中取得鍵/值矩陣。

最終的線性變換和Softmax層(The Final Linear and Softmax Layer)

解碼組件最后會輸出一個實數向量蹋绽。我們如何把浮點數變成一個單詞芭毙?這便是線性變換層要做的工作,它之后就是Softmax層卸耘。

線性變換層是一個簡單的全連接神經網絡退敦,它可以把解碼組件產生的向量投射到一個比它大得多的、被稱作對數幾率(logits)的向量里蚣抗。

不妨假設我們的模型從訓練集中學習一萬個不同的英語單詞(我們模型的“輸出詞表”)侈百。因此對數幾率向量為一萬個單元格長度的向量——每個單元格對應某一個單詞的分數。

接下來的Softmax 層便會把那些分數變成概率(都為正數翰铡、上限1.0)钝域。概率最高的單元格被選中,并且它對應的單詞被作為這個時間步的輸出锭魔。


image.png

這張圖片從底部以解碼器組件產生的輸出向量開始例证。之后它會轉化出一個輸出單詞。

訓練部分總結(Recap Of Training)

既然我們已經過了一遍完整的transformer的前向傳播過程迷捧,那我們就可以直觀感受一下它的訓練過程织咧。

在訓練過程中,一個未經訓練的模型會通過一個完全一樣的前向傳播漠秋。但因為我們用有標記的訓練集來訓練它笙蒙,所以我們可以用它的輸出去與真實的輸出做比較。

為了把這個流程可視化庆锦,不妨假設我們的輸出詞匯僅僅包含六個單詞:“a”, “am”, “i”, “thanks”, “student”以及 “”(end of sentence的縮寫形式)捅位。


image.png

我們模型的輸出詞表在我們訓練之前的預處理流程中就被設定好。

一旦我們定義了我們的輸出詞表搂抒,我們可以使用一個相同寬度的向量來表示我們詞匯表中的每一個單詞艇搀。這也被認為是一個one-hot 編碼。所以燕耿,我們可以用下面這個向量來表示單詞“am”:


image.png

image.png

接下來我們討論模型的損失函數——這是我們用來在訓練過程中優(yōu)化的標準中符。通過它可以訓練得到一個結果盡量準確的模型。

損失函數(The Loss Function)

比如說我們正在訓練模型誉帅,現在是第一步淀散,一個簡單的例子——把“merci”翻譯為“thanks”。

這意味著我們想要一個表示單詞“thanks”概率分布的輸出蚜锨。但是因為這個模型還沒被訓練好档插,所以不太可能現在就出現這個結果。


image.png

為模型的參數(權重)都被隨機的生成亚再,(未經訓練的)模型產生的概率分布在每個單元格/單詞里都賦予了隨機的數值郭膛。我們可以用真實的輸出來比較它,然后用反向傳播算法來略微調整所有模型的權重氛悬,生成更接近結果的輸出则剃。

你會如何比較兩個概率分布呢耘柱?我們可以簡單地用其中一個減去另一個。更多細節(jié)請參考交叉熵和KL散度棍现。
交叉熵:https://colah.github.io/posts/2015-09-Visual-Information/

KL散度:https://www.countbayesie.com/blog/2017/5/9/kullback-leibler-divergence-explained

但注意到這是一個過于簡化的例子调煎。更現實的情況是處理一個句子。例如己肮,輸入“je suis étudiant”并期望輸出是“i am a student”士袄。那我們就希望我們的模型能夠成功地在這些情況下輸出概率分布:

每個概率分布被一個以詞表大小(我們的例子里是6谎僻,但現實情況通常是3000或10000)為寬度的向量所代表娄柳。

第一個概率分布在與“i”關聯的單元格有最高的概率

第二個概率分布在與“am”關聯的單元格有最高的概率

以此類推,第五個輸出的分布表示“”關聯的單元格有最高的概率


image.png

依據例子訓練模型得到的目標概率分布

在一個足夠大的數據集上充分訓練后艘绍,我們希望模型輸出的概率分布看起來像這個樣子:


image.png

我們期望訓練過后赤拒,模型會輸出正確的翻譯。當然如果這段話完全來自訓練集诱鞠,它并不是一個很好的評估指標(參考:交叉驗證需了,鏈接https://www.youtube.com/watch?v=TIgfjmp-4BA)。注意到每個位置(詞)都得到了一點概率般甲,即使它不太可能成為那個時間步的輸出——這是softmax的一個很有用的性質肋乍,它可以幫助模型訓練。

因為這個模型一次只產生一個輸出敷存,不妨假設這個模型只選擇概率最高的單詞墓造,并把剩下的詞拋棄。這是其中一種方法(叫貪心解碼)锚烦。另一個完成這個任務的方法是留住概率最靠高的兩個單詞(例如I和a)觅闽,那么在下一步里,跑模型兩次:其中一次假設第一個位置輸出是單詞“I”涮俄,而另一次假設第一個位置輸出是單詞“me”蛉拙,并且無論哪個版本產生更少的誤差,都保留概率最高的兩個翻譯結果彻亲。然后我們?yōu)榈诙偷谌齻€位置重復這一步驟孕锄。這個方法被稱作集束搜索(beam search)。在我們的例子中苞尝,集束寬度是2(因為保留了2個集束的結果畸肆,如第一和第二個位置),并且最終也返回兩個集束的結果(top_beams也是2)宙址。這些都是可以提前設定的參數轴脐。

再進一步(Go Forth And Transform)

我希望通過上文已經讓你們了解到Transformer的主要概念了。如果你想在這個領域深入,我建議可以走以下幾步:閱讀Attention Is All You Need大咱,Transformer博客和Tensor2Tensor announcement恬涧,以及看看?ukasz Kaiser的介紹,了解模型和細節(jié)碴巾。

Attention Is All You Need:https://arxiv.org/abs/1706.03762

Transformer博客:https://ai.googleblog.com/2017/08/transformer-novel-neural-network.html

Tensor2Tensor announcement:https://ai.googleblog.com/2017/06/accelerating-deep-learning-research.html

?ukasz Kaiser的介紹:https://colab.research.google.com/github/tensorflow/tensor2tensor/blob/master/tensor2tensor/notebooks/hello_t2t.ipynb

接下來可以研究的工作:

Depthwise Separable Convolutions for Neural Machine Translation

https://arxiv.org/abs/1706.03059

One Model To Learn Them All

https://arxiv.org/abs/1706.05137

Discrete Autoencoders for Sequence Models

https://arxiv.org/abs/1801.09797

Generating Wikipedia by Summarizing Long Sequences

https://arxiv.org/abs/1801.10198

Image Transformer

https://arxiv.org/abs/1802.05751

Training Tips for the Transformer Model

https://arxiv.org/abs/1804.00247

Self-Attention with Relative Position Representations

https://arxiv.org/abs/1803.02155

Fast Decoding in Sequence Models using Discrete Latent Variables

https://arxiv.org/abs/1803.03382

Adafactor: Adaptive Learning Rates with Sublinear Memory Cost

https://arxiv.org/abs/1804.04235

0x03.第三層境界

紙上得來終覺淺气破,絕知此事要躬行

參考文章:

1.http://www.reibang.com/p/3f2d4bc126e6
2.https://www.imooc.com/article/51468
3.https://kexue.fm/archives/4765
4.https://blog.csdn.net/weixin_42446330/article/details/86710838
5.https://blog.csdn.net/qq_41664845/article/details/84969266
6.https://jalammar.github.io/illustrated-transformer/
7.[https://blog.csdn.net/longxinchen_ml/article/details/86533005] (https://blog.csdn.net/longxinchen_ml/article/details/86533005)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市餐抢,隨后出現的幾起案子,更是在濱河造成了極大的恐慌低匙,老刑警劉巖旷痕,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異顽冶,居然都是意外死亡欺抗,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進店門强重,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绞呈,“玉大人,你說我怎么就攤上這事间景〉枭” “怎么了?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵倘要,是天一觀的道長圾亏。 經常有香客問我,道長封拧,這世上最難降的妖魔是什么志鹃? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮泽西,結果婚禮上曹铃,老公的妹妹穿的比我還像新娘。我一直安慰自己捧杉,他們只是感情好陕见,可當我...
    茶點故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著味抖,像睡著了一般淳玩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上非竿,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天蜕着,我揣著相機與錄音,去河邊找鬼。 笑死承匣,一個胖子當著我的面吹牛蓖乘,可吹牛的內容都是我干的。 我是一名探鬼主播韧骗,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼嘉抒,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了袍暴?” 一聲冷哼從身側響起些侍,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎政模,沒想到半個月后岗宣,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡淋样,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年耗式,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片趁猴。...
    茶點故事閱讀 40,488評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡刊咳,死狀恐怖,靈堂內的尸體忽然破棺而出儡司,到底是詐尸還是另有隱情娱挨,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布捕犬,位于F島的核電站让蕾,受9級特大地震影響,放射性物質發(fā)生泄漏或听。R本人自食惡果不足惜探孝,卻給世界環(huán)境...
    茶點故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望誉裆。 院中可真熱鬧顿颅,春花似錦、人聲如沸足丢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽斩跌。三九已至绍些,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間耀鸦,已是汗流浹背柬批。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工啸澡, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人氮帐。 一個月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓嗅虏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親上沐。 傳聞我的和親對象是個殘疾皇子皮服,可洞房花燭夜當晚...
    茶點故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內容