【機(jī)器學(xué)習(xí)基礎(chǔ)】(一):5分鐘理解機(jī)器學(xué)習(xí)并上手實(shí)踐
引言
現(xiàn)在市面上的機(jī)器學(xué)習(xí)教程大多先學(xué)習(xí)數(shù)學(xué)基礎(chǔ),然后學(xué)機(jī)器學(xué)習(xí)的數(shù)學(xué)算法,再建立機(jī)器學(xué)習(xí)的數(shù)學(xué)模型,再學(xué)習(xí)深度學(xué)習(xí),再學(xué)習(xí)工程化,再考慮落地。這其中每個(gè)環(huán)節(jié)都在快速發(fā)展,唯獨(dú)落地特別困難。我們花費(fèi)大量時(shí)間成本去學(xué)習(xí)以上內(nèi)容,成本無(wú)疑是特別昂貴的。所以我們不如先“盲人摸象”、“不求甚解”地探索下機(jī)器學(xué)習(xí),淺嘗輒止。如果想到自己的應(yīng)用場(chǎng)景,再學(xué)以致用,深入探索。這無(wú)疑是使沉沒(méi)成本最低的決策。
本教程適合興趣廣泛的人士增加自己知識(shí)的廣度,從應(yīng)用的角度謹(jǐn)“使用”機(jī)器學(xué)習(xí)這款工具,是典型的黑盒思維。這非常契合筆者的思維方式,當(dāng)然也是我個(gè)人的格局局限。
本教程會(huì)淺顯易懂,讓你走的很快。但如果你想走的更遠(yuǎn)還請(qǐng)學(xué)習(xí)數(shù)學(xué)。當(dāng)然我們也只是暫時(shí)放下數(shù)學(xué),先構(gòu)建自己的知識(shí)體系。
先抬頭看路,找準(zhǔn)適合自己的方向,再埋頭趕路,或深耕下去……
把視角拉高
從手工到工業(yè)化再到人工智能,這是把人類(lèi)從生產(chǎn)活動(dòng)中逐漸解放的過(guò)程。用機(jī)器來(lái)幫助人們工作,一直是人類(lèi)的美好愿望。讓機(jī)器智能化,以此來(lái)代替人力做更智能問(wèn)題,這可以作為人工智能的簡(jiǎn)單解釋。
很多教程或者書(shū)籍把人工智能、機(jī)器學(xué)習(xí)、深度學(xué)習(xí)的關(guān)系解釋為從屬關(guān)系,人工智能 > 機(jī)器學(xué)習(xí) > 深度學(xué)習(xí)。這種解釋不錯(cuò),但卻無(wú)法表示他們之間的更深層次的關(guān)系。
機(jī)器學(xué)習(xí)是通過(guò)數(shù)學(xué)方法在數(shù)據(jù)中尋找解釋?zhuān)源藖?lái)實(shí)現(xiàn)人工智能的一種手段。而深度學(xué)習(xí)是參照神經(jīng)系統(tǒng)在機(jī)器學(xué)習(xí)基礎(chǔ)上發(fā)展出的一種高級(jí)技巧。?它們之間是存在一定的依托關(guān)系、進(jìn)化趨勢(shì)的。
狹義地講,傳統(tǒng)的機(jī)器學(xué)習(xí)是通過(guò)數(shù)學(xué)模型不斷求導(dǎo)來(lái)找出數(shù)據(jù)規(guī)律的過(guò)程。這其中數(shù)學(xué)模型的選擇尤為重要。隨著GPU、TPU等算力的發(fā)展,算法技術(shù)的進(jìn)步,甚至出現(xiàn)了自動(dòng)選模型、自動(dòng)調(diào)參的技術(shù)。我們可以構(gòu)建復(fù)雜的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu),只要有足夠的算力支持,足夠的時(shí)間我們可以用深度學(xué)習(xí)處理非常復(fù)雜的任務(wù)。所以在代碼操作上,深度學(xué)習(xí)甚至比傳統(tǒng)的機(jī)器學(xué)習(xí)對(duì)程序員更友好、更易理解。我們先學(xué)習(xí)傳統(tǒng)機(jī)器學(xué)習(xí)而非直接學(xué)習(xí)深度學(xué)習(xí)的好處是,我們可以通過(guò)對(duì)“黑盒”的拆箱來(lái)理解機(jī)器學(xué)習(xí)過(guò)程,掌握機(jī)器學(xué)習(xí)的概念,我會(huì)對(duì)其中應(yīng)用的數(shù)學(xué)模型進(jìn)行解釋。
我們先來(lái)看一下人工智能產(chǎn)業(yè)鏈的結(jié)構(gòu),如下圖:

我們可以看到,機(jī)器學(xué)習(xí)的三大基石---算力、算法與數(shù)據(jù)。機(jī)器學(xué)習(xí)的發(fā)展離不開(kāi)算法數(shù)學(xué)的進(jìn)步,同樣離不開(kāi)算力的發(fā)展。
在技術(shù)層面,機(jī)器學(xué)習(xí)在計(jì)算機(jī)視覺(jué)(CV, Computer Vision)和自然語(yǔ)言處理(NLP, Nature Language Processing)取得了關(guān)鍵的發(fā)展和應(yīng)用。
算法分類(lèi)上,機(jī)器學(xué)習(xí)分為監(jiān)督學(xué)習(xí)、非監(jiān)督學(xué)習(xí)、半監(jiān)督學(xué)習(xí)、強(qiáng)化學(xué)習(xí)等。
監(jiān)督學(xué)習(xí):數(shù)據(jù)樣本有標(biāo)簽。 非監(jiān)督學(xué)習(xí):數(shù)據(jù)樣本無(wú)標(biāo)簽。 半監(jiān)督學(xué)習(xí):數(shù)據(jù)樣本有部分(少量)標(biāo)簽。 強(qiáng)化學(xué)習(xí):趨向結(jié)果則獎(jiǎng)勵(lì),偏離結(jié)果則懲罰。
所謂Garbage in, Garbage out(垃圾進(jìn),垃圾出)。數(shù)據(jù)是機(jī)器學(xué)習(xí)的重中之重。我們需要花費(fèi)大量的時(shí)間來(lái)處理數(shù)據(jù),甚至占到整個(gè)機(jī)器學(xué)習(xí)任務(wù)的90%以上。
比如數(shù)據(jù)處理過(guò)程中的數(shù)據(jù)采集,如果我們采樣的方式欠妥,就可能導(dǎo)致非代表性的數(shù)據(jù)集,這就導(dǎo)致了采樣偏差。
我們的數(shù)據(jù)可能會(huì)有很多無(wú)效的數(shù)據(jù),我們需要剔除無(wú)效的數(shù)據(jù),就叫做數(shù)據(jù)清洗。
我們通過(guò)挖掘大量數(shù)據(jù)來(lái)發(fā)現(xiàn)不太明顯的規(guī)律,就稱(chēng)作數(shù)據(jù)挖掘。
機(jī)器學(xué)習(xí)工業(yè)化流程
我們以一款工業(yè)化流水線工具TFX為例,看一下機(jī)器學(xué)習(xí)的技術(shù)流程。

流程分為數(shù)據(jù)輸入、數(shù)據(jù)驗(yàn)證、特征工程、訓(xùn)練模型、驗(yàn)證模型、應(yīng)用良好模型和提供模型六個(gè)部分:
輸入數(shù)據(jù),并根據(jù)需要拆分?jǐn)?shù)據(jù)集。 生成訓(xùn)練數(shù)據(jù)和服務(wù)數(shù)據(jù)的特征統(tǒng)計(jì)信息。通過(guò)從訓(xùn)練數(shù)據(jù)中推斷出類(lèi)型、類(lèi)別和范圍來(lái)創(chuàng)建架構(gòu)。識(shí)別訓(xùn)練數(shù)據(jù)和服務(wù)數(shù)據(jù)中的異常值。 對(duì)數(shù)據(jù)集執(zhí)行特征工程。 訓(xùn)練模型,調(diào)整模型的超參數(shù)。 對(duì)訓(xùn)練結(jié)果進(jìn)行深入分析,并幫助驗(yàn)證導(dǎo)出的模型。檢查模型是否確實(shí)可以從基礎(chǔ)架構(gòu)提供服務(wù),并防止推送不良模型。 將模型部署到服務(wù)基礎(chǔ)架構(gòu)。
我想通過(guò)以上解釋?zhuān)蠹覒?yīng)該可以對(duì)機(jī)器學(xué)習(xí)的實(shí)踐方法有了一定宏觀的了解。
機(jī)器是如何學(xué)習(xí)的
我們從宏觀角度看了機(jī)器學(xué)習(xí)的產(chǎn)業(yè)結(jié)構(gòu)、工業(yè)化流程,你應(yīng)該對(duì)你自己在機(jī)器學(xué)習(xí)的這些環(huán)節(jié)中有哪些發(fā)揮有了一定的把握。現(xiàn)在我們把視角拉回到微觀層面,看看機(jī)器是如何學(xué)習(xí)的。
我們以攝氏度轉(zhuǎn)換華氏度為例。
傳統(tǒng)編程中,我們要求得攝氏度和華氏度的關(guān)系,我們必須找出公式:
而在對(duì)機(jī)器學(xué)習(xí)來(lái)說(shuō),我們有大量的數(shù)據(jù),卻需要找出關(guān)系。機(jī)器學(xué)習(xí)的過(guò)程就是不斷求導(dǎo),以此來(lái)找出數(shù)學(xué)模型,來(lái)解釋規(guī)律的過(guò)程。

如圖所示,我們有攝氏度數(shù)據(jù)0, 8, 15, 22, 38以及華氏度數(shù)據(jù)32, 46.4, 59, 71.6, 100.4,機(jī)器學(xué)習(xí)的過(guò)程就是找出公式的過(guò)程。其中,攝氏度就是我們的特征,華氏度就是我們的標(biāo)簽,攝氏度與華氏度的關(guān)系就是實(shí)例。
特征:我們模型的輸入。在這種情況下,只有一個(gè)值-攝氏度。 標(biāo)簽:我們的模型預(yù)測(cè)的輸出。在這種情況下,只有一個(gè)值-華氏度。 實(shí)例:訓(xùn)練期間使用的一對(duì)輸入/輸出。在我們的例子中,是攝氏度/華氏度一對(duì)數(shù)據(jù),例如,(0, 32), (8, 46.4)。
藍(lán)色的部分表示我們?cè)O(shè)置好數(shù)學(xué)函數(shù),然后通過(guò)不斷的調(diào)整權(quán)重與偏差不斷地擬合數(shù)據(jù),最終得到可以表示規(guī)律的模型的過(guò)程。
擬合:通過(guò)訓(xùn)練數(shù)據(jù),使模型來(lái)概括表示數(shù)據(jù)的過(guò)程。 模型:圖結(jié)構(gòu),包含了訓(xùn)練過(guò)程中的權(quán)重與偏差的數(shù)據(jù)。其中的圖為由各函數(shù)組成的計(jì)算結(jié)構(gòu)。
簡(jiǎn)單上手機(jī)器學(xué)習(xí)代碼
在上手代碼之前我默認(rèn)你已經(jīng)配置好了環(huán)境,掌握了Jupyter, Numpy, Pandas, Matplotlib的用法。如果你沒(méi)有掌握以上技能,請(qǐng)參考我寫(xiě)的配套教程前置機(jī)器學(xué)習(xí)系列
import?numpy?as?np
import?matplotlib.pyplot?as?plt
celsius????=?[[-40],?[-10],?[?0],?[?8],?[15],?[22],?[?38]]
fahrenheit?=?[[-40],?[?14],?[32],?[46.4],?[59],?[71.6],?[100.4]]
plt.scatter(celsius,fahrenheit,?c='red',?label='real')
plt.xlabel('celsius')
plt.ylabel('fahrenheit')
plt.legend()
plt.grid(True)
plt.title('real?data')
plt.show()
如上代碼所示,我們準(zhǔn)備攝氏度與華氏度的數(shù)據(jù),然后通過(guò)matplotlib庫(kù)繪制圖像。

from?sklearn.linear_model?import?LinearRegression
lr?=?LinearRegression()
lr.fit(celsius,fahrenheit)
我們通過(guò)上方僅僅3行代碼就訓(xùn)練了數(shù)據(jù)。LinearRegression是scikit-learn包下的線性回歸方法,是普通的最小二乘線性回歸。而fit就是擬合的意思,以此來(lái)訓(xùn)練模型。
celsius_test?=?[[-50],[-30],[10],[20],[50],[70]]
fahrenheit_test?=?lr.predict(celsius_test)
plt.scatter(celsius,fahrenheit,?c='red',?label='real')
plt.scatter(celsius_test,fahrenheit_test,?c='orange',?label='predicted')
plt.xlabel('celsius')
plt.ylabel('fahrenheit')
plt.legend()
plt.grid(True)
plt.title('estimated?vs?real?data')
plt.show()
接下來(lái)我們調(diào)用lr.predict(celsius_test)方法來(lái)進(jìn)行預(yù)測(cè),以此來(lái)檢驗(yàn)我們的模型準(zhǔn)確度。我們通過(guò)下方圖像中黃色的點(diǎn)可以看出,我們的模型非常準(zhǔn)確。

你就說(shuō)這玩意簡(jiǎn)單不簡(jiǎn)單!?咳咳,別囂張,我們好好玩。
順帶一提的深度學(xué)習(xí)代碼
既然都上手了,我們也試一試深度學(xué)習(xí)代碼:
import?tensorflow?as?tf
import?numpy?as?np
#?prepare?data
celsius_q????=?np.array([-40,?-10,??0,??8,?15,?22,??38],??dtype=float)
fahrenheit_a?=?np.array([-40,??14,?32,?46.4,?59,?71.6,?100.4],??dtype=float)
#?fit?model
model?=?tf.keras.Sequential([tf.keras.layers.Dense(units=1,?input_shape=[1])])
model.compile(loss='mean_squared_error',?optimizer=tf.keras.optimizers.Adam(0.1))
history?=?model.fit(celsius_q,?fahrenheit_a,?epochs=500,?verbose=False)
print("Finished?training?the?model")
#?print?loss
import?matplotlib.pyplot?as?plt
plt.xlabel('Epoch?Number')
plt.ylabel("Loss?Magnitude")
plt.plot(history.history['loss'])
我們使用TensorFlow內(nèi)置的Keras方法創(chuàng)建了1層的神經(jīng)網(wǎng)絡(luò),選擇了MSE損失函數(shù)以及Adam優(yōu)化器,訓(xùn)練了500代。
如下圖可以看到,隨著代(epoch)數(shù)量的增加,損失函數(shù)的結(jié)果逐漸降低。

那么什么是損失函數(shù)呢?我們?cè)诮酉聛?lái)的文章中一探究竟。感謝您的關(guān)注與支持!
往期精彩回顧
本站知識(shí)星球“黃博的機(jī)器學(xué)習(xí)圈子”(92416895)
本站qq群704220115。
加入微信群請(qǐng)掃碼:
