文章目錄
需要的庫文件
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=
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=;A=sigmoid(Z)
代價函數:J=
梯度下降:
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))