banner
不断学习,不断进步

吴恩达深度学习作业汇总

Scroll down

第二周(编程)

搭建一个可以识别猫的简单的神经网络

库介绍:

  • numpy :是用Python进行科学计算的基本软件包。
  • h5py:是与H5文件中存储的数据集进行交互的常用软件包。
  • matplotlib:是一个著名的库,用于在Python中绘制图表。

lr_utils 实现(加载数据集)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def load_dataset():
train_dataset = h5py.File('datasets/train_catvnoncat.h5', "r")
train_set_x_orig = np.array(train_dataset["train_set_x"][:]) # your train set features
train_set_y_orig = np.array(train_dataset["train_set_y"][:]) # your rain set labels

test_dataset = h5py.File('datasets/test_catvnoncat.h5', "r")
test_set_x_orig = np.array(test_dataset["test_set_x"][:]) # your test set features
test_set_y_orig = np.array(test_dataset["test_set_y"][:]) # your test set labels

classes = np.array(test_dataset["list_classes"][:]) # the list of classes

train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0]))
test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0]))

return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes

其各值的含义:

  • train_set_x_orig :保存的是训练集里面的图像数据(本训练集有209张64x64的图像)。
  • train_set_y_orig :保存的是训练集的图像对应的分类值(【0 | 1】,0表示不是猫,1表示是猫)。
  • test_set_x_orig :保存的是测试集里面的图像数据(本训练集有50张64x64的图像)。
  • test_set_y_orig : 保存的是测试集的图像对应的分类值(【0 | 1】,0表示不是猫,1表示是猫)。
  • classes : 保存的是以bytes类型保存的两个字符串数据,数据为:[b’non-cat’ b’cat’]。

image-20241018201142283

现在加载一张图片展示一下

image-20241018201643108

1
2
3
4
train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes = load_dataset()
index = 25
plt.imshow(train_set_x_orig[index])
plt.show()

也可以同时查看多张图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes = load_dataset()
index = 25
plt.subplot(2,3,1)
plt.imshow(train_set_x_orig[25])
plt.subplot(2,3,2)
plt.imshow(train_set_x_orig[1])
plt.subplot(2,3,3)
plt.imshow(train_set_x_orig[2])
plt.subplot(2,3,4)
plt.imshow(train_set_x_orig[3])
plt.subplot(2,3,5)
plt.imshow(train_set_x_orig[4])
plt.subplot(2,3,6)
plt.imshow(train_set_x_orig[5])
plt.show()

image-20241018202137930

打印图片和对应的标签,现在打印第一张图,看看第一张图是否为猫

1
2
3
4
5
6
7
8
9
train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes = load_dataset()
index = 1
plt.imshow(train_set_x_orig[index])
plt.show()

#打印出当前的训练标签值
#使用np.squeeze的目的是压缩维度,【未压缩】train_set_y[:,index]的值为[1] , 【压缩后】np.squeeze(train_set_y[:,index])的值为1
#只有压缩后的值才能进行解码操作
print("y=" + str(train_set_y_orig[:,index]) + ", it's a " + classes[np.squeeze(train_set_y_orig[:,index])].decode("utf-8") + " picture")

image-20241018202502911

我们查看一下我们加载的图像数据集具体情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
m_train = train_set_y_orig.shape[1] #训练集里图片的数量。
m_test = test_set_y_orig.shape[1] #测试集里图片的数量。
num_px = train_set_x_orig.shape[1] #训练、测试集里面的图片的宽度和高度(均为64x64)。

#现在看一看我们加载的东西的具体情况
print ("训练集的数量: m_train = " + str(m_train))
print ("测试集的数量 : m_test = " + str(m_test))
print ("每张图片的宽/高 : num_px = " + str(num_px))
print ("每张图片的大小 : (" + str(num_px) + ", " + str(num_px) + ", 3)")
print ("训练集_图片的维数 : " + str(train_set_x_orig.shape))
print ("训练集_标签的维数 : " + str(train_set_y_orig.shape))
print ("测试集_图片的维数: " + str(test_set_x_orig.shape))
print ("测试集_标签的维数: " + str(test_set_y_orig.shape))

image-20241018202916384

