吳恩達深度學習第一課--第二週神經網絡基礎作業下代碼實現

需要的庫文件

import numpy as np #矩陣運算
import matplotlib.pyplot as plt #繪圖
import h5py #讀取h5文件

步驟

按照如下步驟來實現Logistic:
1、定義模型結構
2、初始化模型參數
3、循環
3.1、前向傳播
3.2、計算損失
3.3、後向傳播
3.4、更新參數
4、整合成爲一個完整的模型

取出訓練集、測試集

train_dataset = h5py.File('D:\\20200112zhaohuan\\software\\pycharm\\code\\hello\\train_catvnoncat.h5', 'r')
test_dataset = h5py.File('D:\\20200112zhaohuan\\software\\pycharm\\code\\hello\\test_catvnoncat.h5', 'r')

瞭解訓練集、測試集

for key in train_dataset:
    print(key)
print(train_dataset['train_set_x'].shape)
print(train_dataset['train_set_y'].shape)
#print(train_dataset['train_set_x'][:])

print(test_dataset['test_set_x'].shape)
print(test_dataset['test_set_y'].shape)
#print(test_dataset['test_set_x'][:])

得出訓練集數據維度是(209,64,64,3)、測試集數據維度是(50,64,64,3)。訓練集標籤維度是(209,),測試集標籤維度是(50,)

查看圖片

plt.imshow(train_data_org[176])

數據維度處理

m_train = train_data_org.shape[0]  #得到樣本m=209
m_text = text_data_org.shape[0]  #得到樣本m=50

train_data_tran = train_data_org.reshape(m_train,-1).T
test_data_tran = text_data_org.reshape(m_text,-1).T

print(train_data_tran.shape,test_data_tran.shape)

train_lables_tran = train_lables_org[np.newaxis,:]
test_lables_tran = text_lables_org[np.newaxis,:]

print(train_lables_tran.shape,test_lables_tran.shape)

得出訓練集數據維度是(12288,209),測試集數據維度是(12288,50)。訓練集標籤維度是(1,209),測試集標籤維度是(1,50)。

標準化數據

因爲每個值在0~255之間,將所有值除以255,這樣每個值之間的差距就非常小。

train_data_sta = train_data_tran/255
test_data_sta = test_data_tran/255

定義sigmoid函數

sigmoid函數:a=δ(z)=11+ez\delta(z)=\frac{1}{1+e^{-z}}

def sigmoid(z):
	#輸入z,得到經過sigmoid後的值a
    a = 1/(1+np.exp(-z))
    return a

初始化參數

n_dim = train_data_sta.shape[0] #得到特徵長度n
print(n_dim)  #12288
w = np.zeros((n_dim,1))  #初始化nx1維矩陣w
b = 0  #初始化實數b

定義前向傳播函數、代價函數及梯度下降

前向傳播函數:Z=wTX+bw^TX+b;A=sigmoid(Z)
代價函數:J=1mi=1m[YlogA+(1Y)log(1A)]-\frac{1}{m}\sum_{i=1}^m[Y*logA+(1-Y)*log(1-A)]
梯度下降:dw=L(A,Y)w=1mX(AY)Tdb=L(A,Y)b=1mnp.sum(AY)W=Wαdw;b=bαdbdw=\frac{\partial L(A,Y)}{\partial w}=\frac{1}{m}X(A-Y)^T;db=\frac{\partial L(A,Y)}{\partial b}=\frac{1}{m}np.sum(A-Y);W=W-\alpha dw;b=b-\alpha db

def propagate(w,b,X,Y):
	#輸入:權重w,實數b,數據集x,標籤y。
	#輸出:對w的偏導dw,對b的偏導db,將其裝進字典grands。
	#返回:grands和代價值j
	
    #1.前向傳播函數
    z = np.dot(w.T,X)+b
    A = sigmoid(z)

    #2.代價函數
    m = X.shape[1] #樣本數m
    J = -1/m * np.sum(Y*np.log(A)+(1-Y)*np.log(1-A))

    #3.梯度下降
    dw = 1/m * np.dot(X,(A-Y).T)
    db = 1/m * np.sum(A-Y)

    grands = {'dw':dw,'db':db}

    return grands,J

優化部分

def optimize(w,b,X,y,alpha,n_iters):
	#輸入:權重w,實數b,數據集x,標籤集y,學習效率alpha,特徵數n_iters=12288
	#輸出:對w的偏導dw,對b的偏導db,將其裝進字典grands。修正後的w和b,將其裝進字典params。每隔100記錄一次代價值,將其裝進數組costs。
	#返回:grands、params、costs。

    costs = []  #保存代價函數值,爲了後面繪出代價函數圖形
    for i in range(n_iters):
        grands,J = propagate(w,b,X,y)
        dw = grands['dw']
        db = grands['db']

        w = w - alpha * dw
        b = b - alpha * db

        if i % 100 == 0:
            costs.append(J)
            print('n_iters is ',i,',cost is ',J)

    grands = {'dw': dw, 'db': db}
    params = {'w': w, 'b': b}
    return grands,params,costs

預測部分

def predict(w,b,X_test):
	#輸入:權重w,實數b,測試數據x_test
	#輸出:預測矩陣y_pred(值要麼爲1,要麼爲0)

    z = np.dot(w.T, X_test) + b
    A = sigmoid(z)

    m = X_test.shape[1]
    y_pred = np.zeros((1,m)) #初始化維度爲1xm的y_pred矩陣

    for i in range(m):
        if A[:,i] > 0.5:  
            y_pred[:,i] = 1
        else:
            y_pred[:,i] = 0

    return y_pred

模型的整合–合併 優化和預測模塊

def model(w,b,X_train,Y_train,X_test,Y_test,alpha,n_iters):
	#輸入:權重w,實數b,訓練數據集X_train,訓練標籤集Y_train,測試數據集X_test,測試標籤集Y_test,學習效率alpha,特徵值n_iters=12288。
	#輸出:數據字典b

    grands,params,costs = optimize(w, b, X_train, Y_train, alpha, n_iters)
    w = params['w']
    b = params['b']

    y_pred_train = predict(w,b,X_train)
    y_pred_test = predict(w,b,X_test)

    print('the train acc is ', np.mean(y_pred_train == Y_train)*100,'%')
    print('the test acc is ', np.mean(y_pred_test == Y_test)*100,'%')

    b={
        'w':w,
        'b':b,
        'costs':costs,
        'y_pred_train':y_pred_train,
        'y_pred_test':y_pred_test,
        'alpha':alpha
    }   #用數據字典返回,格式類似json

    return  b

完整代碼


import numpy as np
import matplotlib.pyplot as plt
import h5py
from skimage import transform  # 用來調整自己圖片的大小

# 取出訓練集、測試集
train_dataset = h5py.File('D:\\20200112zhaohuan\\software\\pycharm\\code\\hello\\train_catvnoncat.h5','r')
test_dataset = h5py.File('D:\\20200112zhaohuan\\software\\pycharm\\code\\hello\\test_catvnoncat.h5','r')

# 瞭解訓練集、測試集的key
for key in train_dataset:
    print(key)
    # list_classes
    # train_set_x
    # train_set_y
for key in test_dataset:
    print(key)
    # list_classes
    # test_set_x
    # test_set_y

# 取出訓練數據集train_data_org、訓練標籤集train_labels_org、測試數據集test_data_org、測試標籤集test_labels_org
train_data_org = train_dataset['train_set_x'][:]
train_labels_org = train_dataset['train_set_y'][:]

test_data_org = test_dataset['test_set_x'][:]
test_labels_org = test_dataset['test_set_y'][:]

print(train_data_org.shape,train_labels_org.shape,test_data_org.shape,test_labels_org.shape)

# 查看圖片
plt.imshow(train_data_org[150])

# 數據維度處理
m_train = train_data_org.shape[0] # 209
m_test = test_data_org.shape[0] # 50
print(m_train,m_test)
train_data_tran = train_data_org.reshape(m_train,-1).T
test_data_tran = test_data_org.reshape(m_test,-1).T

train_lables_tran = train_labels_org[np.newaxis,:]
test_lables_tran = test_labels_org[np.newaxis,:]

print(train_data_tran.shape,test_data_tran.shape,train_lables_tran.shape,test_lables_tran.shape)

# 標準化數據
train_data_sta = train_data_tran/255
test_data_sta = test_data_tran/255

# 定義sigmoid函數
def sigmoid(z):
    a = 1/(1+np.exp(-z))
    return a

# 初始化參數w,b
n_iters = train_data_sta.shape[0] #12288
w = np.zeros((n_iters,1))
b = 0

# 定義前向傳播函數、代價函數及梯度下降。
def propagate(w,b,X,Y):
    # 輸入:權重w,實數b,數據集x,標籤集y。
    # 輸出:對w的偏導dw,對b的偏導db,將其裝進字典grands。
    # 返回:grands和代價值j


    # 1.前向傳播函數
    Z = np.dot(w.T,X)+b
    A = sigmoid(Z)

    # 2.代價函數
    m = X.shape[1]
    J = -1/m * np.sum(Y * np.log(A) + (1-Y)*np.log(1-A))

    # 3.梯度下降
    dw = 1/m*np.dot(X,(A-Y).T)
    db = 1/m*np.sum(A-Y)

    grands={'dw':dw,'db':db}

    return grands,J

# 優化部分
def optimize(w,b,X,Y,alpha,n_iters):
    # 輸入:權重w,實數b,數據集X,標籤集Y,學習效率alpha,特徵數n_iters=12288
    # 輸出:對w的偏導dw,對b的偏導db,將其裝進字典grands。修正後的w和b,將其裝進字典params。每隔100記錄一次代價值,將其裝進數組costs。
    # 返回:grands、params、costs

    costs=[]
    for i in range(n_iters):
        grands, J = propagate(w, b, X, Y)
        dw = grands['dw']
        db = grands['db']

        w = w - alpha*dw
        b = b - alpha*db

        if i%100==0:
            costs.append(J)
            print('n_iters is ',i,'cost is',J)

    grands = {'dw':dw,'db':db}
    paras = {'w':w,'b':b}
    return grands,paras,costs

# 預測部分
def predict(w,b,X):
    # 輸入:權重w,實數b,數據集X
    # 輸出:預測矩陣y_pred(值要麼爲1,要麼爲0)

    Z = np.dot(w.T, X) + b
    A = sigmoid(Z)

    m = X.shape[1]
    y_pred = np.zeros((1,m))

    for i in range(m):
        if A[:,i]>0.5:
            y_pred[:,i]=1
        else:
            y_pred[:,i]=0

    return y_pred

# 模型的整合
def model(w,b,X_train,Y_train,X_test,Y_test,alpha,n_iters):
    # 輸入:權重w,實數b,訓練數據集X_train,訓練標籤集Y_train,測試數據集X_test,測試標籤集Y_test,學習效率alpha,特徵值n_iters=12288。
    # 輸出:數據字典rs

    grands,paras,costs = optimize(w, b, X_train, Y_train, alpha, n_iters)
    w = paras['w']
    b = paras['b']

    y_pred_train = predict(w,b,X_train)
    y_pred_test = predict(w,b,X_test)

    print('the train acc is ', np.mean(y_pred_train == Y_train)*100,'%')
    print('the test acc is ', np.mean(y_pred_test == Y_test)*100,'%')

    rs = {
        'w':w,
        'b':b,
        'costs':costs,
        'y_pred_train':y_pred_train,
        'y_pred_test':y_pred_test,
        'alpha':alpha
    }

    return rs

rs = model(w,b,train_data_sta,train_lables_tran,test_data_sta,test_lables_tran,alpha=0.005,n_iters=2000)
plt.plot(rs['costs'])
plt.xlabel('per hundred iters')
plt.ylabel('cost')

# 自我檢測一下
index = 2
print('y is ',train_lables_tran[0,index])
print('y_pred is ',rs['y_pred_train'][0,index])
plt.imshow(train_data_org[index])

# 用自己電腦裏面的圖片來檢測一下
from skimage import transform
fname = 'D:\\20200112zhaohuan\\tim.jpg'
image = plt.imread(fname,'rb')
plt.imshow(image)
print(image.shape)
image_tran = transform.resize(image,(64,64,3)).reshape(64*64*3,1)
print(image_tran.shape)
y = predict(rs['w'],rs['b'],image_tran)
print(int(y))

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章