机器学习的目标不是让向机器灌输知识,而是让机器能自己发现规律,甚至发现人类难以发现的规律。
train_set_x_orig :保存的是训练集里面的图像数据(本训练集有209张64x64的图像)。
train_set_y_orig :保存的是训练集的图像对应的分类值(【0 | 1】,0表示不是猫,1表示是猫)。
使用np.squeeze压缩维度,只有压缩后的值才能进行解码操作
test_set_x_orig :保存的是测试集里面的图像数据(本训练集有50张64x64的图像)。
test_set_y_orig : 保存的是测试集的图像对应的分类值(【0 | 1】,0表示不是猫,1表示是猫)。
classes : 保存的是以bytes类型保存的两个字符串数据,数据为:[b’non-cat’ b’cat’]。
每张图片的宽/高 : num_px = 64
每张图片的大小 : (64, 64, 3)
训练集_图片的维数 : (209, 64, 64, 3)
训练集_标签的维数 : (1, 209)
测试集_图片的维数: (50, 64, 64, 3)
测试集_标签的维数: (1, 50)
# 注:pycharm打开训练集图片
plt.figure("Image")
plt.imshow(train_set_x_orig[index])
plt.axis('on')
plt.title('image')
plt.show()
X_flatten = X.reshape(X.shape [0],-1).T
# 训练集降维最后的维度: (12288, 209)
# 测试集降维之后的维度: (12288, 50)
train_set_x = train_set_x_flatten / 255
test_set_x = test_set_x_flatten / 255
Sigmoid函数常被用作神经网络的阈值函数,将变量映射到0,1之间
形状:S型
函数:s = 1 / (1 + np.exp(-z))
建立神经网络的主要步骤是:
def propagate(w, b, X, Y):
"""
参数:
w - 权重,大小不等的数组(12288,1)
b - 偏差,一个标量
X - 图片矩阵,矩阵类型为(12288,209)
Y - 标签矩阵,真正的“标签”矢量(非猫为0,猫为1),矩阵维度为(1,209)
返回:
cost - 逻辑回归的负对数成本
dw - 相对于w的损失梯度,因此与w相同的形状(12288,1)
db - 相对于b的损失梯度,因此与b的形状相同
"""
# 二维数组,y.shape[0]代表行数,y.shape[1]代表列数。
m = X.shape[1]
# numpy语法:dot:矩阵乘法,log:以e为底底数计算
# 正向传播, z(i)=wT x(i)+b
A = sigmoid(np.dot(w.T, X) + b)
# 计算激活值y^(i)=a(i)=sigmoid(z(i))
cost = (- 1 / m) * np.sum(Y * np.log(A) + (1 - Y) * (np.log(1 - A)))
# 计算成本
# 损失函数L(a(i),y(i))=−y(i)log(a(i)) − (1−y(i))log(1−a(i))
# 成本J=1/m ∑(i=1~m) L(a(i),y(i))
# 反向传播
# da = dL(a,y)/da = -(y/a)+(1-y/1-a)
# dz = dL(a,y)/dz = a-y
# dw = 1/m X dzT dw(i) = x(i)dz
# db = 1/m ∑(i=1~m) dz(i)
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
按传入的learning_rate(学习率)优化w和b(权重和偏差)num_iterations(迭代次数)次。每100次打印cost。具体分为以下两个步骤并遍历:
def optimize(w, b, X, Y, num_iterations, learning_rate, print_cost=False):
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
# 每100次记录成本,并按需求打印
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)
用训练出来的w和b通过sigmoid(w.T * X + b) 预测图片是不是猫:
def predict(w, b, X):
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
return Y_prediction
整合之前的函数,完整美观(大概):
def model(X_train, Y_train, X_test, Y_test, num_iterations=2000, learning_rate=0.5, print_cost=False):
#初始化
# 此函数为w创建一个维度为(dim,1)的0向量,并将b初始化为0。
w, b = initialize_with_zeros(X_train.shape[0])
#训练
# 优化w和b
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
print("====================测试model====================")
# 这里加载的是真实的数据,请参见上面的代码部分。
d = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations=2000, learning_rate=0.005, print_cost=True)
# 绘制图
costs = np.squeeze(d['costs'])
plt.plot(costs)
plt.ylabel('cost')
plt.xlabel('iterations (per hundreds)')
plt.title("Learning rate =" + str(d["learning_rate"]))
plt.show()
learning_rates = [0.01, 0.001, 0.0001]
models = {}
for i in learning_rates:
print("learning rate is: " + str(i))
models[str(i)] = model(train_set_x, train_set_y, test_set_x, test_set_y,
num_iterations=1500, learning_rate=i, print_cost=False)
print('\n' + "-------------------------------------------------------" + '\n')
for i in learning_rates:
plt.plot(np.squeeze(models[str(i)]["costs"]), label=str(models[str(i)]["learning_rate"]))
plt.ylabel('cost')
plt.xlabel('iterations')
legend = plt.legend(loc='upper center', shadow=True)
frame = legend.get_frame()
frame.set_facecolor('0.90')
plt.show()