Core ML框架詳細(xì)解析(六) —— 一個(gè)Core ML簡(jiǎn)單示例(二)

版本記錄

版本號(hào) 時(shí)間
V1.0 2018.08.17

前言

目前世界上科技界的所有大佬一致認(rèn)為人工智能是下一代科技革命揽思,蘋果作為科技界的巨頭袭祟,當(dāng)然也會(huì)緊跟新的科技革命的步伐,其中ios API 就新出了一個(gè)框架Core ML庙洼。ML是Machine Learning的縮寫栏赴,也就是機(jī)器學(xué)習(xí),這正是現(xiàn)在很火的一個(gè)技術(shù)耿眉,它也是人工智能最核心的內(nèi)容边翼。感興趣的可以看我寫的下面幾篇。
1. Core ML框架詳細(xì)解析(一) —— Core ML基本概覽
2. Core ML框架詳細(xì)解析(二) —— 獲取模型并集成到APP中
3. Core ML框架詳細(xì)解析(三) —— 利用Vision和Core ML對(duì)圖像進(jìn)行分類
4. Core ML框架詳細(xì)解析(四) —— 將訓(xùn)練模型轉(zhuǎn)化為Core ML
5. Core ML框架詳細(xì)解析(五) —— 一個(gè)Core ML簡(jiǎn)單示例(一)

Using the Image Classifier - 使用圖像分類器

Create ML GUI導(dǎo)出Core ML模型鸣剪,然后您只需將模型拖到舊的Core ML項(xiàng)目中组底,在代碼中更改一個(gè)單詞,就可以了筐骇!

單擊ImageClassifier旁邊的顯示符號(hào)以查看不同的選項(xiàng)集债鸡。 單擊文本,然后將其更改為PetsClassifier铛纬。 將Where位置更改為starter文件夾厌均,然后單擊Save

starter文件夾中打開ClassificationImagesWithVisionAndCoreML項(xiàng)目。 這是Apple的2017年項(xiàng)目:我已將其更新為Swift 4.2告唆,并修復(fù)了照片選擇器調(diào)用棺弊。 它使用MobileNet.mlmodel晶密,它是17.1 MB:

PetsClassifier.mlmodel拖到項(xiàng)目導(dǎo)航器中。 它是17 KB:

在項(xiàng)目中搜索MobileNet

let model code語句中模她,將MobileNet替換為PetsClassifier

let model = try VNCoreMLModel(for: PetsClassifier().model)

Build并運(yùn)行稻艰。 單擊相機(jī)圖標(biāo)以打開照片選取器,然后將一些狗和貓圖像拖入Photos

選一個(gè)侈净,應(yīng)用程序通過顯示每個(gè)標(biāo)簽的概率將其分類為狗或貓:


Turi Create Image Classifier - Turi Create圖像分類器

以下是同一數(shù)據(jù)集的Turi Create image classifier example中的代碼 - 完整的25,000圖像數(shù)據(jù)集:

import turicreate as tc

# 1. Load images (Note: you can ignore 'Not a JPEG file' errors)
data = tc.image_analysis.load_images('PetImages', with_path=True)

# 2. From the path-name, create a label column
data['label'] = data['path'].apply(lambda path: 'dog' if '/Dog' in path else 'cat')

# Note: If you have more than two classes, extract the folder names like this:
# train_data["label"] = train_data["path"].apply(lambda path: os.path.basename(os.path.split(path)[0]))

# 3. Make a train-test split
train_data, test_data = data.random_split(0.8)

# 4. Create the model
model = tc.image_classifier.create(train_data, target='label')

# 5. Save predictions to an SArray
predictions = model.predict(test_data)

# 6. Evaluate the model and save the results into a dictionary
metrics = model.evaluate(test_data)
print(metrics['accuracy'])

# 7. Save the model for later use in Turi Create
model.save('mymodel.model')

# 8. Export for use in Core ML
model.export_coreml('MyCustomImageClassifier.mlmodel')

這比你在playground上寫的代碼要多得多尊勿,但你很快就會(huì)發(fā)現(xiàn)它與Create ML文本分類器代碼相似。

使用您在Create ML中執(zhí)行的操作匹配步驟:

  • 步驟1到4對(duì)應(yīng)于創(chuàng)建Training和Testing文件夾畜侦,然后將Training文件夾拖到視圖上元扔。 Turi Create必須從圖像的路徑中提取類標(biāo)簽,但步驟3隨機(jī)地將20%的數(shù)據(jù)集分配給test_data夏伊,這樣可以節(jié)省創(chuàng)建Training和Testing文件夾的工作摇展,并且每次運(yùn)行這段代碼都可以獲得不同的測(cè)試數(shù)據(jù)集吻氧。

注意:在第2步中溺忧,僅為兩個(gè)類提取類標(biāo)簽是一種特殊情況。 我在上面的代碼中添加了一個(gè)注釋盯孙,以顯示更一般的情況鲁森。 首先,os.path.split()將路徑分成兩部分:文件的名稱(如42.jpg)以及導(dǎo)致它的所有內(nèi)容振惰。 然后os.path.basename()是最后一個(gè)文件夾的名稱歌溉,它是具有類名的文件夾。

  • 步驟5和6對(duì)應(yīng)于將Testing文件夾拖到視圖上骑晶。 Jupyter筆記本可以像Create ML視圖一樣輕松地顯示predictions數(shù)組痛垛。 您還可以過濾數(shù)組以查找錯(cuò)誤的分類,而不是滾動(dòng)測(cè)試圖像桶蛔。

  • 步驟7保存模型供以后使用匙头,因此您可以再次加載它并在不同的測(cè)試數(shù)據(jù)集上運(yùn)行它。

  • 步驟8導(dǎo)出Core ML模型仔雷。

所以Turi Create的圖像分類更加手動(dòng)蹂析,但比Create ML更靈活。 turicreate.create() documentation列出了幾個(gè)可選參數(shù)碟婆。 您可以指定基礎(chǔ)model以匹配Create ML电抚。 請(qǐng)注意Core ML型號(hào)的尺寸差異! 如果您創(chuàng)建了一個(gè)真正代表您的真實(shí)測(cè)試數(shù)據(jù)并且不希望模型使用您的訓(xùn)練數(shù)據(jù)中的隨機(jī)選擇竖共,您還可以提供固定的validation_set蝙叛。

圖像分類是Create ML中的一個(gè)非常特殊的情況:MLImageClassifierBuilder GUI消除了編寫代碼的需要和機(jī)會(huì)。 在下一節(jié)中公给,您將看到其他Create ML模型也需要更多代碼借帘。


Text Classifier - 文本分類器

現(xiàn)在比較Create ML和Turi Create如何訓(xùn)練并測(cè)試文本分類器模型锻煌。 Turi Create模型需要將測(cè)試文本轉(zhuǎn)換為一個(gè)單詞包 - 這是一個(gè)直接的轉(zhuǎn)換,它內(nèi)置于Create ML模型中姻蚓,因此它直接接受測(cè)試文本宋梧。

1. Create ML

這里是代碼Create ML text classifier example

import CreateML

// 1. Load data from a JSON file
let data = try? MLDataTable(contentsOf: URL(fileURLWithPath: "<#/path/to/read/data.json#>"))

// 2. Make a train-test split
let (trainingData, testingData) = data.randomSplit(by: 0.8, seed: 5)

// 3. Create the model
let sentimentClassifier = try? MLTextClassifier(trainingData: trainingData,
  textColumn: "text", labelColumn: "label")
  
// 4. Training accuracy as a percentage
let trainingAccuracy = (1.0 - sentimentClassifier.trainingMetrics.classificationError) * 100

// 5. Validation accuracy as a percentage
let validationAccuracy = (1.0 - sentimentClassifier.validationMetrics.classificationError) * 100

// 6. Evaluation accuracy as a percentage
let evaluationMetrics = sentimentClassifier.evaluation(on: testingData)
let evaluationAccuracy = (1.0 - evaluationMetrics.classificationError) * 100

// 7. Add metadata
let metadata = MLModelMetadata(author: "John Appleseed",
  shortDescription: "A model trained to classify movie review sentiment", version: "1.0")

// 8. Export for use in Core ML
try? sentimentClassifier.write(to: URL(fileURLWithPath: "<#/path/to/save/SentimentClassifier.mlmodel#>"),
    metadata: metadata)
  • 1)步驟1將數(shù)據(jù)加載到包含文本text和標(biāo)簽label列的表中,其中l(wèi)abel的值為正狰挡,負(fù)或中性捂龄。 WWDC 2018 Session 703 video視頻顯示了另一種使用單獨(dú)文本文件在positivenegative命名的文件夾中加載文本數(shù)據(jù)的方法,類似于加載圖像以訓(xùn)練圖像分類器的方式加叁。 這是Create ML中的一個(gè)特殊功能倦沧,它在Turi Create中不可用。

WWDC 2018 Session 703加載labeled文本數(shù)據(jù)的替代方法:

let trainDirectory = URL(fileURLWithPath: “/Users/createml/Desktop/train”)
let testDirectory = URL(fileURLWithPath: “/Users/createml/Desktop/test”)
// Create Model
let classifier = try MLTextClassifier(trainingData: .labeledDirectories(at: trainDirectory))

返回主文本分類器代碼:

  • 2)第2步與Turi Createrandom_split()相同它匕,隨機(jī)地將20%的數(shù)據(jù)分配給testingData展融。 可選的seed參數(shù)設(shè)置隨機(jī)數(shù)生成器的seed
  • 3)第3步與Turi Create的sentence_classifier.create()相同豫柬。
  • 4 ~ 6)步驟4-6計(jì)算訓(xùn)練告希,驗(yàn)證和評(píng)估準(zhǔn)確度指標(biāo)。
  • 7 ~ 8)步驟7和8使用一些元數(shù)據(jù)導(dǎo)出Core ML模型烧给。

2. Turi Create

此代碼來自Natural Language Processing on iOS with Turi Create教程燕偶。 它用10位詩人的詩歌訓(xùn)練句子分類器,以預(yù)測(cè)測(cè)試文本的作者础嫡。

import turicreate as tc

# 1. Load data from a JSON file
data = tc.SFrame.read_json('corpus.json', orient='records')

# 2. Create the model
model = tc.sentence_classifier.create(data, 'author', features=['text'])

# 3. Export for use in Core ML
model.export_coreml('Poets.mlmodel')
  • 1)第1步:與Create ML一樣指么,您可以從JSON或CSV文件加載數(shù)據(jù)。
  • 2)第2步訓(xùn)練模型榴鼎。
  • 3)步驟3導(dǎo)出Core ML模型伯诬。

Turi Create教程材料包括一個(gè)iOS應(yīng)用程序,您可以在其中測(cè)試粘貼到textview中的文本的模型巫财。 該應(yīng)用程序使用wordCounts(text :)輔助函數(shù)盗似,類似于 Turi Create text classification example底部的單詞函數(shù)包。

Turi Create文本分類器期望以單詞和單詞計(jì)數(shù)字典的形式輸入翁涤。 Create ML文本分類器直接接受文本輸入桥言,并創(chuàng)建自己的單詞包。


Turi Create Image Similarity - Turi Create圖像相似度

現(xiàn)在深吸一口氣 - 你正在進(jìn)行Turi Create冒險(xiǎn)葵礼!

Turi Create有五個(gè)以任務(wù)為中心的工具包号阿。

  • 推薦系統(tǒng)
  • 圖像相似度
  • 物體檢測(cè)
  • 風(fēng)格轉(zhuǎn)移
  • 活動(dòng)分類

看貓狗圖片很有趣,所以你會(huì)訓(xùn)練模型找到類似的圖像鸳粉。

是的扔涧,你需要編寫一些Python。 感覺最熟悉的開發(fā)環(huán)境是Jupyter筆記本 - 它就像一個(gè)Xcode playground,但它在你的瀏覽器中運(yùn)行枯夜。

最簡(jiǎn)單的方法是使用Anaconda - 由ML社區(qū)創(chuàng)建弯汰,以整理所有版本的Python和ML庫,并在不同的環(huán)境中管理它們湖雹。


Anaconda & Notebooks

下載Python 3.6 version of Anaconda for macOS咏闪,在home directory中安裝而不是在根目錄文件夾中安裝。

如果顯示您無法在那里安裝它摔吏,請(qǐng)單擊Install on a specific disk…按鈕鸽嫂,然后單擊返回到Home按鈕 - 它應(yīng)該更加令人滿意:

注意:安裝Anaconda并創(chuàng)建Turi Create環(huán)境可能需要幾分鐘時(shí)間。 在您等待的同時(shí)征讲,瀏覽Michael Kennedy 2014年11月的Comparison of Python and Swift Syntax以及Jason Brownlee 2016年5月的 Crash Course in Python for Machine Learning Developers据某。 Brownlee的文章包括使用數(shù)據(jù)科學(xué)庫NumPyMatplotlibPandas的例子诗箍。 Swift和Python語法之間的最大區(qū)別在于您使用縮進(jìn)而不是{...}來定義閉包癣籽,函數(shù)和類。

1. Create Turi Create Environment - 創(chuàng)建Turi Create環(huán)境

使用Anaconda Navigator GUITerminal命令創(chuàng)建一個(gè)可以運(yùn)行Turi Create代碼的環(huán)境滤祖。

GUI:打開Anaconda Navigator筷狼,切換到Environments選項(xiàng)卡,然后導(dǎo)入starter / turienv.yaml - 只需單擊文件夾圖標(biāo)氨距,然后在Finder中找到該文件桑逝。 Anaconda Navigator將從文件中填寫環(huán)境名稱:

Terminal: 打開終端并輸入以下命令:

conda env create -f <drag starter/turienv.yaml file from Finder>

2. Launch Jupyter Notebook

使用GUI或終端命令在turienv環(huán)境中啟動(dòng)Jupyter筆記本。

首先俏让,在Finder中,創(chuàng)建一個(gè)名為notebooks的本地文件夾茬暇。

如果你有一個(gè)非常強(qiáng)大的新Mac首昔,下載并取消歸檔 Kaggle Cats and Dogs Dataset,然后將PetImages文件夾移動(dòng)到notebooks中糙俗,這樣你就可以輕松地將它加載到你即將創(chuàng)建的筆記本中勒奇。

完整的Kaggle數(shù)據(jù)集包含25,000張圖像,這需要很長(zhǎng)時(shí)間才能在較舊的Mac上處理巧骚。 您可以隨意使用Pets-1000文件夾赊颠,也可以創(chuàng)建自己的數(shù)據(jù)集。

GUI:如果您正在使用Anaconda Navigator劈彪,請(qǐng)切換到Home選項(xiàng)卡竣蹦,檢查turienv是否出現(xiàn)在Applications on字段中,然后單擊jupyter Launch

將打開一個(gè)終端窗口以運(yùn)行Jupyter服務(wù)器沧奴,然后瀏覽器窗口將顯示您的主目錄痘括。 導(dǎo)航到您的notebooks文件夾。

終端:如果您正在使用終端,請(qǐng)輸入此命令以加載turienv

source activate turienv

命令行提示現(xiàn)在以(turienv)開頭纲菌。 輸入此命令以啟動(dòng)notebooks文件夾中的Jupyter服務(wù)器挠日,并顯示瀏覽器窗口:

jupyter notebook <drag notebooks folder from the Finder>

Training the Model - 訓(xùn)練模型

創(chuàng)建一個(gè)新的Python 3.6 notebook

雙擊標(biāo)題以重命名筆記本:

注意:此示例與Apple的 Image similarity示例相同,但使用Cat和Dog數(shù)據(jù)集翰舌。

notebook包含一個(gè)空單元格嚣潜。 在單元格中鍵入此行,然后按Shift-Enter運(yùn)行單元格:

import turicreate as tc

注意:如果您只想運(yùn)行一個(gè)代碼語句椅贱,Shift-Enter也適用于Xcode playgrounds郑原。

第一個(gè)下面出現(xiàn)了一個(gè)新的空單元格。 在其中鍵入以下內(nèi)容夜涕,然后運(yùn)行它:

reference_data = tc.image_analysis.load_images('./PetImages')
reference_data = reference_data.add_row_number()
reference_data.save('./kaggle-pets.sframe')

您正在將圖像加載到表中犯犁,向表中添加行號(hào),然后保存它以備將來使用女器。 忽略JPEG decode failure消息酸役。

注意:在鍵入Python代碼時(shí),請(qǐng)使用Tab鍵進(jìn)行自動(dòng)完成驾胆。

在下一個(gè)單元格中涣澡,運(yùn)行此語句以探索數(shù)據(jù):

reference_data.explore()

將打開一個(gè)窗口,顯示id丧诺,path和image列入桂。 將光標(biāo)懸停在一行中會(huì)顯示圖像:

下面,運(yùn)行下面語句:

model = tc.image_similarity.create(reference_data)

這將需要一段時(shí)間 - In [*]中顯示它正在運(yùn)行驳阎。 在您等待的同時(shí)抗愁,請(qǐng)閱讀有關(guān)unsupervised learning的內(nèi)容。

注意:要在單元格完成之前停止單元格呵晚,請(qǐng)單擊Stop按鈕(工具欄中的Run旁邊)蜘腌。 隨意刪除PetImages中的圖像,或者只是加載Pets-1000饵隙。


Unsupervised Learning - 無監(jiān)督學(xué)習(xí)

向圖像分類器提供標(biāo)記數(shù)據(jù)使其能夠通過檢查其對(duì)標(biāo)簽的預(yù)測(cè)來測(cè)量其準(zhǔn)確度撮珠。 這是有監(jiān)督的學(xué)習(xí)supervised learning

雖然您為此圖像相似性訓(xùn)練器提供了相同的標(biāo)記數(shù)據(jù)集金矛,但它不使用標(biāo)簽:此模型使用無監(jiān)督學(xué)習(xí)芯急。 底層模型查看了大量圖像,并自學(xué)了哪些像素值排列構(gòu)成了可用于聚類“相似”圖像的特征驶俊。 因此娶耍,就像圖像分類器一樣,大部分訓(xùn)練時(shí)間用于從數(shù)據(jù)集中提取這些特征废睦。 然后它做"brute force" nearest neighbors:對(duì)于每個(gè)圖像伺绽,它計(jì)算它與每個(gè)其他圖像的距離,并將其他圖像排列成半徑帶。 同樣奈应,與特征提取相比澜掩,這一步驟很快。


Querying the Model - 查詢模型

模型準(zhǔn)備好以后就運(yùn)行下面這行代碼:

query_results = model.query(reference_data[0:10], k=10)
query_results.head()

您傳遞的數(shù)組包含前10個(gè)reference_data圖像杖挣,每個(gè)圖像要求10個(gè)相似的圖像肩榕,然后顯示query_results的前10行。

假設(shè)您要查找第10張圖像的類似圖像惩妇。 首先株汉,看看它是什么:

reference_data[9]['image'].show()

圖像的加載順序是不確定的,因此您的第10張圖像可能是不同的歌殃。 重要的是它應(yīng)該看起來像下一個(gè)單元格的輸出乔妈。

所以運(yùn)行這些行:

similar_rows = query_results[query_results['query_label'] == 9]['reference_label']
reference_data.filter_by(similar_rows, 'id').explore()

目標(biāo)圖像實(shí)際上是返回的第一個(gè)圖像。 其他圖像顯示看起來相似和/或以類似方式定位位置不同的貓氓皱。


Shutting Down

退出jupyter瀏覽器窗口路召。

在運(yùn)行jupyter服務(wù)器的終端窗口中,按Control-C-C以停止服務(wù)器波材。

如果命令行提示符以(turienv)開頭股淡,請(qǐng)輸入以下命令退出:

source deactivate

如果您真的不想保留Anaconda,請(qǐng)輸入以下命令:

rm -rf ~/anaconda3

關(guān)于本文章的內(nèi)容就此結(jié)束了廷区,下面說一下其他方面的唯灵。

探索Create ML及其文檔,但也花一些時(shí)間瀏覽Turi Create User Guide隙轻,即使您不想編寫Python埠帕。

后記

本篇主要講述了一個(gè)Core ML簡(jiǎn)單示例,感興趣的給個(gè)贊或者關(guān)注~~~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末大脉,一起剝皮案震驚了整個(gè)濱河市搞监,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌镰矿,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件俘种,死亡現(xiàn)場(chǎng)離奇詭異秤标,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)宙刘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門苍姜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人悬包,你說我怎么就攤上這事衙猪。” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵垫释,是天一觀的道長(zhǎng)丝格。 經(jīng)常有香客問我,道長(zhǎng)棵譬,這世上最難降的妖魔是什么显蝌? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮订咸,結(jié)果婚禮上曼尊,老公的妹妹穿的比我還像新娘。我一直安慰自己脏嚷,他們只是感情好骆撇,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著父叙,像睡著了一般神郊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上高每,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天屿岂,我揣著相機(jī)與錄音,去河邊找鬼鲸匿。 笑死爷怀,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的带欢。 我是一名探鬼主播运授,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼乔煞!你這毒婦竟也來了吁朦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤渡贾,失蹤者是張志新(化名)和其女友劉穎逗宜,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體空骚,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡纺讲,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了囤屹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片熬甚。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖肋坚,靈堂內(nèi)的尸體忽然破棺而出乡括,到底是詐尸還是另有隱情肃廓,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布诲泌,位于F島的核電站盲赊,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏档礁。R本人自食惡果不足惜角钩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望呻澜。 院中可真熱鬧递礼,春花似錦、人聲如沸羹幸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽栅受。三九已至将硝,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間屏镊,已是汗流浹背依疼。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留而芥,地道東北人律罢。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像棍丐,于是被迫代替她去往敵國(guó)和親误辑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

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