頂級程序員書單系列三:《深度學習入門-基於Python的原理與實現》

推薦理由

這本書用非常簡單精妙的思想講述了深度學習的基本原理。我感覺這本書告訴了我一個很重要的道理,如果你讀了很多書都沒有把一個概念讀懂,那可能真的不一定是你的問題,還有可能是書的問題。一個好的老師,就應該把班裏最笨的學生教會(如果他願意學的話)。我想這本書,可以在我的頂級程序員書單系列排名第3-5位,非常值得一讀。

我的部分筆記

深度學習經驗
1.更深入地理解深度學習,最好的辦法就是親自實現。
2.光看數學公式和理論說明無法理解的情況下,可以嘗試閱讀源代碼並運行。

Pyhon基本入門
import numpy as np
import matplotlib.pyplot as plt
if name == ‘main’:
print(“Hello world”)
print(1 + 2)
print(type(10))
a = [1, 2, 3, 4, 5]
print(a)
print(a[0:2])
me = {‘height’ : 180}
me[‘weight’] = 70
print(me[‘height’])
print(me)
print(True and False)
for i in [1, 2, 3]:
print(i)
def hello():
print(“I Love u”)
hello()

x = np.array([1.0, 2.0, 3.0])
y = np.array([2.0, 4.0, 6.0])
print(x + y)
print(x * y)

A = np.array([[1, 2], [3, 4]])
print(A)
print(A.shape)
# 數學上將一維數組稱爲向量,二維數組成爲矩陣,三維數組稱爲張量
# 廣播:形狀不同的數組進行運算稱爲廣播
B = np.array([10, 20])
print(A * B)
print(A[0])
print(A[1][0])

# 以0。1爲單位,生成0到6的數據
x = np.arange(0, 6, 0.1)
y = np.sin(x)
plt.plot(x, y)
# plt.show()

感知機
感知機是什麼:
感知機接收多個信號,輸出一個信號
神經元計算輸出信號總和,大於閾值(yu zhi)Θ時信號被激活
【x1】——w1——>
【y】
【x2】——w2——>

感知機原理:
w1 * x1 + w2 * x2 <= Θ ?y = 0 : y =1

感知機表示與門,非門,或門:
與門需要滿足的條件
if name == ‘main’:
def AND(x1, x2):
w1, w2, theta = 0.5, 0.5, 0.7
tmp = x1 * w1 + x2 * w2
if tmp <= theta:
return 0
elif tmp > theta:
return 1

print(AND(0, 0))
print(AND(1, 0))

(x1 = 0, x2 = 0) => y = 0
(x1 = 1, x2 = 0) => y = 0
(x1 = 0, x2 = 1) => y = 1
(x1 = 1, x2 = 1) => y = 1

(w1 , w2, Θ) 取 (0.5, 0.5, 0.7)或(1.0, 1.0, 1.0)均可滿足條件
類似的感知機也可以表示非門,或門

感知機的實現:
爲了計算方便,我們把Θ換成-b(偏置),可以進行移項操作了
-b的作用是調整神經元被激活的容易程度
w1 * x1 + w2 * x2 <= Θ ?y = 0 : y =1 ->
w1 * x1 + w2 * x2 <= -b ?y = 0 : y =1 ->
b + w1 * x1 + w2 * x2 <= 0 ?y = 0 : y =1

異或門:
^
|1 0
|0 1
|————>
因爲之前的模型(單層感知機)是線性的切割了,放在這裏就不可以了
感知機的絕妙之處在於它可以“疊加層”

感知機實現異或門
def AND(x1, x2):
x = np.array([x1, x2])
w = np.array([0.5, 0.5])
b = -0.7
tmp = np.sum(w*x) + b
if tmp <= 0:
return 0
else:
return 1

def NAND(x1, x2):
x = np.array([x1, x2])
w = np.array([-0.5, -0.5])
b = 0.7
tmp = np.sum(w*x) + b
if tmp <= 0:
return 0
else:
return 1

def OR(x1, x2):
x = np.array([x1, x2])
w = np.array([0.5, 0.5])
b = -0.2
tmp = np.sum(w*x) + b
if tmp <= 0:
return 0
else:
return 1

def XOR(x1, x2):
s1 = NAND(x1, x2)
s2 = OR(x1, x2)
y = AND(s1, s2)
return y

print(XOR(0, 0))
print(XOR(0, 1))
print(XOR(1, 0))
print(XOR(1, 1))

與門或門是單層感知機,而異或門是2層感知機
XOR函數等價於:
【x1】———— 【s1】—
X y
【x2】———— 【s2】—

啓示:單層感知機無法解決的東西,通過增加一層便可以解決

感知機總結
感知機是具有輸入和輸出的算法,在給定一個輸入後,講述出一個既定的值
感知機將權重和偏置設爲既定參數
使用感知機可以表示與門和或門等邏輯電路
異或門無法通過單層感知機來表示
使用兩層感知機表示異或門
單層感知機只能表示線性空間,多層感知機可以表示非線性空間
多層感知機在理論上可以表示計算機
即便對於複雜的函數,感知機也隱藏着能夠表示它的可能性
壞消息是,設置權重的工作,現在還是人工進行的

