如何使用Elixir語言實現深度學習?剖析多層神經網絡的構建和訓練

2020-12-17 機器之心Pro

選自automating the future機器之心編譯參與:Jane W、吳攀

在這篇文章中,作者們使用 Elixir 程式語言創建一個標準的 3x3 深度學習神經網絡。希望讀者能通過閱讀本文而對先進的遺傳編程(genetic programming)和 Elixir 中新的人工智慧技術有更深的理解。

開篇語

研究深度學習如從事巫術般瘋狂。人們必須花費相當多的時間理解技術,同時在創造真正自動化的東西時考慮其優點和缺點,還要在半夜醒來時擔心自動化將對我們的社會造成多大的顛覆。

創建你的第一個神經網絡是比較簡單的,在過程中你可以看到如何用少量的代碼來自動完成一項給定的任務。

在這篇文章中,我們將使用 Elixir 程式語言創建一個標準的 3x3 深度學習神經網絡。希望讀者能通過閱讀本文而對先進的遺傳編程(genetic programming)和 Elixir 中新的人工智慧技術有更深的理解。

用途

現在的大數據需要未來的自主深度學習系統。為了掌握這些系統工作的原理,我們將構建一個標準的神經網絡來學習一個小的問題集。

我發現用 Elixir 從頭開始設計和構建這些類型的系統時,有三件事是有幫助的。讀者可以參考以下連結作為輔助:

1. 對 Elixir 和 Erlang OTP 生態系統的基本了解:http://elixir-lang.org/getting-started/introduction.html

2.Numerix(一種基於 Elixir 的機器學習庫,由 Safwan Kamarrudin 編寫):https://github.com/safwank/Numerix

3.Matrix(用於計算矩陣的有用的庫,由 Tom Krauss 編寫):https://github.com/twist-vector/elixir-matrix

還有其它的 Elixir 包(如 Tensor)允許 Elixir 開發者做出一些複雜的東西,但這裡我們將只介紹 Matrix 和 Numerix。

範式

正如前面討論的,未來的神經網絡自動化解決問題的方式與傳統訓練的編程模型解決問題的方式有很大的不同。這些系統通過樣本進行學習。訓練者提出所期望的目標或系統實現的目標,並且給系統提供訓練樣本,直到系統學習如何達到想要的目標(target)。

如果通過人類語言溝通,計算機很難理解生活的細微差別,以及我們想要和需要什麼。然而,如果機器通過數字和浮點整數表示實際的數據和問題,那麼奇蹟般地,它們可以開始解決問題並理解人類!

對於新的軟體系統,由過程/對象(procedural/object)驅動的編程現在開始轉變為由統計數學/數據(statistical-mathematical/data)驅動的方法。這種新的模式轉變是至關重要的,以鑑別讀者是否計劃在技術行業保持相關性。自從 2011 年 Jeopardy 節目上 WATSON 的到來,老的編程和解決問題的方式已經死了。擁抱這種數據驅動的統計模式的公司將最終領導整個技術行業。

並沒有明確的程序指示 WATSON 在那晚的節目上做什麼。事實上,WATSON 甚至不知道它會得到什麼問題。它所擁有的只是數據、學習算法和多層神經網絡。

我們在這裡將構建的神經網絡不會像 WATSON 那樣複雜,但能夠說明多層網絡的概念以及工作的原理。

問題

假設我們有一個數字序列,它可以表示特定問題空間中的任何東西。讓我們假設這個數字序列是 1、0 和 0。這會組成一個看起來像 [1,0,0] 的列表(list)。

但是,這個列表是一個問題。我們想要實現一個都是 1 的序列。該列表表示為 [1,1,1]。這個數字列表可以當作我們的目標。

我們的問題空間,簡而言之,列在下表中:

我們將輸入與希望得到的目標一起列出。

我們希望系統能夠區分輸入數據與目標數據,因此我們還需要一個隨機數據集,以便與目標進行比較。該隨機數據集被稱為訓練集。神經網絡用這個訓練集來學習如何得到預測結果。加入新增的訓練集數據,我們的圖表變成下圖:

設計

在計算機中表示神經網絡的最佳方式是通過矩陣。矩陣是線性代數的有用工具,它允許我們對數字向量進行操作。

從圖表中可以看出,有 3 列和 3 行。此圖表可表示一個 3x3 的矩陣!

