機(jī)器學(xué)習(xí)基礎(chǔ)

機(jī)器學(xué)習(xí)基礎(chǔ)

本章涵蓋了以下主題:

[if !supportLists]·?[endif]分類和回歸之外的其他類型的問題墩邀;

[if !supportLists]·?[endif]評估問題眉睹,理解過擬合竹海、欠擬合斋配,以及解決這些問題的技巧艰争;

[if !supportLists]·?[endif]為深度學(xué)習(xí)準(zhǔn)備數(shù)據(jù)甩卓。

請記住逾柿,在本章中討論的大多數(shù)技術(shù)都是機(jī)器學(xué)習(xí)和深度學(xué)習(xí)通用的宅此,一部分用于解決過擬合問題的技術(shù)(如dropout)除外父腕。

4.1 三類機(jī)器學(xué)習(xí)問題

在之前的所有例子中侣诵,嘗試解決的是分類(預(yù)測貓或狗)或回歸(預(yù)測用戶在平臺上花費的平均時間)問題。所有這些都是有監(jiān)督學(xué)習(xí)的例子蘸炸,目的是找到訓(xùn)練樣例和目標(biāo)之間的映射關(guān)系搭儒,并用來預(yù)測未知數(shù)據(jù)淹禾。

有監(jiān)督學(xué)習(xí)只是機(jī)器學(xué)習(xí)的一部分铃岔,機(jī)器學(xué)習(xí)也有其他不同的部分毁习。以下是3種不同類型的機(jī)器學(xué)習(xí):

[if !supportLists]·?[endif]有監(jiān)督學(xué)習(xí)纺且;

[if !supportLists]·?[endif]無監(jiān)督學(xué)習(xí)载碌;

[if !supportLists]·?[endif]強(qiáng)化學(xué)習(xí)嫁艇。

下面詳細(xì)講解各種算法裳仆。

4.1.1 有監(jiān)督學(xué)習(xí)

在深度學(xué)習(xí)和機(jī)器學(xué)習(xí)領(lǐng)域中,大多數(shù)成功用例都屬于有監(jiān)督學(xué)習(xí)偏形。本書中所涵蓋的大多數(shù)例子也都是有監(jiān)督學(xué)習(xí)的一部分俊扭。來看看有監(jiān)督學(xué)習(xí)的一些常見的例子萨惑。

[if !supportLists]·?[endif]分類問題:狗和貓的分類庸蔼。

[if !supportLists]·?[endif]回歸問題:預(yù)測股票價格姐仅、板球比賽成績等掏膏。

[if !supportLists]·?[endif]圖像分割:進(jìn)行像素級分類馒疹。對于自動汽車駕駛來說行冰,從攝像機(jī)拍攝的照片中悼做,識別出每個像素屬于什么物體是很重要的肛走。這些像素可以是汽車朽色、行人葫男、樹梢褐、公共汽車等盈咳。

[if !supportLists]·?[endif]語音識別:OK Google鱼响、Alexa和Siri都是語音識別的例子。

[if !supportLists]·?[endif]語言翻譯:從一種語言翻譯成另一種語言债鸡。

4.1.2 無監(jiān)督學(xué)習(xí)

在沒有標(biāo)簽數(shù)據(jù)的情況時娘锁,可以通過可視化和壓縮來幫助無監(jiān)督學(xué)習(xí)技術(shù)理解數(shù)據(jù)莫秆。兩種常用的無監(jiān)督學(xué)習(xí)技術(shù)是:

[if !supportLists]·?[endif]聚類镊屎;

[if !supportLists]·?[endif]降維缝驳。

聚類有助于將所有相似的數(shù)據(jù)點組合在一起用狱。降維有助于減少維數(shù),從而可視化高維數(shù)據(jù)溺忧,并找到任何隱藏的模式鲁森。

4.1.3 強(qiáng)化學(xué)習(xí)

強(qiáng)化學(xué)習(xí)是最不流行的機(jī)器學(xué)習(xí)范疇歌溉。在真實世界中沒有發(fā)現(xiàn)它的成功用例痛垛。然而榜晦,近年來有了些改變,來自Google的DeepMind團(tuán)隊成功地構(gòu)建了基于強(qiáng)化學(xué)習(xí)的系統(tǒng)朽寞,并且在AlphaGo比賽中贏得世界冠軍脑融。計算機(jī)可以在比賽中擊敗人類的這種技術(shù)上的進(jìn)展肘迎,曾被認(rèn)為需要花費數(shù)十年時間才能實現(xiàn)姻蚓。然而狰挡,使用深度學(xué)習(xí)和強(qiáng)化學(xué)習(xí)卻可以這么快就達(dá)到目標(biāo)加叁,比任何人所預(yù)見的都要快它匕。這些技術(shù)已經(jīng)可以看到早期的成功超凳,但可能需要幾年時間才能成為主流轮傍。

在本書中创夜,我們將主要關(guān)注有監(jiān)督的技術(shù)和一些特定于深度學(xué)習(xí)的無監(jiān)督技術(shù),例如用于創(chuàng)建特定風(fēng)格圖片的生成網(wǎng)絡(luò):風(fēng)格遷移(style transfer)和生成對抗網(wǎng)絡(luò)(generative adversarial network)檬贰。

4.2 機(jī)器學(xué)習(xí)術(shù)語

前面幾章出現(xiàn)了大量的術(shù)語翁涤,如果大家剛?cè)腴T機(jī)器學(xué)習(xí)或深度學(xué)習(xí)領(lǐng)域葵礼,這些術(shù)語看起來會比較生疏鸳粉。這里將列出機(jī)器學(xué)習(xí)中常用的多數(shù)術(shù)語枯夜,這些通常也在深度學(xué)習(xí)文獻(xiàn)中使用卤档。

[if !supportLists]·?[endif]樣本(sample)或輸入(input)或數(shù)據(jù)點(data point):訓(xùn)練集中特定的實例劝枣。我們在上一章中看到的圖像分類問題舔腾,每個圖像都可以被稱為樣本稳诚、輸入或數(shù)據(jù)點。

