2.19 总结-深度学习-Stanford吴恩达教授
| 2.18 Logistic 損失函數(shù)的解釋 | 回到目錄 | 3.1 神經(jīng)網(wǎng)絡(luò)概覽 |
文章目錄
- 總結(jié)
- 習題
- 第 11 題
- 第 12 題
- 第 13 題
- 第 14 題
- 第 15 題
- 第 16 題
- 第 17 題
- 第 18 題
- 第 19 題
- 第 20 題
- 11-20題 答案
- 編程作業(yè)
總結(jié)
習題
第 11 題
神經(jīng)元計算什么?
A.神經(jīng)元計算激活函數(shù)后,再計算線性函數(shù)(z=Wx+b)
B.神經(jīng)元計算一個線性函數(shù)(z=Wx+b),然后接一個激活函數(shù)
C.神經(jīng)元計算一個函數(shù)g,它線性地縮放輸入x(Wx+b)
D.神經(jīng)元先計算所有特征的平均值,然后將激活函數(shù)應(yīng)用于輸出
第 12 題
以下哪一個是邏輯回歸的損失函數(shù)?
A. L(i)(y^(i),y(i))=∣y(i)?y^(i)∣L^{(i)}(\hat{y}^{(i)},y^{(i)})=|y^{(i)}-\hat{y}^{(i)}|L(i)(y^?(i),y(i))=∣y(i)?y^?(i)∣
B. L(i)(y^(i),y(i))=max(0,y(i)?y^(i))L^{(i)}(\hat{y}^{(i)},y^{(i)})=max(0,y^{(i)}-\hat{y}^{(i)})L(i)(y^?(i),y(i))=max(0,y(i)?y^?(i))
C. L(i)(y^(i),y(i))=∣y(i)?y^(i)∣2L^{(i)}(\hat{y}^{(i)},y^{(i)})=|y^{(i)}-\hat{y}^{(i)}|^2L(i)(y^?(i),y(i))=∣y(i)?y^?(i)∣2
D.L(i)(y^(i),y(i))=?(y(i)log?(y^(i))+(1?y(i))log?(1?y^(i)))L^{(i)}(\hat{y}^{(i)},y^{(i)})=-(y^{(i)}\log(\hat{y}^{(i)})+(1-y^{(i)})\log(1-\hat{y}^{(i)}))L(i)(y^?(i),y(i))=?(y(i)log(y^?(i))+(1?y(i))log(1?y^?(i)))
第 13 題
假設(shè)img是一個(32, 32, 3)數(shù)組,表示一個32 x 32圖像,它有三個顏色通道:紅色、綠色和藍色。如何將其重塑為列向量?
A.x = img.reshape((1, 32 * 32, 3))
B.x = img.reshape((32 * 32 * 3, 1))
C.x = img.reshape((3, 32 * 32))
D.x = img.reshape((32 * 32, 3))
第 14 題
考慮以下兩個隨機數(shù)組a和b:
a = np.random.randn(2, 3) # a.shape = (2, 3) b = np.random.randn(2, 1) # b.shape = (2, 1) c = a + bc的維度是什么?
A.c.shape = (3, 2)
B.c.shape = (2, 1)
C.c.shape = (2, 3)
D.計算不成立因為這兩個矩陣維度不匹配
第 15 題
考慮以下兩個隨機數(shù)組a和b:
a = np.random.randn(4, 3) # a.shape = (4, 3) b = np.random.randn(3, 2) # b.shape = (3, 2) c = a * bc的維度是什么?
A.c.shape = (4, 3)
B.c.shape = (3, 3)
C.c.shape = (4, 2)
D.計算不成立因為這兩個矩陣維度不匹配
第 16 題
假設(shè)每個示例有 nxn_xnx? 個輸入特性,X=[X(1),X(2),?,X(m),]X=[X^{(1)},X^{(2)},\cdots,X^{(m)},]X=[X(1),X(2),?,X(m),]。 XXX 的維數(shù)是多少?
A.(m, 1)
B.(1, m)
C.(nxn_xnx? , m)
D.(m, nxn_xnx?)
第 17 題
np.dot(a,b)對a和b的進行矩陣乘法,而a*b執(zhí)行元素的乘法,考慮以下兩個隨機數(shù)組a和b:
a = np.random.randn(12288, 150) # a.shape = (12288, 150) b = np.random.randn(150, 45) # b.shape = (150, 45) c = np.dot(a, b)c的維度是什么?
A.c.shape = (12288, 150)
B.c.shape = (150, 150)
C.c.shape = (12288, 45)
D.計算不成立因為這兩個矩陣維度不匹配
第 18 題
請考慮以下代碼段:
# a.shape = (3,4) # b.shape = (4,1) for i in range(3):for j in range(4):c[i][j] = a[i][j] + b[j]如何將之矢量化?
A.c = a + b
B.c = a +b.T
C.c = a.T + b.T
D.c = a.T + b
第 19 題
請考慮以下代碼段:
a = np.random.randn(3, 3) b = np.random.randn(3, 1) c = a * bc的維度是什么?
A.這會觸發(fā)廣播機制,b會被復制3次變成(3 * 3),而 * 操作是元素乘法,所以c.shape = (3, 3)
B.這會觸發(fā)廣播機制,b會被復制3次變成(3 * 3),而 * 操作是矩陣乘法,所以c.shape = (3, 3)
C.這個操作將一個3x3矩陣乘以一個3x1的向量,所以c.shape = (3, 1)
D.這個操作會報錯,因為你不能用*對這兩個矩陣進行操作,你應(yīng)該用np.dot(a, b)
第 20 題
請考慮以下計算圖:
輸出J是?
A. J = (c - 1) * (b + a)
B. J = (a - 1) * (b + c)
C. J = a * b + b * c + a * c
D. J = (b - 1) * (c + a)
11-20題 答案
11.B 12.D 13.B 14.C 15.D 16.C 17.C 18.B 19.A 20.B
編程作業(yè)
在開始之前,首先聲明本文源自博主何寬的文章,為了方便自己更好的學習,以及加入自己的一些看法,故搬運此。
其次聲明本文參考【Kulbear】的github上的文章,本文參考Logistic Regression with a Neural Network mindset,我基于他的文章加以自己的理解發(fā)表這篇博客,力求讓大家以最輕松的姿態(tài)理解吳恩達的視頻,如有不妥的地方歡迎大家指正。
本文所使用的資料已上傳到百度網(wǎng)盤【點擊下載】,提取碼:2u3w ,請在開始之前下載好所需資料,然后將文件解壓到你的代碼文件同一級目錄下,請確保你的代碼那里有l(wèi)r_utils.py和datasets文件夾。
【博主使用的python版本:3.7.6】
我們要做的事是搭建一個能夠**【識別貓】** 的簡單的神經(jīng)網(wǎng)絡(luò),你可以跟隨我的步驟在Jupyter Notebook中一步步地把代碼填進去,也可以直接復制完整代碼,在完整代碼在本文最底部。
在開始之前,我們有需要引入的庫:
- numpy :是用Python進行科學計算的基本軟件包。
- h5py:是與H5文件中存儲的數(shù)據(jù)集進行交互的常用軟件包。
- matplotlib:是一個著名的庫,用于在Python中繪制圖表。
- lr_utils :在本文的資料包里,一個加載資料包里面的數(shù)據(jù)的簡單功能的庫。
如果你沒有以上的庫,請自行安裝。
import numpy as np import matplotlib.pyplot as plt import h5py from lr_utils import load_datasetlr_utils.py代碼如下,你也可以自行打開它查看:
import numpy as np import h5pydef load_dataset():train_dataset = h5py.File('datasets/train_catvnoncat.h5', "r")train_set_x_orig = np.array(train_dataset["train_set_x"][:]) # your train set featurestrain_set_y_orig = np.array(train_dataset["train_set_y"][:]) # your train set labelstest_dataset = h5py.File('datasets/test_catvnoncat.h5', "r")test_set_x_orig = np.array(test_dataset["test_set_x"][:]) # your test set featurestest_set_y_orig = np.array(test_dataset["test_set_y"][:]) # your test set labelsclasses = np.array(test_dataset["list_classes"][:]) # the list of classestrain_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0]))test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0]))return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes解釋一下上面的 load_dataset() 返回的值的含義:
-
注意:此處圖像變量存儲方式與吳恩達教授的不一致。
- 吳恩達教授:將一個 64?64pixelRGB64*64\ pixel\ RGB64?64?pixel?RGB 圖像存儲為 64?64?3=1228864*64*3=1228864?64?3=12288 列一維向量。
- 此處:將一個 64?64pixelRGB64*64\ pixel\ RGB64?64?pixel?RGB 圖像存儲為三維數(shù)組,大小為 (64,64,3)(64,64,3)(64,64,3) 。
-
train_set_x_orig :保存的是訓練集里面的圖像數(shù)據(jù)(本訓練集有209張64x64的圖像)。
- train_set_y_orig :保存的是訓練集的圖像對應(yīng)的分類值(【0 | 1】,0表示不是貓,1表示是貓)。
- test_set_x_orig :保存的是測試集里面的圖像數(shù)據(jù)(本訓練集有50張64x64的圖像)。
- test_set_y_orig : 保存的是測試集的圖像對應(yīng)的分類值(【0 | 1】,0表示不是貓,1表示是貓)。
- classes : 保存的是以bytes類型保存的兩個字符串數(shù)據(jù),數(shù)據(jù)為:[b’non-cat’, b’cat’]。
現(xiàn)在我們就要把這些數(shù)據(jù)加載到主程序里面:
train_set_x_orig , train_set_y , test_set_x_orig , test_set_y , classes = load_dataset()若你用的是VScode+Pylint,也許會報如下錯誤,這個我從網(wǎng)上查了說是格式的問題,不過正常運行就行,不影響使用。
我們可以看一下我們加載的文件里面的圖片都是些什么樣子的,比如我就查看一下訓練集里面的第26張圖片,當然你也可以改變index的值查看一下其他的圖片。
train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes = load_dataset() index = 25 plt.imshow(train_set_x_orig[index]) plt.show() #print("train_set_y=" + str(train_set_y)) #你也可以看一下訓練集里面的標簽是什么樣的。運行結(jié)果如下:
也可同時查看多個圖片,如下所示。進一步使用方法:可參考
train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes = load_dataset() index = 25 plt.subplot(2,3,1) plt.imshow(train_set_x_orig[25]) plt.subplot(2,3,2) plt.imshow(train_set_x_orig[1]) plt.subplot(2,3,3) plt.imshow(train_set_x_orig[2]) plt.subplot(2,3,4) plt.imshow(train_set_x_orig[3]) plt.subplot(2,3,5) plt.imshow(train_set_x_orig[4]) plt.subplot(2,3,6) plt.imshow(train_set_x_orig[5]) plt.show()
現(xiàn)在我們可以結(jié)合一下訓練集里面的數(shù)據(jù)來看一下我到底都加載了一些什么東西。
打印出的結(jié)果是:y=[1], it's a cat picture,我們進行下一步,我們查看一下我們加載的圖像數(shù)據(jù)集具體情況,我對以下參數(shù)做出解釋:
- m_train :訓練集里圖片的數(shù)量。
- m_test :測試集里圖片的數(shù)量。
- num_px : 訓練、測試集里面的圖片的寬度和高度(均為64x64)。
請記住,train_set_x_orig 是一個維度為(m_??train,num_px,num_px,3)的數(shù)組。
運行之后的結(jié)果:
訓練集的數(shù)量: m_train = 209 測試集的數(shù)量 : m_test = 50 每張圖片的寬/高 : num_px = 64 每張圖片的大小 : (64, 64, 3) 訓練集_圖片的維數(shù) : (209, 64, 64, 3) 訓練集_標簽的維數(shù) : (1, 209) 測試集_圖片的維數(shù): (50, 64, 64, 3) 測試集_標簽的維數(shù): (1, 50)為了方便,我們要把維度為(64,64,3)的numpy數(shù)組重新構(gòu)造為(64 x 64 x 3,1)的數(shù)組,要乘以3的原因是每張圖片是由64x64像素構(gòu)成的,而每個像素點由(R,G,B)三原色構(gòu)成的,所以要乘以3。在此之后,我們的訓練和測試數(shù)據(jù)集是一個numpy數(shù)組,【每列代表一個平坦的圖像】 ,應(yīng)該有 12288(特征數(shù)量)行和 209(樣本數(shù)量)列。
當你想將形狀(a,b,c,d)的矩陣X平鋪成形狀(b * c * d,a)的矩陣X_flatten時,可以使用以下代碼:
#X_flatten = X.reshape(X.shape [0],-1).T #X.T是X的轉(zhuǎn)置 #將訓練集的維度降低并轉(zhuǎn)置。 train_set_x_flatten = train_set_x_orig.reshape(train_set_x_orig.shape[0],-1).T #將測試集的維度降低并轉(zhuǎn)置。 test_set_x_flatten = test_set_x_orig.reshape(test_set_x_orig.shape[0], -1).T這一段意思是指把數(shù)組變?yōu)?09行的矩陣(因為訓練集里有209張圖片),但是我懶得算列有多少,于是我就用-1告訴程序你幫我算,最后程序算出來時12288列,我再最后用一個T表示轉(zhuǎn)置,這就變成了12288行,209列。測試集亦如此。
然后我們看看降維之后的情況是怎么樣的:
print ("訓練集降維最后的維度: " + str(train_set_x_flatten.shape)) print ("訓練集_標簽的維數(shù) : " + str(train_set_y_orig.shape)) print ("測試集降維之后的維度: " + str(test_set_x_flatten.shape)) print ("測試集_標簽的維數(shù) : " + str(test_set_y_orig.shape))執(zhí)行之后的結(jié)果為:
訓練集降維最后的維度: (12288, 209) 訓練集_標簽的維數(shù) : (1, 209) 測試集降維之后的維度: (12288, 50) 測試集_標簽的維數(shù) : (1, 50)為了表示彩色圖像,必須為每個像素指定紅色,綠色和藍色通道(RGB),因此像素值實際上是從0到255范圍內(nèi)的三個數(shù)字的向量。機器學習中一個常見的預處理步驟是對數(shù)據(jù)集進行居中和標準化,這意味著可以減去每個示例中整個numpy數(shù)組的平均值,然后將每個示例除以整個numpy數(shù)組的標準偏差。但對于圖片數(shù)據(jù)集,它更簡單,更方便,幾乎可以將數(shù)據(jù)集的每一行除以255(像素通道的最大值),因為在RGB中不存在比255大的數(shù)據(jù),所以我們可以放心的除以255,讓標準化的數(shù)據(jù)位于 [0,1] 之間,現(xiàn)在標準化我們的數(shù)據(jù)集:
train_set_x = train_set_x_flatten / 255 test_set_x = test_set_x_flatten / 255現(xiàn)在總算是把我們加載的數(shù)據(jù)弄完了,我們現(xiàn)在開始構(gòu)建神經(jīng)網(wǎng)絡(luò)。
以下是數(shù)學表達式,如果對數(shù)學公式不甚理解,請仔細看一下吳恩達的視頻。
對于 x(i)x^{(i)}x(i):
z(i)=wTx(i)+b(1)z^{(i)}=w^Tx^{(i)}+b\tag1z(i)=wTx(i)+b(1)y^(i)=a(i)=sigmoid(z(i))(2)\hat{y}^{(i)}=a^{(i)}=sigmoid(z^{(i)})\tag2y^?(i)=a(i)=sigmoid(z(i))(2)L(a(i),y(i))=?y(i)log?(a(i))?(1?y(i))log?(1?a(i))(3)L(a^{(i)},y^{(i)})=-y^{(i)}\log(a^{(i)})-(1-y^{(i)})\log(1-a^{(i)})\tag3L(a(i),y(i))=?y(i)log(a(i))?(1?y(i))log(1?a(i))(3)
然后通過對所有訓練樣例求和來計算成本:
J=1m∑i=1mL(a(i),y(i))(4)J=\frac1m\sum_{i=1}^mL(a^{(i)},y^{(i)})\tag4J=m1?i=1∑m?L(a(i),y(i))(4)
建立神經(jīng)網(wǎng)絡(luò)的主要步驟是:
定義模型結(jié)構(gòu)(例如輸入特征的數(shù)量)
初始化模型的參數(shù)
循環(huán):
3.1 計算當前損失(正向傳播)
3.2 計算當前梯度(反向傳播)
3.3 更新參數(shù)(梯度下降)
現(xiàn)在構(gòu)建sigmoid(),需要使用 sigmoid(wTx+b)sigmoid(w ^ T x + b)sigmoid(wTx+b) 計算來做出預測。
def sigmoid(z):"""參數(shù):z - 任何大小的標量或numpy數(shù)組。返回:s - sigmoid(z)"""s = 1 / (1 + np.exp(-z))return s我們可以測試一下sigmoid(),檢查一下是否符合我們所需要的條件。
#測試sigmoid() print("====================測試sigmoid====================") print ("sigmoid(0) = " + str(sigmoid(0))) print ("sigmoid(9.2) = " + str(sigmoid(9.2)))打印出的結(jié)果為:
====================測試sigmoid==================== sigmoid(0) = 0.5 sigmoid(9.2) = 0.9998989708060922既然sigmoid測試好了,我們現(xiàn)在就可以初始化我們需要的參數(shù)w和b了。
def initialize_with_zeros(dim):"""此函數(shù)為w創(chuàng)建一個維度為(dim,1)的0向量,并將b初始化為0。參數(shù):dim - 我們想要的w矢量的大小(或者這種情況下的參數(shù)數(shù)量)返回:w - 維度為(dim,1)的初始化向量。b - 初始化的標量(對應(yīng)于偏差)"""w = np.zeros(shape = (dim,1))b = 0#使用斷言來確保我要的數(shù)據(jù)是正確的assert(w.shape == (dim, 1)) #w的維度是(dim,1)assert(isinstance(b, float) or isinstance(b, int)) #b的類型是float或者是intreturn (w , b)初始化參數(shù)的函數(shù)已經(jīng)構(gòu)建好了,現(xiàn)在就可以執(zhí)行“前向”和“后向”傳播步驟來學習參數(shù)。
我們現(xiàn)在要實現(xiàn)一個計算成本函數(shù)及其漸變的函數(shù)propagate()。
def propagate(w, b, X, Y):"""實現(xiàn)前向和后向傳播的成本函數(shù)及其梯度。參數(shù):w - 權(quán)重,大小不等的數(shù)組(num_px * num_px * 3,1)b - 偏差,一個標量X - 矩陣類型為(num_px * num_px * 3,訓練數(shù)量)Y - 真正的“標簽”矢量(如果非貓則為0,如果是貓則為1),矩陣維度為(1,訓練數(shù)據(jù)數(shù)量)返回:cost- 邏輯回歸的負對數(shù)似然成本dw - 相對于w的損失梯度,因此與w相同的形狀db - 相對于b的損失梯度,因此與b的形狀相同"""m = X.shape[1]#正向傳播A = sigmoid(np.dot(w.T,X) + b) #計算激活值,請參考公式2。cost = (- 1 / m) * np.sum(Y * np.log(A) + (1 - Y) * (np.log(1 - A))) #計算成本,請參考公式3和4。#反向傳播dw = (1 / m) * np.dot(X, (A - Y).T) #請參考視頻中的偏導公式。db = (1 / m) * np.sum(A - Y) #請參考視頻中的偏導公式。#使用斷言確保我的數(shù)據(jù)是正確的assert(dw.shape == w.shape)assert(db.dtype == float)cost = np.squeeze(cost)assert(cost.shape == ())#創(chuàng)建一個字典,把dw和db保存起來。grads = {"dw": dw,"db": db}return (grads , cost)寫好之后我們來測試一下。
#測試一下propagate print("====================測試propagate====================") #初始化一些參數(shù) w, b, X, Y = np.array([[1], [2]]), 2, np.array([[1,2], [3,4]]), np.array([[1, 0]]) grads, cost = propagate(w, b, X, Y) print ("dw = " + str(grads["dw"])) print ("db = " + str(grads["db"])) print ("cost = " + str(cost)) print ("grads = " + str(grads))測試結(jié)果是:
====================測試propagate==================== dw = [[0.99993216][1.99980262]] db = 0.49993523062470574 cost = 6.000064773192205 grads = {'dw': array([[0.99993216],[1.99980262]]), 'db': 0.49993523062470574}現(xiàn)在,我要使用漸變下降更新參數(shù)。
目標是通過最小化成本函數(shù) JJJ 來學習 www 和 bbb 。對于參數(shù) θ\thetaθ ,更新規(guī)則是 θ=θ?αdθ\theta = \theta - \alpha \text{ } d\thetaθ=θ?α?dθ,其中 α\alphaα 是學習率。
def optimize(w , b , X , Y , num_iterations , learning_rate , print_cost = True):"""此函數(shù)通過運行梯度下降算法來優(yōu)化w和b參數(shù):w - 權(quán)重,大小不等的數(shù)組(num_px * num_px * 3,1)b - 偏差,一個標量X - 維度為(num_px * num_px * 3,訓練數(shù)據(jù)的數(shù)量)的數(shù)組。Y - 真正的“標簽”矢量(如果非貓則為0,如果是貓則為1),矩陣維度為(1,訓練數(shù)據(jù)的數(shù)量)num_iterations - 優(yōu)化循環(huán)的迭代次數(shù)learning_rate - 梯度下降更新規(guī)則的學習率print_cost - 每100步打印一次損失值返回:params - 包含權(quán)重w和偏差b的字典grads - 包含權(quán)重和偏差相對于成本函數(shù)的梯度的字典成本 - 優(yōu)化期間計算的所有成本列表,將用于繪制學習曲線。提示:我們需要寫下兩個步驟并遍歷它們:1)計算當前參數(shù)的成本和梯度,使用propagate()。2)使用w和b的梯度下降法則更新參數(shù)。"""costs = []for i in range(num_iterations):grads, cost = propagate(w, b, X, Y)dw = grads["dw"]db = grads["db"]w = w - learning_rate * dwb = b - learning_rate * db#記錄成本if i % 100 == 0:costs.append(cost)#打印成本數(shù)據(jù)if (print_cost) and (i % 100 == 0):print("迭代的次數(shù): %i , 誤差值: %f" % (i,cost))params = {"w" : w,"b" : b }grads = {"dw": dw,"db": db } return (params , grads , costs)現(xiàn)在就讓我們來測試一下優(yōu)化函數(shù):
#測試optimize print("====================測試optimize====================") w, b, X, Y = np.array([[1], [2]]), 2, np.array([[1,2], [3,4]]), np.array([[1, 0]]) params , grads , costs = optimize(w , b , X , Y , num_iterations=100 , learning_rate = 0.009 , print_cost = True) print ("w = " + str(params["w"])) print ("b = " + str(params["b"])) print ("dw = " + str(grads["dw"])) print ("db = " + str(grads["db"]))測試結(jié)果為:
====================測試optimize==================== w = [[0.1124579 ][0.23106775]] b = 1.5593049248448891 dw = [[0.90158428][1.76250842]] db = 0.4304620716786828optimize函數(shù)會輸出已學習的w和b的值,我們可以使用w和b來預測數(shù)據(jù)集X的標簽。
現(xiàn)在我們要實現(xiàn)預測函數(shù)predict()。計算預測有兩個步驟:
計算 Y^=A=σ(wT+b)\hat{Y}=A=\sigma(w^T+b)Y^=A=σ(wT+b)
將a的值變?yōu)?(如果激活值<= 0.5)或者為1(如果激活值> 0.5),
然后將預測值存儲在向量Y_prediction中。
def predict(w , b , X ):"""使用學習邏輯回歸參數(shù)logistic (w,b)預測標簽是0還是1,參數(shù):w - 權(quán)重,大小不等的數(shù)組(num_px * num_px * 3,1)b - 偏差,一個標量X - 維度為(num_px * num_px * 3,訓練數(shù)據(jù)的數(shù)量)的數(shù)據(jù)返回:Y_prediction - 包含X中所有圖片的所有預測【0 | 1】的一個numpy數(shù)組(向量)"""m = X.shape[1] #圖片的數(shù)量Y_prediction = np.zeros((1,m)) w = w.reshape(X.shape[0],1)#計預測貓在圖片中出現(xiàn)的概率A = sigmoid(np.dot(w.T , X) + b)for i in range(A.shape[1]):#將概率a [0,i]轉(zhuǎn)換為實際預測p [0,i]Y_prediction[0,i] = 1 if A[0,i] > 0.5 else 0#使用斷言assert(Y_prediction.shape == (1,m))return Y_prediction老規(guī)矩,測試一下。
#測試predict print("====================測試predict====================") w, b, X, Y = np.array([[1], [2]]), 2, np.array([[1,2], [3,4]]), np.array([[1, 0]]) print("predictions = " + str(predict(w, b, X)))結(jié)果為:
====================測試predict==================== predictions = [[1. 1.]]就目前而言,我們基本上把所有的東西都做完了,現(xiàn)在我們要把這些函數(shù)統(tǒng)統(tǒng)整合到一個model()函數(shù)中,屆時只需要調(diào)用一個model()就基本上完成所有的事了。
def model(X_train , Y_train , X_test , Y_test , num_iterations = 2000 , learning_rate = 0.5 , print_cost = True):"""通過調(diào)用之前實現(xiàn)的函數(shù)來構(gòu)建邏輯回歸模型參數(shù):X_train - numpy的數(shù)組,維度為(num_px * num_px * 3,m_train)的訓練集Y_train - numpy的數(shù)組,維度為(1,m_train)(矢量)的訓練標簽集X_test - numpy的數(shù)組,維度為(num_px * num_px * 3,m_test)的測試集Y_test - numpy的數(shù)組,維度為(1,m_test)的(向量)的測試標簽集num_iterations - 表示用于優(yōu)化參數(shù)的迭代次數(shù)的超參數(shù)learning_rate - 表示optimize()更新規(guī)則中使用的學習速率的超參數(shù)print_cost - 設(shè)置為true以每100次迭代打印成本返回:d - 包含有關(guān)模型信息的字典。"""w , b = initialize_with_zeros(X_train.shape[0])parameters , grads , costs = optimize(w , b , X_train , Y_train,num_iterations , learning_rate , print_cost)#從字典“參數(shù)”中檢索參數(shù)w和bw , b = parameters["w"] , parameters["b"]#預測測試/訓練集的例子Y_prediction_test = predict(w , b, X_test)Y_prediction_train = predict(w , b, X_train)#打印訓練后的準確性print("訓練集準確性:" , format(100 - np.mean(np.abs(Y_prediction_train - Y_train)) * 100) ,"%")print("測試集準確性:" , format(100 - np.mean(np.abs(Y_prediction_test - Y_test)) * 100) ,"%")d = {"costs" : costs,"Y_prediction_test" : Y_prediction_test,"Y_prediciton_train" : Y_prediction_train,"w" : w,"b" : b,"learning_rate" : learning_rate,"num_iterations" : num_iterations }return d把整個model構(gòu)建好之后我們這就算是正式的實際測試了,我們這就來實際跑一下。
print("====================測試model====================") #這里加載的是真實的數(shù)據(jù),請參見上面的代碼部分。 d = model(train_set_x, train_set_y_orig, test_set_x, test_set_y_orig, num_iterations = 2000, learning_rate = 0.005, print_cost = True)執(zhí)行后的數(shù)據(jù):
====================測試model==================== 迭代的次數(shù): 0 , 誤差值: 0.693147 迭代的次數(shù): 100 , 誤差值: 0.584508 迭代的次數(shù): 200 , 誤差值: 0.466949 迭代的次數(shù): 300 , 誤差值: 0.376007 迭代的次數(shù): 400 , 誤差值: 0.331463 迭代的次數(shù): 500 , 誤差值: 0.303273 迭代的次數(shù): 600 , 誤差值: 0.279880 迭代的次數(shù): 700 , 誤差值: 0.260042 迭代的次數(shù): 800 , 誤差值: 0.242941 迭代的次數(shù): 900 , 誤差值: 0.228004 迭代的次數(shù): 1000 , 誤差值: 0.214820 迭代的次數(shù): 1100 , 誤差值: 0.203078 迭代的次數(shù): 1200 , 誤差值: 0.192544 迭代的次數(shù): 1300 , 誤差值: 0.183033 迭代的次數(shù): 1400 , 誤差值: 0.174399 迭代的次數(shù): 1500 , 誤差值: 0.166521 迭代的次數(shù): 1600 , 誤差值: 0.159305 迭代的次數(shù): 1700 , 誤差值: 0.152667 迭代的次數(shù): 1800 , 誤差值: 0.146542 迭代的次數(shù): 1900 , 誤差值: 0.140872 訓練集準確性: 99.04306220095694 % 測試集準確性: 70.0 %我們更改一下學習率和迭代次數(shù),有可能會發(fā)現(xiàn)訓練集的準確性可能會提高,但是測試集準確性會下降,這是由于過擬合造成的,但是我們并不需要擔心,我們以后會使用更好的算法來解決這些問題的。
到目前為止,我們的程序算是完成了,但是,我們可以在后面加一點東西,比如畫點圖什么的。
#繪制圖 costs = np.squeeze(d['costs']) plt.plot(costs) plt.ylabel('cost') plt.xlabel('iterations (per hundreds)') plt.title("Learning rate =" + str(d["learning_rate"])) plt.show()跑一波出來的效果圖是這樣的,可以看到成本下降,它顯示參數(shù)正在被學習:
讓我們進一步分析一下,并研究學習率alpha的可能選擇。為了讓漸變下降起作用,我們必須明智地選擇學習速率。學習率 α\alphaα 決定了我們更新參數(shù)的速度。如果學習率過高,我們可能會“超過”最優(yōu)值。同樣,如果它太小,我們將需要太多迭代才能收斂到最佳值。這就是為什么使用良好調(diào)整的學習率至關(guān)重要的原因。
我們可以比較一下我們模型的學習曲線和幾種學習速率的選擇。也可以嘗試使用不同于我們初始化的learning_rates變量包含的三個值,并看一下會發(fā)生什么。
learning_rates = [0.005, 0.01, 0.001, 0.0001] models = {} for i in learning_rates:print ("learning rate is: " + str(i))print("num_iterations=2000")models[str(i)] = model(train_set_x, train_set_y_orig, test_set_x, test_set_y_orig, num_iterations = 2000, learning_rate = i, print_cost = True)print ('\n' + "-------------------------------------------------------" + '\n')for i in learning_rates:plt.plot(np.squeeze(models[str(i)]["costs"]), label= str(models[str(i)]["learning_rate"]))plt.ylabel('cost') plt.xlabel('iterations')legend = plt.legend(loc='upper center', shadow=True) frame = legend.get_frame() frame.set_facecolor('0.90') plt.show()跑一下打印出來的結(jié)果是:
learning rate is: 0.005 num_iterations=2000 訓練集準確性: 99.04306220095694 % 測試集準確性: 70.0 %-------------------------------------------------------learning rate is: 0.01 num_iterations=2000 訓練集準確性: 99.52153110047847 % 測試集準確性: 70.0 %-------------------------------------------------------learning rate is: 0.001 num_iterations=2000 訓練集準確性: 91.38755980861244 % 測試集準確性: 68.0 %-------------------------------------------------------learning rate is: 0.0001 num_iterations=2000 訓練集準確性: 71.29186602870814 % 測試集準確性: 40.0 %-------------------------------------------------------**【完整代碼】: **
# -*- coding: utf-8 -*- """ Created on Wed Mar 21 17:25:30 2018博客地址 :http://blog.csdn.net/u013733326/article/details/79639509@author: Oscar """import numpy as np import matplotlib.pyplot as plt import h5py from lr_utils import load_datasettrain_set_x_orig , train_set_y , test_set_x_orig , test_set_y , classes = load_dataset()m_train = train_set_y.shape[1] #訓練集里圖片的數(shù)量。 m_test = test_set_y.shape[1] #測試集里圖片的數(shù)量。 num_px = train_set_x_orig.shape[1] #訓練、測試集里面的圖片的寬度和高度(均為64x64)。#現(xiàn)在看一看我們加載的東西的具體情況 print ("訓練集的數(shù)量: m_train = " + str(m_train)) print ("測試集的數(shù)量 : m_test = " + str(m_test)) print ("每張圖片的寬/高 : num_px = " + str(num_px)) print ("每張圖片的大小 : (" + str(num_px) + ", " + str(num_px) + ", 3)") print ("訓練集_圖片的維數(shù) : " + str(train_set_x_orig.shape)) print ("訓練集_標簽的維數(shù) : " + str(train_set_y.shape)) print ("測試集_圖片的維數(shù): " + str(test_set_x_orig.shape)) print ("測試集_標簽的維數(shù): " + str(test_set_y.shape))#將訓練集的維度降低并轉(zhuǎn)置。 train_set_x_flatten = train_set_x_orig.reshape(train_set_x_orig.shape[0],-1).T #將測試集的維度降低并轉(zhuǎn)置。 test_set_x_flatten = test_set_x_orig.reshape(test_set_x_orig.shape[0], -1).Tprint ("訓練集降維最后的維度: " + str(train_set_x_flatten.shape)) print ("訓練集_標簽的維數(shù) : " + str(train_set_y.shape)) print ("測試集降維之后的維度: " + str(test_set_x_flatten.shape)) print ("測試集_標簽的維數(shù) : " + str(test_set_y.shape))train_set_x = train_set_x_flatten / 255 test_set_x = test_set_x_flatten / 255def sigmoid(z):"""參數(shù):z - 任何大小的標量或numpy數(shù)組。返回:s - sigmoid(z)"""s = 1 / (1 + np.exp(-z))return sdef initialize_with_zeros(dim):"""此函數(shù)為w創(chuàng)建一個維度為(dim,1)的0向量,并將b初始化為0。參數(shù):dim - 我們想要的w矢量的大小(或者這種情況下的參數(shù)數(shù)量)返回:w - 維度為(dim,1)的初始化向量。b - 初始化的標量(對應(yīng)于偏差)"""w = np.zeros(shape = (dim,1))b = 0#使用斷言來確保我要的數(shù)據(jù)是正確的assert(w.shape == (dim, 1)) #w的維度是(dim,1)assert(isinstance(b, float) or isinstance(b, int)) #b的類型是float或者是intreturn (w , b)def propagate(w, b, X, Y):"""實現(xiàn)前向和后向傳播的成本函數(shù)及其梯度。參數(shù):w - 權(quán)重,大小不等的數(shù)組(num_px * num_px * 3,1)b - 偏差,一個標量X - 矩陣類型為(num_px * num_px * 3,訓練數(shù)量)Y - 真正的“標簽”矢量(如果非貓則為0,如果是貓則為1),矩陣維度為(1,訓練數(shù)據(jù)數(shù)量)返回:cost- 邏輯回歸的負對數(shù)似然成本dw - 相對于w的損失梯度,因此與w相同的形狀db - 相對于b的損失梯度,因此與b的形狀相同"""m = X.shape[1]#正向傳播A = sigmoid(np.dot(w.T,X) + b) #計算激活值,請參考公式2。cost = (- 1 / m) * np.sum(Y * np.log(A) + (1 - Y) * (np.log(1 - A))) #計算成本,請參考公式3和4。#反向傳播dw = (1 / m) * np.dot(X, (A - Y).T) #請參考視頻中的偏導公式。db = (1 / m) * np.sum(A - Y) #請參考視頻中的偏導公式。#使用斷言確保我的數(shù)據(jù)是正確的assert(dw.shape == w.shape)assert(db.dtype == float)cost = np.squeeze(cost)assert(cost.shape == ())#創(chuàng)建一個字典,把dw和db保存起來。grads = {"dw": dw,"db": db}return (grads , cost)def optimize(w , b , X , Y , num_iterations , learning_rate , print_cost = True):"""此函數(shù)通過運行梯度下降算法來優(yōu)化w和b參數(shù):w - 權(quán)重,大小不等的數(shù)組(num_px * num_px * 3,1)b - 偏差,一個標量X - 維度為(num_px * num_px * 3,訓練數(shù)據(jù)的數(shù)量)的數(shù)組。Y - 真正的“標簽”矢量(如果非貓則為0,如果是貓則為1),矩陣維度為(1,訓練數(shù)據(jù)的數(shù)量)num_iterations - 優(yōu)化循環(huán)的迭代次數(shù)learning_rate - 梯度下降更新規(guī)則的學習率print_cost - 每100步打印一次損失值返回:params - 包含權(quán)重w和偏差b的字典grads - 包含權(quán)重和偏差相對于成本函數(shù)的梯度的字典成本 - 優(yōu)化期間計算的所有成本列表,將用于繪制學習曲線。提示:我們需要寫下兩個步驟并遍歷它們:1)計算當前參數(shù)的成本和梯度,使用propagate()。2)使用w和b的梯度下降法則更新參數(shù)。"""costs = []for i in range(num_iterations):grads, cost = propagate(w, b, X, Y)dw = grads["dw"]db = grads["db"]w = w - learning_rate * dwb = b - learning_rate * db#記錄成本if i % 100 == 0:costs.append(cost)#打印成本數(shù)據(jù)if (print_cost) and (i % 100 == 0):print("迭代的次數(shù): %i , 誤差值: %f" % (i,cost))params = {"w" : w,"b" : b }grads = {"dw": dw,"db": db } return (params , grads , costs)def predict(w , b , X ):"""使用學習邏輯回歸參數(shù)logistic (w,b)預測標簽是0還是1,參數(shù):w - 權(quán)重,大小不等的數(shù)組(num_px * num_px * 3,1)b - 偏差,一個標量X - 維度為(num_px * num_px * 3,訓練數(shù)據(jù)的數(shù)量)的數(shù)據(jù)返回:Y_prediction - 包含X中所有圖片的所有預測【0 | 1】的一個numpy數(shù)組(向量)"""m = X.shape[1] #圖片的數(shù)量Y_prediction = np.zeros((1,m)) w = w.reshape(X.shape[0],1)#計預測貓在圖片中出現(xiàn)的概率A = sigmoid(np.dot(w.T , X) + b)for i in range(A.shape[1]):#將概率a [0,i]轉(zhuǎn)換為實際預測p [0,i]Y_prediction[0,i] = 1 if A[0,i] > 0.5 else 0#使用斷言assert(Y_prediction.shape == (1,m))return Y_predictiondef model(X_train , Y_train , X_test , Y_test , num_iterations = 2000 , learning_rate = 0.5 , print_cost = True):"""通過調(diào)用之前實現(xiàn)的函數(shù)來構(gòu)建邏輯回歸模型參數(shù):X_train - numpy的數(shù)組,維度為(num_px * num_px * 3,m_train)的訓練集Y_train - numpy的數(shù)組,維度為(1,m_train)(矢量)的訓練標簽集X_test - numpy的數(shù)組,維度為(num_px * num_px * 3,m_test)的測試集Y_test - numpy的數(shù)組,維度為(1,m_test)的(向量)的測試標簽集num_iterations - 表示用于優(yōu)化參數(shù)的迭代次數(shù)的超參數(shù)learning_rate - 表示optimize()更新規(guī)則中使用的學習速率的超參數(shù)print_cost - 設(shè)置為true以每100次迭代打印成本返回:d - 包含有關(guān)模型信息的字典。"""w , b = initialize_with_zeros(X_train.shape[0])parameters , grads , costs = optimize(w , b , X_train , Y_train,num_iterations , learning_rate , print_cost)#從字典“參數(shù)”中檢索參數(shù)w和bw , b = parameters["w"] , parameters["b"]#預測測試/訓練集的例子Y_prediction_test = predict(w , b, X_test)Y_prediction_train = predict(w , b, X_train)#打印訓練后的準確性print("訓練集準確性:" , format(100 - np.mean(np.abs(Y_prediction_train - Y_train)) * 100) ,"%")print("測試集準確性:" , format(100 - np.mean(np.abs(Y_prediction_test - Y_test)) * 100) ,"%")d = {"costs" : costs,"Y_prediction_test" : Y_prediction_test,"Y_prediciton_train" : Y_prediction_train,"w" : w,"b" : b,"learning_rate" : learning_rate,"num_iterations" : num_iterations }return dd = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 2000, learning_rate = 0.005, print_cost = True)#繪制圖 costs = np.squeeze(d['costs']) plt.plot(costs) plt.ylabel('cost') plt.xlabel('iterations (per hundreds)') plt.title("Learning rate =" + str(d["learning_rate"])) plt.show()新學到知識:
| 2.18 Logistic 損失函數(shù)的解釋 | 回到目錄 | 3.1 神經(jīng)網(wǎng)絡(luò)概覽 |
總結(jié)
以上是生活随笔為你收集整理的2.19 总结-深度学习-Stanford吴恩达教授的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2.18 Logistic 损失函数的解
- 下一篇: 3.1 神经网络概览-深度学习-Stan