人工智能教程(五):Anaconda 以及更多概率論
在本系列的 前一篇文章 中,我們首先介紹了使用 TensorFlow。它是一個(gè)非常強(qiáng)大的開(kāi)發(fā)人工智能和機(jī)器學(xué)習(xí)應(yīng)用程序的庫(kù)。然后我們討論了概率論的相關(guān)知識(shí),為我們后面的討論打下基礎(chǔ)。在本系列的第五篇文章中,我們將繼續(xù)介紹概率和統(tǒng)計(jì)中的概念。
在本文中我將首先介紹 Anaconda,一個(gè)用于科學(xué)計(jì)算的 Python 發(fā)行版。它對(duì)于開(kāi)發(fā)人工智能、機(jī)器學(xué)習(xí)和數(shù)據(jù)科學(xué)的程序特別有用。稍后我們將介紹一個(gè)名為 Theano 的 Python 庫(kù)。但在此之前,讓我們下討論一下人工智能的未來(lái)。
在回顧和修訂之前的文章時(shí),我發(fā)覺(jué)我偶爾對(duì)人工智能前景的懷疑語(yǔ)氣和在一些話題上毫不留情的誠(chéng)實(shí)態(tài)度可能在無(wú)意中使部分讀者產(chǎn)生了消極情緒。
這促使我開(kāi)始從金融角度研究人工智能和機(jī)器學(xué)習(xí)。我想確定涉足人工智能市場(chǎng)的公司類(lèi)型,是否有重量級(jí)的公司大力參與其中?還是只有一些初創(chuàng)公司在努力推動(dòng)?這些公司未來(lái)會(huì)向人工智能市場(chǎng)投入多少資金?是幾百萬(wàn)美元,幾十億美元還是幾萬(wàn)億美元?
我通過(guò)于最近知名報(bào)紙上的的預(yù)測(cè)和數(shù)據(jù)來(lái)理解基于人工智能的經(jīng)濟(jì)發(fā)展背后的復(fù)雜動(dòng)態(tài)性。2020 年《福布斯》上的一篇文章就預(yù)測(cè) 2020 年企業(yè)在人工智能上投入的投入將達(dá)到 500 億美元的規(guī)模。這是一筆巨大的投資。《財(cái)富》雜志上發(fā)表的一篇文章稱(chēng),風(fēng)險(xiǎn)投資者正將部分關(guān)注力從人工智能轉(zhuǎn)移到 Web3 和去中心化金融decentralised finance(DeFi)等更新潮的領(lǐng)域上。但《華爾街日?qǐng)?bào)》在 2022 年自信地預(yù)測(cè),“大型科技公司正在花費(fèi)數(shù)十億美元進(jìn)行人工智能研究。投資者應(yīng)該密切關(guān)注。”
印度《商業(yè)標(biāo)準(zhǔn)報(bào)》在 2022 年報(bào)道稱(chēng),87% 的印度公司將在未來(lái) 3 年將人工智能支出提高 10%。總的來(lái)說(shuō),人工智能的未來(lái)看起來(lái)是非常安全和光明的。 令人驚訝的是,除了亞馬遜、Meta(Facebook 的母公司)、Alphabet(谷歌的母公司)、微軟、IBM 等頂級(jí)科技巨頭在投資人工智能外,殼牌、強(qiáng)生、聯(lián)合利華、沃爾瑪?shù)确?IT 科技類(lèi)公司也在大舉投資人工智能。
很明顯眾多世界級(jí)大公司都認(rèn)為人工智能將在不久的將來(lái)發(fā)揮重要作用。但是未來(lái)的變化和新趨勢(shì)是什么呢?我通過(guò)新聞文章和采訪找到一些答案。在人工智能未來(lái)趨勢(shì)的背景下,經(jīng)常提到的術(shù)語(yǔ)包括負(fù)責(zé)任的人工智能Responsible AI、量子人工智能、人工智能物聯(lián)網(wǎng)、人工智能和倫理、自動(dòng)機(jī)器學(xué)習(xí)等。我相信這些都是需要深入探討的話題,在上一篇文章中我們已經(jīng)討論過(guò)人工智能和倫理,在后續(xù)的文章中我們將詳細(xì)討論一些其它的話題。
Anaconda 入門(mén)
現(xiàn)在讓我們討論人工智能的必要技術(shù)。Anaconda 是用于科學(xué)計(jì)算的 Python 和 R 語(yǔ)言的發(fā)行版。它極大地簡(jiǎn)化了包管理過(guò)程。從本文開(kāi)始,我們將在有需要時(shí)使用 Anaconda。第一步,讓我們安裝 Anaconda。訪問(wèn) 安裝程序下載頁(yè)面 下載最新版本的 Anaconda 發(fā)行版安裝程序。在撰寫(xiě)本文時(shí)(2022 年 10 月),64 位處理器上最新的 Anaconda 安裝程序是 Anaconda3-2022.05-Linux-x86_64.sh
。如果你下載了不同版本的安裝程序,將后面命令中的文件名換成你實(shí)際下載的安裝文件名就行。下載完成后需要檢查安裝程序的完整性。在安裝程序目錄中打開(kāi)一個(gè)終端,運(yùn)行以下命令:
shasum -a 256 Anaconda3-2022.05-Linux-x86_64.sh
終端上會(huì)輸出哈希值和文件名。我的輸出顯示是:
a7c0afe862f6ea19a596801fc138bde0463abcbce1b753e8d5c474b506a2db2d Anaconda3-2022.05-Linux-x86_64.sh
然后訪問(wèn) Anaconda 安裝程序哈希值頁(yè)面,比對(duì)下載安裝文件的哈希值。如果哈希值匹配,說(shuō)明下載文件完整無(wú)誤,否則請(qǐng)重新下載。然后在終端上執(zhí)行以下命令開(kāi)始安裝:
bash Anaconda3-2022.05-Linux-x86_64.sh
按回車(chē)鍵后,向下滾動(dòng)查看并接受用戶協(xié)議。最后,輸入 yes
開(kāi)始安裝。出現(xiàn)用戶交互提示時(shí),一般直接使用 Anaconda 的默認(rèn)選項(xiàng)就行。現(xiàn)在 Anaconda 就安裝完成了。
默認(rèn)情況下,Anaconda 會(huì)安裝 Conda。這是一個(gè)包管理器和環(huán)境管理系統(tǒng)。Anaconda 發(fā)行版會(huì)自動(dòng)安裝超過(guò) 250 個(gè)軟件包,并可選擇安裝超過(guò) 7500 個(gè)額外的開(kāi)源軟件包。而且使用 Anaconda 安裝的任何包或庫(kù)都可以在 Jupyter Notebook 中使用。在安裝新包的過(guò)程中, Anaconda 會(huì)自動(dòng)處理它的依賴(lài)項(xiàng)的更新。
至此之后我們終于不用再擔(dān)心安裝軟件包和庫(kù)的問(wèn)題了,可以繼續(xù)我們的人工智能和機(jī)器學(xué)習(xí)程序的開(kāi)發(fā)。注意,Anaconda
只有一個(gè)命令行界面。好在我們的安裝項(xiàng)中包括 Anaconda Navigator。這是一個(gè)用于 Anaconda
的圖形用戶界面。在終端上執(zhí)行命令 anaconda-navigator
運(yùn)行 Anaconda Navigator(圖 1)。我們馬上會(huì)通過(guò)例子看到它的強(qiáng)大功能。
圖 1:Anaconda Navigator
Theano 介紹
Theano 是一個(gè)用于數(shù)學(xué)表達(dá)式計(jì)算的優(yōu)化編譯的 Python 庫(kù)。在 Anaconda Navigator 中安裝Theano 非常容易。打開(kāi) Anaconda Navigator 后點(diǎn)擊 “環(huán)境Environments” 按鈕(圖 1 中用紅框標(biāo)記)。在打開(kāi)的窗口中會(huì)顯示當(dāng)前安裝的所有軟件包的列表。在頂部的下拉列表中選擇“尚未安裝Not installed”選項(xiàng)。向下滾動(dòng)并找到 Theano,然后勾選左側(cè)的復(fù)選框。點(diǎn)擊窗口右下角的綠色 “應(yīng)用Apply” 按鈕。Anaconda 會(huì)在彈出菜單中顯示安裝 Theano 的所有依賴(lài)項(xiàng)。圖 2 是我安裝 Theano 時(shí)的彈出菜單。可以看到,除了 Theano 之外,還安裝了一個(gè)新的包,并修改了 8 個(gè)包。
想象一下,如果要手動(dòng)安裝 Theano,這將是多么麻煩。有了 Anaconda,我們只需要點(diǎn)幾個(gè)按鈕就行了。只需要等待一會(huì)兒,Theano 就安裝好了。現(xiàn)在我們可以在 Jupyter Notebook 中使用 Theano 了。
圖 2:安裝 Theano
我們已經(jīng)熟悉了用于符號(hào)計(jì)算的 Python 庫(kù) SymPy,但 Theano 將符號(hào)計(jì)算提升到了一個(gè)新的水平。圖 3 是一個(gè)使用 Theano 的例子。第 1 行代碼導(dǎo)入 Theano。第 2 行導(dǎo)入 theano.tensor
并將其命名為 T
。我們?cè)诮榻B TensorFlow 時(shí)已經(jīng)介紹過(guò)張量tensor了。
圖 3:使用 Theano 的代碼例子
在數(shù)學(xué)上,可以將張量看作多維數(shù)組。張量是 Theano 的關(guān)鍵數(shù)據(jù)結(jié)構(gòu)之一,它可用于存儲(chǔ)和操作標(biāo)量(數(shù)字)、向量(一維數(shù)組)、矩陣(二維數(shù)組)、張量(多維數(shù)組)等。在第 3 行中,從 Theano 導(dǎo)入了 function()
的函數(shù)。第 4 行導(dǎo)入名為 pp()
的 Theano 函數(shù),該函數(shù)用于格式化打印。第 5 行創(chuàng)建了一個(gè)名為 x
的 double
類(lèi)型的標(biāo)量符號(hào)變量。你可能會(huì)在理解符號(hào)變量這個(gè)概念上遇到一些困難。這里你可以把它看作是沒(méi)有綁定具體值的 double
類(lèi)型的對(duì)象。類(lèi)似地,第 6 行創(chuàng)建了另一個(gè)名為 y
的標(biāo)量符號(hào)變量。第 7 行告訴 Python 解釋器,當(dāng)符號(hào)變量 x
和 y
得到值時(shí),將這些值相加并存儲(chǔ)在 a
里面。
為了進(jìn)一步解釋符號(hào)操作,仔細(xì)看第 8 行的輸出是 (x+y)
。這表明兩個(gè)數(shù)字的實(shí)際相加還沒(méi)有發(fā)生。第 9 到 11 行類(lèi)似地分別定義了符號(hào)減法、乘法和除法。你可以自己使用函數(shù) pp()
來(lái)查找 b
、c
和 d
的值。第 12 行非常關(guān)鍵。它使用 Theano 的 function()
函數(shù)定義了一個(gè)名為 f()
的新函數(shù)。 函數(shù) f()
的輸入是 x
和 y
,輸出是 [a b c d]
。最后在第 13 行中,給函數(shù) f()
提供了實(shí)際值來(lái)調(diào)用該函數(shù)。該操作的輸出也顯示在圖 3 中。我們很容易驗(yàn)證所顯示的輸出是正確的。
圖 4:用 Theano 處理矩陣
下面讓我們通過(guò)圖 4 的代碼來(lái)看看如何使用 Theano 創(chuàng)建和操作矩陣。需要注意的是,圖中我省略了導(dǎo)入代碼。如果你要直接運(yùn)行圖 4 的代碼,需要自己添加上這幾行導(dǎo)入代碼(圖 3 中的前三行)。第 1 行創(chuàng)建了兩個(gè)符號(hào)矩陣 x
和 y
。這里我使用了復(fù)數(shù)構(gòu)造函數(shù)plural constructor imatrices
,它可以同時(shí)構(gòu)造多個(gè)矩陣。第 2 行到第 4 行分別對(duì)符號(hào)矩陣 x
和 y
執(zhí)行符號(hào)加法、減法和乘法。這里你可以使用 print(pp(a))
、print(pp(b))
和 print(pp(c))
來(lái)幫助理解符號(hào)操作的性質(zhì)。第 5 行創(chuàng)建了一個(gè)函數(shù) f()
,它的輸入是兩個(gè)符號(hào)矩陣 x
和 y
,輸出是 [a b c]
,它們分別表示符號(hào)加法、減法和乘法。最后,在第 6 行中,為函數(shù) f()
提供實(shí)際的值來(lái)調(diào)用該函數(shù)。該操作的輸出也顯示在圖 4 中。很容易驗(yàn)證所示的三個(gè)輸出矩陣是否正確。注意,除了標(biāo)量和矩陣,張量還提供了向量、行、列類(lèi)型張量的構(gòu)造函數(shù)。Theano 暫時(shí)就介紹到這里了,在討論概率和統(tǒng)計(jì)的進(jìn)階話題時(shí)我們還會(huì)提到它。
再來(lái)一點(diǎn)概率論
圖 5:算術(shù)平均值和標(biāo)準(zhǔn)偏差
現(xiàn)在我們繼續(xù)討論概率論和統(tǒng)計(jì)。我在上一篇文章中我建議你仔細(xì)閱讀三篇維基百科文章,然后介紹了正態(tài)分布。在我們開(kāi)始開(kāi)發(fā)人工智能和機(jī)器學(xué)習(xí)程序之前,有必要回顧一些概率論和統(tǒng)計(jì)的基本概念。我們首先要介紹的是 算術(shù)平均值arithmetic mean和標(biāo)準(zhǔn)差standard deviation。
算術(shù)平均值可以看作是一組數(shù)的平均值。標(biāo)準(zhǔn)差可以被認(rèn)為是一組數(shù)的分散程度。如果標(biāo)準(zhǔn)差較小,則表示集合中的元素都接近平均值。相反,如果標(biāo)準(zhǔn)差很大,則表示集合的中的元素分布在較大的范圍內(nèi)。如何使用 Python 計(jì)算算術(shù)平均值和標(biāo)準(zhǔn)差呢?Python 中有一個(gè)名為 statistics
的模塊,可用于求平均值和標(biāo)準(zhǔn)差。但專(zhuān)家用戶認(rèn)為這個(gè)模塊太慢,因此我們選擇 NumPy。
圖 5 所示的代碼打印兩個(gè)列表 C1
和 C2
的平均值和標(biāo)準(zhǔn)差(我暫時(shí)隱藏了兩個(gè)列表的實(shí)際內(nèi)容)。你能從這些值中看出什么呢?目前它們對(duì)你來(lái)說(shuō)只是一些數(shù)字而已。現(xiàn)在我告訴你,這些列表分別包含學(xué)校 A 和學(xué)校 B 的 6 名學(xué)生的數(shù)學(xué)考試成績(jī)(滿分 50 分,及格 20 分)。均值告訴我們,兩所學(xué)校的學(xué)生平均成績(jī)都較差,但學(xué)校 B 的成績(jī)略好于學(xué)校 A。標(biāo)準(zhǔn)差值告訴我們什么呢?學(xué)校 B 的巨大的標(biāo)準(zhǔn)差值雖然隱藏在平均值之下,但卻清楚地反映了學(xué)校 B 的的教學(xué)失敗。為了進(jìn)一步加深理解,我將給出兩個(gè)列表的值,C1 =[20,22,20,22,22,20]
,C2 =[18,16,17,16,15,48]
。這個(gè)例子清楚地告訴我們,我們需要更復(fù)雜的參數(shù)來(lái)處理問(wèn)題的復(fù)雜性。概率和統(tǒng)計(jì)將提供更復(fù)雜的模型來(lái)描述復(fù)雜和混亂的數(shù)據(jù)。
隨機(jī)數(shù)生成是概率論的重要組成部分。但實(shí)際上我們只能生成偽隨機(jī)數(shù)。偽隨機(jī)數(shù)序列具有和真隨機(jī)數(shù)序列近似的性質(zhì)。在圖 6 中我們介紹了幾個(gè)生成偽隨機(jī)數(shù)的函數(shù)。第 1 行導(dǎo)入 Python 的 random
包。第 2 行代碼生成兩個(gè)隨機(jī)數(shù),并將它們存儲(chǔ)在名為 new_list
的列表中。其中函數(shù) random.random()
生成隨機(jī)數(shù),代碼 new_list = [random.random() for i in range(2)]
使用了 Python 的列表推導(dǎo)list comprehension語(yǔ)法。第 3 行將此列表打印輸出。注意,每次執(zhí)行代碼打印出的兩個(gè)隨機(jī)數(shù)會(huì)變化,并且連續(xù)兩次打印出相同數(shù)字的概率理論上為 0。圖 6 的第二個(gè)代碼單元中使用了 random.choice()
函數(shù)。這個(gè)函數(shù)從給定的選項(xiàng)中等概率地選擇數(shù)據(jù)。代碼片 random.choice(["Heads", "Tails"])
將等概率地在“Heads”和“Tails”之間選擇。注意,該行代碼也使用了列表推導(dǎo),它會(huì)連續(xù)執(zhí)行 3 次選擇操作。從圖 6 的輸出可以看到,三次都選中了“Tails”。
圖 6:偽隨機(jī)數(shù)生成
現(xiàn)在,我們用一個(gè)簡(jiǎn)單的例子來(lái)說(shuō)明概率論中著名的大數(shù)定理xxx。大數(shù)定理表明從大量試驗(yàn)中獲得的結(jié)果的平均值應(yīng)該接近期望值,并且隨著試驗(yàn)次數(shù)的增加這個(gè)平均值會(huì)越來(lái)越接近期望值。我們都知道,投擲一個(gè)均勻的骰子得到數(shù)字 6 的概率是 1/6。我們用圖 7 中的 Python 代碼來(lái)模擬這個(gè)實(shí)驗(yàn)。第 1 行導(dǎo)入 Python 的 random
包。第 2 行設(shè)置重復(fù)試驗(yàn)的次數(shù)為 1000。第 3 行將計(jì)數(shù)器 ct
初始化為 0。第 4 行是一個(gè)循環(huán),它將迭代 1000 次。第 5 行的 random.randint(1, 6)
隨機(jī)生成 1 到 6 之間的整數(shù)(包括 1 和 6)。然后檢查生成的數(shù)字是否等于 6;如果是,則轉(zhuǎn)到第 7 行,將計(jì)數(shù)器 ct
增加 1。循環(huán)迭代 1000 次后,第 8 行打印數(shù)字 6 出現(xiàn)的次數(shù)與總試驗(yàn)次數(shù)之間的比例。圖 7 顯示該比例為 0.179,略高于期望值 1/6 = 0.1666…。這與期望值的差異還是比較大的。將第 2 行中 n
的值設(shè)置為 10000,再次運(yùn)行代碼并觀察打印的輸出。很可能你會(huì)得到一個(gè)更接近期望值的數(shù)字(它也可能是一個(gè)小于期望值的數(shù)字)。不斷增加第 2 行中 n
的值,你將看到輸出越來(lái)越接近期望值。
圖 7:大數(shù)定理
雖然大數(shù)定理的描述樸實(shí)簡(jiǎn)單,但如果你了解到哪些數(shù)學(xué)家證明了大數(shù)定理或改進(jìn)了原有的證明,你一定會(huì)大吃一驚的。他們包括卡爾達(dá)諾、雅各布·伯努利、丹尼爾·伯努利、泊松、切比雪夫、馬爾科夫、博雷爾、坎特利、科爾莫戈羅夫、欽欽等。這些都是各自領(lǐng)域的數(shù)學(xué)巨匠。
目前我們還沒(méi)有涵蓋概率的隨機(jī)變量、概率分布等主題,它們對(duì)開(kāi)發(fā)人工智能和機(jī)器學(xué)習(xí)程序是必不可少的。我們對(duì)概率和統(tǒng)計(jì)的討論仍處于初級(jí)階段,在下一篇文章中還會(huì)加強(qiáng)這些知識(shí)。與此同時(shí),我們將重逢兩個(gè)老朋友,Pandas 和 TensorFlow。另外我們還將介紹一個(gè)與 TensorFlow 關(guān)系密切的庫(kù) Keras。