深度學習火了那麼多年,到底怎麼搞?使用Numpy快速入門

人工智能越來越火,甚至成了日常生活無處不在的要素。人工智能是什麼?深度學習、機器學習又與人工智能有什麼關係?作為開發者如何進入人工智能領域?

近期我們將連載一個深度學習專題,由百度深度學習技術平臺部主任架構師畢然分享,讓你快速入門深度學習,參與到人工智能浪潮中。

從本專題中,你將學習到:

  1. 深度學習基礎知識
  2. Numpy實現神經網絡構建和梯度下降算法
  3. 計算機視覺領域主要方向的原理、實踐
  4. 自然語言處理領域主要方向的原理、實踐
  5. 個性化推薦算法的原理、實踐

本文是專題第一篇,會涉及三個知識點:

  1. 人工智能、機器學習、深度學習三者的關係,並簡要介紹了深度學習的發展歷史以及未來趨勢。
  2. 介紹構建深度模型的五個步驟,並使用Numpy實現神經網絡。
  3. 原理介紹和代碼實踐並行,詳細介紹了使用Numpy實現梯度下降算法。

深度學習介紹

對於深度學習初學者來說,容易遇到三個入門級問題:

  1. 人工智能、機器學習、深度學習三者之間關係是什麼?
  2. 一般的機器學習方法是什麼?
  3. 為什麼那麼多人看好深度學習,其未來的發展趨勢是什麼?

首先對第一個問題,以人工智能、機器學習、深度學習三者的關係開始。三者覆蓋的技術範疇是逐層遞減的,人工智能是最寬泛的概念,機器學習則是實現人工智能的一種方式,也是目前較有效的方式。

深度學習是機器學習算法中最熱的一個分支,在近些年取得了顯著的進展,並代替了多數傳統機器學習算法。所以,三者的關係可用下圖表示,人工智能 > 機器學習 > 深度學習。

深度學習火了那麼多年,到底怎麼搞?使用Numpy快速入門

圖1:人工智能、機器學習和深度學習三者之間的概念範圍

其次,對於第二個問題,一般的機器學習方法是什麼?

舉例類比,機器如一個機械的學生一樣,只能通過嘗試答對(最小化損失)大量的習題(已知樣本)來學習知識(模型參數w),期望用學習到的知識w組成完整的模型

深度學習火了那麼多年,到底怎麼搞?使用Numpy快速入門

,能回答不知道答案的考試題(未知樣本)。

最小化損失是模型的優化目標,實現損失最小化的方法稱為優化算法,也稱為尋解算法(找到使得損失函數最小的參數解)。參數和輸入X組成公式的基本結構稱為假設。

在中學期間,傾斜滑動法計算重力加速度時,基於對物體重量和作用力數據的觀測,我們提出的是線性假設,即作用力和加速度是線性關係。牛頓第二定律的驗證過程也是機器學習的參數確定過程。由此可見,模型假設,評價函數(損失/優化目標)和優化算法是構成一個模型的三個部分。

深度學習火了那麼多年,到底怎麼搞?使用Numpy快速入門

圖2:學習確定參數的方法

關於第三個問題。在深度學習框架出現之前,機器學習工程師處於手工業作坊生產的時代。為了完成建模,工程師需要儲備大量數學知識,併為特徵工程工作積累大量行業知識。每個模型是極其個性化的,建模者如同手工業者一樣,將自己的積累形成模型的“個性化簽名”。

深度學習火了那麼多年,到底怎麼搞?使用Numpy快速入門

圖3:深度學習有悠久的發展歷史,但在2010年後才逐漸成熟。

而今,“深度學習工程師”進入了工業化大生產時代。只要掌握深度學習必要但少量的理論知識,掌握Python編程即可以在深度學習框架實現極其有效的模型,甚至與該領域最領先的實現模型不相上下。建模這個被“老科學家”們長期把持的建模領域面臨著顛覆,也是新入行者的機遇。

用Python搭建神經網絡

