吴恩达《机器学习》学习笔记八——逻辑回归(多分类)代码
吳恩達(dá)《機(jī)器學(xué)習(xí)》筆記八——邏輯回歸(多分類)代碼
- 導(dǎo)入模塊及加載數(shù)據(jù)
- sigmoid函數(shù)與假設(shè)函數(shù)
- 代價(jià)函數(shù)
- 梯度下降
- 一對(duì)多分類
- 預(yù)測(cè)驗(yàn)證
課程鏈接:https://www.bilibili.com/video/BV164411b7dx?from=search&seid=5329376196520099118
之前筆記七里介紹了二分類問題的邏輯回歸代碼,涉及到了線性與非線性假設(shè),是否使用正則化等問題,這次做一個(gè)推廣,用邏輯回歸來解決一個(gè)多分類問題,手寫數(shù)字識(shí)別,這個(gè)問題如今更多在深度學(xué)習(xí)里使用神經(jīng)網(wǎng)絡(luò)來解決。
本次筆記用到的數(shù)據(jù)集:
鏈接:https://pan.baidu.com/s/1_HvmGeQfzv4bc7zBTvyEXw
提取碼:rdks
導(dǎo)入模塊及加載數(shù)據(jù)
import numpy as np import pandas as pd import matplotlib.pyplot as plt from scipy.io import loadmat數(shù)據(jù)集是在MATLAB的本機(jī)格式,所以要加載它到Python,需要使用一個(gè)SciPy工具。
data = loadmat('ex3data1.mat') data
看一下數(shù)據(jù)的維度:
圖像在martix X中表示為400維向量(其中有5,000個(gè))。 400維“特征”是原始20 x 20圖像中每個(gè)像素的灰度強(qiáng)度。類標(biāo)簽在向量y中作為表示圖像中數(shù)字的數(shù)字類。
第一個(gè)任務(wù)是將我們的邏輯回歸實(shí)現(xiàn)修改為完全向量化(即沒有“for”循環(huán))。這是因?yàn)?strong>向量化代碼除了簡(jiǎn)潔外,還能夠利用線性代數(shù)優(yōu)化,并且通常比迭代代碼快得多。
sigmoid函數(shù)與假設(shè)函數(shù)
g 代表一個(gè)常用的邏輯函數(shù)(logistic function)為S形函數(shù)(Sigmoid function),公式為:
邏輯回歸模型的假設(shè)函數(shù):
代價(jià)函數(shù)
def cost(theta, X, y, learningRate):# INPUT:參數(shù)值theta,數(shù)據(jù)X,標(biāo)簽y,學(xué)習(xí)率# OUTPUT:當(dāng)前參數(shù)值下的交叉熵?fù)p失# TODO:根據(jù)參數(shù)和輸入的數(shù)據(jù)計(jì)算交叉熵?fù)p失函數(shù)# STEP1:將theta, X, y轉(zhuǎn)換為numpy類型的矩陣theta =np.matrix(theta)X = np.matrix(X)y = np.matrix(y)# STEP2:根據(jù)公式計(jì)算損失函數(shù)(不含正則化)cross_cost =np.multiply(-y, np.log(sigmoid(X * theta.T)))-np.multiply((1 - y), np.log(1 - sigmoid(X * theta.T)))# STEP3:根據(jù)公式計(jì)算損失函數(shù)中的正則化部分reg = (learningRate / (2 * len(X))) * np.sum(np.power(theta[:,1:theta.shape[1]], 2))# STEP4:把上兩步當(dāng)中的結(jié)果加起來得到整體損失函數(shù)whole_cost=np.sum(cross_cost)/len(X)+regreturn whole_cost梯度下降
如果我們要使用梯度下降法令這個(gè)代價(jià)函數(shù)最小化,因?yàn)槲覀兾磳?duì) θ0 進(jìn)行正則化,所以梯度下降算法將分兩種情形:
一對(duì)多分類
現(xiàn)在已經(jīng)定義了代價(jià)函數(shù)和梯度函數(shù),是構(gòu)建分類器的時(shí)候了。 對(duì)于這個(gè)任務(wù),我們有10個(gè)可能的類,并且由于邏輯回歸只能一次在2個(gè)類之間進(jìn)行分類,我們需要多類分類的策略。 在本練習(xí)中,任務(wù)是實(shí)現(xiàn)一對(duì)一全分類方法,其中具有k個(gè)不同類的標(biāo)簽就有k個(gè)分類器,每個(gè)分類器在“類別 i”和“不是 i”之間決定。 我們將把分類器訓(xùn)練包含在一個(gè)函數(shù)中,該函數(shù)計(jì)算10個(gè)分類器中的每個(gè)分類器的最終權(quán)重,并將權(quán)重返回為k ×(n + 1)數(shù)組,其中n是參數(shù)數(shù)量。
from scipy.optimize import minimizedef one_vs_all(X, y, num_labels, learning_rate):rows = X.shape[0]params = X.shape[1]# k X (n + 1) array for the parameters of each of the k classifiersall_theta = np.zeros((num_labels, params + 1))# insert a column of ones at the beginning for the intercept termX = np.insert(X, 0, values=np.ones(rows), axis=1)# labels are 1-indexed instead of 0-indexedfor i in range(1, num_labels + 1):theta = np.zeros(params + 1)y_i = np.array([1 if label == i else 0 for label in y])y_i = np.reshape(y_i, (rows, 1))# minimize the objective functionfmin = minimize(fun=cost, x0=theta, args=(X, y_i, learning_rate), method='TNC', jac=gradient)all_theta[i-1,:] = fmin.xreturn all_theta這里需要注意的幾點(diǎn):首先,我們?yōu)閠heta添加了一個(gè)額外的參數(shù)(與訓(xùn)練數(shù)據(jù)一列),以計(jì)算截距項(xiàng)(常數(shù)項(xiàng))。 其次,我們將y從類標(biāo)簽轉(zhuǎn)換為每個(gè)分類器的二進(jìn)制值(要么是類i,要么不是類i)。 最后,我們使用SciPy的較新優(yōu)化API來最小化每個(gè)分類器的代價(jià)函數(shù)。 如果指定的話,API將采用目標(biāo)函數(shù),初始參數(shù)集,優(yōu)化方法和jacobian(漸變)函數(shù)。 然后將優(yōu)化程序找到的參數(shù)分配給參數(shù)數(shù)組。
實(shí)現(xiàn)向量化代碼的一個(gè)更具挑戰(zhàn)性的部分是正確地寫入所有的矩陣,保證維度正確。
rows = data['X'].shape[0] params = data['X'].shape[1]all_theta = np.zeros((10, params + 1))X = np.insert(data['X'], 0, values=np.ones(rows), axis=1)theta = np.zeros(params + 1)y_0 = np.array([1 if label == 0 else 0 for label in data['y']]) y_0 = np.reshape(y_0, (rows, 1))X.shape, y_0.shape, theta.shape, all_theta.shape
注意,theta是一維數(shù)組,因此當(dāng)它被轉(zhuǎn)換為計(jì)算梯度的代碼中的矩陣時(shí),它變?yōu)?#xff08;1×401)矩陣。 我們還檢查y中的類標(biāo)簽,以確保它們看起來像我們想象的一致。
讓我們確保我們的訓(xùn)練函數(shù)正確運(yùn)行,并且得到合理的輸出。
預(yù)測(cè)驗(yàn)證
我們現(xiàn)在準(zhǔn)備好最后一步 - 使用訓(xùn)練完畢的分類器預(yù)測(cè)每個(gè)圖像的標(biāo)簽。 對(duì)于這一步,我們將計(jì)算每個(gè)類的類概率,對(duì)于每個(gè)訓(xùn)練樣本(使用當(dāng)然的向量化代碼),并將輸出類標(biāo)簽為具有最高概率的類。
Tip:可以使用np.argmax()函數(shù)找到矩陣中指定維度的最大值。
def predict_all(X, all_theta):# INPUT:參數(shù)值theta,測(cè)試數(shù)據(jù)X# OUTPUT:預(yù)測(cè)值# TODO:對(duì)測(cè)試數(shù)據(jù)進(jìn)行預(yù)測(cè)# STEP1:獲取矩陣的維度信息rows = X.shape[0]params = X.shape[1]num_labels = all_theta.shape[0]# STEP2:把矩陣X加入一行零元素X = np.insert(X, 0, values=np.ones(rows), axis=1)# STEP3:把矩陣X和all_theta轉(zhuǎn)換為numpy型矩陣X = np.matrix(X)all_theta = np.matrix(all_theta)# STEP4:計(jì)算樣本屬于每一類的概率h = sigmoid(X * all_theta.T)# STEP5:找到每個(gè)樣本中預(yù)測(cè)概率最大的值h_argmax = np.argmax(h, axis=1)# STEP6:因?yàn)槲覀兊臄?shù)組是零索引的,所以我們需要為真正的標(biāo)簽+1h_argmax = h_argmax + 1return h_argmax現(xiàn)在我們可以使用predict_all函數(shù)為每個(gè)實(shí)例生成類預(yù)測(cè),看看我們的分類器是如何工作的。
y_pred = predict_all(data['X'], all_theta) correct = [1 if a == b else 0 for (a, b) in zip(y_pred, data['y'])] accuracy = (sum(map(int, correct)) / float(len(correct))) print ('accuracy = {0}%'.format(accuracy * 100))總結(jié)
以上是生活随笔為你收集整理的吴恩达《机器学习》学习笔记八——逻辑回归(多分类)代码的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 图像处理-5
- 下一篇: L1/L2/smooth_l1_loss