为了方便,我们要把维度为(64,64,3)的numpy数组重新构造为(64 x 64 x 3,1)的数组,要乘以3的原因是每张图片是由64x64像素构成的,而每个像素点由(R,G,B)三原色构成的,所以要乘以3。在此之后,我们的训练和测试数据集是一个numpy数组,【每列代表一个平坦的图像】 ,应该有 12288(特征数量)行和 209(样本数量)列。

当你想将形状(a,b,c,d)的矩阵X平铺成形状(b * c * d,a)的矩阵X_flatten时,可以使用以下代码:

1
2
3
4
5
6
7
8
9
10
#X_flatten = X.reshape(X.shape [0],-1).T #X.T是X的转置
#将训练集的维度降低并转置。
train_set_x_flatten = train_set_x_orig.reshape(train_set_x_orig.shape[0],-1).T
#将测试集的维度降低并转置。
test_set_x_flatten = test_set_x_orig.reshape(test_set_x_orig.shape[0], -1).T

print ("训练集降维最后的维度: " + str(train_set_x_flatten.shape))
print ("训练集_标签的维数 : " + str(train_set_y_orig.shape))
print ("测试集降维之后的维度: " + str(test_set_x_flatten.shape))
print ("测试集_标签的维数 : " + str(test_set_y_orig.shape))

这一段意思是指把数组变为209行的矩阵(因为训练集里有209张图片),但是我懒得算列有多少,于是我就用-1告诉程序你帮我算,最后程序算出来时12288列,我再最后用一个T表示转置,这就变成了12288行,209列。测试集亦如此。

image-20241018203234237

为了表示彩色图像,必须为每个像素指定红色,绿色和蓝色通道(RGB),因此像素值实际上是从0到255范围内的三个数字的向量。机器学习中一个常见的预处理步骤是对数据集进行居中和标准化,这意味着可以减去每个示例中整个numpy数组的平均值,然后将每个示例除以整个numpy数组的标准偏差。但对于图片数据集,它更简单,更方便,几乎可以将数据集的每一行除以255(像素通道的最大值),因为在RGB中不存在比255大的数据,所以我们可以放心的除以255,让标准化的数据位于 [0,1] 之间,现在标准化我们的数据集:

1
2
train_set_x = train_set_x_flatten / 255
test_set_x = test_set_x_flatten / 255

image-20241018203457066

整理完数据进行神经网络构建:

image-20241018203551107

构建神经网络的步骤:

  1. 定义模型结构(例如输入特征的数量)
  2. 初始化模型的参数
  3. 循环:
    3.1 计算当前损失(正向传播)
    3.2 计算当前梯度(反向传播)
    3.3 更新参数(梯度下降)

构建sigmoid函数:

1
2
3
# 构建sigmoid
def sigmoid(x):
return 1/(1+np.exp(-x))

初始化参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
def initialize_with_zeros(dim):
"""
此函数为w创建一个维度为(dim,1)的0向量,并将b初始化为0。

参数:
dim - 我们想要的w矢量的大小(或者这种情况下的参数数量)

返回:
w - 维度为(dim,1)的初始化向量。
b - 初始化的标量(对应于偏差)
"""
w = np.zeros(shape = (dim,1))
b = 0
#使用断言来确保我要的数据是正确的
assert(w.shape == (dim, 1)) #w的维度是(dim,1)
assert(isinstance(b, float) or isinstance(b, int)) #b的类型是float或者是int

return (w , b)

执行前向后向传播学习参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
def propagate(w, b, X, Y):
"""
实现前向和后向传播的成本函数及其梯度。
参数:
w - 权重,大小不等的数组(num_px * num_px * 3,1)
b - 偏差,一个标量
X - 矩阵类型为(num_px * num_px * 3,训练数量)
Y - 真正的“标签”矢量(如果非猫则为0,如果是猫则为1),矩阵维度为(1,训练数据数量)

返回:
cost- 逻辑回归的负对数似然成本
dw - 相对于w的损失梯度,因此与w相同的形状
db - 相对于b的损失梯度,因此与b的形状相同
"""
m = X.shape[1]

#正向传播
A = sigmoid(np.dot(w.T,X) + b) #计算激活值,请参考公式2。
cost = (- 1 / m) * np.sum(Y * np.log(A) + (1 - Y) * (np.log(1 - A))) #计算成本,请参考公式3和4。

#反向传播
dw = (1 / m) * np.dot(X, (A - Y).T) #请参考视频中的偏导公式。
db = (1 / m) * np.sum(A - Y) #请参考视频中的偏导公式。

#使用断言确保我的数据是正确的
assert(dw.shape == w.shape)
assert(db.dtype == float)
cost = np.squeeze(cost)
assert(cost.shape == ())

#创建一个字典,把dw和db保存起来。
grads = {
"dw": dw,
"db": db
}
return (grads , cost)

梯度下降更新参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
def optimize(w , b , X , Y , num_iterations , learning_rate , print_cost = True):
"""
此函数通过运行梯度下降算法来优化w和b

参数:
w - 权重,大小不等的数组(num_px * num_px * 3,1)
b - 偏差,一个标量
X - 维度为(num_px * num_px * 3,训练数据的数量)的数组。
Y - 真正的“标签”矢量(如果非猫则为0,如果是猫则为1),矩阵维度为(1,训练数据的数量)
num_iterations - 优化循环的迭代次数
learning_rate - 梯度下降更新规则的学习率
print_cost - 每100步打印一次损失值

返回:
params - 包含权重w和偏差b的字典
grads - 包含权重和偏差相对于成本函数的梯度的字典
成本 - 优化期间计算的所有成本列表,将用于绘制学习曲线。

提示:
我们需要写下两个步骤并遍历它们:
1)计算当前参数的成本和梯度,使用propagate()。
2)使用w和b的梯度下降法则更新参数。
"""

costs = []

for i in range(num_iterations):

grads, cost = propagate(w, b, X, Y)

dw = grads["dw"]
db = grads["db"]

w = w - learning_rate * dw
b = b - learning_rate * db

#记录成本
if i % 100 == 0:
costs.append(cost)
#打印成本数据
if (print_cost) and (i % 100 == 0):
print("迭代的次数: %i , 误差值: %f" % (i,cost))

params = {
"w" : w,
"b" : b }
grads = {
"dw": dw,
"db": db }
return (params , grads , costs)

构建预测函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def predict(w , b , X ):
"""
使用学习逻辑回归参数logistic (w,b)预测标签是0还是1,

参数:
w - 权重,大小不等的数组(num_px * num_px * 3,1)
b - 偏差,一个标量
X - 维度为(num_px * num_px * 3,训练数据的数量)的数据

返回:
Y_prediction - 包含X中所有图片的所有预测【0 | 1】的一个numpy数组(向量)

"""

m = X.shape[1] #图片的数量
Y_prediction = np.zeros((1,m))
w = w.reshape(X.shape[0],1)

#计预测猫在图片中出现的概率
A = sigmoid(np.dot(w.T , X) + b)
for i in range(A.shape[1]):
#将概率a [0,i]转换为实际预测p [0,i]
Y_prediction[0,i] = 1 if A[0,i] > 0.5 else 0
#使用断言
assert(Y_prediction.shape == (1,m))

return Y_prediction

就目前而言,我们基本上把所有的东西都做完了,现在我们要把这些函数统统整合到一个model()函数中,届时只需要调用一个model()就基本上完成所有的事了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
def model(X_train , Y_train , X_test , Y_test , num_iterations = 2000 , learning_rate = 0.5 , print_cost = True):
"""
通过调用之前实现的函数来构建逻辑回归模型

参数:
X_train - numpy的数组,维度为(num_px * num_px * 3,m_train)的训练集
Y_train - numpy的数组,维度为(1,m_train)(矢量)的训练标签集
X_test - numpy的数组,维度为(num_px * num_px * 3,m_test)的测试集
Y_test - numpy的数组,维度为(1,m_test)的(向量)的测试标签集
num_iterations - 表示用于优化参数的迭代次数的超参数
learning_rate - 表示optimize()更新规则中使用的学习速率的超参数
print_cost - 设置为true以每100次迭代打印成本

返回:
d - 包含有关模型信息的字典。
"""
w , b = initialize_with_zeros(X_train.shape[0])

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