實踐出真知,理論知識說得天花亂墜也不如多寫幾行代碼,接下來將介紹使用Numpy構建神經網絡、實現梯度下降的具體方法。本次實驗實現波士頓房價預測的迴歸模型。

應用於不同場景的深度學習模型具備一定的通用性,均分為五個步驟來完成模型的構建和訓練,使用Numpy實現神經網絡也不外乎如此,步驟如下:

  • 數據處理:從本地文件或網絡地址讀取數據,並做預處理操作,如校驗數據的正確性等。
  • 模型設計:完成網絡結構的設計(模型要素1),相當於模型的假設空間,即模型能夠表達的關係集合。
  • 訓練配置:設定模型採用的尋解算法(模型要素2),即優化器,並指定計算資源。
  • 訓練過程:循環調用訓練過程,每輪均包括前向計算 、損失函數(優化目標,模型要素3)和後向傳播這三個步驟。
  • 保存模型:將訓練好的模型保存,以備預測時調用。

下面使用Python編寫預測波士頓房價的模型,一樣遵循這樣的五個步驟。正是由於這個建模和訓練的過程存在通用性,即不同的模型僅僅在模型三要素上不同,而五個步驟中的其它部分保持一致,深度學習框架才有用武之地。

數據處理與讀取

首先進行數據處理,完成數據集劃分、數據歸一化,以及構建數據讀取生成器。代碼如下:

def load_data():

# 從文件導入數據

datafile = './work/housing.data'

data = np.fromfile(datafile, sep=' ')

# 每條數據包括14項,其中前面13項是影響因素,第14項是相應的房屋價格中位數

feature_names = [ 'CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', \\

'DIS', 'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV' ]

feature_num = len(feature_names)

# 將原始數據進行Reshape,變成[N, 14]這樣的形狀

