具有神经网络思维的逻辑回归(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.调整学习速率(“超参数”)可以对算法产生很大的影响。

最后,我们利用神经网络思维建立了最简单的逻辑回归模型。如果您想用它进行更多的测试,您可以尝试不同的初始化方法并比较结果!


分享到:


相關文章: