Ng-機器學習(Day 4)

1 多變量Logistic迴歸:

多變量Logistic迴歸的基本思想就是:假設又K個類別,那麼就用K個分類器,一個一個的挑出每一個類別與其他的類別進行比較。比如:類別包括:晴,陰天,雨三個分類。那麼我就需要三個分類器。第一個分類器將晴作爲一類,其他的作爲一類利用二元Logistic迴歸的思想找到最優θ,依此類推。

  1. 首先獲取數據,查看數據
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from scipy.io import loadmat
data = loadmat('E:/Data/Ng/Coursera-ML-AndrewNg-Notes-master/code/\
ex3-neural network/ex3data1.mat')
#因爲文件保存爲了.mat的格式所以要藉助scipy.io的loadmat來讀取
data

結果如下:
在這裏插入圖片描述

  1. 編寫sigmoid函數、代價函數、梯度函數
def sigmoid(z):
	return 1/(1+np.exp(-z)

def cost(theta,x,y,l):
	theta = np.mat(theta)
	x = np.mat(x)
	y = np.mat(y)
	first = -y.transpose() *np.log(sigmoid(x*theta.transpose())
	second = (1-y).transpose()*np.log(1-sigmoid(x*theta.transpose())
	reg = (l/(2*len(x))) * theta[:,1:]*theta[:,1:].transpose() #因爲不對θ0進行正則化

def gradient(theta,x,y,l):
	theta = np.mat(theta)
	x = np.mat(x)
	y = np.mat(y)
	
	error = sigmoid(x*theta.transpose())-y
	grad  = (error.transpose() * x)/(len(x)) + (l/len(x))*theta
	grad[0,0] = (error.transpose()*x[:,0])/(len(x)) #因爲θ0不進行正則化
	
	return np.array(grad).reval()
  1. 寫分離器:
def one_vs_all(x,y,label_num,l):
	"""進行逐一分類
	Params:
		x:特徵值數據
		y:分類變量
		label_num:類別總數
		l:lambda
	return:
		all_theta:存放所有10個類別的最優擬合參數"""
	
	x = np.mat(x)
	y = np.mat(y)
	rows = x.shape[0]
	params = x.shape[1]
	x = np.insert(x,0,np.ones(rows),axis=1)
	all_theta = np.zeros((rows,params+1)) #加一是爲了增加一個x0的位置

	for i in range(1,label_num+1): #因爲我的分類是從1開始到10各個整數
		theta = np.zeros(params+1)
		y_i = [1 if label=i else 0 for label in y] 
		#將1,2,3,...,10分別單獨拎出來與其他進行比較,轉化爲2分類標籤
		y_i = np.reshape(y_i,(rows,1))
		fmin = minimize(fun=cost,x0=theta,args=(x,y_i,l),method='TNC',jac=gradient)
		all_theta[i-1,:] = fmin.x
	return all_theta
  1. 寫預測函數
def pred(x,y,theta):
	rows = x.shape[0]
	x = np.insert(x,0,np.ones(row),axis=1)
	x = np.mat(x)
	theta = np.mat(theta)
	h = sigmoid(x*theta.transpose())
	h_argmax = np.argmax(h,axis=1) #挑選出每一行當中最大的值並返回其索引(也就是可能性最大的值)
	h_argmax= h_argmax+1 #因爲我們的索引是從0-10,所以我們要加一
	return h_argmax

if __name__ == '__mian__':
	x = data['X']
	y= data['y']
	label_num = x.shape[1]
	l=1
	all_theta= one_vs_all(x,y,label_num,l)
	pred_y = pred(x,y,all_theta)
	correct = [1 if (a==b) else 0 for (a,b) in zip(pred_y,y)]
	accuracy = [sum(map(int,correct))/float(len(correct))]
	print('accuracy={}%'.format(accuracy*100))

結果如下:
在這裏插入圖片描述

2 神經網絡

個人對神經網絡的一個理解

以下圖的這個結構爲例:
首先第一層是我們傳入的一個參數,這裏我把傳入的參數比作一個很複雜,很精簡,很難懂數學公式。把機器比作一個人,對他提出的要求是理解這個公式,並且以後能夠儘可能準確的去應用這個公式。

把第二層視作爲他嘗試理解這個公式的第一天,他能夠理解一些,並且他試着轉化爲自己能夠更加直觀理解的方式去看這個公式(就像我現在在做的),然後第二層表示理解這層定義的第二天,依此類推,如果我們給他的層數(天數)越多,他最後可能會理解的更加準確,更好的應用,但是這會耗費很長時間,所以我根據定義的難度(特徵數)和他的能力給他合理的層數(天數)讓他理解,隨着一層一層的推進,他就越來越能夠以自己的方式進行解釋,最後以正確的進行應用。

在這裏插入圖片描述

1. 非線性假設:

面對有很多特徵變量的時候,使用Logistic迴歸要得到一個複雜的決策邊界就會出現非常多的二次項,很有可能出現過擬合併且運算量巨大。

在這裏插入圖片描述
在這裏插入圖片描述

2. 神經元工作原理

我們大腦中的神經,Dendrite可以看作是一個Input,Axon可以看作是一個Output。那麼Input和output之間的這一個部分就可以被看作爲是處理信息和運算的這麼一個部分。
在這裏插入圖片描述

當一個神經元想要將信息傳輸到另一個神經元的時候,就會一個神經元的Axon(output)傳出來,傳到另一個神經元的Dendrite(Input),然後同理可以再繼續傳遞。
在這裏插入圖片描述

下圖模擬了一個簡單的神經元,我們將x1,x2,x3(有時可以將x0(bias unit)輸入,有時不輸入)輸入到黃色的神經細胞進行處理,最後再進行輸出。這裏的函數名叫做Sigmoid (logistic)activation function。這裏的θ也可以叫做weight(權重)。
在這裏插入圖片描述

而所謂的神經網絡是有一組神經元所構成的。如下圖我們可以看到這個神經網絡一共有三層。第一層:輸入層(x);第二層:隱藏層(在計算時看不見);第三次:輸出層
在這裏插入圖片描述

a^(j)_i:j表示所在層,i表示項號。
θ^(j):是由第j+1層的項數作爲行,第j層的項數+1作爲列的權重矩陣。
在這裏插入圖片描述

在這裏插入圖片描述

神經網絡與Logistic迴歸在最後一部分的做法很相同,都是通過最後輸出的hypothesis函數的值來進行預測。不同的是他使用的特徵值輸入不再是x1,x2,x3,而是通過自己訓練得到的a1,a2,a3。更具weight_1的不同我們可以得到不同的複查模型。
在這裏插入圖片描述

下圖中,x1 XOR(或) x2表示x1或者x2; x1 XNOR x2表示Not(x1 XOR x2),即與其相反的結果。
其中XOR表示相同取0,相異取1
在這裏插入圖片描述

下圖舉了一個小例子 AND:
假設:
x1,x2:只能取0(假)或1(真)
y = x1ANDx2,且參數已知。
根據圖下個我們可以看到,當z爲4.6時,函數值爲0.99非常接近於1。當z爲-4.6時,函數值爲0.01非常接近於0。這個就非常像我們的Logistic迴歸了。

然後我們分別輸入不同的x1和x2的值,可以看到如右邊的列表所示的結果,然後就可以用於判斷結果。

可知當x1爲真ANDx2爲真時纔有h(x)爲真。
所以使用AND
在這裏插入圖片描述

OR function:
下面只要x1和x2當中有一個爲真即可使得h(x)爲真,所以叫OR函數
在這裏插入圖片描述

下圖的例子中,只有當x1=0的時候才能使h(x)爲真,即這個是NOT函數
在這裏插入圖片描述

用NXOR(表示x1與x2取值相同,即都爲0或都爲1)

在這裏插入圖片描述

若要構造一個XNOR我們可以進行拆分
下圖先構造了 (NOT(x1))AND(NOT(x2))
在這裏插入圖片描述

再將其與x1ANDx2用OR組合,即可得到XNOT。

在這裏插入圖片描述

在這裏插入圖片描述

3 神經網絡多分類問題:

在這裏插入圖片描述

在這裏插入圖片描述

1.神經網絡代價函數:

L:層數
s(j):表示第j層激活項的數量

下圖中左下爲2分類問題;右下爲多分類問題。
在這裏插入圖片描述

下圖中上面的部分是Logistic迴歸正則化的代價函數

下面部分爲神經網絡的代價函數:
在邏輯迴歸中,我們只有一個輸出變量,又稱標量(scalar),也只有一個因變量y,但是在神經網絡中,我們可以有很多輸出變量,我們的h_θ (x)是一個維度爲K的向量,並且我們訓練集中的因變量也是同樣維度的一個向量,因此我們的代價函數會比邏輯迴歸更加複雜一些,爲: h_θ (x)∈R^K ,(h_θ (x))_i=i^th output

這個看起來複雜很多的代價函數背後的思想還是一樣的,我們希望通過代價函數來觀察算法預測的結果與真實情況的誤差有多大,唯一不同的是,對於每一行特徵,我們都會給出K個預測(K代表我們的類別數,比如我們要機器來預測圖片是一個人還是車還是摩托,那麼我們的K=3,每次輸入一組特徵,就會做出三次預測,然後選擇三次預測中可能性最大的那個來與實際的進行比較),基本上我們可以利用循環,對每一行特徵都預測K個不同結果,然後在利用循環在K個預測中選擇可能性最高的一個,將其與y中的實際數據進行比較。

正則化的那一項只是排除了每一層θ_0後,每一層的θ 矩陣的和。最裏層的循環j循環所有的行(由s_l +1 層的激活單元數決定),循環i則循環所有的列,由該層(s_l層)的激活單元數所決定。即:h_θ (x)與真實值之間的距離爲每個樣本-每個類輸出的加和,對參數進行regularization的bias項處理所有參數的平方和。

在這裏插入圖片描述

2.反向傳播算法:

δ(l)_j表示第l層的預測值與第l層的實際值之間的差。

我們從最後一層的誤差開始計算,誤差是激活單元的預測(a^(4) )與實際值(y^k)之間的誤差,(k=1:k)。
我們用δ來表示誤差,則:δ^((4))=a ^((4))-y

在這裏插入圖片描述
在這裏插入圖片描述

前向傳播的固定步驟:
首先輸入訓練集,
θ * x^(i) = z^(2)
然後利用g(z^(2))計算 a(2),依此類推最後計算出a(4)
在這裏插入圖片描述

反向傳播:

首先觀察只有一個樣本集的反向傳播算法。
假設λ=0,然後就只關注圖裏括號中的那一項,這一項的意思可以近似的看成是預測值與實際值之間的方差。
在這裏插入圖片描述

δ^(l)_j可以被看作是第I層第j項的a的誤差。

δ是對於cost函數(預測值與實際值的方差)進行求z偏導之後的結果。
而我們的cost函數又是關於y(實際值)與h(預測值)的等式。其中h函數=g(z),所以說如果z的值改變了,那麼就會影響到誤差δ。
在這裏插入圖片描述

首先計算出δ^(4) = a^(4) - y^(4)
然後反向計算出,δ^(3), δ^(2),
其中δ^(2)_2 =
在這裏插入圖片描述
在這裏插入圖片描述

3.梯度檢驗:

採用近似估計:
因爲我們求偏導求出來的是一個斜率,那我們可以在點的兩邊各取一個近似的值,然後畫出圖形,可以看見,這兩個近似點所連接的紅色線段與上面的藍色線段非常的接近。所以我們可以通過計算這兩個點所構成圖形的對邊比臨邊來近似估計真正點的導數。
在這裏插入圖片描述

當我們的θ不是一個實際值的時候,我們就可以用一下方法:
在這裏插入圖片描述

然後將得出的計算結果與反向傳播得出的結果比較,看是不是近似的,若是近似的就表示結果是可信的。

如果將所有的θ都初始化爲0,那麼就會使得每個權重都相同,所以應該隨機化參數。
在這裏插入圖片描述

4.實現的步驟:

  1. 隨機初始化權重
  2. 使用前向傳播來計算x的h函數值
  3. 使用代碼去計算代價函數
  4. 使用後向傳播來計算代價函數的偏導數
  5. 進行梯度檢測
    在這裏插入圖片描述

參考資料:

  1. Ng機器學習
  2. 黃博筆記
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章