小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

【干貨】手把手教你Python實現(xiàn)自動貝葉斯調(diào)整超參數(shù)

 LibraryPKU 2018-07-07

【導(dǎo)讀】機(jī)器學(xué)習(xí)中,調(diào)參是一項繁瑣但至關(guān)重要的任務(wù),因為它很大程度上影響了算法的性能。手動調(diào)參十分耗時,網(wǎng)格和隨機(jī)搜索不需要人力,但需要很長的運(yùn)行時間。因此,誕生了許多自動調(diào)整超參數(shù)的方法。貝葉斯優(yōu)化是一種用模型找到函數(shù)最小值方法,已經(jīng)應(yīng)用于機(jī)器學(xué)習(xí)問題中的超參數(shù)搜索,這種方法性能好,同時比隨機(jī)搜索省時。此外,現(xiàn)在有許多Python庫可以實現(xiàn)貝葉斯超參數(shù)調(diào)整。本文將使用Hyperopt庫演示梯度提升機(jī)(Gradient Boosting Machine,GBM) 的貝葉斯超參數(shù)調(diào)整的完整示例。文章由貝葉斯優(yōu)化方法、優(yōu)化問題的四個部分、目標(biāo)函數(shù)、域空間、優(yōu)化過程、及結(jié)果展示幾個部分組成。


作者|William Koehrsen

編譯|專知

整理|YIngying,李大囧


貝葉斯優(yōu)化方法

貝葉斯優(yōu)化通過基于目標(biāo)函數(shù)的過去評估結(jié)果建立替代函數(shù)(概率模型),來找到最小化目標(biāo)函數(shù)的值。貝葉斯方法與隨機(jī)或網(wǎng)格搜索的不同之處在于,它在嘗試下一組超參數(shù)時,會參考之前的評估結(jié)果,因此可以省去很多無用功。


超參數(shù)的評估代價很大,因為它要求使用待評估的超參數(shù)訓(xùn)練一遍模型,而許多深度學(xué)習(xí)模型動則幾個小時幾天才能完成訓(xùn)練,并評估模型,因此耗費(fèi)巨大。貝葉斯調(diào)參發(fā)使用不斷更新的概率模型,通過推斷過去的結(jié)果來“集中”有希望的超參數(shù)。


Python中的選擇

Python中有幾個貝葉斯優(yōu)化庫,它們目標(biāo)函數(shù)的替代函數(shù)不一樣。在本文中,我們將使用Hyperopt,它使用Tree Parzen Estimator(TPE)。其他Python庫包括Spearmint(高斯過程代理)和SMAC(隨機(jī)森林回歸)。


優(yōu)化問題的四個部分

貝葉斯優(yōu)化問題有四個部分:

  1. 目標(biāo)函數(shù):我們想要最小化的內(nèi)容,在這里,目標(biāo)函數(shù)是機(jī)器學(xué)習(xí)模型使用該組超參數(shù)在驗證集上的損失。

  2. 域空間:要搜索的超參數(shù)的取值范圍

  3. 優(yōu)化算法:構(gòu)造替代函數(shù)并選擇下一個超參數(shù)值進(jìn)行評估的方法。

  4. 結(jié)果歷史記錄:來自目標(biāo)函數(shù)評估的存儲結(jié)果,包括超參數(shù)和驗證集上的損失。


數(shù)據(jù)集

在本例中,我們將使用Caravan Insurance數(shù)據(jù)集,其目標(biāo)是預(yù)測客戶是否購買保險單。 這是一個有監(jiān)督分類問題,訓(xùn)練集和測試集的大小分別為5800和4000。評估性能的指標(biāo)是AUC(曲線下面積)評估準(zhǔn)則和ROC(receiver operating characteristic,以真陽率和假陽率為坐標(biāo)軸的曲線圖)曲線,ROC AUC越高表示模型越好。 數(shù)據(jù)集如下所示:



因為Hyperopt最小化目標(biāo)函數(shù),我們的目標(biāo)函數(shù)返回1-ROC AUC,從而提高ROC AUC。


梯度提升模型

梯度提升機(jī)(GBM)是一種基于使用弱學(xué)習(xí)器(如決策樹)組合成強(qiáng)學(xué)習(xí)器的模型。 GBM中有許多超參數(shù)控制整個集合和單個決策樹,如決策樹數(shù)量,決策樹深度等。簡單了解了GBM,接下來我們介紹這個問題對應(yīng)的優(yōu)化模型的四個部分。


目標(biāo)函數(shù)

目標(biāo)函數(shù)是需要我們最小化的。 它的輸入為一組超參數(shù),輸出需要最小化的值(交叉驗證損失)。Hyperopt將目標(biāo)函數(shù)視為黑盒,只考慮它的輸入和輸出。 在這里,目標(biāo)函數(shù)定義為:


def objective(hyperparameters):
   '''Returns validation score from hyperparameters'''

   model = Classifier(hyperparameters)
   validation_loss = cross_validation(model, training_data)
   return validation_loss


我們評估的是超參數(shù)在驗證集上的表現(xiàn),但我們不將數(shù)據(jù)集劃分成固定的驗證集和訓(xùn)練集,而是使用K折交叉驗證。使用10倍交叉驗證和提前停止的梯度提升機(jī)的完整目標(biāo)函數(shù)如下所示。

import lightgbm as lgb
from hyperopt import STATUS_OK

N_FOLDS = 10

# Create the dataset
train_set = lgb.Dataset(train_features, train_labels)


def objective(params, n_folds=N_FOLDS):
   '''Objective function for Gradient Boosting Machine Hyperparameter Tuning'''

   # Perform n_fold cross validation with hyperparameters
   # Use early stopping and evalute based on ROC AUC
   cv_results = lgb.cv(params, train_set, nfold=n_folds, num_boost_round=10000,
                       early_stopping_rounds=100, metrics='auc', seed=50)

   # Extract the best score
   best_score = max(cv_results['auc-mean'])

   # Loss must be minimized
   loss = 1 - best_score

   # Dictionary with information for evaluation
   return {'loss': loss, 'params': params, 'status': STATUS_OK}


關(guān)鍵點(diǎn)是cvresults = lgb.cv(...)。為了實現(xiàn)提前停止的交叉驗證,我們使用LightGBM函數(shù)cv,它輸入為超參數(shù),訓(xùn)練集,用于交叉驗證的折數(shù)等。我們將迭代次數(shù)(numboostround)設(shè)置為10000,但實際上不會達(dá)到這個數(shù)字,因為我們使用earlystopping_rounds來停止訓(xùn)練,當(dāng)連續(xù)100輪迭代效果都沒有提升時,則提前停止,并選擇模型。因此,迭代次數(shù)并不是我們需要設(shè)置的超參數(shù)。


一旦交叉驗證完成,我們就會得到最好的分?jǐn)?shù)(ROC AUC),然后,因為我們最小化目標(biāo)函數(shù),所以計算1- ROC AUC,然后返回這個值。


域空間

域空間表示我們要為每個超參數(shù)計算的值的范圍。在搜索的每次迭代中,貝葉斯優(yōu)化算法將從域空間為每個超參數(shù)選擇一個值。當(dāng)我們進(jìn)行隨機(jī)或網(wǎng)格搜索時,域空間是一個網(wǎng)格。在貝葉斯優(yōu)化中,想法是一樣的,但是不是按照順序(網(wǎng)格)或者隨機(jī)選擇一個超參數(shù),而是按照每個超參數(shù)的概率分布選擇。


而確定域空間是最困難的。如果我們有機(jī)器學(xué)習(xí)方法的經(jīng)驗,我們可以通過在我們認(rèn)為最佳值的位置放置更大的概率來使用它來告知我們對超參數(shù)分布的選擇。然而,不同數(shù)據(jù)集之間最佳模型不一樣,并且具有高維度問題(許多超參數(shù)),超參數(shù)之間也會互相影響。在我們不確定最佳值的情況下,我們可以將范圍設(shè)定的大一點(diǎn),讓貝葉斯算法為我們做推理。


首先,我們看看GBM中的所有超參數(shù):

import lgb
# Default gradient boosting machine classifier
model = lgb.LGBMClassifier()
model
LGBMClassifier(boosting_type='gbdt', n_estimators=100,
              class_weight=None, colsample_bytree=1.0,
              learning_rate=0.1, max_depth=-1,                      
              min_child_samples=20,
              min_child_weight=0.001, min_split_gain=0.0,
              n_jobs=-1, num_leaves=31, objective=None,
              random_state=None, reg_alpha=0.0, reg_lambda=0.0,
              silent=True, subsample=1.0,
              subsample_for_bin=200000, subsample_freq=1)


其中一些我們不需要調(diào)整(例如objective和randomstate),我們將使用提前停止來找到最好的n_estimators。 但是,我們還有10個超參數(shù)要優(yōu)化! 首次調(diào)整模型時,我通常會創(chuàng)建一個以默認(rèn)值為中心的寬域空間,然后在后續(xù)搜索中對其進(jìn)行細(xì)化。

例如,讓我們在Hyperopt中定義一個簡單的域,這是GBM中每棵樹中葉子數(shù)量的離散均勻分布:

from hyperopt import hp
# Discrete uniform distribution
num_leaves = {'num_leaves': hp.quniform('num_leaves', 30, 150, 1)}


這里選擇離散的均勻分布,因為葉子的數(shù)量必須是整數(shù)(離散),并且域中的每個值都可能(均勻)。


另一種分布選擇是對數(shù)均勻,它在對數(shù)標(biāo)度上均勻分布值。 我們將使用對數(shù)統(tǒng)一(從0.005到0.2)來獲得學(xué)習(xí)率,因為它在幾個數(shù)量級上變化:

# Learning rate log uniform distribution
learning_rate = {'learning_rate': hp.loguniform('learning_rate',
                                                np.log(0.005),
                                                np.log(0.2)}


下面分別繪制了均勻分布和對數(shù)均勻分布的圖。 這些是核密度估計圖,因此y軸是密度而不是計數(shù)!



現(xiàn)在,讓我們定義整個域:

# Define the search space
space = {
   'class_weight': hp.choice('class_weight', [None, 'balanced']),
   'boosting_type': hp.choice('boosting_type',
                              [{'boosting_type': 'gbdt',
                                   'subsample': hp.uniform('gdbt_subsample', 0.5, 1)},
                                {'boosting_type': 'dart',
                                    'subsample': hp.uniform('dart_subsample', 0.5, 1)},
                                {'boosting_type': 'goss'}]),
   'num_leaves': hp.quniform('num_leaves', 30, 150, 1),
   'learning_rate': hp.loguniform('learning_rate', np.log(0.01), np.log(0.2)),
   'subsample_for_bin': hp.quniform('subsample_for_bin', 20000, 300000, 20000),
   'min_child_samples': hp.quniform('min_child_samples', 20, 500, 5),
   'reg_alpha': hp.uniform('reg_alpha', 0.0, 1.0),
   'reg_lambda': hp.uniform('reg_lambda', 0.0, 1.0),
   'colsample_bytree': hp.uniform('colsample_by_tree', 0.6, 1.0)
}


這里我們使用了許多不同的域分發(fā)類型:

  • choice:類別變量

  • quniform:離散均勻(整數(shù)間隔均勻)

  • uniform:連續(xù)均勻(間隔為一個浮點(diǎn)數(shù))

  • loguniform:連續(xù)對數(shù)均勻(對數(shù)下均勻分布)

# boosting type domain
boosting_type = {'boosting_type': hp.choice('boosting_type',
                                           [{'boosting_type': 'gbdt',
                                                 'subsample': hp.uniform('subsample', 0.5, 1)},
                                            {'boosting_type': 'dart',
                                                 'subsample': hp.uniform('subsample', 0.5, 1)},
                                            {'boosting_type': 'goss',
                                                 'subsample': 1.0}])}


這里我們使用條件域,這意味著一個超參數(shù)的值取決于另一個超參數(shù)的值。 對于提升類型“goss”,gbm不能使用子采樣(僅選擇訓(xùn)練觀察的子樣本部分以在每次迭代時使用)。 因此,如果提升類型是“goss”,則子采樣率設(shè)置為1.0(無子采樣),否則為0.5-1.0。 這是使用嵌套域?qū)崿F(xiàn)的。


定義域空間之后,我們可以從中采樣查看樣本。

# Sample from the full space
example = sample(space)

# Dictionary get method with default
subsample = example['boosting_type'].get('subsample', 1.0)

# Assign top-level keys
example['boosting_type'] = example['boosting_type']['boosting_type']
example['subsample'] = subsample


example
{'boosting_type': 'gbdt',
'class_weight': 'balanced',
'colsample_bytree': 0.8111305579351727,
'learning_rate': 0.16186471096789776,
'min_child_samples': 470.0,
'num_leaves': 88.0,
'reg_alpha': 0.6338327001528129,
'reg_lambda': 0.8554826167886239,
'subsample_for_bin': 280000.0,
'subsample': 0.6318665053932255}


優(yōu)化算法

雖然這是貝葉斯優(yōu)化中概念上最難的部分,但在Hyperopt中創(chuàng)建優(yōu)化算法只需一行。 要使用Tree Parzen Estimator,代碼為:

from hyperopt import tpe
# Algorithm
tpe_algorithm = tpe.suggest


在優(yōu)化時,TPE算法根據(jù)過去的結(jié)果構(gòu)建概率模型,并通過最大化預(yù)期的改進(jìn)來決定下一組超參數(shù)以在目標(biāo)函數(shù)中進(jìn)行評估。


結(jié)果歷史

跟蹤結(jié)果并不是絕對必要的,因為Hyperopt將在內(nèi)部為算法執(zhí)行此操作。 但是,如果我們想知道幕后發(fā)生了什么,我們可以使用Trials對象來存儲基本的訓(xùn)練信息,還可以使用從目標(biāo)函數(shù)返回的字典(包括損失和范圍)。 制創(chuàng)建Trials對象也只要一行代碼:

from hyperopt import Trials
# Trials object to track progress
bayes_trials = Trials()


為了監(jiān)控訓(xùn)練運(yùn)行進(jìn)度,可以將結(jié)果歷史寫入csv文件,防止程序意外中斷導(dǎo)致評估結(jié)果消失。

import csv

# File to save first results
out_file = 'gbm_trials.csv'
of_connection = open(out_file, 'w')
writer = csv.writer(of_connection)

# Write the headers to the file
writer.writerow(['loss', 'params', 'iteration', 'estimators', 'train_time'])
of_connection.close()


然后在目標(biāo)函數(shù)中我們可以在每次迭代時添加行寫入csv:

# Write to the csv file ('a' means append)
of_connection = open(out_file, 'a')
writer = csv.writer(of_connection)
writer.writerow([loss, params, iteration, n_estimators, run_time])
of_connection.close()


優(yōu)化


一旦我們定義好了上述部分,就可以用fmin運(yùn)行優(yōu)化:

from hyperopt import fmin

MAX_EVALS = 500

# Optimize
best = fmin(fn = objective, space = space, algo = tpe.suggest,
           max_evals = MAX_EVALS, trials = bayes_trials)


在每次迭代時,算法從代理函數(shù)中選擇新的超參數(shù)值,該代理函數(shù)基于先前的結(jié)果構(gòu)建并在目標(biāo)函數(shù)中評估這些值。 這繼續(xù)用于目標(biāo)函數(shù)的MAX_EVALS評估,其中代理函數(shù)隨每個新結(jié)果不斷更新。


結(jié)果


從fmin返回的最佳對象包含在目標(biāo)函數(shù)上產(chǎn)生最低損失的超參數(shù):

{'boosting_type': 'gbdt',
  'class_weight': 'balanced',
  'colsample_bytree': 0.7125187075392453,
  'learning_rate': 0.022592570862044956,
  'min_child_samples': 250,
  'num_leaves': 49,
  'reg_alpha': 0.2035211643104735,
  'reg_lambda': 0.6455131715928091,
  'subsample': 0.983566228071919,
  'subsample_for_bin': 200000}


一旦我們有了這些超參數(shù),我們就可以使用它們來訓(xùn)練完整訓(xùn)練數(shù)據(jù)的模型,然后評估測試數(shù)據(jù)。 最終結(jié)果如下:

The best model scores 0.72506 AUC ROC on the test set.
The best cross validation score was 0.77101 AUC ROC.
This was achieved after 413 search iterations.


作為參考,500次隨機(jī)搜索迭代返回了一個模型,該模型在測試集上評分為0.7232 ROC AUC,在交叉驗證中評分為0.76850。沒有優(yōu)化的默認(rèn)模型在測試集上評分為0.7143 ROC AUC。


在查看結(jié)果時,請記住一些重要的注意事項:

  1. 最佳超參數(shù)是那些在交叉驗證方面表現(xiàn)最佳的參數(shù),而不一定是那些在測試數(shù)據(jù)上做得最好的參數(shù)。當(dāng)我們使用交叉驗證時,我們希望這些結(jié)果可以推廣到測試數(shù)據(jù)。

  2. 即使使用10倍交叉驗證,超參數(shù)調(diào)整也會過度擬合訓(xùn)練數(shù)據(jù)。交叉驗證的最佳分?jǐn)?shù)顯著高于測試數(shù)據(jù)。

  3. 隨機(jī)搜索可以通過純粹的運(yùn)氣返回更好的超參數(shù)(重新運(yùn)行筆記本可以改變結(jié)果)。貝葉斯優(yōu)化不能保證找到更好的超參數(shù),并且可能陷入目標(biāo)函數(shù)的局部最小值。


另一個重點(diǎn)是超參數(shù)優(yōu)化的效果將隨數(shù)據(jù)集的不同而不同。相對較小的數(shù)據(jù)集(訓(xùn)練集大小為6000),調(diào)整超參數(shù),最終得到的模型的提升并不大,但數(shù)據(jù)集更大時,效果會很明顯。


因此,通過貝葉斯概率來優(yōu)化超參數(shù),我們可以:

  • 在測試集上得到更好的性能

  • 調(diào)整超參數(shù)的迭代次數(shù)減少


可視化結(jié)果


繪制結(jié)果圖表是一種直觀的方式,可以了解超參數(shù)搜索過程中發(fā)生的情況。此外,通過將貝葉斯優(yōu)化與隨機(jī)搜索進(jìn)行比較,可以看出方法的不同之處。


首先,我們可以制作隨機(jī)搜索和貝葉斯優(yōu)化中采樣的learning_rate的核密度估計圖。作為參考,我們還可以顯示采樣分布。垂直虛線表示學(xué)習(xí)率的最佳值(根據(jù)交叉驗證)。



我們將學(xué)習(xí)率定義為0.005到0.2之間的對數(shù)正態(tài),貝葉斯優(yōu)化結(jié)果看起來與采樣分布類似。 這告訴我們,我們定義的分布看起來適合于任務(wù),盡管最佳值比我們放置最大概率的值略高。 這可用于告訴域進(jìn)一步搜索。


另一個超參數(shù)是增強(qiáng)類型,在隨機(jī)搜索和貝葉斯優(yōu)化期間評估每種類型的條形圖。 由于隨機(jī)搜索不關(guān)注過去的結(jié)果,我們預(yù)計每種增強(qiáng)類型的使用次數(shù)大致相同。



根據(jù)貝葉斯算法,gdbt提升模型比dart或goss更有前途。 同樣,這可以幫助進(jìn)一步搜索,貝葉斯方法或網(wǎng)格搜索。 如果我們想要進(jìn)行更明智的網(wǎng)格搜索,我們可以使用這些結(jié)果來定義圍繞超參數(shù)最有希望的值的較小網(wǎng)格。


由于我們有它們,讓我們看看參考分布,隨機(jī)搜索和貝葉斯優(yōu)化中的所有數(shù)字超參數(shù)。 垂直線再次表示每次搜索的超參數(shù)的最佳值:








在大多數(shù)情況下(subsampleforbin除外),貝葉斯優(yōu)化搜索傾向于在超參數(shù)值附近集中(放置更多概率),從而產(chǎn)生交叉驗證中的最低損失。這顯示了使用貝葉斯方法進(jìn)行超參數(shù)調(diào)整的基本思想:花費(fèi)更多時間來評估有希望的超參數(shù)值。


此處還有一些有趣的結(jié)果可能會幫助我們在將來定義要搜索的域空間時。僅舉一個例子,看起來regalpha和reglambda應(yīng)該相互補(bǔ)充:如果一個是高(接近1.0),另一個應(yīng)該更低。不能保證這會解決問題,但通過研究結(jié)果,我們可以獲得可能適用于未來機(jī)器學(xué)習(xí)問題的見解!


搜索的演變


隨著優(yōu)化的進(jìn)展,我們期望貝葉斯方法關(guān)注超參數(shù)的更有希望的值:那些在交叉驗證中產(chǎn)生最低誤差的值。我們可以繪制超參數(shù)與迭代的值,以查看是否存在明顯的趨勢。



黑星表示最佳值。 colsamplebytree和learningrate會隨著時間的推移而減少,這可能會指導(dǎo)我們未來的搜索。



最后,如果貝葉斯優(yōu)化工作正常,我們預(yù)計平均驗證分?jǐn)?shù)會隨著時間的推移而增加(相反,損失減少):



來自貝葉斯超參數(shù)優(yōu)化的驗證集上的分?jǐn)?shù)隨著時間的推移而增加,表明該方法正在嘗試“更好”的超參數(shù)值(應(yīng)該注意,僅根據(jù)驗證集上的表現(xiàn)更好)。隨機(jī)搜索沒有顯示迭代的改進(jìn)。


繼續(xù)搜索


如果我們對模型的性能不滿意,我們可以繼續(xù)使用Hyperopt進(jìn)行搜索。我們只需要傳入相同的試驗對象,算法將繼續(xù)搜索。


隨著算法的進(jìn)展,它會進(jìn)行更多的挖掘 - 挑選過去表現(xiàn)良好的價值 , 而不是探索 - 挑選新價值。因此,開始完全不同的搜索可能是一個好主意,而不是從搜索停止的地方繼續(xù)開始。如果來自第一次搜索的最佳超參數(shù)確實是“最優(yōu)的”,我們希望后續(xù)搜索專注于相同的值。


經(jīng)過另外500次訓(xùn)練后,最終模型在測試集上得分為0.72736 ROC AUC。 (我們實際上不應(yīng)該評估測試集上的第一個模型,而只依賴于驗證分?jǐn)?shù)。理想情況下,測試集應(yīng)該只使用一次,以便在部署到新數(shù)據(jù)時獲得算法性能的度量)。同樣,由于數(shù)據(jù)集的小尺寸,這個問題可能導(dǎo)致進(jìn)一步超參數(shù)優(yōu)化的收益遞減,并且最終會出現(xiàn)驗證錯誤的平臺(由于隱藏變量導(dǎo)致數(shù)據(jù)集上任何模型的性能存在固有限制未測量和噪聲數(shù)據(jù),稱為貝葉斯誤差。


結(jié)論


可以使用貝葉斯優(yōu)化來完成機(jī)器學(xué)習(xí)模型的超參數(shù)自動調(diào)整。與隨機(jī)或網(wǎng)格搜索相比,貝葉斯優(yōu)化對目標(biāo)函數(shù)的評估較少,測試集上的更好的泛化性能。


在本文中,我們使用Hyperopt逐步完成了Python中的貝葉斯超參數(shù)優(yōu)化。除了網(wǎng)格和隨機(jī)搜索之外,我們還能夠提高梯度增強(qiáng)機(jī)的測試集性能,盡管我們需要謹(jǐn)慎對待訓(xùn)練數(shù)據(jù)的過度擬合。此外,我們通過可視化結(jié)果表看到隨機(jī)搜索與貝葉斯優(yōu)化的不同之處,這些圖表顯示貝葉斯方法對超參數(shù)值的概率更大,導(dǎo)致交叉驗證損失更低。


使用優(yōu)化問題的四個部分,我們可以使用Hyperopt來解決各種各樣的問題。貝葉斯優(yōu)化的基本部分也適用于Python中實現(xiàn)不同算法的許多庫。從手動切換到隨機(jī)或網(wǎng)格搜索只是一小步,但要將機(jī)器學(xué)習(xí)提升到新的水平,需要一些自動形式的超參數(shù)調(diào)整。貝葉斯優(yōu)化是一種易于在Python中使用的方法,并且可以比隨機(jī)搜索返回更好的結(jié)果。


原文鏈接:

https:///automated-machine-learning-hyperparameter-tuning-in-python-dfda59b72f8a

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多