吳恩達深度學習課程第一課第二週課程作業
學過吳恩達的Machine Learning課程,現在跟著學深度學習,本來是想付費的,奈何搞半天付款沒有成功,沒辦法只能下載資料集自己搞了。由於門外漢,安裝工具軟體加上完成作業花了一天時間,其實第二週的作業和機器學習課程基本是一樣的,沒有什麼太大難度,都是初級入門,但是課程視訊還是講了一些之前沒有接觸過的內容。
課程作業資料集和程式碼可以到百度雲下載:
連結:https://pan.baidu.com/s/1cwd8IE 密碼:1xkv
1、作業前環境安裝和工具準備
本部分只針對不知道咋自己搭建作業環境的同學,當然大神也不會瀏覽到我的部落格啦 哈哈!
第一步 安裝jupyter notebook,安裝方法很簡單,只要安裝了Python和pip工具就可以了
win系統在cmd命令列輸入pip install jupyter notebook
安裝後就是啟動jupyter notebook,直接在命令視窗輸入jupyter notebook即可啟動了,由預設瀏覽器開啟。
預設的資料夾是C盤下使用者資料夾,可以通過修改配置檔案修改預設資料夾,詳見http://blog.csdn.net/qq_33039859/article/details/54604533
然後就把資料集和模組檔案放到裡面去,然後點“New”選擇Python新建檔案,點選這個檔案就可以進行程式設計了。
第二步是安裝第三方工具庫,本週用到的庫有numpy h5py matplotlib PIL scipy ,這些庫都可以使用pip工具安裝,和上面安裝notebook步驟是一樣的,不再贅述了。(可以在Python IDLE裡面import一下看有沒有安裝成功)
2、安裝包,前面說過了,這幾個包主要是科學計算和圖片處理用的,具體可以上網搜一下。
import numpy as np
import matplotlib.pyplot as plt
import h5py
import scipy
from PIL import Image
from scipy import ndimage
from lr_utils import load_dataset
3、資料集處理
匯入資料,使用課程提供lr_utils模組load_dataset函式
train_set_x_orig, train_set_y, test_set_x_orig, test_set _y, classes = load_dataset()
獲得樣本數量
m_train=train_set_x_orig.shape[0]
m_test=test_set_x_orig.shape[0]
num_px=train_set_x_orig[0].shape[0]
列印資料集中樣本的一些引數,可以直觀檢查資料規模
print (“Number of training examples: m_train = ” +
str(m_train))
print (“Number of testing examples: m_test = ” + str(m_test))
print (“Height/Width of each image: num_px = ” + str(num_px))
print (“Each image is of size: (” + str(num_px) + “, ” + str(num_px) + “, 3)”)
print (“train_set_x shape: ” + str(train_set_x_orig.shape))
print (“train_set_y shape: ” + str(train_set_y.shape))
print (“test_set_x shape: ” + str(test_set_x_orig.shape))
print (“test_set_y shape: ” + str(test_set_y.shape))
Number of training examples: m_train = 209
Number of testing examples: m_test = 50
Height/Width of each image: num_px = 64
Each image is of size: (64, 64, 3)
train_set_x shape: (209, 64, 64, 3)
train_set_y shape: (1, 209)
test_set_x shape: (50, 64, 64, 3)
test_set_y shape: (1, 50)
可以看到訓練集一共是209個樣本,每個樣本都是一個3通道(RGB)圖片的陣列,每個樣本大小是64*64*3
資料展開,由於圖片直接翻譯過來的是多維陣列,不利於後續資料處理,需要對資料進行展開處理:
train_set_x_flatten=train_set_x_orig.reshape(m_train,num_px**2*3).T
test_set_x_flatten=test_set_x_orig.reshape(m_test,-1).T
列印看一下展開結果:
print ("train_set_x_flatten shape: " + str(train_set_x_flatten.shape))
print ("train_set_y shape: " + str(train_set_y.shape))
print ("test_set_x_flatten shape: " + str(test_set_x_flatten.shape))
print ("test_set_y shape: " + str(test_set_y.shape))
print ("sanity check after reshaping: " + str(train_set_x_flatten[0:5,0]))
結果:
train_set_x_flatten shape: (12288, 209)
train_set_y shape: (1, 209)
test_set_x_flatten shape: (12288, 50)
test_set_y shape: (1, 50)
sanity check after reshaping: [17 31 56 22 33]
除以255,均值化
train_set_x = train_set_x_flatten/255.
test_set_x = test_set_x_flatten/255.
4、函式定義
定義激勵函式
def sigmoid(z):
s=1/(1+np.exp(-z))
return s
定義引數初始化函式
def initialize_with_zeros(dim):
w=np.zeros((dim,1))
b=0
assert(w.shape==(dim,1))
assert(isinstance(b,float) or isinstance(b,int))
return w,b
定義傳播函式,可以計算梯度和損失函式:
def propagate(w,b,X,Y):
m=X.shape[1]
A=sigmoid(np.dot(w.T,X)+b)
cost=-np.sum(np.multiply(Y,np.log(A))+np.multiply(1-Y,np.log(1-A)))/m
dw=1/m*np.dot(X,(A-Y).T)
db=1/m*np.sum(A-Y)
assert(dw.shape==w.shape)
assert(db.dtype==float)
cost = np.squeeze(cost)#刪除陣列中為1的那個維度
assert(cost.shape == ())#cost為實數
grads={'dw':dw,
'db':db}
return grads,cost
定義優化函式,進行梯度下降演算法實現,得到最終優化引數W,b:
def optimize(w, b, X, Y, num_iterations, learning_rate, print_cost = False):
costs=[]
for i in range(num_iterations):
grads,cost=propagate(w,b,X,Y)
dw=grads['dw']
db=grads['db']
w=w-learning_rate*dw
b=b-learning_rate*db
if i%100==0:
costs.append(cost)
if print_cost and i % 100 == 0:
print ("Cost after iteration %i: %f" %(i, cost))
params={'w':w,
'b':b}
grads = {"dw": dw,
"db": db}
return params, grads, costs
以上部分已經完成了對於邏輯迴歸演算法的實現,下面進行預測,在得到W和b引數後,對於一個確定的樣本集進行分類預測,根據概率大小進行分類。
def predict(w,b,X):
m = X.shape[1]
Y_prediction = np.zeros((1,m))
w = w.reshape(X.shape[0], 1)
A = sigmoid(np.dot(w.T, X) + b)
for i in range(A.shape[1]):
if A[0,i]>=0.5:
Y_prediction[0,i]=1
else:
Y_prediction[0,i]=0
assert(Y_prediction.shape == (1, m))
return Y_prediction
可以進行列印輸出
print ("predictions = " + str(predict(w, b, X)))
最後將前面邏輯迴歸的所有函式集合到一個模型中,便於呼叫:
def model(X_train,Y_train,X_test,Y_test,num_iterations=2000,learning_rate=0.005, print_cost = False):
w,b=np.zeros((X_train.shape[0],1)),0
parameters, grads, costs = optimize(w, b, X_train, Y_train, num_iterations, learning_rate, print_cost)
w = parameters["w"]
b = parameters["b"]
Y_prediction_test=predict(w,b,X_test)
Y_prediction_train=predict(w,b,X_train)
print('train accuracy: {} %'.format(100-np.mean(np.abs(Y_prediction_train-Y_train))*100))
print("test accuracy: {} %".format(100 - np.mean(np.abs(Y_prediction_test - Y_test)) * 100))
d={"costs": costs,
"Y_prediction_test": Y_prediction_test,
"Y_prediction_train" : Y_prediction_train,
"w" : w,
"b" : b,
"learning_rate" : learning_rate,
"num_iterations": num_iterations
}
return d
5、執行模型
執行資料集檢視結果,迭代2000次,學習率0.005
d = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 2000, learning_rate = 0.005, print_cost = True)
結果,訓練集精度99%,測試集精度70%,有一些過擬合了,模型精度有待提高:
Cost after iteration 0: 0.693147
Cost after iteration 100: 0.584508
Cost after iteration 200: 0.466949
Cost after iteration 300: 0.376007
Cost after iteration 400: 0.331463
Cost after iteration 500: 0.303273
Cost after iteration 600: 0.279880
Cost after iteration 700: 0.260042
Cost after iteration 800: 0.242941
Cost after iteration 900: 0.228004
Cost after iteration 1000: 0.214820
Cost after iteration 1100: 0.203078
Cost after iteration 1200: 0.192544
Cost after iteration 1300: 0.183033
Cost after iteration 1400: 0.174399
Cost after iteration 1500: 0.166521
Cost after iteration 1600: 0.159305
Cost after iteration 1700: 0.152667
Cost after iteration 1800: 0.146542
Cost after iteration 1900: 0.140872
train accuracy: 99.04306220095694 %
test accuracy: 70.0 %
可以看一下模型效果,使用PIL庫的圖片顯示函式imshow將資料集的陣列轉化為圖片顯示出來,顯示之前要reshape為imshow需要的尺寸:
index=1
plt.imshow(test_set_x[:,index].reshape((num_px,num_px,3))) #使用imshow必須是RGB影象格式,3通道
print('y= '+str(test_set_y[0,index])+ ", you predicted that it is a \""+classes[int(d['Y_prediction_test'][0,index])].decode('utf-8')+"\"picture.")
結果:
y= 1, you predicted that it is a "cat"picture.
6、學習率的影響
學習率大小影響模型最終的精度和收斂速度
測試一下,把上面模型的學習率分別賦值0.01,0.001,0.0001觀察損失函式隨著迭代次數增加的反應:
learning_rates=[0.01,0.001,0.0001]
models={}
for i in learning_rates:
print ("learning_rate is: "+str(i))
models[str(i)]=model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 1500, learning_rate = i, print_cost = False)
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()
可以看到學習率太大會使得損失函式波動較大,但是收斂速度快,學習率太小會導致模型精度降低。
7、試一下自己的圖片
可以把自己的圖片匯入模型看一下效果,把圖片放入到images資料夾下面,將下面程式碼的my_image的值改為你圖片的名稱即可。圖片處理是通過scipy庫imresize函式將圖片解析度調整為模型可接受的64*64*3的大小,然後通過plt庫的imshow函式顯示,要注意的是顯示的是原圖片大小,並不是處理後的圖片。
my_image = "image1219.jpg"
fname = "images/" + my_image
image = np.array(ndimage.imread(fname, flatten=False))
my_image = scipy.misc.imresize(image, size=(num_px,num_px)).reshape((1, num_px*num_px*3)).T
my_predicted_image = predict(d["w"], d["b"], my_image)
plt.imshow(image)
print("y = " + str(np.squeeze(my_predicted_image)) + ", your algorithm predicts a \"" + classes[int(np.squeeze(my_predicted_image)),].decode("utf-8") + "\" picture.")
結果:
y = 1.0, your algorithm predicts a “cat” picture.
以上基本就是本次作業的主要內容,很多課程的說明文件沒有拿過來,主要是因為網上有大量的參考,我只針對主要模組進行了簡要說明,而且邏輯迴歸比較簡單,和原來的機器學習作業基本類似,從理論上沒有引入新的東西,如果對這個課程學起來感覺有難度可以先去把機器學習的課看一下,對於很多基礎的概念就清楚了。