中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

編程進(jìn)階之路:用簡單的面向?qū)ο缶幊烫嵘疃葘W(xué)習(xí)原型

2019-07-29    來源:raincent

容器云強(qiáng)勢上線!快速搭建集群,上萬Linux鏡像隨意使用

不會(huì)寫一手漂亮代碼的數(shù)據(jù)科學(xué)家不是好工程師。將面向?qū)ο缶幊讨心切┖唵蔚母拍?如函數(shù)化和類繼承),應(yīng)用到深度學(xué)習(xí)原型代碼中,可以獲得巨大的收益。

 

 

簡介

本文的目標(biāo)讀者是像我這樣沒有軟件工程師背景的數(shù)據(jù)科學(xué)家和機(jī)器學(xué)習(xí)(ML)從業(yè)者,而非經(jīng)驗(yàn)豐富的軟件工程師。

由于 Python 語言對(duì) ML 和數(shù)據(jù)科學(xué)社區(qū)來說實(shí)在是太棒了,我們通常在工作中使用 Python。它在現(xiàn)代的數(shù)據(jù)驅(qū)動(dòng)分析和人工智能(AI)應(yīng)用領(lǐng)域中一路高歌猛進(jìn),成為增長最快的主要語言。

然而,Python 同樣被用于簡單的腳本開發(fā),比如辦公自動(dòng)化、假設(shè)檢驗(yàn)、創(chuàng)建用于進(jìn)行頭腦風(fēng)暴的交互式圖表,控制實(shí)驗(yàn)儀器等等。

但事實(shí)是,用 Python 開發(fā)軟件和用 Python 寫腳本并非完全相同——至少在數(shù)據(jù)科學(xué)領(lǐng)域中是如此。

腳本(主要)是寫給自己用的代碼,而軟件則是和隊(duì)友們一起寫給別人用的代碼集合。

不得不承認(rèn)的是,大多數(shù)沒有軟件工程師背景的數(shù)據(jù)科學(xué)家在編寫 Python 程序?qū)崿F(xiàn) AI/ML 模型或者做統(tǒng)計(jì)分析時(shí),往往是寫代碼給自己用。他們只想快速地直達(dá)隱藏在數(shù)據(jù)里的模式,而沒有深入考慮普通用戶的需求。

他們寫代碼來繪制出信息豐富的、精美的圖表,但卻不會(huì)專門創(chuàng)建一個(gè)相關(guān)的函數(shù),便于以后復(fù)用。

他們會(huì)導(dǎo)入很多標(biāo)準(zhǔn)庫中的方法和類,但是卻不會(huì)通過繼承和添加新的方法來創(chuàng)建自己的子類,以此來擴(kuò)展類的功能。

函數(shù)、繼承、方法、類——這些都是魯棒的面向?qū)ο缶幊?OOP)的核心思想,但是如果你只是想用 Jupyter notebook 來做數(shù)據(jù)分析和繪圖,那么這些概念也不是非用不可。

你可以避免使用 OOP 的那些法則帶來的最初的痛苦,然而你總會(huì)付出代價(jià)的,那就是代碼無法復(fù)用也無法擴(kuò)展。

簡而言之,你的代碼除了你自己以外誰都用不了,到最后你自己也會(huì)忘了當(dāng)初寫這段代碼的邏輯。但可讀性(和由此帶來的可重用性)至關(guān)重要,這是對(duì)你所產(chǎn)出代碼的真實(shí)考驗(yàn),不是針對(duì)自己,而是面向他人。

但最重要的是,為了降低那些年輕而充滿干勁的學(xué)習(xí)者的負(fù)擔(dān),網(wǎng)絡(luò)上數(shù)百門有關(guān)數(shù)據(jù)科學(xué)和 AI/ML 的在線課程或慕課(MOOC)也都沒有強(qiáng)調(diào)這方面的編碼問題。他們是來學(xué)習(xí)炫酷的算法和神經(jīng)網(wǎng)絡(luò)優(yōu)化的,而非 Python 中的 OOP。因此,編碼方面的問題仍然被忽視。

那么,你能為此做些什么?

簡單運(yùn)用 OOP 的原理就可以大幅改善你的深度學(xué)習(xí)(DL)代碼

我有生以來從未做過軟件工程師,因此,當(dāng)我開始探索 ML 和數(shù)據(jù)科學(xué)時(shí),我草草地寫了一大堆的不可重用的代碼。

但我逐漸開始嘗試優(yōu)化代碼,通過簡單地增強(qiáng)代碼風(fēng)格來使代碼對(duì)于其他人更加有用。

而且,我還發(fā)現(xiàn)在有關(guān)數(shù)據(jù)科學(xué)的代碼中開始應(yīng)用 OOP 原則并不難。

只要你站在別人的立場上去思考他人會(huì)怎樣建設(shè)性地接受并采用你的代碼,即使你從未上過軟件工程課程,有些想法也會(huì)自然而然地出現(xiàn)在你的腦海中。

當(dāng)你在做數(shù)據(jù)分析時(shí),如果某一個(gè)代碼塊(完全相同或者略有不同地)出現(xiàn)了不止一次,你能否為其創(chuàng)建一個(gè)函數(shù)進(jìn)行封裝?

當(dāng)你創(chuàng)建了這個(gè)函數(shù),應(yīng)該向其傳遞哪些參數(shù)?有哪些參數(shù)可以是可選參數(shù)?參數(shù)的默認(rèn)值應(yīng)該是多少?

如果在當(dāng)前情況下無法確定需要傳遞多少參數(shù),你使用 Python 中提供的 *args 和 *kwargs 了嗎?

你有沒有為這個(gè)函數(shù)寫一個(gè)「docstring」注釋,來說明函數(shù)實(shí)現(xiàn)的功能、需要的參數(shù)以及使用示例等信息?

當(dāng)你已經(jīng)寫了大量此類實(shí)用函數(shù)后,你是繼續(xù)在同一個(gè) notebook 上工作,還是新開一個(gè) notebook,然后通過調(diào)用「from my_utility_script import func1, func2, func3」導(dǎo)入函數(shù)?(前提是你已經(jīng)根據(jù)之前 Jupyter notebook 的代碼創(chuàng)建了一個(gè)簡單的 Python 腳本文件「my_utility_script」。)

你有沒有把「my_utility_script」腳本放進(jìn)一個(gè)文件夾,然后在該文件夾下創(chuàng)建一個(gè)「__init__.py」文件(哪怕是空文件),以此來創(chuàng)建一個(gè)像 NumPy 或者 Pandas 一樣的可導(dǎo)入的 Python 模塊呢?

你有沒有想過在使用像 NumPy 或 TensorFlow 那樣功能強(qiáng)大的包時(shí),不僅僅是從中導(dǎo)入類和方法,你還可以向其中加入自己的方法來擴(kuò)展它們的功能?

以上這些到底意味著什么呢?接下來我們通過一個(gè)簡單的例子來加以說明——基于「fashion MNIST」數(shù)據(jù)集來實(shí)現(xiàn)一個(gè) DL 圖像分類問題。

DL 分類任務(wù)案例說明

方法

詳細(xì)代碼見我的 Github 代碼倉庫。歡迎讀者將其克隆(fork)到自己的代碼倉庫中進(jìn)行使用和擴(kuò)展。

代碼地址:https://github.com/tirthajyoti/Computer_vision/blob/master/Notebooks/OOP_principle_deep_learning.ipynb

代碼對(duì)于構(gòu)建優(yōu)秀軟件至關(guān)重要,但卻并不適合寫文章分析。你可以閱讀下面的代碼來獲得啟發(fā),而非實(shí)際調(diào)試或者重構(gòu)練習(xí)。

因此,我只選取一部分代碼片段,以此說明我如何編碼實(shí)現(xiàn)前文中詳細(xì)介紹的那些原則。

核心 ML 任務(wù)和更高階的業(yè)務(wù)問題

核心的 ML 任務(wù)很簡單——為 fashion MNIST 數(shù)據(jù)集構(gòu)建一個(gè)深度學(xué)習(xí)分類器,該數(shù)據(jù)集是對(duì)于傳統(tǒng)的著名的 MNIST 手寫數(shù)字?jǐn)?shù)據(jù)集的有趣變體。Fashion MNIST 數(shù)據(jù)集包含 60,000 張像素大小為 28 x 28 的訓(xùn)練圖像,圖像內(nèi)容為與時(shí)尚相關(guān)的物品,比如帽子、鞋子、褲子、T 恤、裙子等等。該數(shù)據(jù)集還包含 10,000 張測試圖像用于驗(yàn)證和測試。

 

 

Fashion MNIST 數(shù)據(jù)集

但是,如果圍繞此核心 ML 任務(wù)存在更高階的優(yōu)化或可視化分析問題,那么模型架構(gòu)的復(fù)雜度會(huì)如何影響達(dá)到目標(biāo)準(zhǔn)確率所需的最小迭代次數(shù)(epoch)呢?

讀者應(yīng)該清楚我們?yōu)槭裁匆獮檫@個(gè)問題煩惱,因?yàn)檫@與整體業(yè)務(wù)優(yōu)化有關(guān)。訓(xùn)練神經(jīng)網(wǎng)絡(luò)不是一個(gè)簡單的計(jì)算問題。因此,研究達(dá)到目標(biāo)性能指標(biāo)必須進(jìn)行的最少的訓(xùn)練工作,以及架構(gòu)選擇對(duì)該性能指標(biāo)的影響,是很有必要的。

在本例中,我們甚至不采用卷積網(wǎng)絡(luò),因?yàn)橐粋(gè)簡單的密集連接的神經(jīng)網(wǎng)絡(luò)就可以達(dá)到相當(dāng)高的準(zhǔn)確率,并且事實(shí)上我們也需要一些次優(yōu)的性能來說明前文提到的高階優(yōu)化問題的要點(diǎn)。

解決方案

那么,我們需要解決兩個(gè)問題——

如何確定達(dá)到目標(biāo)準(zhǔn)確率所需最小的 epoch 數(shù)量?
特定模型架構(gòu)如何影響最小的 epoch 數(shù)或者訓(xùn)練行為?

為了實(shí)現(xiàn)這兩個(gè)目標(biāo),我們將使用以下兩個(gè)簡單的 OOP 原則:

從基類對(duì)象創(chuàng)建出一個(gè)繼承的類;

創(chuàng)建實(shí)用函數(shù),然后在代碼塊中調(diào)用它們,該代碼塊可以給外部用戶進(jìn)行更高階的優(yōu)化和分析。

良好實(shí)踐的代碼片段示例

我們將通過展示下面的一些代碼片段,來說明如何簡單使用 OOP 原則來實(shí)現(xiàn)我們的解決方案。為了便于理解,代碼中添加了相關(guān)的注釋。

首先,我們繼承一個(gè) Keras 類從而創(chuàng)建了我們的子類,在子類中添加了一個(gè)查看訓(xùn)練準(zhǔn)確率并根據(jù)該值作出反應(yīng)的方法。

 

 

這個(gè)簡單的回調(diào)函數(shù)可以動(dòng)態(tài)控制 epoch——當(dāng)準(zhǔn)確率達(dá)到指定閾值后訓(xùn)練自動(dòng)停止。

 

 

我們將 Keras 的模型構(gòu)造代碼封裝在一個(gè)實(shí)用函數(shù)中,從而使得任意層數(shù)架構(gòu)的模型(只要它們是密集連接的)都可以通過簡單的用戶接口傳遞函數(shù)參數(shù)來生成。

 

 

我們甚至可以將編譯和訓(xùn)練代碼封裝在一個(gè)實(shí)用函數(shù)中,從而在更高階的優(yōu)化循環(huán)中方便地使用超參數(shù)。

 

 

接下來,我們將編寫可視化代碼,同樣地,我們通過函數(shù)化實(shí)現(xiàn)該功能。通用繪圖函數(shù)將原始數(shù)據(jù)作為輸入。然而,如果我們有這樣一個(gè)特殊目的——繪制出訓(xùn)練集上準(zhǔn)確率的演化情況并且顯示出其與目標(biāo)準(zhǔn)確率的對(duì)比,那么我們的繪圖函數(shù)只需要將深度學(xué)習(xí)模型作為輸入,然后繪制目標(biāo)圖形。

 

 

典型的結(jié)果如下所示,

 

 

最終緊湊簡單的分析代碼

現(xiàn)在我們可以充分利用之前定義的所有函數(shù)和類,將其組合來實(shí)現(xiàn)更高階的任務(wù)。

因此,最終的代碼將十分緊湊,但它將生成同樣有趣的、各種準(zhǔn)確率閾值和神經(jīng)網(wǎng)絡(luò)架構(gòu)的損失和準(zhǔn)確率隨著 epoch 增多而變化的示意圖,如前文所示。

這將使得用戶可以使用最少的代碼來完成性能指標(biāo)(本例中是準(zhǔn)確率)與神經(jīng)網(wǎng)絡(luò)架構(gòu)的選擇的可視化分析。這是構(gòu)建一個(gè)優(yōu)化的機(jī)器學(xué)習(xí)系統(tǒng)的第一步。

我們生成了一些分析案例,

from itertools import product

accuracy_desired = [0.85,0.9,0.95]num_neurons = [16,32,64,128]

cases = list(product(accuracy_desired,num_neurons))

print("So, the cases we are considering are as follows...\n")for i,c in enumerate(cases): print("Accuracy target {}, number of neurons: {}".format(c[0],c[1])) if (i+1)%4==0 and (i+1)!=len(cases): print("-"*50)

 

 

最終的分析/優(yōu)化代碼簡潔易懂,適用于高級(jí)用戶,他們不需要了解 Keras 模型構(gòu)建或回調(diào)類的復(fù)雜性。

這是 OOP 背后蘊(yùn)含的核心原則——為完成深度學(xué)習(xí)任務(wù)所做的復(fù)雜層次的抽象。

請(qǐng)注意我們將「print_msg = False」傳遞給類實(shí)例的方法。盡管我們在初始檢查/調(diào)試時(shí)確實(shí)需要打印出基本的狀態(tài),但卻需要對(duì)優(yōu)化任務(wù)靜默地進(jìn)行分析。如果我們在定義類時(shí)未設(shè)置該參數(shù),后面就難以停止打印調(diào)試信息了。

for c in cases: # Create a mycallback class with the specific accuracy target callbacks = myCallback(c[0], print_msg=False) # Build a model with a specific number of neurons model = build_model(num_layers=1,architecture=[c[1]]) # Compile and train the model passing on the callback class, # choose suitable batch size and a max epoch limit model = compile_train_model(model, x_train,y_train,callbacks=callbacks, batch_size=32,epochs=30) # Construct a suitable title string for displaying the results properly title = "Loss and accuracy over the epochs for\naccuracy threshold \ {} and number of neurons {}".format(c[0],c[1]) # Use the plotting utility function, pass on the accuracy target, # trained model, and the custom title string plot_loss_acc(model,target_acc=c[0],title=title)

我們展示了一些通過執(zhí)行上述代碼自動(dòng)生成的具有代表性的結(jié)果?梢郧宄吹,如何通過最少的高階代碼來生成可視化分析,從而判斷通過各級(jí)性能指標(biāo)衡量的各種神經(jīng)架構(gòu)的相對(duì)性能。這使得用戶可以根據(jù)其性能需求,在不調(diào)整較低級(jí)別功能的情況下輕松地選擇模型。

 

 

另外,請(qǐng)注意每個(gè)圖表的自定義標(biāo)題。這些標(biāo)題清楚地闡明了目標(biāo)性能和神經(jīng)網(wǎng)絡(luò)的復(fù)雜度,從而使分析變得容易。

它是繪圖實(shí)用函數(shù)的一個(gè)小細(xì)節(jié),但這表明在創(chuàng)建這樣的函數(shù)時(shí)需要仔細(xì)設(shè)計(jì)。如果我們沒有為函數(shù)設(shè)置這樣的參數(shù),就不可能為每個(gè)圖生成自定義標(biāo)題。這種應(yīng)用程序接口(API)的精心設(shè)計(jì)是良好 OOP 的重要組成部分。

最后,將腳本變成簡單的 Python 模塊

到目前為止,你可能一直在用 Jupyter notebook 工作,但要想在未來任何時(shí)候?qū)脒@些功能,就需要將其轉(zhuǎn)換成清爽的 Python 模塊。

如同「from matplotlib import pyplot」一樣,你可以在任何地方導(dǎo)入這些實(shí)用函數(shù)(Keras 模型的構(gòu)建、訓(xùn)練和繪圖)。

 

 

總結(jié)和結(jié)論

本文展示了一些從 OOP 借鑒而來的簡單的良好實(shí)踐,將其應(yīng)用于 DL 分析任務(wù)。這些內(nèi)容對(duì)于經(jīng)驗(yàn)豐富的軟件開發(fā)者來說似乎微不足道,但本文的目標(biāo)讀者是那些可能沒有這種背景,但又應(yīng)該理解在機(jī)器學(xué)習(xí)工作流程中灌輸這些良好實(shí)踐的重要性的數(shù)據(jù)科學(xué)家新人。

冒著重復(fù)自己太多次的風(fēng)險(xiǎn),讓我在這里再次總結(jié)一下,

只要有機(jī)會(huì),就為重復(fù)的代碼塊生成函數(shù)。

一定要仔細(xì)設(shè)計(jì) API 和函數(shù)(比如,所需要的最小參數(shù)集是怎樣的?它們是如何為高級(jí)編程任務(wù)服務(wù)的?)

不要忘了為函數(shù)寫注釋,哪怕只簡單寫一行說明也行。

如果你為同一對(duì)象積累了許多實(shí)用函數(shù),那么就該考慮為其定義一個(gè)類,并且將這些實(shí)用函數(shù)作為該類的方法。

只要有機(jī)會(huì)使用繼承完成復(fù)雜分析,就可以擴(kuò)展類的函數(shù)。

不要僅僅停留在使用 Jupyter notebooks。請(qǐng)將代碼轉(zhuǎn)換成腳本文件,并將它們封裝在小模塊中。養(yǎng)成模塊化工作的習(xí)慣,這樣任何人都可以輕松地復(fù)用和擴(kuò)展它。

說不定當(dāng)你攢了足夠多的實(shí)用的類和子模塊時(shí),你就可以在 Python 包管理倉庫(PyPi 服務(wù)器)上發(fā)布實(shí)用程序包,然后,你就可以大肆吹噓自己發(fā)布過原始開源軟件包了。:-)

原文鏈接:https://towardsdatascience.com/how-a-simple-mix-of-object-oriented-programming-can-sharpen-your-deep-learning-prototype-19893bd969bd

標(biāo)簽: 深度學(xué)習(xí) 編程語言

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請(qǐng)聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點(diǎn)!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請(qǐng)與原作者聯(lián)系。

上一篇:我們?nèi)绾螢閑Bay數(shù)據(jù)中心節(jié)省1000臺(tái)服務(wù)器?

下一篇:AI領(lǐng)域必看的45篇論文(附下載地址)