戰(zhàn):用 SQL 訓(xùn)練 DNNClassifier 完成鳶尾花(Iris)三分類與預(yù)測)
人工智能機(jī)器學(xué)習(xí)后端編譯器【免費(fèi)下載鏈接】sqlflowBrings SQL and AI together.項(xiàng)目地址https://gitcode.com/gh_mirrors/sq/sqlflow點(diǎn)擊查看免費(fèi)下載本文以 SQLFlow 官方教程 doc/tutorial/iris-dnn.md 為骨架結(jié)合倉庫源碼展開介紹如何用一條帶擴(kuò)展語法的 SQL 語句在 Iris 數(shù)據(jù)集上訓(xùn)練 DNN 分類模型、手動(dòng)與自動(dòng)調(diào)優(yōu)并完成預(yù)測。讀完本文你將掌握 SQLFlow 訓(xùn)練語句的完整寫法TO TRAIN/WITH/COLUMN/LABEL/INTO、超參數(shù)調(diào)優(yōu)思路以及從數(shù)據(jù)表到模型的端到端實(shí)戰(zhàn)能力。SQLFlow 的核心主張是讓 SQL 和 AI 走到一起B(yǎng)rings SQL and AI together用戶在熟悉的 SQL 語句后追加模型訓(xùn)練子句SQLFlow 就會(huì)把整條語句翻譯成等價(jià)的 Python 程序去執(zhí)行無需手寫訓(xùn)練代碼。Iris鳶尾花數(shù)據(jù)集因?yàn)橐?guī)模小、維度低、類別清晰一直是驗(yàn)證這一能力最典型的入門案例。本教程將用它走完訓(xùn)練 → 調(diào)優(yōu) → 自動(dòng)調(diào)優(yōu) → 預(yù)測的完整鏈路。數(shù)據(jù)集Iris 的表結(jié)構(gòu)、準(zhǔn)備方式與數(shù)據(jù)預(yù)覽Iris 數(shù)據(jù)集包含四個(gè)特征表征鳶尾花的植物學(xué)形態(tài)和一個(gè)標(biāo)簽表示鳶尾花的亞種。四個(gè)特征均為浮點(diǎn)數(shù)標(biāo)簽為整數(shù)取值為 0、1、2分別對(duì)應(yīng)山鳶尾Iris setosa、雜色鳶尾Iris versicolor和維吉尼亞鳶尾Iris virginica。列名數(shù)據(jù)類型描述sepal_lengthfloat花萼長度cm特征sepal_widthfloat花萼寬度cm特征petal_lengthfloat花瓣長度cm特征petal_widthfloat花瓣寬度cm特征classint亞種類別0, 1, 2標(biāo)簽在 SQLFlow 官方鏡像中Iris 數(shù)據(jù)集被預(yù)先裝載到iris.train和iris.test兩張表中分別作為訓(xùn)練集和測試集。你可以在倉庫的 doc/datasets/popularize_iris.sql 中看到完整的建表與數(shù)據(jù)裝載 SQL它創(chuàng)建了iris.train約 120 行樣本與iris.test10 行樣本兩張表字段類型與上表完全一致。在 Jupyter Notebook 中%%sqlflow是 SQLFlow 的 magic 指令。運(yùn)行以下標(biāo)準(zhǔn) SQL 即可快速查看數(shù)據(jù)結(jié)構(gòu)與樣例數(shù)據(jù)%%sqlflow describe iris.train;%%sqlflow select * from iris.train limit 5;SELECT子句指定了訓(xùn)練數(shù)據(jù)來源它完全遵循 ANSI SQL 標(biāo)準(zhǔn)意味著你既可以直接SELECT * FROM iris.train也可以像SELECT * FROM iris.train WHERE class2這樣用WHERE過濾樣本——這一點(diǎn)在倉庫的端到端測試 go/cmd/sqlflowserver/e2e_common_cases.go 中被反復(fù)驗(yàn)證。訓(xùn)練編寫第一條 SQLFlow 訓(xùn)練語句訓(xùn)練語句的整體結(jié)構(gòu)SQLFlow 的擴(kuò)展語法把訓(xùn)練過程嵌入標(biāo)準(zhǔn) SQL 中。完整的訓(xùn)練語句由 select、train、column、label 和 into 五類子句組成語法定義見 doc/language_guide.mdSELECT select_expr [, select_expr ...] FROM table_references [WHERE where_condition] [LIMIT row_count] TO TRAIN model_identifier [WITH model_attr_expr [, model_attr_expr ...] [, train_attr_expr ...]] COLUMN column_expr [, column_expr ...] [LABEL label_expr] INTO table_references;本教程要訓(xùn)練的是一個(gè)三分類的DNNClassifier包含兩個(gè)隱藏層、每層 10 個(gè)節(jié)點(diǎn)。通過訓(xùn)練子句可以很容易地指定模型結(jié)構(gòu)TO TRAIN DNNClassifier WITH model.n_classes 3, model.hidden_units [10, 10]TO TRAIN DNNClassifier指定模型類型。這里的DNNClassifier是 TensorFlow 預(yù)置的 Estimator 模型SQLFlow 在代碼生成時(shí)會(huì)將它直接映射為tensorflow.estimator.DNNClassifier見 go/codegen/tensorflow/template_train.go 中from tensorflow.estimator import (DNNClassifier, ...)的導(dǎo)入邏輯。model.n_classes 3類別總數(shù)Iris 是三分類問題。model.hidden_units [10, 10]每個(gè)隱藏層的神經(jīng)元個(gè)數(shù)[10, 10]表示 2 個(gè)隱藏層、每層 10 個(gè)神經(jīng)元。用 COLUMN 與 LABEL 顯式指定特征和標(biāo)簽SQLFlow 支持兩種特征指定方式顯式指定用COLUMN子句列出特征列、LABEL子句指定標(biāo)簽列COLUMN sepal_length, sepal_width, petal_length, petal_width LABEL class自動(dòng)推斷省略COLUMN子句讓 SQLFlow 根據(jù)數(shù)據(jù)庫字段類型自動(dòng)推斷合適的特征列。根據(jù) doc/language_guide.md如果字段類型是 float就會(huì)被自動(dòng)作為數(shù)值型特征列使用如果字段是 CSV 格式的整數(shù)數(shù)組如1,39,82,29則會(huì)被當(dāng)作 embedding 特征列處理。本教程采用顯式方式語義更清晰。值得一提的是SQLFlow 的擴(kuò)展語法中字段名可能與關(guān)鍵字沖突。例如若表中有名為label的字段需要用雙引號(hào)包裹LABEL label以規(guī)避解析錯(cuò)誤。INTO 子句把模型保存到數(shù)據(jù)庫表INTO sqlflow_models.my_dnn_model指定模型保存位置。訓(xùn)練結(jié)束后訓(xùn)練好的 DNN 模型會(huì)被存入sqlflow_models庫中的my_dnn_model表——模型以表的形式落庫這也是 SQLFlow模型即表設(shè)計(jì)思路的體現(xiàn)后續(xù)預(yù)測時(shí)可以直接USING這個(gè)表引用模型。完整訓(xùn)練語句把以上片段拼起來就是第一條完整的 SQLFlow 訓(xùn)練語句%%sqlflow SELECT * FROM iris.train TO TRAIN DNNClassifier WITH model.n_classes 3, model.hidden_units [10, 10], train.epoch 10 COLUMN sepal_length, sepal_width, petal_length, petal_width LABEL class INTO sqlflow_models.my_dnn_model;說明第一行的%%sqlflow是 Jupyter Notebook 的 magic 指令如果使用 SQLFlow 命令行或其他客戶端則不需要這一行。參數(shù)前綴的含義model. / train. / validation. / optimizer.上述WITH子句中的參數(shù)并非平鋪而是按前綴分組的。從 go/codegen/tensorflow/codegen.go 的CategorizeAttributes函數(shù)可以看到SQLFlow 會(huì)把參數(shù)劃分為三類model.*模型結(jié)構(gòu)參數(shù)如model.hidden_units、model.n_classes最終傳入模型的構(gòu)造函數(shù)train.*訓(xùn)練過程參數(shù)如train.epoch、train.batch_size、train.max_stepsvalidation.*驗(yàn)證參數(shù)如validation.select指定驗(yàn)證集、validation.metrics、validation.steps。此外還有optimizer.*如optimizer.learning_rate這類優(yōu)化器參數(shù)它們?cè)赾onstructOptimizers函數(shù)中被收集并拼裝成 Python 優(yōu)化器對(duì)象。下面是常用訓(xùn)練參數(shù)及其默認(rèn)值與含義依據(jù) go/codegen/tensorflow/codegen.go 中commonAttributes的定義參數(shù)默認(rèn)值說明train.batch_size1訓(xùn)練 batch size范圍 [1, ∞)train.epoch1訓(xùn)練輪數(shù)范圍 [1, ∞)train.verbose0訓(xùn)練日志級(jí)別可取 0、1、2train.max_steps0最大訓(xùn)練步數(shù)0 表示不限制train.save_checkpoints_steps100保存 checkpoint 的間隔步數(shù)train.log_every_n_iter10每隔多少輪迭代打印一次日志validation.select驗(yàn)證集 SQL例如SELECT * FROM iris.testvalidation.metricsAccuracy訓(xùn)練與評(píng)估時(shí)使用的指標(biāo)如Accuracy,AUCvalidation.steps1驗(yàn)證步數(shù)訓(xùn)練輸出與首次效果評(píng)估上述訓(xùn)練語句通常幾分鐘內(nèi)可以跑完SQLFlow 的典型輸出如下{accuracy: 0.4, average_loss: 1.0920922, loss: 1.0920922, global_step: 1100}如你所見這條訓(xùn)練語句的平均 loss 并不理想——對(duì) Iris 數(shù)據(jù)集而言較理想的平均 loss 一般應(yīng)小于 0.4。這引出了機(jī)器學(xué)習(xí)工作流中最關(guān)鍵也最耗時(shí)的一環(huán)模型調(diào)優(yōu)。模型調(diào)優(yōu)從網(wǎng)絡(luò)寬度到學(xué)習(xí)率在機(jī)器學(xué)習(xí)中超參數(shù)hyperparameter是指學(xué)習(xí)過程開始前就可以設(shè)定的參數(shù)與之相對(duì)其他參數(shù)如網(wǎng)絡(luò)權(quán)重是在訓(xùn)練過程中學(xué)到的。根據(jù)萬能近似理論Universal approximation theoremDNNClassifier這類多層前饋網(wǎng)絡(luò)只要具備足夠強(qiáng)的結(jié)構(gòu)就有潛力逼近任意函數(shù)。因此第一個(gè)優(yōu)化方向就是增強(qiáng)網(wǎng)絡(luò)結(jié)構(gòu)。第一輪調(diào)優(yōu)增大 hidden_units前饋網(wǎng)絡(luò)的寬度對(duì)擬合能力影響很大。把每個(gè)隱藏層的節(jié)點(diǎn)數(shù)從 10 提升到 100%%sqlflow SELECT * FROM iris.train TO TRAIN DNNClassifier WITH model.n_classes 3, model.hidden_units [100, 100], train.epoch 10 COLUMN sepal_length, sepal_width, petal_length, petal_width LABEL class INTO sqlflow_models.my_dnn_model;運(yùn)行后 loss 顯著下降縮小了近 50%{accuracy: 0.72, average_loss: 0.5695601, loss: 0.5695601, global_step: 1100}不過 DNN 的表達(dá)能力極高對(duì) Iris 這樣的小數(shù)據(jù)集而言還有不少改進(jìn)空間。第二輪調(diào)優(yōu)調(diào)大學(xué)習(xí)率優(yōu)化器及其學(xué)習(xí)率可能是 DNN 中最為關(guān)鍵的超參數(shù)。DNNClassifier默認(rèn)使用 AdaGrad 優(yōu)化器默認(rèn)學(xué)習(xí)率為 0.001。這一默認(rèn)值在 SQLFlow 的代碼生成邏輯中也有對(duì)應(yīng)實(shí)現(xiàn)在 go/codegen/tensorflow/codegen.go 的setDefaultOptimizer函數(shù)中DNN 模型的默認(rèn)優(yōu)化器被硬編碼為Adagrad而在 Keras 運(yùn)行時(shí) python/runtime/tensorflow/train_keras.py 的keras_compile中當(dāng)用戶未在WITH子句指定優(yōu)化器時(shí)默認(rèn)使用tf.keras.optimizers.Adagrad(lr0.001)。理論上在神經(jīng)元不死亡dying neuron problem的前提下AdaGrad 的學(xué)習(xí)率可以盡量調(diào)大實(shí)踐中略微調(diào)大 AdaGrad 的學(xué)習(xí)率往往能帶來效果提升。把學(xué)習(xí)率調(diào)到默認(rèn)值的 10 倍%%sqlflow SELECT * FROM iris.train TO TRAIN DNNClassifier WITH model.n_classes 3, model.hidden_units [100, 100], optimizer.learning_rate0.1, train.epoch 10 COLUMN sepal_length, sepal_width, petal_length, petal_width LABEL class INTO sqlflow_models.my_dnn_model;結(jié)果改善明顯{accuracy: 0.98, average_loss: 0.10286382, loss: 0.10286382, global_step: 1100}這里optimizer.learning_rate0.1的寫法值得展開說明SQLFlow 會(huì)把optimizer.*前綴的參數(shù)收集起來拼裝成 Python 優(yōu)化器對(duì)象的構(gòu)造代碼。在 go/codegen/tensorflow/codegen.go 的constructOptimizers中optimizer.learning_rate會(huì)被轉(zhuǎn)換成Adagrad(learning_rate0.1)這樣的 Python 代碼再通過eval生成優(yōu)化器實(shí)例傳入模型見 go/codegen/tensorflow/template_train.go 中model_params_constructed[optimizer_arg] eval(...)的調(diào)用。實(shí)際上調(diào)參在機(jī)器學(xué)習(xí)工作中的重要性非常高通常會(huì)占據(jù)整條鏈路中最多的工時(shí)。如果你覺得手動(dòng)調(diào)參枯燥費(fèi)時(shí)AutoML 技術(shù)可以作為一個(gè)替代方案。自動(dòng)調(diào)優(yōu)用 AutoClassifier 替代手動(dòng)調(diào)參SQLFlow 通過特定 Estimator 提供了基于神經(jīng)架構(gòu)搜索NASNeural Architecture Search的自動(dòng)調(diào)優(yōu)能力。只需把DNNClassifier換成sqlflow_models.AutoClassifier就不需要再手動(dòng)指定網(wǎng)絡(luò)結(jié)構(gòu)——hidden_units會(huì)在WITH子句中省略因?yàn)锳utoClassifier會(huì)自動(dòng)搜索合適的網(wǎng)絡(luò)架構(gòu)而默認(rèn)學(xué)習(xí)率也能應(yīng)付大部分情況。%%sqlflow SELECT * FROM iris.train TO TRAIN sqlflow_models.AutoClassifier WITH model.n_classes 3, train.epoch 10 COLUMN sepal_length, sepal_width, petal_length, petal_width LABEL class INTO sqlflow_models.my_dnn_model;由于AutoClassifier需要搜索最合適的網(wǎng)絡(luò)架構(gòu)運(yùn)行時(shí)間會(huì)比之前的語句更久。運(yùn)行結(jié)束后輸出類似{accuracy: 0.98, average_loss: 0.08678584, loss: 0.08678584, global_step: 1000}這個(gè)結(jié)果看起來與手動(dòng)調(diào)優(yōu)的結(jié)果非常接近但因?yàn)镈NNClassifier和AutoClassifier的訓(xùn)練過程都帶有隨機(jī)性你自己運(yùn)行得到的結(jié)果可能略有差異平均 loss 可能稍大或稍小。從源碼可以印證AutoClassifier在 SQLFlow 中的真實(shí)地位go/modelzooserver/add_default_model_defs.go 將sqlflow_models.AutoClassifier列為官方模型倉庫中的默認(rèn)模型定義之一go/cmd/sqlflowserver/e2e_common_cases.go 的端到端測試用例中有專門針對(duì)它的訓(xùn)練與解釋驗(yàn)證TO TRAIN sqlflow_models.AutoClassifier WITH model.n_classes 3訓(xùn)練后還能用TO EXPLAIN sqlflow_models.my_adanet_model對(duì)模型做可解釋性分析。SQLFlow 項(xiàng)目組計(jì)劃在未來支持更多的 NAS 模型同時(shí)也計(jì)劃支持自動(dòng)超參搜索HPO即 automatic hyperparameter tuning等其他 AutoML 技術(shù)。預(yù)測一行 SQL 完成模型推理SQLFlow 開箱即用地支持預(yù)測。和訓(xùn)練語句一樣用標(biāo)準(zhǔn) SQL 語句SELECT * FROM iris.test指定預(yù)測數(shù)據(jù)。如果想用之前訓(xùn)練并存放在sqlflow_models.my_dnn_model的模型預(yù)測iris.test中的數(shù)據(jù)并把預(yù)測結(jié)果寫入iris.predict表的class列完整的預(yù)測語句如下%%sqlflow SELECT * FROM iris.test TO PREDICT iris.predict.class USING sqlflow_models.my_dnn_model;這條語句的語義拆解SELECT * FROM iris.test指定預(yù)測數(shù)據(jù)TO PREDICT iris.predict.class指定結(jié)果寫入目標(biāo)表iris.predict的目標(biāo)列classUSING sqlflow_models.my_dnn_model指定使用訓(xùn)練階段保存的模型。一個(gè)必須遵守的約束TO PREDICT前的SELECT語句產(chǎn)生的數(shù)據(jù) schema 必須與TO TRAIN前的SELECT一致這樣才能保證預(yù)測數(shù)據(jù)的特征與訓(xùn)練時(shí)的特征完全對(duì)應(yīng)這一要求同樣適用于TO EXPLAIN見 doc/language_guide.md。從底層實(shí)現(xiàn)看python/runtime/tensorflow/predict.py 的pred函數(shù)預(yù)測階段 SQLFlow 會(huì)先根據(jù)訓(xùn)練語句恢復(fù)模型結(jié)構(gòu)與特征列定義加載已保存的模型權(quán)重然后以 batch_size1 逐行推理將結(jié)果寫回目標(biāo)表。對(duì)于分類模型取各類別概率中最大者argmax作為最終類別輸出回歸模型則直接輸出預(yù)測值。預(yù)測語句運(yùn)行結(jié)束后可以用標(biāo)準(zhǔn) SQL 查看預(yù)測結(jié)果%%sqlflow SELECT * FROM iris.predict LIMIT 5;延伸閱讀想要全面了解訓(xùn)練、預(yù)測、解釋語句的完整語法定義可閱讀 doc/language_guide.md想了解 SQLFlow 支持的所有模型及其可配置參數(shù)如model.batch_norm、model.dropout、model.optimizer等可查閱 doc/sqlflow.org_cn/models.md想親手在本地重現(xiàn)本教程的數(shù)據(jù)集可直接執(zhí)行 doc/datasets/popularize_iris.sql 完成建表與數(shù)據(jù)裝載想在 MySQL 上運(yùn)行 SQLFlow 并復(fù)現(xiàn)本教程的訓(xùn)練與預(yù)測可參考 doc/run_with_mysql.md 與 doc/quick_start.md若想深入了解 SQLFlow 如何把上述 SQL 翻譯成 Python 程序可從 go/codegen/tensorflow/codegen.go 與 go/codegen/tensorflow/template_train.go 入手。以上就是用 SQLFlow 完成 Iris 分類任務(wù)的完整流程從建表裝載數(shù)據(jù)到編寫TO TRAIN訓(xùn)練語句再到通過hidden_units與optimizer.learning_rate手動(dòng)調(diào)優(yōu)、用AutoClassifier自動(dòng)調(diào)優(yōu)最后用TO PREDICT完成推理。整個(gè)過程不需要手寫任何 Python 訓(xùn)練代碼這正是 SQLFlow 把 SQL 和 AI 結(jié)合在一起的直接體現(xiàn)。贊分享人工智能機(jī)器學(xué)習(xí)后端編譯器【免費(fèi)下載鏈接】sqlflowBrings SQL and AI together.項(xiàng)目地址https://gitcode.com/gh_mirrors/sq/sqlflow點(diǎn)擊查看免費(fèi)下載相關(guān)推薦TensorFlow 1.x 預(yù)置 Estimator 實(shí)戰(zhàn)用 DNNClassifier 完成鳶尾花三分類TensorFlow 1.x 預(yù)置 Estimator 實(shí)戰(zhàn)用 DNNClassifier 完成鳶尾花三分類 本指南以 TensorFlow 1.x本倉庫文檔開發(fā)工具教程SQLFlow 實(shí)戰(zhàn)用 Titanic 數(shù)據(jù)集訓(xùn)練 DNNClassifier 并預(yù)測乘客生還SQLFlow 實(shí)戰(zhàn)用 Titanic 數(shù)據(jù)集訓(xùn)練 DNNClassifier 并預(yù)測乘客生還 本篇技術(shù)指南以 SQLFlow 倉庫中的 Titanic DN人工智能機(jī)器學(xué)習(xí)后端編譯器SQLFlow 信用卡欺詐檢測實(shí)戰(zhàn)用 SQL 完成 DNN 分類的完整流程訓(xùn)練 · 預(yù)測 · 解釋SQLFlow 信用卡欺詐檢測實(shí)戰(zhàn)用 SQL 完成 DNN 分類的完整流程訓(xùn)練 · 預(yù)測 · 解釋 本篇教程以 Kaggle 信用卡欺詐數(shù)據(jù)集為例演示如人工智能機(jī)器學(xué)習(xí)后端編譯器上一篇如何3步配置Citra模擬器從模糊到高清的游戲體驗(yàn)升級(jí)指南下一篇GHelper技術(shù)解析華碩筆記本性能調(diào)優(yōu)的輕量級(jí)控制解決方案創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考