#从字典“参数”中检索参数w和b
w , b = parameters["w"] , parameters["b"]

#预测测试/训练集的例子
Y_prediction_test = predict(w , b, X_test)
Y_prediction_train = predict(w , b, X_train)

#打印训练后的准确性
print("训练集准确性:" , format(100 - np.mean(np.abs(Y_prediction_train - Y_train)) * 100) ,"%")
print("测试集准确性:" , format(100 - np.mean(np.abs(Y_prediction_test - Y_test)) * 100) ,"%")

d = {
"costs" : costs,
"Y_prediction_test" : Y_prediction_test,
"Y_prediciton_train" : Y_prediction_train,
"w" : w,
"b" : b,
"learning_rate" : learning_rate,
"num_iterations" : num_iterations }
return d

测试model

1
2
print("====================测试model====================")     
d = model(train_set_x, train_set_y_orig, test_set_x, test_set_y_orig, num_iterations = 2000, learning_rate = 0.005, print_cost = True)

image-20241018205356031

第三周(编程)

构建一个神经网络

准备一些软件包:

  • numpy:是用Python进行科学计算的基本软件包。

  • sklearn:为数据挖掘和数据分析提供的简单高效的工具。

  • matplotlib :是一个用于在Python中绘制图表的库。

  • testCases:提供了一些测试示例来评估函数的正确性,参见下载的资料或者在底部查看它的代码。

  • planar_utils :提供了在这个任务中使用的各种有用的功能,参见下载的资料或者在底部查看它的代码

1
2
3
4
5
6
7
8
9
10
11
import numpy as np
import matplotlib.pyplot as plt
from testCases import *
import sklearn
import sklearn.datasets
import sklearn.linear_model
from planar_utils import plot_decision_boundary, sigmoid, load_planar_dataset, load_extra_datasets

#%matplotlib inline #如果你使用用的是Jupyter Notebook的话请取消注释。

np.random.seed(1) #设置一个固定的随机种子,以保证接下来的步骤中我们的结果是一致的。

加载和查看数据集

1
2
3
4
X, Y = load_planar_dataset()

plt.scatter(X[0, :], X[1, :], c=Y, s=40, cmap=plt.cm.Spectral) #绘制散点图
plt.show()

image-20241023193510811

数据看起来像一朵红色(y = 0)和一些蓝色(y = 1)的数据点的花朵的图案。 我们的目标是建立一个模型来适应这些数据。现在,我们已经有了以下的东西:

  • X:一个numpy的矩阵,包含了这些数据点的数值
  • Y:一个numpy的向量,对应着的是X的标签【0 | 1】(红色:0 , 蓝色 :1)

我们继续来仔细地看数据:

1
2
3
4
5
6
7
shape_X = X.shape
shape_Y = Y.shape
m = Y.shape[1] # 训练集里面的数量

print ("X的维度为: " + str(shape_X))
print ("Y的维度为: " + str(shape_Y))
print ("数据集里面的数据有:" + str(m) + " 个")

image-20241023193640850

这里我们假如使用逻辑回归,那么效果如下:

1
2
3
4
5
6
7
8
9
10
11
clf = sklearn.linear_model.LogisticRegressionCV()
clf.fit(X.T,Y.T)
plot_decision_boundary(lambda x: clf.predict(x), X, Y) #绘制决策边界
plt.title("Logistic Regression") #图标题
LR_predictions = clf.predict(X.T) #预测结果
print ("逻辑回归的准确性: %d " % float((np.dot(Y, LR_predictions) +
np.dot(1 - Y,1 - LR_predictions)) / float(Y.size) * 100) +
"% " + "(正确标记的数据点所占的百分比)")
plt.show()

# 逻辑回归的准确性: 47 % (正确标记的数据点所占的百分比)

image-20241023194122286

构建神经网络

如下:

image-20241023194853657

image-20241023194907488

构建神经网络的一般方法是:

  1. 定义神经网络结构(输入单元的数量,隐藏单元的数量等)。

  2. 初始化模型的参数

  3. 循环:

    • 实施前向传播

    • 计算损失

    • 实现向后传播

    • 更新参数(梯度下降)

定义神经网络结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def layer_sizes(X , Y):
"""
参数:
X - 输入数据集,维度为(输入的数量,训练/测试的数量)
Y - 标签,维度为(输出的数量,训练/测试数量)

返回:
n_x - 输入层的数量
n_h - 隐藏层的数量
n_y - 输出层的数量
"""
n_x = X.shape[0] #输入层
n_h = 4 #,隐藏层,硬编码为4
n_y = Y.shape[0] #输出层

return (n_x,n_h,n_y)

初始化参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 初始化模型参数
def initialize_parameters(n_x,n_h,n_y):
"""
参数:
n_x - 输入层节点的数量
n_h - 隐藏层节点的数量
n_y - 输出层节点的数量

返回:
parameters - 包含参数的字典:
W1 - 权重矩阵,维度为(n_h,n_x)
b1 - 偏向量,维度为(n_h,1)
W2 - 权重矩阵,维度为(n_y,n_h)
b2 - 偏向量,维度为(n_y,1)

"""
np.random.seed(2) #指定一个随机种子,以便你的输出与我们的一样。
W1 = np.random.randn(n_h,n_x)*0.01
b1 = np.zeros(shape=(n_h,1))
W2 = np.random.randn(n_y,n_h)*0.01
b2 = np.zeros(shape=(n_y,1))

assert (W1.shape == (n_h,n_x))
assert (b1.shape == (n_h,1))
assert (W2.shape == (n_y,n_h))
assert (b2.shape == (n_y,1))

parameters = {
'W1': W1,
'b1': b1,
'W2': W2,
'b2': b2,
}

return parameters

为什么乘0.01:

  1. 避免梯度消失/爆炸问题:
    • 如果初始化的权重过大,在反向传播过程中,权重更新的梯度可能会非常大,导致参数更新过快,使得训练过程不稳定,甚至发生梯度爆炸。
    • 相反,如果初始化的权重过小,在反向传播过程中,权重更新的梯度可能会非常小,导致参数更新过慢,使得训练过程进展缓慢,发生梯度消失。
  2. 有利于模型训练收敛:
    • 通过将权重初始化为较小的值(乘以 0.01),可以帮助模型在训练初期就能找到一个较好的起始点,从而更快地收敛到最优解。
  3. 防止饱和:
    • 如果权重初始化过大,可能会使得神经网络的激活函数(如 sigmoid 或 tanh)处于饱和区域,导致梯度更新缓慢。

前向传播

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 前向传播
def forward_propagation(X, parameters):
"""
参数:
X - 维度为(n_x,m)的输入数据。
parameters - 初始化函数(initialize_parameters)的输出

返回:
A2 - 使用sigmoid()函数计算的第二次激活后的数值
cache - 包含“Z1”,“A1”,“Z2”和“A2”的字典类型变量
"""
W1 = parameters['W1']
b1 = parameters['b1']
W2 = parameters['W2']
b2 = parameters['b2']

# 前向传播计算
Z1 = np.dot(W1, X) + b1
A1 = np.tanh(Z1)
Z2 = np.dot(W2,A1)+ b2
A2 = sigmoid(Z2)

assert (A2.shape == (1,X.shape[1]))
cache = {
'Z1': Z1,
'A1': A1,
'Z2': Z2,
'A2': A2,
}
return (A2, cache)

计算损失

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
def compute_cost(A2, Y, parameters):
"""
计算方程(6)中给出的交叉熵成本,

参数:
A2 - 使用sigmoid()函数计算的第二次激活后的数值
Y - "True"标签向量,维度为(1,数量)
parameters - 一个包含W1,B1,W2和B2的字典类型的变量

返回:
成本 - 交叉熵成本给出方程(13)
"""
m = Y.shape[1]
W1 = parameters['W1']
W2 = parameters['W2']

# 计算成本
logprobs = np.multiply(np.log(A2), Y)+ np.multiply((1-Y),np.log(1 - A2))
cost= -np.sum(logprobs)/m
cost = float(np.squeeze(cost))

assert (isinstance(cost, float))

return cost

向后传播

image-20241023201826661

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 向后传播
def backward_propagation(parameters,cache,X,Y):
"""
使用上述说明搭建反向传播函数。

参数:
parameters - 包含我们的参数的一个字典类型的变量。
cache - 包含“Z1”,“A1”,“Z2”和“A2”的字典类型的变量。
X - 输入数据,维度为(2,数量)
Y - “True”标签,维度为(1,数量)

返回:
grads - 包含W和b的导数一个字典类型的变量。
"""
m = X.shape[1]
W1 = parameters['W1']
W2 = parameters['W2']

A1 = cache['A1']
A2 = cache['A2']

dZ2 = A2 - Y
dW2 =(1/m) *np.dot(dZ2,A1.T)
db2 =(1/m) *np.sum(dZ2,axis=1,keepdims=True)
dZ1 =np.multiply(np.dot(W2.T,dZ2),1-np.power(A1,2))
dW1 =(1/m) * np.dot(dZ1,X.T)
db1 =(1/m) *np.sum(dZ1,axis=1,keepdims=True)

grads ={
"dW1": dW1,
"db1": db1,
"dW2": dW2,
"db2": db2,
}
return grads

tanh求导为1-tanh平方

更新参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def update_parameters(parameters,grads,learning_rate=1.2):
"""
使用上面给出的梯度下降更新规则更新参数

参数:
parameters - 包含参数的字典类型的变量。
grads - 包含导数值的字典类型的变量。
learning_rate - 学习速率

返回:
parameters - 包含更新参数的字典类型的变量。
"""
W1,W2 = parameters["W1"],parameters["W2"]
b1,b2 = parameters["b1"],parameters["b2"]

dW1,dW2 = grads["dW1"],grads["dW2"]
db1,db2 = grads["db1"],grads["db2"]

W1 = W1 - learning_rate * dW1
b1 = b1 - learning_rate * db1
W2 = W2 - learning_rate * dW2
b2 = b2 - learning_rate * db2

parameters = {"W1": W1,
"b1": b1,
"W2": W2,
"b2": b2}

return parameters

整合模型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
def nn_model(X,Y,n_h,num_iterations,print_cost=False):
"""
参数:
X - 数据集,维度为(2,示例数)
Y - 标签,维度为(1,示例数)
n_h - 隐藏层的数量
num_iterations - 梯度下降循环中的迭代次数
print_cost - 如果为True,则每1000次迭代打印一次成本数值

返回:
parameters - 模型学习的参数,它们可以用来进行预测。
"""
np.random.seed(3)
n_x = layer_sizes(X,Y)[0]
n_y = layer_sizes(X,Y)[2]

parameters = initialize_parameters(n_x,n_h,n_y)
W1,W2 = parameters["W1"],parameters["W2"]
b1,b2 = parameters["b1"],parameters["b2"]

for i in range(num_iterations):
A2, cache = forward_propagation(X,parameters)
cost = compute_cost(A2,Y,parameters)
grads = backward_propagation(parameters,cache,X,Y)
parameters = update_parameters(parameters,grads,learning_rate=0.5)

if print_cost:
if i%1000 == 0:
print("第 ",i," 次循环,成本为:"+str(cost))

return parameters

预测

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def predict(parameters,X):
"""
使用学习的参数,为X中的每个示例预测一个类

参数:
parameters - 包含参数的字典类型的变量。
X - 输入数据(n_x,m)

返回
predictions - 我们模型预测的向量(红色:0 /蓝色:1)

"""
A2 , cache = forward_propagation(X,parameters)
predictions = np.round(A2)

return predictions

搭建完成,进行测试

1
2
3
4
5
6
7
8
9
parameters = nn_model(X, Y, n_h = 4, num_iterations=10000, print_cost=True)

#绘制边界
plot_decision_boundary(lambda x: predict(parameters, x.T), X, Y)
plt.title("Decision Boundary for hidden layer size " + str(4))

predictions = predict(parameters, X)
print ('准确率: %d' % float((np.dot(Y, predictions.T) + np.dot(1 - Y, 1 - predictions.T)) / float(Y.size) * 100) + '%')
plt.show()

image-20241023205821602

其他文章
cover
微信小程序
  • 24/10/20
  • 21:59
  • 1.4k
  • 5
cover
iotdb
  • 24/10/09
  • 19:00
  • 5.9k
  • 26