神經網絡
神經網絡就是爲了解決感知機只能手動調參的問題
神經網絡的一個重要性質是它可以自動地從數據中學習到合適的權重參數
網絡的名稱:輸入層,中間層,輸出層的總數減去1
前文提到的感知機b + w1 * x1 + w2 * x2 <= 0 ?y = 0 : y =1
可以用函數來表示
y = { 0 ( b+w1x1+w2x2 <= 0 )
{ 1 ( b+w1x1+w2x2 > 0 )
我們可以通過引入新的式子y=h( b + w1x1 + w2x2)將上面的函數轉換爲
h(x) = { 0 ( x <= 0 )
{ 1 ( x > 0 )
引入激活函數的概念:將輸入信號的總和轉換爲輸出信號,將上面式子拆分如下
Y = h(a) 其中 a = b + w1x1 + w2x2
a表示輸入信號的總和,h( ) 表示激活函數,y表示輸出,h( ) 將輸入信號a轉化爲了輸出信號y

激活函數的重要地位:是連接感知機和神經網絡的重要橋樑

神經網絡各層信號傳遞
第一層:a1 = w11x1 + w12x2 + b1
第一層的圖 == A = XW + B
第二層和第一層的激活函數不同
第一層使用sigmoid函數,第二層使用恆等函數
輸出層的激活函數,根據問題的性質決定

一般地,迴歸問題可以使用恆等函數
二元問題可以使用sigmoid函數
多元問題可以使用softmax函數

3層神經網絡的實現
import numpy as np
if name == ‘main’:
def init_network():
network = {}
network[‘W1’] = np.array([[0.1, 0.3, 0.5], [0.2, 0.4, 0.6]])
network[‘b1’] = np.array([[0.1, 0.2, 0.3]])
network[‘W2’] = np.array([[0.1, 0.4], [0.2, 0.5], [0.3, 0.6]])
network[‘b2’] = np.array([[0.1, 0.2]])
network[‘W3’] = np.array([[0.1, 0.3], [0.2, 0.4]])
network[‘b3’] = np.array([[0.1, 0.2]])
return network

def forward(network, x):
    W1, W2, W3 = network['W1'], network['W2'], network['W3']
    b1, b2, b3 = network['b1'], network['b2'], network['b3']

    a1 = np.dot(x, W1) + b1
    z1 = sigmoid(a1)
    a2 = np.dot(z1, W2) + b2
    z2 = sigmoid(a2)
    a3 = np.dot(z2, W3) + b3
    y = identity_function(a3)

    return y

def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def identity_function(x):
    return x

network = init_network()
x = np.array([1.0, 0.5])
y = forward(network, x)
print(y)

softmax
import numpy as np
if name == ‘main’:
def softmax_old(a): # 存在溢出風險
exp_a = np.exp(a) # 指數函數
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return y

def sofymax(a):
    c = np.max(a)
    exp_a = np.exp(a - c) # 溢出對策
    sum_exp_a = np.sum(exp_a)
    y = exp_a / sum_exp_a
    return y

a = np.array([0.3, 2.9, 4.0])
y = softmax_old(a)
print(y)
print(np.sum(y))

一般而言,使用softmax可以用概率的方法來處理問題,
實際上數組的大小關係沒有發生特別大的變化
神經網絡只把輸出值最大的神經元作爲結果進行識別
在神經網絡分類時,輸出層softmax可以省略
在實際問題中,由於指數函數需要計算,softmax也可以省略

手寫數字識別
批處理:批處理對計算機的運行大有益處,可以大幅度縮短每張圖像的處理時間
爲什麼批處理可以縮短處理時間?
因爲大多數處理數值運算的庫都進行了能高效處理大型數組運算的最優化
並且,在神經網絡的運算中,當數據傳送爲瓶頸時,批處理可以減輕數據總線的負荷
(嚴格地講,相對於數據讀入,可以將更多的時間用在計算上)
也就是說,批處理一次性計算大型數組要比分開逐步計算各個小型數組更快

神經網絡中的學習
數據—————人想到的算法—————答案
數據——人想到的特徵量(SIFT,HOG)—機器學習(SVM,KNN)—答案
數據——神經網絡(深度學習)—答案

損失函數
均方誤差:均方誤差會計算神經網絡的輸出和正確解監督數據的各個元素之差的平方

def mean_squared_error(y, t):
return 0.5 * np.sum((y - t) ** 2)
交叉熵誤差:它的值是由正確標籤所對應的輸出結果決定的

def cross_entropy_error(y, t):
delta = 1e-7;
return -np.sum(t * np.log(y + delta))

Mini-batch:假設訓練數據有6w個,從其中隨機選擇100個來訓練
思想:用隨機選擇的小批量數據作爲全體訓練數據的近似值

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章