-
激活函數
激活函數的存在,是神經網絡與感覺機不同的地方。
神經網絡的激活函數必須使用非線性函數!
- sigmoid函數
g(x)=1/(1+exp(−x))g(x)=1/(1+exp(-x) ) g(x)=1/(1+exp(−x))
![sigmoid函數表達式為:g(x)=1/(1+e^(-x) );](https://secure1.wostatic.cn/static/81mgxiAPGXreqKe11SLQfY/sigmoid.jpg)
Sigmoid函數其定義域在全體實數,值域在[0,1]之間,并且在0點位置為0.5。 當x的取值為[-∞,0]時,g(x)<=0; 當x的取值為[0,+∞]時,g(x)>=0; Sigmoid函數具有兩個非常好的性質: (1):當x趨近于正無窮時,g(x)趨近于1,當x趨近于負無窮時,g(x)趨近于0.這一點非常适合做分類機率模型。 (2):除此之外,sigmoid函數還具有一個很到的導數性質,即sigmoid函數時任意階可導的凸函數。
** 2. ReLu函數**
ReLu函數是最近才開始使用的函數,**ReLu函數在輸入大于0時,直接輸出該值;在輸出小于等于0時,輸出0。**
- softmax函數
softmax函數一般用于神經網絡的輸出層,softmax函數的性質是:softmax函數的輸出是0.0~1.0之間的實數,并且softmax函數的輸出值的總和是1**。**是以我們可以把softmax函數的輸出解釋為“機率”。
即便是使用softmax函數,輸出值最大的神經元的位置也不會改變。
sigmoid激活函數
def sigmoid(x):
return 1/(1+np.exp(-x))
#ReLu激活函數
def ReLu(x):
if x < 0:
return 0
else:
return x
#softmax激活函數(輸出層)
def softmax(x):
exp_x = np.exp(x)
sum_exp_x = np.sum(exp_x)
y = exp_x/sum_exp_x
return y
-
損失函數
神經網絡以某個名額為線索尋找最優權重參數。神經網絡的學習中所用的名額成為損失函數(loss function)。這個損失函數可以使用任意的函數表示,但是一般來說都使用均方誤差和交叉熵誤差等。
在尋找最優參數(權重和偏置)時,要尋找使得損失函數的值盡可能小的參數。為了尋找到使得損失函數的值盡可能小的地方,需要計算參數的導數(确切地将時梯度),然後以這個導數為指引,逐漸更新參數的值。
#均方誤差損失函數
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(np.array(t)*np.log(np.array(y)+delta))
-
梯度
變量的偏導數彙總而成的向量稱為梯度(gradient)。
機器學習的主要任務是在學習中尋找最優參數。同樣地,神經網絡也必須在學習時找到最優參數(權重和偏置)。這裡所說的最優參數是指損失函數取最小值時的參數。
通過梯度來尋找函數最小值(或者盡可能小的值)的方法就是梯度法。
尋找最小值的梯度法為梯度下降法,尋找最大值的梯度法稱為梯度上升法。(神經網絡學習中,梯度法主要是指梯度下降法)。
![](https://secure1.wostatic.cn/static/5dJy2FASPV6sm1b79jPcPU/捕獲 1.jpg)
其中η表示更新量,在神經網絡的學習中,稱為學習率(learning rate)。(學習率過大或者過小都無法得到好結果)
#求梯度
def numerical_gradient(f,x):
h = 1e-4
grad = np.zeros_like(x)
for i in range(x.size):
tmp = x[i]
x[i] = tmp + h
fxh1 = f(x)
x[i] = tmp - h
fxh2 = f(x)
grad[i] = (fxh1 - fxh2) / (h*2)
x[i] = tmp
return grad
#梯度下降法
def gradient_descent(f, init_x, lr=0.01, step_num=100):
x = init_x
for i in range(step_num):
grad = numerical_gradient(f, x)
x -= lr * grad
return x
-
總結 學習算法的實作
前提
神經網絡存在合适的權重和偏置,調整權重和偏置以便拟合訓練資料的
過程稱為“學習”。神經網絡的學習分成下面4個步驟。
步驟1( mini-batch)
從訓練資料中随機選出一部分資料,這部分資料稱為mini-batch。我們
的目标是減小mini-batch的損失函數的值。
步驟2(計算梯度)
為了減小mini-batch的損失函數的值,需要求出各個權重參數的梯度。
梯度表示損失函數的值減小最多的方向。
步驟3(更新參數)
将權重參數沿梯度方向進行微小更新。
步驟4(重複)
重複步驟1、步驟2、步驟3。
- 兩層神經網絡程式設計實作(采用前向傳播)
變量 | 說明 |
---|---|
params | 儲存神經網絡的參數的字典型變量(執行個體變量)。 params['W1']是第1層的權重, params['b1']是第1層的偏置。 params['W2']是第2層的權重, params['b2']是第2層的偏置 |
grads | 儲存梯度的字典型變量( numerical_gradient()方法的傳回值)。grads['W1']是第1層權重的梯度, grads['b1']是第1層偏置的梯度。grads['W2']是第2層權重的梯度, grads['b2']是第2層偏置的梯度。 |
方法 | 說明 |
---|---|
init(self, input_size,hidden_size, output_size) | 進行初始化。 參數從頭開始依次表示輸入層的神經元數、隐藏層的神經元數、輸出層的神經元數 |
predict(self, x) | 進行識别(推理)。 參數x是圖像資料。 |
loss(self, x, t) | 計算損失函數的值。 參數 x是圖像資料, t是正确解标簽(後面3個方法的參數也一樣)。 |
accuracy(self, x, t) | 計算識别精度。 |
numerical_gradient(self, x, t) | 計算權重參數的梯度。 |
gradient(self, x, t) | 計算權重參數的梯度。 |
**權重的初始化使用符合高斯分布的随機數進行初始化,偏置使用0進行初始化**
-
mini-batch的實作
mini-batch學習就是i從訓練資料中,随機選擇一部分資料(這部分資料稱之為mini-batch),再以這部分資料為對象,使用梯度法更新參數。
#2層神經網絡的分類
#輸入層激活函數sigmoid
def sigmoid(x):
return 1/(1+np.exp(-x))
#輸出層激活函數softmax
def softmax(x):
exp_x = np.exp(x)
sum_exp_x = np.sum(exp_x)
y = exp_x/sum_exp_x
return y
#交叉熵損失函數
def cross_entropy_error(y,t):
delta = 1e-7
return -np.sum(np.array(t)*np.log(np.array(y)+delta))
#求梯度
def numerical_gradient(f,x):
h = 1e-4
grad = np.zeros_like(x)
for i in range(x.size):
tmp = x[i]
x[i] = tmp + h
fxh1 = f(x)
x[i] = tmp - h
fxh2 = f(x)
grad[i] = (fxh1 - fxh2) / (h*2)
x[i] = tmp
return grad
class twolayernet:
def __init__(self,input_size,hidden_size,output_size,weight_init_std=0.01):
#初始化權重
self.params = {}
self.params['w1'] = weight_init_std * np.random.randn(input_size,hidden_size)
self.params['b1'] = np.zeros(hidden_size)
self.params['w2'] = weight_init_std * np.random.randn(hidden_size,output_size)
self.params['b2'] = np.zeros(output_size)
def predict(self,x):
w1,w2 = self.params['w1'],self.params['w2']
b1,b2 = self.params['b1'],self.params['b2']
a1 = np.dot(x,w1)+b1
z1 = sigmoid(a1)
a2 = np.dot(z1,w2)+b2
y = softmax(a2)
return y
def loss(self,x,t):
y = self.predict(x)
return cross_entropy_error(y,t)
def accuracy(self,x,t):
y = self.predict(x)
y = np.argmax(y,axis=1)
t = np.argmax(t,axis=1)
accuracy = np.sum(y == t) / float(x.shape[0])
return accuracy
#x:輸入資料 y:監督資料
def numerical_gradient(self,x,t):
loss_w = lambda w:self.loss(x,t)
grads = {}
grads['w1'] = numerical_gradient(loss_w,self.params['w1'])
grads['b1'] = numerical_gradient(loss_w, self.params['b1'])
grads['w2'] = numerical_gradient(loss_w, self.params['w2'])
grads['b2'] = numerical_gradient(loss_w, self.params['b2'])
return grads