[if !supportLists]·?[endif]預(yù)測(prediction)或輸出(output):由算法生成的值稱為輸出氨距。例如俏让,在先前的例子中,我們的算法對特定圖像預(yù)測的結(jié)果為0,而0是給定的貓的標(biāo)簽赊颠,所以數(shù)字0就是我們的預(yù)測或輸出巨税。

[if !supportLists]·?[endif]目標(biāo)(target)或標(biāo)簽(label):圖像實際標(biāo)注的標(biāo)簽。

[if !supportLists]·?[endif]損失值(loss value)或預(yù)測誤差(prediction error):預(yù)測值與實際值之間的差距远寸。數(shù)值越小驰后,準(zhǔn)確率越高灶芝。

[if !supportLists]·?[endif]類別(classes):給定數(shù)據(jù)集的一組可能的值或標(biāo)簽。在前一章的例子中有貓和狗兩種類別女器。

[if !supportLists]·?[endif]二分類(binary classification):將輸入實例歸類為兩個互斥類別中的其中一個的分類任務(wù)驾胆。

[if !supportLists]·?[endif]多類別分類(multi-class classification):將輸入實例歸類為兩個以上的不同類別的分類任務(wù)。

[if !supportLists]·?[endif]多標(biāo)簽分類(multi-label classification):一個輸入實例可以用多個標(biāo)簽來標(biāo)記锅必。例如根據(jù)提供的食物不同來標(biāo)記餐館搞隐,如意大利菜、墨西哥菜和印度菜癞季。另一個常見的例子是圖片中的對象檢測绷柒,它使用算法識別出圖片中的不同對象废睦。

[if !supportLists]·?[endif]標(biāo)量回歸(scalar regression):每個輸入數(shù)據(jù)點都與一個標(biāo)量質(zhì)量(scalar quality)相關(guān)聯(lián)奈应,該標(biāo)量質(zhì)量是數(shù)值型的杖挣。這樣的例子有預(yù)測房價、股票價格和板球得分等屿附。

[if !supportLists]·?[endif]向量回歸(vector regression):算法需要預(yù)測不止一個標(biāo)量質(zhì)量挺份。一個很好的例子當(dāng)你試圖識別圖片中魚的位置邊界框時。為了預(yù)測邊界框各聘,您的算法需要預(yù)測表示正方形邊緣的4個標(biāo)量。

[if !supportLists]·?[endif]批(batch):大多數(shù)情況下大脉,我們在稱為批的輸入樣本集上訓(xùn)練我們的算法镰矿。取決于GPU的內(nèi)存绝淡,批尺寸一般從2~256不等牢酵,權(quán)重也在每個批次上進(jìn)行更新,因此算法往往比在單個樣例上訓(xùn)練時學(xué)習(xí)的更快潘拨。

[if !supportLists]·?[endif]輪數(shù):在整個數(shù)據(jù)集上運行一遍算法稱為一個Epoch。通常要訓(xùn)練(更新權(quán)重)幾個Epoch茫船。

4.3 評估機(jī)器學(xué)習(xí)模型

在上一章中介紹的圖像分類示例中,我們將數(shù)據(jù)分成兩個不同的部分然眼,一個用于訓(xùn)練,一個用于驗證鲸匿。使用單獨的數(shù)據(jù)集來測試算法的性能是一種很好的做法,因為在訓(xùn)練集上測試算法可能無法讓用戶獲得算法真正的泛化能力烤惊。在大多數(shù)現(xiàn)實世界的用例中乔煞,基于驗證的準(zhǔn)確率,我們經(jīng)常以不同方式來調(diào)整算法柒室,例如添加更多的層或不同的層瘤缩,或者使用不同的技術(shù),這些將在本章的后面部分進(jìn)行介紹伦泥。因此锦溪,選擇基于驗證數(shù)據(jù)集來調(diào)整算法的可能性更高。以這種方式訓(xùn)練的算法往往在訓(xùn)練數(shù)據(jù)集和驗證數(shù)據(jù)集上表現(xiàn)良好府怯,但當(dāng)應(yīng)用到未知的數(shù)據(jù)時可能會失敗刻诊。驗證數(shù)據(jù)集上的信息泄露會影響到對算法的調(diào)整。

為了避免信息泄露并改進(jìn)泛化的問題牺丙,通常的做法是將數(shù)據(jù)集分成3個不同的部分则涯,即訓(xùn)練、驗證和測試數(shù)據(jù)集冲簿。我們在訓(xùn)練集和驗證集上訓(xùn)練算法并調(diào)優(yōu)所有超參數(shù)粟判。最后,當(dāng)完成整個訓(xùn)練時峦剔,在測試數(shù)據(jù)集上對算法進(jìn)行測試档礁。我們討論過有兩種類型的參數(shù)。一種是在算法內(nèi)使用的參數(shù)或權(quán)重吝沫,通過優(yōu)化器或反向傳播進(jìn)行調(diào)優(yōu)呻澜。另一種是稱為超參數(shù)(hyper parameter)的參數(shù),這些參數(shù)控制著網(wǎng)絡(luò)中所用層的數(shù)量惨险、學(xué)習(xí)率以及通常改變架構(gòu)(這種改變經(jīng)常是手動調(diào)整的)的其他類型的參數(shù)羹幸。

特定的算法在訓(xùn)練集中表現(xiàn)非常優(yōu)越,但在驗證集或測試集上卻表現(xiàn)不佳的現(xiàn)象稱為過擬合(overfitting)辫愉,或者說算法缺乏泛化的能力栅受。存在一種相反的現(xiàn)象,即算法在訓(xùn)練集上的表現(xiàn)不佳恭朗,這種現(xiàn)象稱為欠擬合(underfitting)屏镊。后面將學(xué)習(xí)可以幫助解決過擬合和欠擬合問題的不同策略。

在了解過擬合和欠擬合之前冀墨,先看看可用于拆分?jǐn)?shù)據(jù)集的各種策略闸衫。

4.3.1 訓(xùn)練、驗證和測試集的拆分

將數(shù)據(jù)劃分成3個部分——訓(xùn)練诽嘉、驗證和測試數(shù)據(jù)集是最佳實踐蔚出。使用保留(holdout)數(shù)據(jù)集的最佳方法如下所示。

1.在訓(xùn)練數(shù)據(jù)集上訓(xùn)練算法虫腋。

2.在驗證數(shù)據(jù)集上進(jìn)行超參數(shù)調(diào)優(yōu)骄酗。

3.迭代執(zhí)行前兩個步驟,直到達(dá)到預(yù)期的性能悦冀。

4.在凍結(jié)算法和超參數(shù)后趋翻,在測試數(shù)據(jù)集上進(jìn)行評估这溅。

應(yīng)避免只將數(shù)據(jù)劃分成兩部分住闯,因為這可能導(dǎo)致信息泄露咐柜。在相同的數(shù)據(jù)集上進(jìn)行訓(xùn)練和測試是絕對不不允許的黔龟,這將無法保證算法的泛化能力。將數(shù)據(jù)分割成訓(xùn)練集和驗證集有3種常用的保留策略讨惩,它們是:

[if !supportLists]·?[endif]簡單保留驗證辟癌;

[if !supportLists]·?[endif]K折驗證;

[if !supportLists]·?[endif]迭代K折驗證荐捻。

1.簡單保留驗證

劃分一定比例的數(shù)據(jù)作為測試數(shù)據(jù)集黍少。留出多大比例的數(shù)據(jù)可能是和特定問題相關(guān)的,并且很大程度上依賴于可用的數(shù)據(jù)量处面。特別是對于計算機(jī)視覺和自然語言處理領(lǐng)域中的問題厂置,收集標(biāo)簽數(shù)據(jù)可能非常昂貴,因此留出30%的測試數(shù)據(jù)(比例相當(dāng)大)可能會使算法學(xué)習(xí)起來非常困難魂角,因為用于訓(xùn)練的數(shù)據(jù)很少昵济。因此,需要根據(jù)數(shù)據(jù)的可用性或颊,謹(jǐn)慎地選擇劃分比例砸紊。測試數(shù)據(jù)拆分后传于,在凍結(jié)算法及其超參數(shù)前囱挑,要保持?jǐn)?shù)據(jù)的隔離。為了給問題選擇最佳超參數(shù)沼溜,請選擇單獨的驗證數(shù)據(jù)集平挑。為了避免過擬合,通常將可用數(shù)據(jù)劃分成3個不同的集合系草,如圖4.1所示通熄。

上一章使用了圖4.1的簡單實現(xiàn)來創(chuàng)建驗證數(shù)據(jù)集,實現(xiàn)的快照如下:


圖4.1

這是最簡單的保留策略之一找都,通常在開始時使用唇辨。在小型數(shù)據(jù)集上使用這種劃分策略有一個弊端,驗證數(shù)據(jù)集或測試數(shù)據(jù)集中的現(xiàn)有數(shù)據(jù)可能不具有統(tǒng)計代表性能耻。在劃分?jǐn)?shù)據(jù)前混洗數(shù)據(jù)即可以輕松意識到這一點赏枚。如果得到的結(jié)果不一致,那么需要使用更好的方法晓猛。為了避免這個問題饿幅,我們最后通常使用K折(K-fold)驗證或迭代K折(iterated k-fold)驗證。

2.K折驗證

留出一定比例的數(shù)據(jù)用于測試戒职,然后將整個數(shù)據(jù)集分成K個數(shù)據(jù)包栗恩,其中K可以是任意數(shù)值,通常從2到10不等洪燥。在任意給定的迭代中磕秤,選取一個包作為驗證數(shù)據(jù)集乳乌,并用其余的數(shù)據(jù)包訓(xùn)練算法。最后的評分通常是在K個包上獲得的所有評分的平均值市咆。圖4.2所示為一個K折驗證的實現(xiàn)钦扭,其中K為4;也就是說床绪,數(shù)據(jù)劃分成4部分(稱為4折驗證)客情。

使用K折驗證數(shù)據(jù)集時,要注意的一個關(guān)鍵問題是它的代價非常昂貴癞己,因為需要在數(shù)據(jù)集的不同部分上運行該算法數(shù)次膀斋,這對于計算密集型算法來說是非常昂貴的,特別是在計算機(jī)視覺算法領(lǐng)域痹雅。有時候仰担,訓(xùn)練算法可以花費從幾分鐘到幾天的時間。所以绩社,請謹(jǐn)慎地使用這項技術(shù)摔蓝。

3.帶混洗的K折驗證

為了使算法變得復(fù)雜和健壯,可以在每次創(chuàng)建保留的驗證數(shù)據(jù)集時混洗數(shù)據(jù)愉耙。當(dāng)小幅度的性能提升提升可能會對業(yè)務(wù)產(chǎn)生巨大影響時贮尉,這種做法是有益的。如果我們的情況是快速構(gòu)建和部署算法朴沿,并且可以接受百分之幾的性能差異猜谚,那么這種方法可能并不值得。所有這一切都取決于試圖要解決的問題赌渣,以及對準(zhǔn)確率的要求魏铅。


圖4.2

在拆分?jǐn)?shù)據(jù)時可能需要考慮其他一些事情,例如:

[if !supportLists]·?[endif]數(shù)據(jù)代表性坚芜;

[if !supportLists]·?[endif]時間敏感性览芳;

[if !supportLists]·?[endif]數(shù)據(jù)冗余。

1.?dāng)?shù)據(jù)代表性

在上一章中的例子中鸿竖,我們把圖像分類為狗或者貓沧竟。假設(shè)有這樣一個場景,所有的圖像已被排序千贯,其中前60%的圖像是狗屯仗,其余的是貓。如果選擇前面的80%作為訓(xùn)練數(shù)據(jù)集搔谴,其余的作為驗證集來分割這個數(shù)據(jù)集魁袜,那么驗證數(shù)據(jù)集將無法代表數(shù)據(jù)集的真實性,因為它只包含貓的圖像。因此峰弹,在這些情況下店量,應(yīng)該注意通過在分割或進(jìn)行分層抽樣之前對數(shù)據(jù)進(jìn)行混洗來實現(xiàn)數(shù)據(jù)的良好混合。分層抽樣是指從每個類別中提取數(shù)據(jù)點來創(chuàng)建驗證和測試數(shù)據(jù)集鞠呈。

2.時間敏感性

讓我們以股價預(yù)測為例融师。我們有從1月到12月的數(shù)據(jù)。在這種情況下蚁吝,如果進(jìn)行混洗或分層抽樣旱爆,那么最終將會造成信息的泄露,因為價格很可能是時間敏感的窘茁。因此怀伦,創(chuàng)建驗證數(shù)據(jù)集時應(yīng)采用不會引起信息泄露的方式。本例中山林,選擇12月的數(shù)據(jù)作為驗證數(shù)據(jù)集可能更合理房待。實際的股價預(yù)測用例比這要復(fù)雜得多,因此在選擇驗證分割時驼抹,特定領(lǐng)域的知識也會發(fā)揮作用桑孩。

3.?dāng)?shù)據(jù)冗余

重復(fù)數(shù)據(jù)是很常見的。需要注意的是框冀,在訓(xùn)練流椒、驗證和測試集中存在的數(shù)據(jù)應(yīng)該是唯一的。如果有重復(fù)左驾,那么模型可能無法很好地泛化未知數(shù)據(jù)镣隶。

4.4 數(shù)據(jù)預(yù)處理與特征工程

我們已經(jīng)了解了使用不同的方法來劃分?jǐn)?shù)據(jù)集并構(gòu)建評估策略极谊。在大多數(shù)情況下诡右,接收到的數(shù)據(jù)可能并不是訓(xùn)練算法立即可用的格式。本節(jié)將介紹一些預(yù)處理技術(shù)和特征工程技術(shù)轻猖。雖然大部分的特征工程技術(shù)都是針對特定領(lǐng)域的帆吻,特別是計算機(jī)視覺和文本處理領(lǐng)域,但還是有一些通用的特征工程技術(shù)咙边,這將在本章中討論猜煮。

神經(jīng)網(wǎng)絡(luò)的數(shù)據(jù)預(yù)處理是一個使數(shù)據(jù)更適合于深度學(xué)習(xí)算法訓(xùn)練的過程。以下是一些常用的數(shù)據(jù)預(yù)處理步驟:

[if !supportLists]·?[endif]向量化败许;

[if !supportLists]·?[endif]歸一化王带;

[if !supportLists]·?[endif]缺失值;

[if !supportLists]·?[endif]特征提取市殷。

4.4.1 向量化

數(shù)據(jù)通常表現(xiàn)為各種格式愕撰,如文本、聲音、圖像和視頻搞挣。首先要做的就是把數(shù)據(jù)轉(zhuǎn)換成PyTorch張量带迟。在前面的例子中,使用tourchvision的工具函數(shù)將Python圖形庫(Python Imaging Library囱桨,PIL)的圖片轉(zhuǎn)換成張量對象仓犬,盡管PyTorchtorchvision庫抽取出了大部分的復(fù)雜度。在第7章中處理遞歸神經(jīng)網(wǎng)絡(luò)(Recurrent Neural Network舍肠,RNN)時搀继,將了解如何把文本數(shù)據(jù)轉(zhuǎn)換成PyTorch張量。對于涉及結(jié)構(gòu)化數(shù)據(jù)的問題翠语,數(shù)據(jù)已經(jīng)以向量化的格式存在律歼,我們需要做的就是把它們轉(zhuǎn)換成PyTorch張量。

4.4.2 值歸一化

在將數(shù)據(jù)傳遞到任何機(jī)器學(xué)習(xí)算法或深度學(xué)習(xí)算法之前啡专,將特征歸一化是一種通用實踐险毁。它有助于更快地訓(xùn)練算法并達(dá)到更高的性能。歸一化是指们童,將特定特征的數(shù)據(jù)表示成均值為0畔况、標(biāo)準(zhǔn)差為1的數(shù)據(jù)的過程。

在上一章所描述的狗貓分類的例子中慧库,使用了ImageNet數(shù)據(jù)集中已有的均值和標(biāo)準(zhǔn)差來歸一化數(shù)據(jù)跷跪。我們選擇ImageNet數(shù)據(jù)集的均值和標(biāo)準(zhǔn)差的原因,是因為使用的ReNet模型的權(quán)重是在ImageNet上進(jìn)行預(yù)訓(xùn)練的齐板。通常的做法是將每個像素值除以255吵瞻,使得所有值都在0和1之間,尤其是在不使用預(yù)訓(xùn)練權(quán)重的情況下甘磨。

歸一化也適用于涉及結(jié)構(gòu)化數(shù)據(jù)的問題橡羞。假設(shè)我們正在研究房價預(yù)測問題,可能存在不同規(guī)模的不同特征济舆。例如卿泽,到最近的機(jī)場的距離和房子的屋齡是具備不同度量的變量或特征。將它們與神經(jīng)網(wǎng)絡(luò)一起使用可以防止梯度收斂滋觉。簡單來說签夭,損失可能不會像預(yù)期的那樣下降。因此椎侠,在對算法進(jìn)行訓(xùn)練之前第租,應(yīng)該謹(jǐn)慎地將歸一化應(yīng)用到任何類型的數(shù)據(jù)上。為了使算法或模型性能更好我纪,應(yīng)確保數(shù)據(jù)遵循以下規(guī)則慎宾。

[if !supportLists]·?[endif]取較小的值:通常取值在0和1之間儡羔。

[if !supportLists]·?[endif]相同值域:確保所有特征都在同一數(shù)據(jù)范圍內(nèi)。

4.4.3 處理缺失值

缺失值在現(xiàn)實世界的機(jī)器學(xué)習(xí)問題中是很常見的璧诵。從之前預(yù)測房價的例子來看汰蜘,房屋屋齡的某些信息可能會丟失。通常用不可能出現(xiàn)的數(shù)字替換缺失值是安全的之宿。算法將能夠識別模式族操。還有其他技術(shù)可用于處理更特定領(lǐng)域的缺失值。

4.4.4 特征工程

特征工程是利用特定問題的領(lǐng)域知識來創(chuàng)建可以傳遞給模型的新變量或特征的過程比被。為了更好地理解色难,來看一個銷售預(yù)測的問題。假設(shè)我們有促銷日期等缀、假期枷莉、競爭者的開始日期、與競爭對手的距離以及特定日期的銷售情況尺迂。在現(xiàn)實世界中笤妙,有數(shù)以百計的特征可以用來預(yù)測店鋪的價格,可能有一些信息在預(yù)測銷售方面很重要噪裕。一些重要的特征或衍生價值是:

[if !supportLists]·?[endif]知道下一次促銷的日期蹲盘;

[if !supportLists]·?[endif]距離下一個假期還有多少天;

[if !supportLists]·?[endif]競爭對手的業(yè)務(wù)開放天數(shù)膳音。

還有許多這樣的特征可以從領(lǐng)域知識中提取出來召衔。對于任何機(jī)器學(xué)習(xí)算法或深度學(xué)習(xí)算法,算法自動提取這種類別的特征都是相當(dāng)具有挑戰(zhàn)性的祭陷。對于某些領(lǐng)域苍凛,特別是在計算機(jī)視覺和文本領(lǐng)域,現(xiàn)代深度學(xué)習(xí)算法有助于我們擺脫特征工程兵志。除了這些領(lǐng)域醇蝴,良好的特征工程對下述方面也總是有益的。

[if !supportLists]·?[endif]用較少的計算資源就可以更快地解決問題毒姨。

[if !supportLists]·?[endif]深度學(xué)習(xí)算法可以使用大量數(shù)據(jù)自己學(xué)習(xí)出特征哑蔫,不再使用手動的特征工程。所以弧呐,如果你注重數(shù)據(jù),可以專注于構(gòu)建良好的特征工程嵌纲。

4.5 過擬合與欠擬合

理解過擬合和欠擬合是成功構(gòu)建機(jī)器學(xué)習(xí)和深度學(xué)習(xí)模型的關(guān)鍵俘枫。在本章的開頭,我們簡要地描述了什么是過擬合和欠擬合逮走,這里將詳細(xì)解釋過擬合和欠擬合的概念鸠蚪,以及如何解決過擬合和欠擬合問題。

過擬合或不泛化,是機(jī)器學(xué)習(xí)和深度學(xué)習(xí)中的一類常見問題茅信。當(dāng)特定的算法在訓(xùn)練數(shù)據(jù)集上執(zhí)行得很好盾舌,但在未知數(shù)據(jù)或驗證和測試數(shù)據(jù)集上表現(xiàn)不佳時,就說算法過擬合了蘸鲸。這種情況的發(fā)生主要是因為算法過于特定于訓(xùn)練集而造成的妖谴。簡單來說,我們可以理解為該算法找出了一種方法來記憶數(shù)據(jù)集酌摇,使其在訓(xùn)練數(shù)據(jù)集上表現(xiàn)得很好膝舅,但無法對未知數(shù)據(jù)執(zhí)行。有不同的技術(shù)可以用來避免算法的過擬合窑多。這些技術(shù)是:

[if !supportLists]·?[endif]獲取更多數(shù)據(jù)仍稀;

[if !supportLists]·?[endif]縮小網(wǎng)絡(luò)規(guī)模;

[if !supportLists]·?[endif]應(yīng)用權(quán)重正則化埂息;

[if !supportLists]·?[endif]應(yīng)用dropout技潘。

4.5.1 獲取更多數(shù)據(jù)

如果能夠獲得更多的用于算法訓(xùn)練的數(shù)據(jù),則可以通過關(guān)注一般模式而不是特定于小數(shù)據(jù)點的模式來幫助算法避免過擬合千康。在某些情況下崭篡,獲取更多標(biāo)簽數(shù)據(jù)可能是一項挑戰(zhàn)。

有一些技術(shù)吧秕,如數(shù)據(jù)增強(qiáng)琉闪,可用于在計算機(jī)視覺相關(guān)的問題中生成更多的訓(xùn)練數(shù)據(jù)。數(shù)據(jù)增強(qiáng)是一種讓用戶通過執(zhí)行不同的操作砸彬,如旋轉(zhuǎn)颠毙、裁剪和生成更多數(shù)據(jù),來輕微調(diào)整圖像的技術(shù)砂碉。在對行業(yè)知識足夠了解時蛀蜜,如果獲取實際數(shù)據(jù)的成本很高,也可以創(chuàng)建人造數(shù)據(jù)增蹭。當(dāng)無法獲得更多數(shù)據(jù)時滴某,還有其他方法可以幫助避免過擬合。讓我們看看這些方法滋迈。

4.5.2 縮小網(wǎng)絡(luò)規(guī)模

網(wǎng)絡(luò)的大小通常是指網(wǎng)絡(luò)中使用的層數(shù)或權(quán)重參數(shù)的數(shù)量霎奢。在上一章中的圖像分類例子中,我們使用了一個ResNet模型饼灿,它包含具有不同層的18個組成模塊幕侠。PyTorch中的torchvision庫具有不同大小的ResNet模型,從18個塊開始碍彭,最多可達(dá)152個塊晤硕。比如說悼潭,如果我們使用具有152個塊的ResNet模型導(dǎo)致了過擬合,那么可以嘗試使用101個塊或50個塊的ResNet舞箍。在構(gòu)建的自定義架構(gòu)中舰褪,可以簡單地去除一些中間線性層,從而阻止我們的PyTorch模型記憶訓(xùn)練數(shù)據(jù)集疏橄。讓我們來看一個示例代碼片段占拍,它演示了縮小網(wǎng)絡(luò)規(guī)模的確切含義:

上面的架構(gòu)有3個線性層,假設(shè)它在訓(xùn)練數(shù)據(jù)上過擬合了软族,讓我們重新創(chuàng)建更低容量的架構(gòu):

上面的架構(gòu)只有兩個線性層刷喜,減少了容量后,潛在地避免了訓(xùn)練數(shù)據(jù)集的過擬合問題立砸。

4.5.3 應(yīng)用權(quán)重正則化

有助于解決過擬合或泛化問題的關(guān)鍵原則之一是建立更簡單的模型掖疮。一種構(gòu)建簡單模型的技術(shù)是通過減小模型大小來降低架構(gòu)的復(fù)雜性。另一個重要的事情是確保不會采用更大的網(wǎng)絡(luò)權(quán)重值颗祝。當(dāng)模型的權(quán)重較大時浊闪,正則化通過懲罰模型來提供對網(wǎng)絡(luò)的約束。每當(dāng)模型使用較大的權(quán)重值時螺戳,正則化開始啟動并增加損失值搁宾,從而懲罰模型。有兩種類型的可能的正則化方案倔幼,如下所示盖腿。

[if !supportLists]·?[endif]L1正則化:權(quán)重系數(shù)的絕對值之和被添加到成本中。它通常稱為權(quán)重的L1范數(shù)损同。

[if !supportLists]·?[endif]L2正則化:所有權(quán)重系數(shù)的平方和被添加到成本中翩腐。它通常稱為權(quán)重的L2范數(shù)。

PyTorch提供了一種使用L2正則化的簡單方法膏燃,就是通過在優(yōu)化器中啟用weight_decay參數(shù):

默認(rèn)情況下茂卦,權(quán)重衰減參數(shù)設(shè)置為0∽榱ǎ可以嘗試不同的權(quán)重衰減值等龙;一個較小的值,比如1e-5大多時候都是有效的伶贰。

4.5.4 應(yīng)用dropout

dropout是深度學(xué)習(xí)中最常用和最強(qiáng)大的正則化技術(shù)之一蛛砰,由多倫多大學(xué)的Hinton和他的學(xué)生開發(fā)。dropout在訓(xùn)練期間被應(yīng)用到模型的中間層幕袱。讓我們看一下如何在生成10個值的線性層的輸出上應(yīng)用dropout(見圖4.3)暴备。

圖4.3所示為dropout閾值設(shè)置為0.2并應(yīng)用于線性層時發(fā)生的情況。它隨機(jī)地屏蔽或歸零20%的數(shù)據(jù)们豌,這樣模型將不依賴于一組特定的權(quán)重或模式涯捻,從而不會導(dǎo)致過擬合。讓我們來看另一個例子望迎,在這里使用一個閾值為0.5的dropout(見圖4.4)障癌。


圖4.3


圖4.4

通常dropout的閾值在0.2~0.5的范圍內(nèi),并且dropout可以應(yīng)用在不同的層辩尊。dropout僅在訓(xùn)練期間使用涛浙,在測試期間,輸出值使用與dropout相等的因子縮小摄欲。PyTroch允許將dropout作為一層轿亮,從而使它更容易使用。下面的代碼片段展示了如何在PyTorch中使用一個dropout層:

dropout層接受一個名為training的參數(shù)胸墙,它需要在訓(xùn)練階段設(shè)置為True我注,而在驗證階段或測試階段時設(shè)置為False。

4.5.5 欠擬合

當(dāng)模型明顯在訓(xùn)練數(shù)據(jù)集上表現(xiàn)不佳時迟隅,模型可能無法學(xué)習(xí)出任何模式但骨。當(dāng)模型無法擬合的時候,通常的做法是獲取更多的數(shù)據(jù)來訓(xùn)練算法智袭。另一種方法是通過增加層數(shù)或增加模型所使用的權(quán)重或參數(shù)的數(shù)量奔缠,來提高模型的復(fù)雜度。通常在實際過擬合數(shù)據(jù)集之前吼野,最好不要使用上述的任何正則化技術(shù)校哎。

4.6 機(jī)器學(xué)習(xí)項目的工作流

在本節(jié)中,我們通過將問題描述瞳步、評估闷哆、特征工程和避免過擬合結(jié)合起來,形成一個可用于解決任何機(jī)器學(xué)習(xí)問題的解決方案框架谚攒。

4.6.1 問題定義與數(shù)據(jù)集創(chuàng)建

為了定義問題阳准,我們需要兩件重要的事情,即輸入數(shù)據(jù)和問題類型馏臭。

我們的輸入數(shù)據(jù)和對應(yīng)標(biāo)簽是什么野蝇?比如說,我們希望根據(jù)顧客提供的評論基于提供的特色菜式對餐館進(jìn)行分類括儒,區(qū)別意大利菜绕沈、墨西哥菜、中國菜和印度菜等帮寻。要開始處理這類問題乍狐,需要手動將訓(xùn)練數(shù)據(jù)標(biāo)注為可能的類別之一,然后才可以對算法進(jìn)行訓(xùn)練固逗。在此階段浅蚪,數(shù)據(jù)可用性往往是一個具有挑戰(zhàn)性的因素藕帜。

識別問題的類型將有助于確定它是二分類、多分類惜傲、標(biāo)量回歸(房屋定價)還是向量回歸(邊界框)洽故。有時,我們可能不得不使用一些無監(jiān)督的技術(shù)盗誊,如聚類和降維时甚。一旦識別出問題類型,就更容易確定應(yīng)該使用什么樣的架構(gòu)哈踱、損失函數(shù)和優(yōu)化器荒适。

在獲得了輸入并確定了問題的類型后,就可以開始使用以下假設(shè)來構(gòu)建模型:

[if !supportLists]·?[endif]數(shù)據(jù)中隱藏的模式有助于將輸入映射到輸出开镣;

[if !supportLists]·?[endif]我們擁有的數(shù)據(jù)足以讓模型進(jìn)行學(xué)習(xí)刀诬。

作為機(jī)器學(xué)習(xí)的實踐者,我們需要理解的是可能無法僅用一些輸入數(shù)據(jù)和目標(biāo)數(shù)據(jù)來構(gòu)建模型哑子。下面以股票價格預(yù)測為例舅列。假設(shè)有代表歷史價格、歷史表現(xiàn)和競爭細(xì)節(jié)的特征卧蜓,但仍然不能建立一個有意義的模型來預(yù)測股票價格帐要,因為股票價格實際上可能受到各種其他因素的影響,比如國內(nèi)外政治環(huán)境弥奸、自然因素榨惠,以及輸入數(shù)據(jù)可能無法表示的許多其他因素。因此盛霎,任何機(jī)器學(xué)習(xí)或深度學(xué)習(xí)模型都無法識別出模式赠橙。因此,請基于領(lǐng)域仔細(xì)挑選可以成為目標(biāo)變量的真實指標(biāo)的特征愤炸。所有這些都可能是模型不擬合的原因期揪。

機(jī)器學(xué)習(xí)還有另一個重要的假設(shè)。未來或未知的數(shù)據(jù)將接近歷史數(shù)據(jù)所描述的模式规个。有時凤薛,模型失敗的原因可能是歷史數(shù)據(jù)中不存在模式,或者模型訓(xùn)練的數(shù)據(jù)未涵蓋某些季節(jié)性或模式诞仓。

4.6.2 成功的衡量標(biāo)準(zhǔn)

成功的衡量標(biāo)準(zhǔn)將直接取決于業(yè)務(wù)目標(biāo)缤苫。例如,當(dāng)試圖預(yù)測風(fēng)車何時會發(fā)生下一次機(jī)器故障時墅拭,我們會對模型能夠預(yù)測到故障的次數(shù)更感興趣活玲。簡單地使用準(zhǔn)確率可能是錯誤的度量,因為大多數(shù)時候模型在機(jī)器不出現(xiàn)故障時預(yù)測都正確,因為這是最常見的輸出舒憾。假設(shè)得到了98%的準(zhǔn)確率镀钓,但模型每次預(yù)測故障時都是錯誤的,這樣的模型在現(xiàn)實世界中可能沒有任何用處珍剑。選擇正確的成功度量標(biāo)準(zhǔn)對于業(yè)務(wù)問題至關(guān)重要掸宛。通常死陆,這類問題具有不平衡的數(shù)據(jù)集招拙。

對于平衡分類問題,其中所有的類別都具有相似的準(zhǔn)確率措译,ROC和AUC是常見的度量别凤。對于不平衡的數(shù)據(jù)集,可以使用查準(zhǔn)率(precision)和查全率(recall)领虹。對于排名問題规哪,可以使用平均精度均值(Mean Average Precision,MAP)塌衰。

4.6.3 評估協(xié)議

決定好如何評估當(dāng)前的進(jìn)展后诉稍,重要的事情就是如何評估數(shù)據(jù)集∽罱可以從評估進(jìn)展的3種不同方式中進(jìn)行選擇杯巨。

[if !supportLists]·?[endif]保留驗證集:這是最常用的,尤其是當(dāng)有足夠的數(shù)據(jù)時努酸。

[if !supportLists]·?[endif]K折交叉驗證:當(dāng)數(shù)據(jù)有限時服爷,這個策略有助于對數(shù)據(jù)的不同部分進(jìn)行評估,從而有助于更好地了解性能获诈。

[if !supportLists]·?[endif]迭代K折驗證:想進(jìn)一步提升模型的性能時仍源,這種方法會有所幫助。

4.6.4 準(zhǔn)備數(shù)據(jù)

通過向量化將不同格式的可用數(shù)據(jù)轉(zhuǎn)換成張量舔涎,并確保所有特征進(jìn)行了伸縮和歸一化處理笼踩。

4.6.5 模型基線

創(chuàng)建一個非常簡單的模型來打破基線分?jǐn)?shù)。在之前的狗貓分類示例中亡嫌,基線準(zhǔn)確度應(yīng)該是0.5嚎于,我們的簡單模型應(yīng)該能夠超過這個分?jǐn)?shù)。如果無法超過基線分?jǐn)?shù)昼伴,則輸入數(shù)據(jù)可能不包含進(jìn)行必要預(yù)測所需的必要信息匾旭。記住,不要在這一步引入任何正則化或dropout圃郊。

要使模型工作价涝,必須要做出3個重要的選擇。

[if !supportLists]·?[endif]最后一層的選擇:對于回歸問題持舆,應(yīng)該是生成標(biāo)量值作為輸出的線性層色瘩。對于向量回歸問題伪窖,應(yīng)是生成多個標(biāo)量輸出的相同線性層。對于邊界框問題居兆,輸出的是4個值覆山。對于二分類問題,通常使用sigmoid泥栖,對于多類別分類問題簇宽,則為softmax。

[if !supportLists]·?[endif]損失函數(shù)的選擇:問題的類型將有助于決定損失函數(shù)吧享。對于回歸問題魏割,如預(yù)測房價,我們使用均方誤差(Mean Squared Error钢颂,MSE)钞它,對于分類問題,使用分類交叉熵殊鞭。

[if !supportLists]·?[endif]優(yōu)化:選擇正確的優(yōu)化算法及其中的一些超參數(shù)是相當(dāng)棘手的遭垛,我們可以通過試驗找出。對于大多數(shù)用例操灿,Adam或RMSprop優(yōu)化算法效果更好锯仪。下面將介紹一些可用于學(xué)習(xí)率選擇的技巧。

下面總結(jié)一下在深度學(xué)習(xí)算法中牲尺,網(wǎng)絡(luò)的最后一層將使用什么樣的損失函數(shù)和激活函數(shù)(見表4.1)卵酪。

表4.1

問題類型激活函數(shù)損失函數(shù)

二分類sigmoidnn.CrossEntropyLoss()

多類別分類softmaxnn.CrossEntropyLoss()

多標(biāo)簽分類sigmoidnn.CrossEntropyLoss()

回歸無MSE

向量回歸無MSE

4.6.6 大到過擬合的模型

一旦模型具有了足夠的容量來超越基線分?jǐn)?shù),就要增加基線容量谤碳。增加架構(gòu)能力的一些簡單技巧如下:

[if !supportLists]·?[endif]為現(xiàn)有架構(gòu)中添加更多層溃卡;

[if !supportLists]·?[endif]為已存在的層加入更多權(quán)重;

[if !supportLists]·?[endif]訓(xùn)練更多輪數(shù)蜒简。

我們通常將模型訓(xùn)練足夠的輪數(shù)瘸羡,當(dāng)訓(xùn)練準(zhǔn)確率還在提高但驗證準(zhǔn)確性卻停止增加并且可能開始下降時停止訓(xùn)練,這就是模型開始過擬合的地方搓茬。到達(dá)這個階段后犹赖,就需要應(yīng)用正則化技術(shù)。

請記住卷仑,層的數(shù)量峻村、大小和訓(xùn)練輪數(shù)可能會因問題而異。較小的架構(gòu)可以用于簡單的分類問題锡凝,但是對于面部識別等復(fù)雜問題粘昨,模型架構(gòu)要有足夠的表示能力,并且模型要比簡單的分類問題訓(xùn)練更長的時間。

4.6.7 應(yīng)用正則化

找到最佳的方法來調(diào)整模型或算法是過程中最棘手的部分之一张肾,因為有很多參數(shù)需要調(diào)整芭析。可對下面這些用于正則化模型的參數(shù)進(jìn)行調(diào)整吞瞪。

[if !supportLists]·?[endif]添加dropout:這可能很復(fù)雜馁启,因為可以在不同的層之間添加,并且找到最佳位置通常是通過試驗來完成的芍秆。要添加的dropout百分比也很棘手惯疙,因為它純粹依賴于我們試圖解決的問題的描述。從較小的數(shù)值開始(如0.2)浪听,通常是最佳實踐螟碎。

[if !supportLists]·?[endif]嘗試不同的架構(gòu):可以嘗試不同的架構(gòu)、激活函數(shù)迹栓、層數(shù)、權(quán)重俭缓,或?qū)拥膮?shù)克伊。

[if !supportLists]·?[endif]添加L1或L2正則化:可以使用正則化中的任何一個。

[if !supportLists]·?[endif]嘗試不同的學(xué)習(xí)率:在這里有不同的技術(shù)可以使用华坦,本章后面部分將討論愿吹。

[if !supportLists]·?[endif]添加更多特征或更多數(shù)據(jù):可以通過獲取更多的數(shù)據(jù)或增強(qiáng)數(shù)據(jù)來實現(xiàn)。

我們將使用驗證數(shù)據(jù)集來調(diào)整所有上述的超參數(shù)惜姐。在不斷地迭代和調(diào)整超參數(shù)的同時犁跪,可能會遇到數(shù)據(jù)泄露的問題。因此歹袁,應(yīng)確保有用于測試的保留數(shù)據(jù)坷衍。如果模型在測試數(shù)據(jù)集上的性能相比訓(xùn)練集和驗證集要好,那么我們的模型很有可能在未知的數(shù)據(jù)上表現(xiàn)良好条舔。但是枫耳,如果模型在測試數(shù)據(jù)上表現(xiàn)不佳,但是在驗證和訓(xùn)練數(shù)據(jù)上表現(xiàn)很好孟抗,那么驗證數(shù)據(jù)很可能不是對真實世界數(shù)據(jù)集的良好表示迁杨。在這樣的情況下,可以使用K折驗證或迭代K折驗證數(shù)據(jù)集凄硼。

4.6.8 學(xué)習(xí)率選擇策略

找到合適的學(xué)習(xí)率來訓(xùn)練模型是一個還在進(jìn)行中的研究領(lǐng)域铅协,并且已經(jīng)取得了很多進(jìn)展。PyTorch提供了一些調(diào)整學(xué)習(xí)率的技術(shù)摊沉,它們由torch.optim.lr_sheduler包提供狐史。我們將探討PyTorch提供的一些動態(tài)選擇學(xué)習(xí)率的技術(shù)。

[if !supportLists]·?[endif]StepLR:這個調(diào)度器有兩個重要的參數(shù)。第一個參數(shù)是步長预皇,它表示學(xué)習(xí)率多少輪改變一次侈玄,第二個參數(shù)是gamma,它決定學(xué)習(xí)率必須改變多少吟温。對學(xué)習(xí)率0.01來說序仙,在步長10和gamma為0.1的情況下,學(xué)習(xí)率每10輪以gamma的倍數(shù)變化鲁豪。也就是說潘悼,對于前10輪,學(xué)習(xí)率變?yōu)?.001爬橡,并且在接下來的10輪治唤,變成0.0001。下面的代碼解釋了StepLR的實現(xiàn)糙申。

[if !supportLists]·?[endif]MultiStepLR:MultiStepLR與StepLR的工作方式類似宾添,只不過步長不是規(guī)則間斷的,步長以列表的形式給出柜裸。例如缕陕,給出的步長列表為10、15疙挺、30扛邑,并且對于每個步長,學(xué)習(xí)率要乘上gamma值铐然。下面的代碼演示了MultiStepLR的實現(xiàn)蔬崩。

[if !supportLists]·?[endif]ExponentialLR:每一輪都將學(xué)習(xí)率乘上gamma值。

[if !supportLists]·?[endif]ReduceLROnPlateau:這是常用的學(xué)習(xí)率策略之一搀暑。應(yīng)用本策略時沥阳,當(dāng)特定的度量指標(biāo),如訓(xùn)練損失险掀、驗證損失或準(zhǔn)確率不再變化時,學(xué)習(xí)率就會改變樟氢。通用實踐是將學(xué)習(xí)率的原始值降低為原來的1/2~1/10冈绊。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市埠啃,隨后出現(xiàn)的幾起案子死宣,更是在濱河造成了極大的恐慌,老刑警劉巖碴开,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件毅该,死亡現(xiàn)場離奇詭異博秫,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)眶掌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門挡育,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人朴爬,你說我怎么就攤上這事即寒。” “怎么了召噩?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵母赵,是天一觀的道長。 經(jīng)常有香客問我具滴,道長凹嘲,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上慢睡,老公的妹妹穿的比我還像新娘。我一直安慰自己谷醉,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布冈闭。 她就那樣靜靜地躺著,像睡著了一般抖单。 火紅的嫁衣襯著肌膚如雪萎攒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天矛绘,我揣著相機(jī)與錄音耍休,去河邊找鬼。 笑死货矮,一個胖子當(dāng)著我的面吹牛羊精,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播囚玫,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼喧锦,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了抓督?” 一聲冷哼從身側(cè)響起燃少,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎铃在,沒想到半個月后阵具,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體碍遍,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年阳液,在試婚紗的時候發(fā)現(xiàn)自己被綠了怕敬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡帘皿,死狀恐怖东跪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情矮烹,我是刑警寧澤越庇,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站奉狈,受9級特大地震影響卤唉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜仁期,卻給世界環(huán)境...
    茶點故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一桑驱、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧跛蛋,春花似錦熬的、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至理逊,卻和暖如春橡伞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背晋被。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工兑徘, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人羡洛。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓挂脑,卻偏偏與公主長得像,于是被迫代替她去往敵國和親欲侮。 傳聞我的和親對象是個殘疾皇子崭闲,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,033評論 2 355

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