主體的神經網絡模型表示為線性代數矩陣列表。數組(array)中的每個元素可以被認為是一個節點/神經元。每個神經元負責計算和生成輸出,輸出又會影響整個神經網絡系統。

多層神經網絡分為三部分。第一部分稱為輸入層。第二層稱為隱藏層。最後一部分稱為輸出層。非常複雜的網絡有多個隱藏層,但是對於本文的例子,我們只有一個隱藏層。

當我們從左到右顯示數據流時,我們神經網絡的圖片看起來像這樣:

數據流從左到右IL 代表輸入層(Input layer),HL 代表隱藏層(hidden layer),OL 代表輸出層(output layer)每個神經元在網絡內表示。我們建立一個 3x3 的網絡,因此有 9 個神經元。

如果我們將圖表變成這樣的架構,它的可視化看起來如下:

I= 輸入,h 表示隱藏,而 o 表示輸出。每個數字對應於上面數據圖表上列出的數字。

這是我們希望神經網絡做的。我們需要它來計算輸入,並將其變成我們想要的輸出!

代碼

現在我們要做的第一件事是創建 Elixir 項目。我決定叫它「DEEPNET」。我們想要一個 Supervisor 讓這個項目能更自動化啟動,所以我們使用命令:

mix new deepnet --sup

這條命令創建了一個帶有 supervisor 的 Elixir 項目。

加載相關包

接下來要做的是加載所需的相關包。我上面提到了 Numerix 和 Matrix,我也加載了 sfmt,以確保我們的隨機權重確實是隨機的。

開始應用

我們需要一種方法讓 Supervisor 自動啟動我們的神經網絡。因為想要一個 3x3 的架構,我們需要創建 9 個神經元。這意味著每層都需要有 3 個神經元。這些神經元可以在啟動時創建。我們編寫一個啟動函數來告訴 Supervisor 這樣做。

應用的 Supervisor 引用了 Deepnet.Network 模塊(我們將在下面介紹)。我們還需要設定神經網絡在每一層創建的節點數。

創建網絡

我們在這裡引用一個 create 函數。這將有助於 Supervisor 下面的工作。create 函數將處理這些數字列表。因為這些數字代表層中的神經元。將初始狀態(state)存儲在 Elixir 代理(agent)中可能比較明智。

每個參數對應於層中的多個節點。第 4 個參數是學習速率(learning rate),默認為 1.0。這將在後面進一步闡釋。

初始化隨機權重

如果你一直在學習 ATF,你可能會記得所有神經元都需要與其相關的權重。我們希望權重儘可能隨機。這種隨機化使我們相信我們在訓練期間已經收斂到正確的解決方案。神經網絡的訓練重點是找到適合於當前特定問題的適當權重。對於每個神經元,我們需要一個函數來創建 9 個不同的權重。我們的計算也需要考慮偏差(bias)。這個函數如下:

首先,我們利用 sfmt 來播種我們的時間戳以幫助確保我們獲得隨機權重。接下來我們為輸入生成隨機權重。但是,我們不想止於此。這會有助於增加新的偏差以便真正平衡我們的權重,隨意從一個 0.5 的矩陣減去我們的輸入權重將能給我們一個很好的隨機化的權重分類以開始。最終,我們使用這些初始化的權重對網絡進行了更新。我們的 9 個權重應該看起來像這樣:

網絡中所有神經元所對應的隨機權重。它的優點在於有一個負權重和正權重的組合

現在我們馬上能夠得到權重了。讓我們先看看矩陣的大小。

現在我們有 3x3 的初始化權重結構。我們的整個神經網絡現在看起來像這樣

我們的神經網絡被表示為 Elixir Struct。除錯誤率和目標(我們將在下一步探索)之外,我們已經設置好所有的數值。

計算誤差

神經網絡需要不斷地反饋預測性能。這個反饋是通過我們所說的錯誤率(error rate)收集的。有不同的計算錯誤率的方法,其方法完全取決於個人。在本文中,我們將使用 MSE,即均方誤差(Mean Squared Error)。

神經網絡在訓練期間的工作是不斷的將其輸出與訓練期間給出的目標輸出進行比較。我們需要一種方法來計算並存儲神經網絡的錯誤,以便我們監控訓練的效果。這個函數的形式很明確:

我們取得神經網絡的最終輸出和初始輸入。然後將整個網絡的最終輸出與目標進行比較,以便我們可以計算均方誤差。

我們引用了 List.flatten/1 函數,旨在將我們的多維列表改為單個列表,使計算更加容易。

最後,我們通過使用神經網絡新的錯誤率來更新代理。

調整網絡權重

在上面函數的最後一行你可能已經注意到對 Deepnet.Network.adjust_weights/2 函數的引用。這個步驟很重要。在訓練期間,如果神經網絡發現與訓練的目標發生偏離,它需要一種方法來改進。剛才我提到了學習速率常數。這就是改進神經網絡要用到的。讓我們來探索 Deepnet.Network.adjust_weights/2 函數:

用 adjust_weights 函數接受圖層的輸出和初始輸入接下來要做的是計算 delta(增量)。這裡我們得到目標與輸出的差異,並計算該結果的點積。這兒需要單獨的計算,即 delta(或小變化)計算。接下處理梯度(gradient),這是我們能做的使我們更接近最終目標的最小幅變化。因為我們可以處理許多輸出,我們將並行(parallel)映射(map)所有輸出的梯度計算。梯度計算定義為:輸出 x delta x learning_rate(學習速率)這個學習速率可以是從 1.0 到 3.0 的任何值。也有人用其它的值域。它取決於神經網絡的創建者以及需要多快的學習進度。在我們的例子中,我將使用 1.0,因為這個問題並不重要。最後,取當前的權重,並從梯度中減去它們得到新權重。然後為網絡更新新權重。

計算神經元輸出

你可能想知道如何產生連續傳入函數的輸出。我們需要一種方法來計算每個神經元的輸出。這裡有一篇博客來幫助你複習神經元如何計算其輸出(http://www.automatingthefuture.com/blog/2016/10/2/the-power-of-activating-the-artificial-neurons)。

對於我們的特定問題集,我們將使用 sigmoid 函數作為我們的激活函數(activation function)。記住,神經元內部的數據信號經過 3 個階段。第一階段是計算輸入和權重的總和或點積。下一階段是使用激活函數。最後一個階段是加入偏差。我們已經在初始化權重時計入了偏差,所以我們的函數不需要有那個部分。那麼我們所有要做的事是階段 1 和 2。

這裡我們取輸入和權重並做並行映射。每個權重對應一個輸入,所以在 Elixir 中我們可以將它們壓縮成元組(tuple)。元組的第一個元素是輸入,第二個元素是權重。對於每個輸入和權重,我們計算:點積(dot_product)/總和 summation。接下來,我們使用 Numerix.Special.logistic/1 函數,它本質上是另一個名稱的 sigmoid 函數。

因為我們需要將每一個計算中結果作為一個列表,我們然後打包結果以形成適當形式的輸出。

我們現在可以計算、神經元的輸出。但是,在完成之前還需要一個步驟。我們需要一種將數據從一層移動到下一層的方法。將數據從上一層移動到下一層的這個過程被稱為前饋(feed-forward)。由於我們將數據從輸入層前饋到隱藏層,然後將隱藏層的輸出傳送到輸出層,因此我們基本上將數據前饋兩次。幸運的是,我們可以很容易的通過 Elixir 的模式匹配做到這一點。

第一個前饋僅接受輸入列表,並計算輸入層與隱藏層相連接的輸出。然後將該結果傳遞到第二個前饋函數。

第二個前饋函數接收前一層的輸出以及前一層的舊權重和原始輸入。然後計算最終輸出。至此整個神經網絡的計算結束。在這裡,通過計算網絡中的錯誤率,我們可以看到得到的結果有多好。

過程

學習是一個重複的過程。如果我們的網絡沒有得到正確的解決方案,它必須再次重複整個過程,直到得到正確結果。每次神經網絡將對其自身進行小幅調整,直到達到其最終目標。可以認為這個過程是一個巨大的學習循環。

每次循環完成並且網絡再次啟動以便最小化錯誤時,我們將該過程稱為反向傳播(back propagation)。這是因為誤差通過網絡傳播以進行重新調整。這就是現代系統與傳統系統的區別。傳統系統不得不等待人類來解決存在的錯誤。現代系統想要最大限度地減少它們的錯誤率,並力求完美從而減輕工程師的維護負擔。從解決問題的角度,希望你開始看到這種好處!

訓練自動化

對於神經網絡,自動化訓練過程總是一個好辦法。有時候,對特定問題集的訓練可能需要幾個小時甚至幾天。手動執行這個過程是不明智的,所以我們將編寫一個函數來處理這個過程。

首先,我們取輸入列表和目標列表。然後,我們將輸入和目標都轉換成二維列表。然後我們用目標更新我們的代理,使它不再為零。最後,我們開始前饋過程。

學習自動化

如前所述,學習過程是一個循環。Elixir 是一種功能語言,這使得我們能夠使用函數來處理循環。在我們的循環中,我們需要收集輸入和目標,並將其傳入到網絡中。網絡訓練數據並計算錯誤率。我們希望得到的錯誤率最小。因此我希望網絡訓練的誤差率低於 0.02。如果發現其錯誤率高於 0.02,那麼它必須繼續訓練。這就是學習過程。神經網絡必須經歷重複循環,直到學習的任務幾乎沒有錯誤。我們可以通過模式匹配(pattern matching)實現:

第一個學習函數接收網絡的錯誤率、用戶數據和 epoch。epoch 是神經網絡迭代一次的周期。你可以認為一個 epoch 就是一個網絡的時間長。此函數僅在我們的錯誤率高於 0.02 時被調用。調用該函數將向系統表明它需要更多的訓練。每次訓練循環後 epoch 的數值增加 1。如果錯誤率小於 0.02,則提取錯誤率並傳入最終的學習函數。如果不是,我們稱它為當前的學習函數。第二個學習函數採用相同的參數,但它被當作停止函數(stopping function)。當訓練完成並且達到可以接受的錯誤率時使用此函數。它表明我們的系統已經完全訓練了數據集,並準備好進行測試。

最後我們需要做的是為我們的用戶輸入和目標創建數據結構(data struct)。然後,這個信息將傳遞給一個能夠啟動整個過程的學習函數。

我們原始的數據表定義為一個結構。

現在我們通過最終函數來啟動整個過程:

這裡我們初始化隨機權重,並將我們的用戶數據和我們想要的目標傳遞給網絡。接下來,我們通過傳入錯誤率、用戶數據和我們網絡的 epoch(第一次啟動的初始值為 0)來調用我們的學習函數。

現在,我們的網絡已經完全建成了。當我們啟動程序時會發生什麼?

成了!我們可以看到用了 13 個 epoch 來完成訓練。我們的網絡終於達到我們的目標列表 [1,1,1],並且有低於 0.02 的錯誤率!這非常令人吃驚。

結論

你可能會想,這有什麼意義?如何在實際中使用它?機器學習的重要性對於下一個技術時代是至關重要的,它允許工程師處理大量的數據,同時訓練系統來得到洞察或預測結果,並解決我們可能無法得到線索的問題。正如我們剛才見到的,我們可以看到這些系統如何擅長最小化錯誤,這在現實中是無價的。

神經網絡的美麗之處在於,我們可以用不同的方式構建它們,在我們的軟體系統中創建類似人類的智能。在本文中,我們沒有介紹所有的算法和這些網絡架構不同的方式。未來的自動化目標是繼續為 Elixir 社區提供如何使用神經網絡解決各種各樣的問題的精彩例子。

現在我們知道如何設計一個基本的多層神經網絡,我們可以應用到一些真正自動化軟體系統的優秀的案例項目,以便學習和解決我們未來遇到的不同類型的問題。我將相關 Deepnet 代碼放在了 GitHub 上,有興趣可以查閱 https://github.com/TheQuengineer/deepnet。你可以 fork、實驗和更改代碼。這個帖子可以作為 Elixir 社區的一個例子,作為從頭開始學習設計深度學習網絡的一種方式!

相關焦點

  • 教程| 如何使用TensorFlow構建、訓練和改進循環神經網絡
    目前有很多人工智慧應用都依賴於循環深度神經網絡,在谷歌(語音搜索)、百度(DeepSpeech)和亞馬遜的產品中都能看到RNN的身影。然而,當我們開始著手構建自己的 RNN 模型時,我們發現在使用神經網絡處理語音識別這樣的任務上,幾乎沒有簡單直接的先例可以遵循。
  • 為什麼深度神經網絡這麼難訓練?
    假設你能使用某種特殊的邏輯對任意多的輸入執行AND運算,還能使用多輸入的與非門對多個輸入執行AND運算和NOT運算。由這類特殊的邏輯門構建出來的雙層深度電路就可以計算任何函數。 理論上成立並不代表這是一個好的想法。在實際解決電路設計問題或其他大多數算法問題時,通常要考慮如何解決子問題,然後逐步集成這些子問題的解。換言之,要通過多層抽象來得到最終解。
  • 神經網絡和深度學習簡史(全)
    讓我告訴你,說來話長——這不僅僅是一個有關神經網絡的故事,也不僅僅是一個有關一系列研究突破的故事,這些突破讓深度學習變得比「大型神經網絡」更加有趣,而是一個有關幾位不放棄的研究員如何熬過黑暗數十年,直至拯救神經網絡,實現深度學習夢想的故事。
  • 推薦| 九本不容錯過的深度學習和神經網絡書籍
    搭建你自己的神經網絡(Make Your Own Neural Network)價格:45 美元一步步讓你了解神經網絡的數學原理並用 Python 搭建自己的神經網絡。神經網絡是深度學習和人工智慧的關鍵元素。然而,幾乎很少有人真正了解神經網絡如何運作。本書從非常簡單的思想開始,讓你在趣味和從容不迫中,逐漸了解神經網絡的運作原理。2.
  • 為什麼深度神經網絡這麼難訓練?|贈書
    假設你能使用某種特殊的邏輯對任意多的輸入執行AND運算,還能使用多輸入的與非門對多個輸入執行AND運算和NOT運算。由這類特殊的邏輯門構建出來的雙層深度電路就可以計算任何函數。理論上成立並不代表這是一個好的想法。在實際解決電路設計問題或其他大多數算法問題時,通常要考慮如何解決子問題,然後逐步集成這些子問題的解。換言之,要通過多層抽象來得到最終解。
  • 推薦 九本不容錯過的深度學習和神經網絡書籍
    搭建你自己的神經網絡(Make Your Own Neural Network)價格:45 美元一步步讓你了解神經網絡的數學原理並用 Python 搭建自己的神經網絡。神經網絡是深度學習和人工智慧的關鍵元素。然而,幾乎很少有人真正了解神經網絡如何運作。
  • 什麼是深度學習? - 45分鐘理解深度神經網絡和深度學習
    為了使學生們能夠更好、更快理解和使用深度神經網絡和深度學習,特撰寫此文。本文的目的是幫助非人工智慧領域的學生(主要是計算機圖形學領域的學生及筆者的學生)來搞懂深度學習(這裡指狹義的深度學習,即基於DNN的深度學習)的基本概念和方法。筆者嘗試用通俗的語言,從函數逼近論的角度來闡釋深度神經網絡的本質。
  • 神經網絡與深度學習
    隱藏層使得感知機能夠發展為擬合萬物的神經網絡模型,而反向傳播算法則是整個神經網絡訓練的核心要義。要學習深度學習,恐怕不得不先溫習一下機器學習,搞清楚二者之間的關係。簡單來說,機器學習就是從歷史數據中探索和訓練出數據的普遍規律,將其歸納為相應的數學模型,並對未知的數據進行預測的過程。
  • 深度學習之用Go語言構建一個屬於自己的神經網絡(附代碼)
    Go語言完全從頭開始構建簡單神經網絡的初學者指南介紹在本文中,我們將完全從頭開始在Golang中構建一個簡單的神經網絡(單層感知器)。我們還將在樣本數據上訓練它並進行一些預測。從頭開始創建自己的神經網絡將會更好地了解神經網絡內部發生的情況,對之後學習算法的工作更加了解。什麼是感知器?感知器由弗蘭克·羅森布拉特於1958 年發明,是最簡單的神經網絡,由n個輸入,一個神經元和一個輸出組成,其中n是數據集的特徵數量。
  • 深度學習:神經網絡算法的昨天、今天和明天
    深度學習就是人工神經網絡(Artificial Neural Network)。神經網絡算法得名於其對於動物神經元傳遞信息方式的模擬,而深度學習這一「俗稱」又來自於多層級聯的神經元:眾多的層讓信息的傳遞實現了「深度」。
  • Halcon實戰之基於MLP多層神經網絡的訓練學習
    MLP多層感知器其實是一種人工神經網絡結構,屬於非參數估計,可以用於解決分類和回歸問題。
  • 神經網絡太難?學習如何用你擅長的 Java 庫來快速實現它!
    本文主要內容是首先介紹神經網絡的發展從McCulloch和Pitt的神經元開始,然後通過Hebb的發現,實現了Rosenblatt的感知器來增強它,並說明了它為什麼不能解決XOR問題。其次介紹了通過連接神經元,生成一個多層感知器,並通過應用反向傳播算法進行學習,從而實現XOR問題的解決方案。
  • 深度森林第三彈:周志華組提出可做表徵學習的多層梯度提升決策樹
    此外,與層級表徵的神經網絡不同,他們提出的方法並不要求每一層都是可微,也不需要使用反向傳播更新參數。因此,多層分布式表徵學習不僅有深度神經網絡,同時還有決策樹!近十年來,深層神經網絡的發展在機器學習領域取得了顯著進展。
  • 《神經網絡和深度學習》系列文章四:神經網絡的結構
    本節譯者:哈工大SCIR碩士生 徐偉 (https://github.com/memeda)聲明:我們將在每周一,周四,周日定期連載該書的中文翻譯,如需轉載請聯繫wechat_editors@ir.hit.edu.cn,未經授權不得轉載。
  • 使用GPU和Theano加速深度學習
    GPU和Theano加速深度學習,教程從多層感知器到卷積神經網絡,由淺入深,是不錯的入門資料。【編者按】GPU因其浮點計算和矩陣運算能力有助於加速深度學習是業界的共識,Theano是主流的深度學習Python庫之一,亦支持GPU,然而Theano入門較難,Domino的這篇博文介紹了如何使用GPU和Theano加速深度學習,使用更簡單的基於Theano的 Nolearn庫。教程由多層感知器及卷積神經網絡,由淺入深,是不錯的入門資料。
  • (圖解)類神經網絡的復興:深度學習簡史
    這使得類神經網絡在剛出現時雖大為火紅、卻在不久後又沒落了下去。經歷了單層感知機、和多層感知機的兩次失敗,當時的學界只要看到出現「神經網絡」字眼的論文或研究計劃,便會立刻貶斥,認為:多層的神經網絡是不可能的。然而若採用僅有兩層的神經網絡,不如使用其他理論更完備也更好實踐、同樣只有兩層的「淺層」機器學習模型。
  • 多倫多大學2021《機器學習》課程,講述深度學習理論中的神經網絡訓練動力學
    畢竟,深度學習優化是非凸的、高度非線性的、高維的,那麼我們為什麼能夠訓練這些網絡呢?在許多情況下,它們擁有的參數遠遠多於記憶數據所需的參數,那麼為什麼它們能夠很好地推廣呢?儘管這些主題已經佔據了機器學習研究領域的大部分注意力,但當涉及到更簡單的模型時,神經網絡領域的原則是先數據訓練再說。顯然,這招奏效了。
  • 神經網絡和深度學習簡史(第一部分):從感知機到BP算法
    這一部分,我們會介紹1958年感知機神經網絡的誕生,70年代人工智慧寒冬以及1986年BP算法讓神經網絡再度流行起來。深度學習掀起海嘯如今,深度學習浪潮拍打計算機語言的海岸已有好幾年,但是,2015年似乎才是這場海嘯全力衝擊自然語言處理(NLP)會議的一年。——Dr. Christopher D.
  • 【深度學習最精煉中文講義】前饋與卷積神經網絡詳解,復旦邱錫鵬老師《神經網絡與深度學習》報告分享02(附報告pdf下載)
    1947 年圖靈就已經闡述了如何對機器學習的結果進行檢查的方法,而且這一方法是很有遠見和可操作性的。1948年圖靈在論文中描述了一種「B型圖靈機」。神經網絡研究的另一個突破是在1958 年。1974年哈佛大學博士Paul Werbos在博士論文中提出了用誤差反向傳導來訓練人工神經網絡有效地解決了異或迴路問題,使訓練多層神經網絡成為可能,但是並未受到重視。
  • 人工智慧-Andrew Ng版|神經網絡和深度學習|深度學習概述
    About this Course這裡列一下本系列深度學習專項課程有哪些:第一門課程 Nerual Networks and Deep Le arning 神經網絡和深度學習將學習神經網絡和深度學習將學習如何建立神經網絡(