天天看點

機器學習-貓狗識别(入門實戰案例)!重點學習!

作者:AI人工智能知識庫

各位小夥伴動動手指關注一下小編,持續分享程式設計幹貨!你想學習哪方面内容下方留言喲~

AI人工智能必備學習的18個實戰項目B站學習連結:「連結」

案例分析:下載下傳貓狗圖檔,進行分類。對資料進行分類,訓練集和測試集。

訓練集和測試集都進行命名規範,把貓标記為1,狗标記為0。

處理流程: 資料處理,把資料處理為64X64大小的格式,參數初始化分被初始化 各層權重 W 和 偏置 b,(一般情況下W進行随機指派,b指派為1),前向傳播,确定激活函數(淺層選擇tanh函數,深層選擇ReLu),交叉熵損失,反向傳播(梯度下降),更新參數,建構神經網絡,訓練進行測試,進行優化(後面還會更新的)。

導包引用:

import os
from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
import skimage.io as io           

資料處理:

機器學習-貓狗識别(入門實戰案例)!重點學習!
def clean(path, save_path, w=64,h=64):
"""
:param path: 讀取圖檔的路徑
:param save_path: 存放圖檔的路徑
:param w: 圖檔寬度
:param h: 圖檔高度
:return:
"""
if not os.path.exists(save_path):
os.mkdir(save_path)
file_names = os.listdir(path) # 擷取路徑下所有檔案的名字
for file_name in file_names:
bl_dir = os.path.isdir(path + "/" + file_name)
if bl_dir:
lower_directory = path + "/" + str(file_name)
save_ds = save_path + "/" + str(file_name)
if not os.path.exists(save_ds):
os.mkdir(save_ds)
lower_directory_names = os.listdir(lower_directory)
else:
lower_directory = path
lower_directory_names = file_names
for lower_directory_name in lower_directory_names:
# # print(save_name)
bl_save_dir = os.path.isdir(lower_directory + "/" + lower_directory_name)
photo_path = lower_directory + "/" + lower_directory_name
save_name = lower_directory + "/" + lower_directory_name
try:
pic = Image.open(photo_path)
pic = pic.resize((w, h))
pic.save(save_name)
print("成功")
except:
print("fail")           

資料準備

def normalization():
train_file = "dataset/train/*.jpg"
test_file = "dataset/test/*.jpg"
train_coll = io.ImageCollection(train_file) # 加載檔案下所有以.jpg的圖檔
test_coll = io.ImageCollection(test_file)
X_train = np.asarray(train_coll) # 轉成成array
Y_train = np.hstack((np.ones((1, 250)), np.zeros((1, 250))))
X_test = np.asarray(test_coll)
Y_test = np.hstack((np.ones((1, 98)), np.zeros((1, 99))))
m_train = X_train.shape[0]
w, h, d = X_train.shape[1], X_train.shape[2], X_train.shape[3]
print("訓練集樣本%d " % m_train)
print(w, h, d)
m_test = X_test.shape[0]
print("測試樣本有%d" % m_test)
idx = [np.random.choice(m_train) for i in range(10)]
lable = Y_train[0, idx]
for i in range(2):
for j in range(5):
plt.subplot(2, 5, 5 * i + j + 1)
plt.imshow(X_train[idx[5 * i + j]])
plt.title("y=" + str([lable[5 * i + j]]))
plt.axis('off')
plt.show()
X_train = X_train.reshape(m_train, -1).T
print("訓練樣本次元" + str(X_train.shape))
X_train = X_train / 250
X_test = X_test.reshape(m_test, -1).T
X_test = X_test / 250
return X_train, Y_train, X_test, Y_test           

參數初始化

def initialize_parameters(layer_dims):
"""
W權重進行随機,b初始化為1
:param layer_dims: 網絡層神經元個數
:return: 儲存參數的字典
"""
np.random.seed(5)
parameters = {}
L = len(layer_dims)
for l in range(1, L):
parameters['W' + str(l)] = np.random.randn(layer_dims[l], layer_dims[l-1]) * 0.1
parameters['b' + str(l)] = np.zeros((layer_dims[l], 1))
return parameters           

前向傳播

def relu(Z):
"""
深度網絡選擇Relu
:param Z: 激活函數輸入 神經元線性輸出
:return: A 激活函數輸出,神經元非線性輸出
"""
A = np.maximum(0, Z)
return A
def sidmoid(Z):
"""
淺層網絡 sidmoid
:param Z: 激活函數輸入 神經元線性輸出
:return: A 激活函數輸出,神經元非線性輸出
"""
A = 1 / (1 + np.exp(-Z))
return A
# 前向傳播
def single_layer_forward(A_prev, W, b, activation):
"""
:param A_prev: 該網絡的輸入,上層網絡的輸出
:param W: 該層網絡的權重
:param b: 該層網絡的偏置參數
:param activation: 激活函數
:return: A 該網絡的輸出層
cache: 儲存所有的中間變量 A_prev W b Z
"""
Z = np.dot(W, A_prev) + b
if activation == "sigmoid":
A = sidmoid(Z)
elif activation == "relu":
A = relu(Z)
cache = (A_prev, W, b, Z)
return A , cache
def forward_propagation(X, parameters):
"""
:param X: 神經網絡的輸入
:param parameters: 該層網絡的權重資料
:return: A 該層網絡的輸出 cache 儲存該層網絡所有的中間變量
"""
caches = []
A = X
L = len(parameters) # 因為有wb兩個,是以需要除以2
L = int(L/2)
for l in range(1, L):
A_prev = A
A, cache = single_layer_forward(A_prev, parameters['W' + str(l)], parameters['b' + str(l)], "relu")
caches.append(cache)
Al, cache = single_layer_forward(A, parameters['W' + str(L)], parameters['b' + str(L)], "sigmoid")
caches.append(cache)
return Al, caches           

交叉熵損失

def compute_cost(AL, Y):
"""
:param AL:神經網絡輸出層輸出
:param Y: 神經網絡真是标簽
:return: 交叉熵損失
"""
m = AL.shape[1]
cross_entropy = -(Y * np.log(AL) + (1 - Y) * np.log(1 - AL))
cost = 1.0 / m * np.sum(cross_entropy)
return cost           

反向傳播

def relu_backward(dA, Z):
"""
:param dA: A 的梯度
:param z: 神經網絡的輸出
:return: dZ Z的梯度
"""
dZ = np.array(dA, copy=True)
dZ[Z <= 0] = 0
return dZ
def sigmoid_backward(dA, Z):
"""
:param dA:A 的梯度
:param Z: 神經網絡的輸出
:return: dZ Z的梯度
"""
s = 1/ (1 + np.exp(-Z))
dZ = dA * s * (1-s)
return dZ
def single_layer_backward(dA, cache, activation):
"""
:param dA:A 的梯度
:param cache: 儲存所有中間變量 A_prev W b Z
:param activation: 選擇的激活函數
:return: dA_prev 上一層A_prev 的梯度 dW 參數W的梯度 db 參數b梯度
"""
A_prev, W, b, Z = cache
if activation == "relu":
dZ = relu_backward(dA, Z)
elif activation == "sigmoid":
dZ = sigmoid_backward(dA, Z)
m = dA.shape[1]
dW = 1/m*np.dot(dZ, A_prev.T)
db = 1 / m * np.sum(dZ, axis=1, keepdims=True)
dA_prev = np.dot(W.T, dZ)
return dA_prev, dW, db
def backward_propagarion(AL, Y, caches):
"""
:param AL: 神經網絡輸出的層數
:param cache: 儲存所有中間變量 A_prev W b Z
:param Y:真實标簽
:return: grads 所有參數梯度
"""
gards = {}
L = len(caches)
m = AL.shape[1]
dAL = -(np.divide(Y, AL) - np.divide(1 - Y , 1 - AL))
current_cache = caches[L-1]
gards["dA" + str(L-1)],gards["dW" + str(L-1)], gards["db" + str(L-1)] = single_layer_backward(dAL, current_cache, activation="sigmoid")
for l in reversed(range(L-1)):
current_cache = caches[l]
dA_prev_temp, dW_temp, db_temp = single_layer_backward(gards["dA" + str(l + 1)], current_cache, activation="relu")
gards["dA" + str(l)] = dA_prev_temp
gards["dW" + str(l)] = dW_temp
gards["db" + str(l)] = db_temp
return gards           

更新參數

def update_parameters(parameters, grads, learning=0.1):
"""
:param parameters: 網絡參數
:param grads: 神經網絡參數梯度
:param learning: 學習速率
:return: 網絡參數
"""
L = len(parameters)
L = int(L/2)
for l in range(L):
parameters["W" +str(l+1)] -= learning * grads["dW" + str(l)]
parameters["b" +str(l+1)] -= learning * grads["db" + str(l)]
return parameters           

構模組化型

def nn_model(X, Y, layers_dims, num_iterations=300, learning_rate=0.01,):
"""
:param X:神經網絡輸入
:param Y: 樣本标簽
:param layers_dims:神經網絡各層神經元個數,包括輸入層和輸出層
:param learning_rate: 學習速率
:param num_iterations: 學習率
:return: 訓練完成後的網絡模型
"""
np.random.seed(1)
costs = []
parameters = initialize_parameters(layers_dims)
for i in range(num_iterations):
AL, caches = forward_propagation(X, parameters)
cost = compute_cost(AL, Y)
grads = backward_propagarion(AL, Y, caches)
parameters = update_parameters(parameters, grads, learning_rate)
if (i+1) % 100 == 0:
print("Cost after iteration %i : %f" % (i+1, cost))
costs.append(cost)
plt.plot(np.squeeze(costs))
plt.ylabel('cost')
plt.xlabel('loop humber')
plt.title("learning" + str(learning_rate))
plt.show()
plt.close()
return parameters           

進行預測

def predit(X, parameter):
"""
:param X:神經網絡輸入
:param parameter: 訓練完成後的網絡參數
:return: 預測樣本标簽
"""
AL, caches = forward_propagation(X, parameter)
Y_pred = np.zeros((1, X.shape[1]))
Y_pred[AL > 0.5] = 1
return Y_pred           
if __name__ == "__main__":
layers_dims = [64*64*3, 200, 100, 10, 1]
X_train, Y_train, X_test, Y_test = normalization()
parameters = nn_model(X_train, Y_train, layers_dims, num_iterations=2000, learning_rate=0.01)
# print(parameters)
Y_test_pred = predit(X_test, parameters)
print(Y_test_pred)
print("*" * 50)
print(Y_test)
acc_test = np.mean(Y_test_pred == Y_test)
print("測試資料的精确度為:%f " % (acc_test))           

運作結果:網絡結構(輸入層 隐藏層(1) 輸出層)疊代1000

機器學習-貓狗識别(入門實戰案例)!重點學習!
機器學習-貓狗識别(入門實戰案例)!重點學習!
機器學習-貓狗識别(入門實戰案例)!重點學習!
機器學習-貓狗識别(入門實戰案例)!重點學習!

參考書目:深度學習入門(基于pytorch和TensorFlow的理論與實作)

繼續閱讀