人工智能教程(一):基礎知識
如今,計算機科學領域的學生和從業者絕對有必要了解人工智能artificial intelligence、數據科學data science、機器學習machine learning、深度學習deep learning方面的基本知識。但是應該從哪里開始呢?
為了找到答案,我瀏覽了大量人工智能的教材和教程。它們有的從大量數學理論開始,有的用編程語言無關的方式(不要求你了解某一門特定的編程語言)講解,有的假設你是線性代數、概率論和統計學專家。在很大程度上,它們都很有用。但它們都沒有回答最重要的問題:真正的初學者應該從哪里開始學習人工智能?
開始學習人工智能的方式多種多樣,但是我對它們各有擔憂。涉及太多的數學會讓人分心,但如果數學介紹得太少就好像駕駛員不知道汽車引擎在哪里一樣。對于未來的人工智能工程師和數據科學家來說,從進階概念開始講解是最有效率的方式,因為他們精通線性代數、概率論和統計學。如果從基礎知識開始,然后在中間某個地方結束也可以,只要學員想要在這里結束學習。考慮到所有這些事實,我認為初學者的人工智能教程應該從基礎知識開始,并以一個實際的人工智能項目結束。這個項目可能很小,但是在相同任務上它將會超越任何傳統項目。
本系列將從最基礎的知識講到中等水平內容。除了討論人工智能,我還希望對相關的話題進行一些澄清,因為人們對人工智能、機器學習、數據科學等術語有很多困惑。人工智能程序是必要的,因為我們每天會產生海量的數據。根據互聯網上查詢到的結果,我們每天大約會產生 2.5x1018 字節的數據。但是,這些數據中的大多數與我們完全無關,包括大量沒有價值的 YouTube 視頻,不經思考就發送的電子郵件,瑣碎的新聞報道等等。然而,這片浩瀚的數據海洋中同樣蘊含著無價的寶貴知識。傳統軟件無法完成處理這些數據的艱巨任務。人工智能是少數能夠應對這種信息過載的技術之一。
當談到到人工智能時,我們還需要區分事實和假象。我記得幾年前聽一位人工智能專家的演講。他講述了一個人工智能圖像識別系統,它能近乎絕對準確地分辨西伯利亞雪橇犬和西伯利亞雪狼的圖像。在互聯網上搜索一下,你會看到這兩種動物有多么相似。如果這個系統確實那么準確,它將是人工智能的奇跡。可惜的是,事實并非如此。該圖像識別系統只是對圖像的背景進行了分類。西伯利亞雪橇犬是家養動物,它的圖像背景中幾乎總會有一些矩形或圓形的物體。而西伯利亞雪狼是野生動物,它所在的背景中有雪。這些例子導致近年來人們對人工智能提出了準確性擔保要求。
確實,最近幾年人工智能展現了一些真正的力量。舉個簡單例子就是 YouTube、Amazon 等網站的推薦系統。很多時候我驚訝于它們的推薦結果,就好像它們會讀心術一樣。然而不論這些推薦的質量如何,“人工智能到底是好是壞?”都是一個很熱門話題。我認為,一個像《終結者》中機器有意識地攻擊人類的未來還遙遙無期。然而,前面那句話中的“有意識地”一詞非常重要。目前的人工智能系統可能發生故障,并且意外地傷害到人類。但是,許多號稱具有人工智能能力的系統實際上只是包含大量分支和循環的常規軟件。因此目前可以安全地說,我們還沒有在日常生活中看到人工智能的真正威力。不論是好的影響(如治愈癌癥),還是壞的影響(合成的世界領導人視頻導致的暴動和戰爭),我們都只能拭目以待了。就個人而言,我相信人工智能是一種福祉,并將大大提高未來幾代人的生活質量。
什么是人工智能?
在我們進一步探討之前,讓我們試著理解人工智能(AI)、機器學習(ML)、深度學習(DL)、數據科學(DS)等之間的聯系和區別。這些術語經常被誤用為同義詞。圖 1 表示了人工智能、機器學習、深度學習和數據科學之間的關系。當然這不是唯一的劃分方式,你可能會看到其它的劃分圖。但在我看來,圖 1 是最貼切的,它能夠最大程度地概括這些領域之間關系。
圖 1:人工智能體系結構和數據科學
在本系列的第一篇文章中,我不會對每個術語定義進行精確的定義。我認為在現階段,精確地定義它們是適得其反的,是浪費時間。但在后續的文章中,我們將重新討論這些術語并正式定義它們。目前我們可以暫時把人工智能看作是可以在某種程度上模仿人類智能的程序。那人類智能又是指什么呢?
想象一下你的人工智能程序是一個一歲大的嬰兒。這個寶寶會通過聽周圍人說話來學習母語。他/她將很快學會識別形狀,顏色,物體等,沒有任何困難。此外,他/她將能夠對周圍人的情緒做出反應。例如,任何一個三歲的嬰兒都知道如何用甜言蜜語讓父母給他/她巧克力和棒棒糖。同樣,人工智能程序也將能夠感知并適應環境,就像嬰兒一樣。然而,這種真正的人工智能只能在遙遠的未來實現。
圖 1 顯示機器學習是人工智能的真子集,它也是實現人工智能系統的技術之一。機器學習是使用大量數據來訓練程序的技術,以便有效地執行必要的任務。它的準確性隨著訓練集的增大而增加。請注意,還有其它技術用于開發人工智能系統,如基于布爾邏輯的系統,基于模糊邏輯的系統,基于遺傳編程的系統等。然而,如今機器學習是實現人工智能系統的最主流的技術。圖 1 還顯示深度學習是機器學習的真子集,它只是眾多機器學習技術中的一種。但目前實際上大多數嚴肅的機器學習技術都用到了深度學習。在這一點上,我甚至避免嘗試定義深度學習。請記住,深度學習涉及到使用大型人工神經網絡。
那數據科學(圖 1 中的紅圈)是做什么的呢?數據科學是計算機科學/數學領域中的一門處理和解讀大規模數據的學科。我說的“大”,有多大呢?早在 2010 年,Facebook 等一些企業巨頭就聲稱它們的服務器可以處理幾 Pb 的數據。當我們說大數據時,通常指的是 Tb 或 Pb 級的數據規模,而不是 Gb 級的。許多數據科學應用涉及人工智能、機器學習和深度學習技術的使用。因此,當我們討論人工智能時,很難不提到數據科學。數據科學也使用很多傳統的編程和數據庫管理技術,比如使用 Apache Hadoop 進行大數據分析。
本系列的討論將主要集中在人工智能和機器學習上,并涉及數據科學。
教學環境搭建
在表明了本系列文章的主題后,現在說說本教程的前置條件。你需要一臺 Linux 電腦(當然 Windows 或 macOS 機器也可以,只是在一些安裝步驟上可能需要額外的協助),并了解基本的數學和計算機編程知識。我希望在細心地閱讀本系列文章后,你會感受到人工智能的強大。
用編程語言無關的方式來學習人工智能是可能的,但本系列將基于一門編程語言并涉及大量的編程。在決定使用哪一門編程語言之前,我們先來回顧一下人工智能、機器學習、深度學習和數據科學領域流行的編程語言。Lisp 是一種函數式編程語言,它是最早用于開發人工智能程序的語言之一。Prolog 是一種邏輯編程語言,在 20 世紀 70 年代也被用于同樣的目的。我們將在接下來的介紹人工智能歷史的文章中更詳細地介紹 Lisp 和 Prolog。
如今,Java、C、C++、Scala、Haskell、MATLAB、R、Julia 等編程語言也被用于開發人工智能程序。Python 在人工智能程序開發中被廣泛使用,這使我們選擇它作為本教程的編程語言。但我必須聲明,從這里開始做的選擇(更確切地說,是我替你做的選擇),主要考慮的因素是易用性、受歡迎程度、(在少數情況下)我自己對該軟件/技術的適應和熟悉程度、對本教程效率的提升。但同時,我也鼓勵你嘗試其它的編程語言、軟件和工具。也許從長遠來看,它們對你來說可能是更好的選擇。
現在我們需要立即做出另一個選擇:使用 Python 2 還是 Python 3?考慮到本系列有許多年輕的讀者,他們還有漫長的職業生涯,我將選擇使用 Python 3。在 Ubuntu 系統終端中執行命令 sudo apt install python3
安裝最新版本的 Python 3(你的系統中可能已經安裝了 Python 3)。在其它 Linux 發行版、Windows 和 macOS 機器上安裝 Python 3 也非常容易。執行下面的命令查看安裝的 Python 3 的版本:
python3 --version
Python 3.8.10
在后續的教程中,我們需要安裝許多 Python 包,所以需要一個包管理器。目前主流的包管理器有 pip、Conda 和 Mamba 等。我選擇 pip 作為包在本教程的管理器。它相對簡單,也是推薦的 Python 安裝工具。我認為 Conda 和 Mamba 是比 pip
更強大的工具,你可以嘗試一下它們。運行命令 sudo apt install python3-pip
將在 Ubuntu 系統中安裝 pip。pip、Conda 和 Mamba 是跨平臺軟件,它們可以安裝在 Linux、Windows 和 macOS 系統上。運行命令 pip3 --version
查看系統中安裝的 pip 版本,如下所示:
pip 20.0.2 from /usr/lib/python3/dist-packages/pip (python 3.8)
現在我們需要一個 Python 集成開發環境(IDE)。IDE 能幫助程序員更容易地編寫、編譯、調試和執行代碼。PyCharm、IDLE、Spyder 等都是流行的 Python IDE。然而,由于我們的主要目的是開發人工智能和數據科學程序,這里考慮另外兩個強有力的競爭者 —— JupyterLab 和谷歌 Colab。嚴格地說,它們不僅僅是 IDE;它們是非常強大的基于網絡的交互式開發環境。兩者都可以在網絡瀏覽器上工作,并提供強大的功能。JupyterLab 是由非營利組織 Project Jupyter 支持的免費開源軟件。谷歌 Colab 遵循 免費增值freemium
可以使用命令 pip3 install JupyterLab
在本地安裝 JupyterLab。執行命令 jupyter-lab
將在系統的默認網絡瀏覽器中運行 JupyterLab。Project Jupyter 還提供一個更老的類似系統,稱為Jupyter Notebook。可以通過 pip3 install Notebook
命令在本地安裝 Jupyter Notebook,用Jupyter Notebook
運行它。但 Jupyter Notebook 的功能不如 JupyterLab 強大,且官方宣布它最終會被 JupyterLab
取代。在本教程中,我們將在合適的階段使用 JupyterLab。但在開始階段,我們將使用 Linux 終端來運行 Python
程序,因此急需的是包管理器 pip。
Anaconda 是一個非常流行的 Python 和 R 編程語言發行版,它主要用于機器學習和數據科學領域。作為未來的人工智能工程師和數據科學家,熟悉使用 Anaconda 也是一個不錯的選擇。
現在我們需要確定最重要的一點 —— 本教程的風格。有大量人工智能開發相關的 Python 庫,比如 NumPy、SciPy、Pandas、Matplotlib、Seaborn、TensorFlow、Keras、Scikit-learn 和 PyTorch。許多關于人工智能、機器學習和數據科學的教材和教程都是基于對其中一個或多個庫的完整講解。盡管對特定包的功能進行這樣的覆蓋講解是一種高效的方式,但我的教程是更面向數學的。我們將首先討論開發人工智能程序所需的數學概念,然后再介紹需要的 Python 基礎知識和 Python 庫。我們會為了探索實現這些數學概念所需的特性而不斷回顧這些 Python 庫。有時我也會要求你自己學習一些 Python 和數學的基本概念。
在完成這些準備工作之后,如果我們就在這里結束,任何代碼或數學概念都不講,那將是一種罪過。因此,我們將繼續學習人工智能和機器學習中最重要的數學概念:向量和矩陣。
向量和矩陣
矩陣是按行和列排列的數字、符號或數學表達式構成的矩形陣列。圖 2 顯示了一個 2 × 3 矩陣,它有 2 行和 3 列。如果你熟悉編程,在許多流行的編程語言中這個矩陣可以表示為一個二維數組。只有一行的矩陣稱為行向量,只有一列的矩陣稱為列向量。
就是一個行向量。
圖 2:一個: A 2 × 3 的矩陣
為什么矩陣和向量在人工智能和機器學習中如此重要呢?人工智能和機器學習中廣泛使用線性代數,而矩陣和向量是線性代數的核心。幾個世紀以來,數學家們一直在研究矩陣和向量的性質和應用。高斯、歐拉、萊布尼茨、凱利、克萊姆和漢密爾頓等數學家在線性代數和矩陣論領域都有以他們的名字命名的定理。多年來,線性代數中發展出了許多分析矩陣和向量性質的技術。
復雜的數據通常可以很容易用向量或矩陣來表示。舉一個簡單的例子,從一個人的醫療記錄中,可以得到詳細的年齡、身高(厘米)、體重(公斤)、收縮壓、舒張壓和空腹血糖(毫克/分升)。這些信息可以很容易用行向量來表示,
。人工智能和機器學習的第一個挑戰來了:如果醫療記錄有十億條怎么辦?即使動用成千上萬的專業人員從中手動提取數據,這項任務也是無法完成的。因此,人工智能和機器學習利用程序來提取數據。
人工智能和機器學習的第二個挑戰是數據解讀。這是一個廣闊的領域,有許多技術值得探索。我將在后續文章中介紹相關內容。人工智能和機器學習應用除了面臨數學/計算方面的挑戰外,還面臨硬件方面的挑戰。隨著處理的數據量的增加,數據存儲、處理器速度、功耗等也成為人工智能應用面臨的重要挑戰。但現在讓我們先拋開這些挑戰,動手編寫第一行人工智能代碼。
我們將編寫一個簡單的 Python 腳本,用來將兩個向量相加。我們將用到名為 NumPy 的 Python 庫,它支持多維矩陣(數組)的數學運算。用命令 pip3 install numpy
為 Python 3 安裝 NumPy 包。如果你使用的是 JupyterLab、谷歌 Colab 或 Anaconda,那么 NumPy 應該已經被預安裝了。但是為了演示,在本系列的前幾篇文章中,我們都將在 Linux 終端上操作。在 Linux 終端上執行命令 python3
進入 Python 控制臺。在這個控制臺中可以逐行執行 Python 代碼。圖 3 展示了在控制臺中逐行運行 Python 代碼,將兩個向量相加,并輸出結果。
圖 3:兩個向量求和的 Python 代碼
首先,讓我們試著逐行理解這些代碼。由于本教程假定的編程經驗很少,所以我將代碼行標記為【基本】或【AI】。標記為【基本】的行是經典 Python 代碼,標記為【AI】的行是用于開發人工智能程序的代碼。通過區分基本和進階的 Python 代碼,我希望具有基本知識和中級編程技能的程序員都能夠高效地使用本教程。
import numpy as np #【基本】
a = np.array([11, 22, 33]) #【AI】
b = np.array([44, 55, 66]) #【AI】
c = np.add(a, b) #【AI】
print(c) #【基本】
import numpy as np
導入 numpy 庫并將其命名為 np
。Python 中的 import
語句類似于在 C/C++ 用 #include
來包含頭文件,或者在 Java 中用import
來使用包。
a = np.array([11, 22, 33])
和 b = np.array([44, 55, 66])
分別創建了名為 a
和 b
的一維數組(為了便于理解,目前假設向量等價于一維數組)。
c = np.add(a, b)
將向量 a
和b
相加,并將結果存儲在名為 c
的向量中。當然,用 a
,b
,c
作為變量名是一種糟糕的編程實踐,但數學家傾向于將向量命名為 、
、
等。如果你完全沒有 Python 編程經驗,請自行了解 Python 變量的相關知識。
print(c)
在終端上打印對象的值,即向量 [55 77 99]
。你可以暫時這樣理解向量相加, c = [55=11+44 77=22+55 99=33+66]
。如果你想正式地了解向量和矩陣是如何相加的,但手頭又沒有相關的教材,我建議閱讀維基百科上關于矩陣加法的文章。在網上搜索一下就會發現,用經典的 C/C++ 或 Java 程序來實現向量相加需要更多的代碼。這說明 Python 很適合處理向量和矩陣。當我們執行越來越復雜的向量運算時,Python 的強大將進一步顯現。
在我們結束本文之前,我要做兩個聲明。第一,上面討論的示例只處理了兩個行向量(確切地說是 1 x 3 的矩陣)的相加,但真正的機器學習應用可能要處理 1000000 X 1000000 的矩陣。但不用擔心,通過練習和耐心,我們將能夠處理這些問題。第二,本文中給出許多定義包含了粗略的簡化和不充分的描述。但如前面所說,在本系列結束之前,我將給這些模糊的術語下一個正式的定義。
現在我們該結束這篇文章了。我希望所有人都安裝文中提到的必要軟件,并運行本文中的代碼。在下一篇文章中,我們將首先討論人工智能的歷史、范疇和未來,然后深入探討線性代數的支柱——矩陣論。