datadata = data.reshape([data.shape[0] // feature_num, feature_num])

# 將原數據集拆分成訓練集和測試集

# 這裡使用80%的數據做訓練,20%的數據做測試

# 測試集和訓練集必須是沒有交集的

ratio = 0.8

offset = int(data.shape[0] * ratio)

training_data = data[:offset]

# 計算train數據集的最大值,最小值,平均值

maximums, minimums, avgs = training_data.max(axis=0), training_data.min(axis=0), \\

training_data.sum(axis=0) / training_data.shape[0]

# 對數據進行歸一化處理

for i in range(feature_num):

#print(maximums[i], minimums[i], avgs[i])

data[:, i] = (data[:, i] - avgs[i]) / (maximums[i] - minimums[i])

# 訓練集和測試集的劃分比例

training_data = data[:offset]

test_data = data[offset:]

return training_data, test_data

構建神經網絡

將波士頓房價預測輸出的過程以“類和對象”的方式來描述,實現的方案如下所示。類成員變量有參數 w 和 b,並寫了一個forward函數(代表“前向計算”)完成上述從特徵和參數到輸出預測值的計算過程。

class Network(object):

def __init__(self, num_of_weights):

# 隨機產生w的初始值

# 為了保持程序每次運行結果的一致性,

# 此處設置固定的隨機數種子

np.random.seed(0)

self.w = np.random.randn(num_of_weights, 1)

self.b = 0.

def forward(self, x):

z = np.dot(x, self.w) + self.b

目前已經實現了房價預測模型的前向過程,但是如何知道預測的結果呢,假設預測值為z而真是房價為y,這時我們需要有某種指標來衡量預測值z跟真實值y之間的差距。

對於迴歸問題,最常採用的衡量方法是使用均方誤差作為評價模型好壞的指標,具體定義如下:

深度學習火了那麼多年,到底怎麼搞?使用Numpy快速入門

上式中的Loss(簡記為: L)通常也被稱作損失函數,它是衡量模型好壞的指標,在迴歸問題中均方誤差是一種比較常見的形式。

由於實現的房價預測模型的權重是隨機初始化的,這個權重參數處在模型極小值的概率幾乎為0,我們需要使用梯度下降算法不斷更新權重,直到該權重處於模型的極小值或最小值附近。

Numpy實現梯度下降算法

前文已提到,構建機器學習模型的首要是從一個假設空間,構建算法,去達到這個假設空間的最優值。以下圖為例,

深度學習火了那麼多年,到底怎麼搞?使用Numpy快速入門

圖4:梯度下降方向示意圖

從隨機初始化的點達到坡底(最優值)的過程,特別類似於一位想從山峰走到坡谷的盲人,他看不見坡谷在哪(無法逆向求解出Loss導數為0時的參數值),但可以伸腳探索身邊的坡度(當前點的導數值,也稱為梯度)。

那麼,求解Loss函數最小值可以“從當前的參數取值,一步步的按照下坡的方向下降,直到走到最低點”實現。

現在我們要找出一組的值,使得損失函數最小,實現梯度下降法的方案如下:

深度學習火了那麼多年,到底怎麼搞?使用Numpy快速入門

上面我們講過了損失函數的計算方法,公式定義損失函數如下:

深度學習火了那麼多年,到底怎麼搞?使用Numpy快速入門

其中是

深度學習火了那麼多年,到底怎麼搞?使用Numpy快速入門

網絡對i第個樣本的預測值

深度學習火了那麼多年,到底怎麼搞?使用Numpy快速入門

根據公式,可以計算出L對w和b的偏導數

深度學習火了那麼多年,到底怎麼搞?使用Numpy快速入門

從導數的計算過程可以看出,因子被消掉了,這是因為二次函數求導的時候會產生因子,這也是我們將損失函數改寫的原因

這裡我們感興趣的是和,

深度學習火了那麼多年,到底怎麼搞?使用Numpy快速入門

則可以在Network類中定義如下的梯度計算函數。

梯度計算公式

深度學習火了那麼多年,到底怎麼搞?使用Numpy快速入門

藉助於Numpy裡面的矩陣操作,我們可以直接對所有 一次性的計算出13個參數所對應的梯度來。

公式看不懂沒關係。且看下述代碼如何實現梯度計算,網絡訓練和參數更新。

def gradient(self, x, y):

z = self.forward(x)

gradient_w = (z-y)*x

gradient_w = np.mean(gradient_w, axis=0)

gradient_wgradient_w = gradient_w[:, np.newaxis]

gradient_b = (z - y)

gradient_b = np.mean(gradient_b)

return gradient_w, gradient_b

def update(self, graident_w5, gradient_w9, eta=0.01):

net.w[5] = net.w[5] - eta * gradient_w5

net.w[9] = net.w[9] - eta * gradient_w9

def train(self, x, y, iterations=100, eta=0.01):

points = []

losses = []

for i in range(iterations):

points.append([net.w[5][0], net.w[9][0]])

z = self.forward(x)

L = self.loss(z, y)

gradient_w, gradient_b = self.gradient(x, y)

gradient_wgradient_w5 = gradient_w[5][0]

gradient_wgradient_w9 = gradient_w[9][0]

self.update(gradient_w5, gradient_w9, eta)

losses.append(L)

if i % 50 == 0:

print('iter {}, point {}, loss {}'.format(i, [net.w[5][0], net.w[9][0]], L))

return points, losses

運行代碼後,從下面這個圖裡可以清晰的看到損失函數的下降過程。

深度學習火了那麼多年,到底怎麼搞?使用Numpy快速入門

圖5:損失函數下降過程

總結一下,本文以機器學習深度學習概述開篇,講解了深度學習的基礎知識,通過使用Numpy實現房價預測模型,詳細講解了構建深度學習模型的五個步驟,以及梯度下降的基本原理、如何使用Numpy實現梯度下降等內容,希望對你入門深度學習有幫助。

最後,小編想說:我是一名python開發工程師,

整理了一套最新的python系統學習教程,

想要這些資料的可以關注私信小編“01”即可(免費分享哦)希望能對你有所幫助

正在學習python的小夥伴或者打算學習的,可以私信小編“01”領取資料!


分享到:


相關文章: