具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

Logistic迴歸是一種二元分類方法。在本文中,在對貓和狗的圖像進行訓練之後,然後給出一張之前從未見過的貓(y = 0)或狗(y = 1)的圖片,我們將發現機器是否可以預測正確的類型。正如我們所看到的,即使像邏輯迴歸這樣的簡單算法也可以令人驚訝地完成這項任務。

我們想要創建可以接受任意數量輸入的模型,並將輸出約束在0和1之間。這意味著,我們計劃構建具有神經網絡思維模式的Logistic迴歸模型。

在本文中,我將指導您如何做到這一點,因此,我還將磨練您對深度學習的直覺。

在本文中,我們將使用優化算法(梯度下降)構建一個學習算法的一般架構,包括:參數初始化、成本函數及其梯度計算。然後,我們將按照正確的順序將上面的三個函數收集到一個主模型函數中。總而言之,我們不會在代碼中使用循環(for / while),除非有必要這樣做,以最大化我們的代碼性能。

準備Cats vs Dogs數據

首先,導入需要的所有包:

import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
import scipy
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

在本文中,我將使用免費的Dogs vs. Cats Kaggle數據集。我不會使用所有圖像,因為它對我們的模型來說太大了。在我的例子中,我將使用3000只貓和3000只狗圖像作為訓練模型。為了測試模型,我將使用500只貓和500只狗圖像。

首先,我們應該定義我們的圖像大小。由於我們的數據集中的圖像大小不同,我們需要將它們調整為特定大小。然後定義訓練和測試圖像位置。在最後一步中,我從訓練和測試數據集中讀取所有圖像位置,並將它們作為列表:

ROWS = 64
COLS = 64
CHANNELS = 3
TRAIN_DIR = 'Train_data/'
TEST_DIR = 'Test_data/'
# use this to read full dataset
train_images = [TRAIN_DIR+i for i in os.listdir(TRAIN_DIR)]
test_images = [TEST_DIR+i for i in os.listdir(TEST_DIR)]
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

接下來我們需要創建一個簡單的函數,我們將用它來讀取文件路徑中的每個圖像,調整大小並將其返回以供將來使用:

def read_image(file_path):
img = cv2.imread(file_path, cv2.IMREAD_COLOR)
return cv2.resize(img, (ROWS, COLS), interpolation=cv2.INTER_CUBIC)
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

現在我們將創建一個函數來準備我們的數據以供進一步使用。在下面的函數中我們將分隔數據,所以如果我們的圖像是條狗,我們將給出索引為1,如果是隻貓,我們將給出0的索引:

def prepare_data(images):
m = len(images)
X = np.zeros((m, ROWS, COLS, CHANNELS),dtype=np.uint8)
y = np.zeros((1, m))
for i, image_file in enumerate(images):
X[i,:] = read_image(image_file)
if 'dog' in image_file.lower():
y[0, i] = 1
elif 'cat' in image_file.lower():
y[0, i] = 0
return X, y
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

現在調用我們創建的函數來讀取我們文件夾中的所有測試和訓練圖像:

train_set_x, train_set_y = prepare_data(train_images) 

test_set_x, test_set_y = prepare_data(test_images)
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

現在我們應該將形狀 (ROWS, COLS, CHANNELS)的圖像重新塑造為一個形狀的numpy數組(ROWS∗COLS∗CHANNELS, 1):

train_set_x_flatten = train_set_x.reshape(train_set_x.shape[0], CHANNELS*COLS*ROWS).T
test_set_x_flatten = test_set_x.reshape(test_set_x.shape[0], -1).T
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

輸出我們的數據形狀:

print("train_set_x shape " + str(train_set_x.shape))
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 shape " + str(test_set_x.shape))
print("test_set_x_flatten shape: " + str(test_set_x_flatten.shape))
print("test_set_y shape: " + str(test_set_y.shape))
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

輸出我們的形狀後,我們應該看到它們:

train_set_x shape (6002, 64, 64, 3)
train_set_x_flatten shape: (12288, 6002)
train_set_y shape: (1, 6002)

test_set_x shape (1000, 64, 64, 3)
test_set_x_flatten shape: (12288, 1000)
test_set_y shape: (1, 1000)
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

為了表示彩色圖像,必須為每個像素指定紅、綠、藍通道(RGB),因此像素值實際上是一個由3個數字組成的向量,範圍從0到255。

機器學習中一個常見的預處理步驟是對數據集進行集中和標準化,這意味著我們從每個示例中減去整個numpy數組的平均值,然後用整個numpy數組的標準差除以每個示例。但是對於圖像數據集來說,將數據集的每一行除以255(像素通道的最大值)會更簡單、更方便,而且幾乎同樣有效:

train_set_x = train_set_x_flatten/255
test_set_x = test_set_x_flatten/255
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

現在我們知道了如何準備圖像數據集。

學習算法的體系結構

在這部分中,我們將設計一個簡單的算法來區分貓、狗圖像。我們將使用神經網絡思維模式構建Logistic迴歸。下圖解釋了為什麼Logistic迴歸實際上是一個非常簡單的神經網絡(一個神經元):

具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

我們構建“神經網絡”的主要步驟是:

•定義模型結構(數據形狀)。

•初始化模型的參數。

•通過最小化成本來了解模型的參數:

- 計算當前損耗(正向傳播)。

- 計算當前梯度(反向傳播)。

- 更新參數(梯度下降)。

•使用學習的參數進行預測(在測試集上)。

•分析結果並得出結論。

我們將分別構建上面的部分,然後我們將它們集成到一個名為model()的函數中。

以前我們已經編寫了一個sigmoid函數,這裡直接使用:

def sigmoid(z):
s = 1/(1+np.exp(-z))
return s
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

正向傳播:

首先,權重和偏差值通過模型正向傳播以得到預測輸出。在每個神經元/節點處,輸入的線性組合乘以激活函數-在我們的示例中為sigmoid函數。在此過程中,權重和偏差從輸入傳播到輸出稱為正向傳播。在達到預測輸出之後,計算訓練示例的損失。

具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

正向傳播算法的數學表達式舉例:

具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

然後通過對所有訓練示例求和來計算成本:

具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

我們的最終正向傳播成本函數將如下所示:

具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

反向傳播:

反向傳播是計算從損失函數到輸入函數的偏導數的過程,我們在更新w和b的值,使我們得到最小值。寫出從dA開始的偏導數有助於理解如何得到dw和db。

具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

反向傳播的數學表達式(計算導數):

具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

編寫正向和反向傳播:

所以我們將實現上面解釋的函數,但首先讓我們看看輸入和輸出是什麼:

參數:

w - 權重,numpy數組(ROWS * COLS * CHANNELS,1)

b - 偏差,標量

X - 數據的大小(ROWS * COLS * CHANNELS,數量示例)

Y - 真“標籤”向量(0如果是狗,1如果是貓)的大小(1,例子數)

返回:

成本 - 邏輯迴歸的成本

dw - 損耗對w的梯度,形狀與w相同

db - 損失對b的梯度,形狀與b相同

以下是我們編寫的代碼:

def propagate(w, b, X, Y):
m = X.shape[1]

# FORWARD PROPAGATION (FROM X TO COST)

z = np.dot(w.T, X)+b # tag 1
A = sigmoid(z) # tag 2
cost = (-np.sum(Y*np.log(A)+(1-Y)*np.log(1-A)))/m # tag 5

# BACKWARD PROPAGATION (TO FIND GRAD)
dw = (np.dot(X,(A-Y).T))/m # tag 6
db = np.average(A-Y) # tag 7
cost = np.squeeze(cost)
grads = {"dw": dw,
"db": db}

return grads, cost
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

讓我們用樣本數據測試上面的函數:

w = np.array([[1.],[2.]])
b = 4.

X = np.array([[5., 6., -7.],[8., 9., -10.]])
Y = np.array([[1,0,1]])
grads, cost = propagate(w, b, X, Y)
print ("dw = " + str(grads["dw"]))
print ("db = " + str(grads["db"]))
print ("cost = " + str(cost))
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

結果你應該得到:

dw = [[4.33333333]
[6.33333333]]
db = 2.934645119504845e-11
cost = 16.999996678946573
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

在本部分中,我們定義了一般的學習體系結構,並定義了實現學習模型所需的步驟 我解釋了什麼是正向/反向傳播,我們學習瞭如何在代碼中實現它們。

成本優化函數

在之前,我們定義了模型結構,學習計算成本函數及其梯度。在本文中,我們將編寫一個優化函數來學習使用梯度下降更新參數。

因此,我們將優化函數通過最小化成本函數J來學習w和b。參數θ,更新規則是(α是學習速率):

具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

邏輯迴歸中的成本函數:

我們使用成本函數進行邏輯迴歸的原因之一是它是一個凸函數,具有單一全局最優。你可以想象把一個球滾下碗狀函數 - 它會落在底部。

具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

類似地,要找到最小的成本函數,我們需要找到最低點。要做到這一點,我們可以從函數上的任何位置開始,沿著最陡的斜率迭代向下移動,調整w和b的值,使其達到最小值。為此,我們使用了以下兩個公式:

具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

在這兩個方程中,偏導數dw和db分別代表了w和b的變化對成本函數的影響。通過求斜率並取斜率的負數,我們可以確保我們總是沿著最小值的方向移動。為了更好地理解,讓我們用圖形來表示dw:

具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

當導數是正的時候,我們向相反的方向移動w的值,當導數是負的時候,我們向增加w的方向移動,從而確保我們總是向最小值移動。

偏導數前面的項叫做學習率,它衡量的是每次迭代要走多大的一步。學習參數的選擇是一個重要的因素,它太小,模型需要很長時間才能找到最小值,太大,模型可能會超過最小值而不能找到最小值。

梯度下降是學習過程的本質——通過它,機器知道什麼值的權重和偏差最小化了成本函數。它通過迭代地將一組數據的預測輸出與訓練過程中的真實輸出進行比較來做到這一點。

編寫優化函數:

所以我們將實現優化函數,但首先讓我們看看它的輸入和輸出是什麼:

參數:

w - 權重,numpy數組(ROWS * COLS * CHANNELS,1)

b - 偏差,標量

X - 數據的大小(ROWS * COLS * CHANNELS,數量示例)

Y - 真“標籤”向量(0如果是狗,1如果是貓)大小(1,示例數)

num_iterations - 優化循環的迭代次數

learning_rate - 梯度下降更新規則的學習速率

print_cost - 為每100步輸出一次損失

返回:

params - 包含權重w和偏差b

grads - 包含梯度的權重和偏差相對於成本函數

cost - 在優化過程中計算的所有成本的列表

代碼如下:

def optimize(w, b, X, Y, num_iterations, learning_rate, print_cost = False):
costs = []
for i in range(num_iterations):
# Cost and gradient calculation
grads, cost = propagate(w, b, X, Y)

# Retrieve derivatives from grads
dw = grads["dw"]
db = grads["db"]
# update w and b
w = w - learning_rate*dw
b = b - learning_rate*db
# Record the costs
if i % 100 == 0:
costs.append(cost)

# Print the cost every 100 training iterations
if print_cost and i % 100 == 0:
print ("Cost after iteration %i: %f" %(i, cost))

# update w and b to dictionary
params = {"w": w,
"b": b}

# update derivatives to dictionary
grads = {"dw": dw,
"db": db}

return params, grads, costs
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

讓我們用之前編寫propogate()函數的教程中的變量來測試上面的函數:

params, grads, costs = optimize(w, b, X, Y, num_iterations = 100, learning_rate = 0.009, print_cost = False)
print("w = " + str(params["w"]))
print("b = " + str(params["b"]))
print("dw = " + str(grads["dw"]))

print("db = " + str(grads["db"]))
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

如果一切正確,你應該得到:

w = [[-0.49157334]
[-0.16017651]]
b = 3.948381664135624
dw = [[ 0.03602232]
[-0.02064108]]
db = -0.01897084202791005
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

所以在這部分我們學習瞭如何更新學習參數(梯度下降)。

實現預測函數

在前面,我們編寫了優化函數,它將輸出學習到的w和b參數。現在我們可以使用w和b來預測數據集X的標籤。因此在本文中我們將實現predict()函數。計算預測將有兩個步驟:

1、計算Y = A =σ(wT * X + b)

2、將a 的元素轉換為0(如果激活≤0.5,我們將得到一隻狗)或1(如果激活> 0.5,我們會得到一隻貓)。我們將預測存儲在向量“Y_prediction”中。

編寫預測函數:

所以我們將實現預測函數,但首先讓我們看看它的輸入和輸出是什麼:

參數:

w - 權重,numpy數組(ROWS * COLS * CHANNELS,1)

b - 偏差,標量

X - 數據的大小(ROWS * COLS * CHANNELS,示例數)

返回:

Y_prediction - numpy數組( vector)包含X中示例的所有預測(0/1)

代碼如下:

def predict(w, b, X): 
m = X.shape[1]
Y_prediction = np.zeros((1, m))
w = w.reshape(X.shape[0], 1)

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

for i in range(A.shape[1]):
# Convert probabilities A[0,i] to actual predictions p[0,i]
if A[0,i] > 0.5:
Y_prediction[[0],[i]] = 1
else:
Y_prediction[[0],[i]] = 0

return Y_prediction
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

如果我們對之前的值“predict(w, b, X)”運行我們的新函數,我們應該會收到以下結果:

predictions = [[1. 1. 0.]]
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

從我們的結果我們可以說我們預測了兩隻貓和一隻狗。但是因為輸入的不是真實的圖像,而是一個簡單的隨機測試數字,所以我們的預測也沒有任何意義。

到目前為止,我們已經知道如何準備訓練數據,如何迭代優化損失來學習w和b參數(計算成本及其梯度,使用梯度下降更新參數)。在這一部分中,我們使用learn (w,b)來預測給定例子的標籤。在下一部分中,我們將把所有函數合併到一個模型中,我們將訓練它預測貓和狗。

所有函數合併為最終的模型

在這一部分中,您將看到整個模型的結構是通過將所有構建塊按正確的順序放在一起。

在構建模型之前,我們將再編寫一個函數,我們將使用它來定義模型權重和偏差:

def initialize_with_zeros(dim):
w = np.zeros((dim,1))
b = 0
return w, b
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

所以我們將實現最終模型,但和以前一樣,首先讓我們看看它的輸入和輸出是什麼:

參數:

X_train - 由numpy數組表示的訓練集形狀(ROWS * COLS * CHANNELS,m_train)

Y_train - 由形狀(1,m_train)的numpy數組(向量)表示的訓練標籤

X_test - 由numpy數組表示的測試集形狀(ROWS * COLS * CHANNELS,m_test)

Y_test - 由形狀(1,m_test)的numpy數組(向量)表示的測試標籤

num_iterations - 表示優化參數的迭代次數的超參數

learning_rate - 表示所用學習速率的超參數在optimize()

print_cost - 設置為true,以便每100次迭代輸出成本

返回:

dict - 包含模型信息的字典。

下面是最終模型代碼:

def model(X_train, Y_train, X_test, Y_test, num_iterations = 2000, learning_rate = 0.5, print_cost = False):
# initialize parameters with zeros
w, b = initialize_with_zeros(X_train.shape[0])

# Gradient descent
parameters, grads, costs = optimize(w, b, X_train, Y_train, num_iterations, learning_rate, print_cost)

# Retrieve parameters w and b from dictionary "parameters"
w = parameters["w"]
b = parameters["b"]

# Predict test/train set examples
Y_prediction_test = predict(w,b,X_test)
Y_prediction_train = predict(w,b,X_train)
# Print train/test Errors
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))

dict = {"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 dict
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

所以最後我們定義了最終的邏輯迴歸模型,讓我們在我們的數據集上進行3000次迭代訓練,學習率為0.003:

d = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 3000, learning_rate = 0.003, print_cost = True)
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

現在我們已經訓練了我們的模型,讓我們用一個測試圖像測試它:

test_image = "cat.jpg"
my_image = read_image(test_image).reshape((1, ROWS*COLS*CHANNELS)).T
my_predicted_image = predict(d["w"], d["b"], my_image)
print(np.squeeze(my_predicted_image))

具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

下面是我們的訓練結果,我們進行了3000個訓練步驟,測試準確率為58.6%,訓練準確率為68.24%。這不是很準確,但是評估我們使用的是簡單的邏輯迴歸它並沒有那麼糟糕,甚至它預測了我們作為一隻貓的形象!

Cost after iteration 100: 0.671626
Cost after iteration 200: 0.663768
Cost after iteration 300: 0.658534
Cost after iteration 400: 0.654486
Cost after iteration 500: 0.651100
Cost after iteration 600: 0.648129
Cost after iteration 700: 0.645438

Cost after iteration 800: 0.642949
Cost after iteration 900: 0.640613
Cost after iteration 1000: 0.638401
Cost after iteration 1100: 0.636290
Cost after iteration 1200: 0.634267
Cost after iteration 1300: 0.632320
Cost after iteration 1400: 0.630441
Cost after iteration 1500: 0.628624
Cost after iteration 1600: 0.626863
Cost after iteration 1700: 0.625154
Cost after iteration 1800: 0.623493
Cost after iteration 1900: 0.621878
Cost after iteration 2000: 0.620305
Cost after iteration 2100: 0.618771
Cost after iteration 2200: 0.617275
Cost after iteration 2300: 0.615814
Cost after iteration 2400: 0.614387
Cost after iteration 2500: 0.612991
Cost after iteration 2600: 0.611626
Cost after iteration 2700: 0.610289
Cost after iteration 2800: 0.608979
Cost after iteration 2900: 0.607695
train accuracy: 68.24391869376875 %
test accuracy: 58.6 %
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

完整的代碼:

import os
import cv2
import numpy as np
import matplotlib.pyplot as plt
import scipy
ROWS = 64
COLS = 64
CHANNELS = 3
TRAIN_DIR = 'Train_data/'
TEST_DIR = 'Test_data/'
train_images = [TRAIN_DIR+i for i in os.listdir(TRAIN_DIR)]
test_images = [TEST_DIR+i for i in os.listdir(TEST_DIR)]
def read_image(file_path):
img = cv2.imread(file_path, cv2.IMREAD_COLOR)
return cv2.resize(img, (ROWS, COLS), interpolation=cv2.INTER_CUBIC)
def prepare_data(images):
m = len(images)
X = np.zeros((m, ROWS, COLS, CHANNELS), dtype=np.uint8)
y = np.zeros((1, m))
for i, image_file in enumerate(images):
X[i,:] = read_image(image_file)
if 'dog' in image_file.lower():
y[0, i] = 1
elif 'cat' in image_file.lower():
y[0, i] = 0
return X, y
def sigmoid(z):
s = 1/(1+np.exp(-z))
return s
def propagate(w, b, X, Y):
m = X.shape[1]

# FORWARD PROPAGATION (FROM X TO COST)
z = np.dot(w.T, X)+b # tag 1
A = sigmoid(z) # tag 2
cost = (-np.sum(Y*np.log(A)+(1-Y)*np.log(1-A)))/m # tag 5

# BACKWARD PROPAGATION (TO FIND GRAD)
dw = (np.dot(X,(A-Y).T))/m # tag 6
db = np.average(A-Y) # tag 7
cost = np.squeeze(cost)
grads = {"dw": dw,
"db": db}

return grads, cost
def optimize(w, b, X, Y, num_iterations, learning_rate, print_cost = False):

costs = []
for i in range(num_iterations):
# Cost and gradient calculation
grads, cost = propagate(w, b, X, Y)

# Retrieve derivatives from grads
dw = grads["dw"]
db = grads["db"]

# update w and b
w = w - learning_rate*dw
b = b - learning_rate*db
# Record the costs
if i % 100 == 0:
costs.append(cost)

# Print the cost every 100 training iterations
if print_cost and i % 100 == 0:
print ("Cost after iteration %i: %f" %(i, cost))
# update w and b to dictionary
params = {"w": w,
"b": b}

# update derivatives to dictionary
grads = {"dw": dw,
"db": db}

return params, grads, costs
def predict(w, b, X):
m = X.shape[1]
Y_prediction = np.zeros((1, m))
w = w.reshape(X.shape[0], 1)

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

for i in range(A.shape[1]):
# Convert probabilities A[0,i] to actual predictions p[0,i]
if A[0,i] > 0.5:
Y_prediction[[0],[i]] = 1
else:
Y_prediction[[0],[i]] = 0

return Y_prediction
def initialize_with_zeros(dim):
w = np.zeros((dim, 1))
b = 0
return w, b
def model(X_train, Y_train, X_test, Y_test, num_iterations = 2000, learning_rate = 0.5, print_cost = False):
# initialize parameters with zeros

w, b = initialize_with_zeros(X_train.shape[0])
# Gradient descent
parameters, grads, costs = optimize(w, b, X_train, Y_train, num_iterations, learning_rate, print_cost)

# Retrieve parameters w and b from dictionary "parameters"
w = parameters["w"]
b = parameters["b"]

# Predict test/train set examples
Y_prediction_test = predict(w,b,X_test)
Y_prediction_train = predict(w,b,X_train)
# Print train/test Errors
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))

dict = {"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 dict
train_set_x, train_set_y = prepare_data(train_images)
test_set_x, test_set_y = prepare_data(test_images)
train_set_x_flatten = train_set_x.reshape(train_set_x.shape[0], ROWS*COLS*CHANNELS).T
test_set_x_flatten = test_set_x.reshape(test_set_x.shape[0], -1).T
train_set_x = train_set_x_flatten/255
test_set_x = test_set_x_flatten/255
d = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 3000, learning_rate = 0.003, print_cost = True)
test_image = "cat.jpg"
my_image = read_image(test_image).reshape(1, ROWS*COLS*CHANNELS).T
my_predicted_image = predict(d["w"], d["b"], my_image)
print(np.squeeze(my_predicted_image))
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

我們建立了我們的第一個圖像分類模型。在最後一部分中,我們將進一步分析它,並檢查學習率α的可能選擇。

學習率的最佳選擇

為了使梯度下降起作用,我們必須明智地選擇學習率。學習速率α決定我們如何快速更新參數。如果學習率過大,我們可能會“超調”最優值。同樣,如果它太小,我們將需要太多的迭代來收斂到最佳值。這就是為什麼使用良好的學習速度是至關重要的。

我們將比較模型的學習曲線與幾種學習率的選擇。運行以下代碼。也可以嘗試不同於初始化的值。

learning_rates = [0.001, 0.003, 0.005, 0.01]
models = {}
for i in learning_rates:
print ("learning rate is: ",i)
models[i] = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 500, learning_rate = i, print_cost = False)
print ("-------------------------------------------------------")
for i in learning_rates:
plt.plot(np.squeeze(models[i]["costs"]), label= str(models[i]["learning_rate"]))
plt.ylabel('cost')
plt.xlabel('iterations (hundreds)')
legend = plt.legend(loc='upper center', shadow=True)
frame = legend.get_frame()
frame.set_facecolor('0.90')
plt.show()
具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

我們將以不同的學習率獲得此類訓練和測試準確度:

學習率為:0.001

訓練精度:63.628790403198934%

測試精度:59.0%

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -

學習率為:0.002

訓練精度:66.27790736421193%

測試精度:60.0%

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -

學習率為:0.003

訓練精度:68.24391869376875%

測試精度:58.6%

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -

學習率為:0.005

訓練精度:54.08197267577474%

測試精度:53.0%

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -

學習率為:0.01

訓練精度:54.18193935354882%

測試精度:53.3%

- - - - - - - - - - - - - - - - - - - - - - - - - - - - -

您可以在下圖中看到的學習率結果:

具有神經網絡思維的邏輯迴歸(Cats VS Dogs)

結果:

•不同的學習率會產生不同的成本和不同的預測結果。

•如果學習率太大(0.01),成本可能會上下波動。使用0.01仍然是一個良好的性價比。

•較低的成本並不意味著更好的模型。你必須檢查是否有可能過度擬合。當訓練精度遠高於測試精度時,就會發生這種情況。

•在深度學習中,通常建議選擇更好地降低成本函數的學習率。

從Logistic迴歸中要記住什麼:

1.預處理數據集很重要。

2.最好分別實現每個函數:initialize(),propagate(),optimize()。然後構建了一個最終模型()。

3.調整學習速率(“超參數”)可以對算法產生很大的影響。

最後,我們利用神經網絡思維建立了最簡單的邏輯迴歸模型。如果您想用它進行更多的測試,您可以嘗試不同的初始化方法並比較結果!


分享到:


相關文章: