python代码如下,如下代码使用单神经网络判断图像中是否有猫:
# Jupyter Notebook环境
# 加载一写工具库并取别名
import numpy as np # 科学计算工具库
import matplotlib.pyplot as plt # 绘图
import h5py # 加载HDF数据集
import skimage.transform as tf # 这里我们用它来缩放图片
%matplotlib.inline # 用matplotlib绘制的图显示在页面里而不是弹出一个窗口
def load_dataset():
train_dataset = h5py.File('E:/python/1/datasets/train_catvnoncat.h5', "r") # 加载训练数据
train_set_x_orig = np.array(train_dataset["train_set_x"][:]) # 从训练数据中提取出图片的特征数据
train_set_y_orig = np.array(train_dataset["train_set_y"][:]) # 从训练数据中提取出图片的标签数据
test_dataset = h5py.File('E:/python/1/datasets/test_catvnoncat.h5', "r") # 加载测试数据
test_set_x_orig = np.array(test_dataset["test_set_x"][:])
test_set_y_orig = np.array(test_dataset["test_set_y"][:])
classes = np.array(test_dataset["list_classes"][:]) # 加载标签类别数据,这里的类别只有两种,1代表有猫,0代表无猫
train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0])) # 把数组的维度从(209,)变成(1, 209),这样好方便后面进行计算
test_set_y_orig = test_set_y_orig.reshape((1, test_set_y_orig.shape[0])) # 从(50,)变成(1, 50)
return train_set_x_orig, train_set_y_orig, test_set_x_orig, test_set_y_orig, classes
train_set_x_orig, train_set_y, test_set_x_orig, test_set_y, classes = load_dataset()
index = 20
plt.imshow(train_set_x_orig[index])
print ("标签为" + str(train_set_y[:, index]) + ", 这是一个'" + classes[np.squeeze(train_set_y[:, index])].decode("utf-8") + "' 图片.")
# 输出变量的维度,厘清变量维度信息
print ("train_set_x_orig shape:" + str(train_set_x_orig.shape))
print ("train_set_y shape:" + str(train_set_y.shape))
print ("test_set_x_orig shape:" + str(test_set_x_orig.shape))
print ("test_set_y shape:" + str(test_set_y.shape))
m_train = train_set_x_orig.shape[0]
m_test = test_set_x_orig.shape[0]
num_px = train_set_x_orig.shape[1]
print ("训练样本数: m_train = " + str(m_train))
print ("测试样本数: m_test = " + str(m_test))
print ("每张图片的宽/高: num_px = " + str(num_px))
# 为了便于运算, 将数据向量化
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 ("train_set_x_flatten shape: " + str(train_set_x_flatten.shape))
print ("test_set_x_flatten shape: " + str(test_set_x_flatten.shape))
# 数据简要预处理,使其范围在[0,1]
train_set_x = train_set_x_flatten/255
test_set_x = test_set_x_flatten/255
# sigmoid 函数
def sigmoid(z):
"""
输入参数:z - 数或数组
输出参数:s - sigmoid函数计算之后的结果,在[0,1]之间
"""
s = 1 / (1 + np.exp(-z))
return s
# 初始化参数w和b
def initialize_with_zeros(dim):
"""
dim - w的维度,一个数字
返回值:w - 权重, b - 偏置
"""
w = np.zeros((dim, 1))
b = 0;
return w, b
# 计算梯度和成本函数
def propagate(w, b, X, Y):
"""
参数:
w -- 权重数组,维度是(12288, 1) b -- 偏置bias
X -- 图片的特征数据,维度是 (12288, 209)
Y -- 图片对应的标签,0或1,0是无猫,1是有猫,维度是(1,209)
返回值: cost -- 成本 dw -- w的梯度 db -- b的梯度
"""
number = X.shape[1]
# 前向传播
A = sigmoid(np.dot(w.T, X) + b)
cost = -np.sum(Y*np.log(A) + (1-Y)*np.log(1-A)) / number
# 反向传播
dZ = A - Y
dw = np.dot(X, dZ.T) / number
db = np.sum(dZ) / number
# 将dw和db保存到字典里面
grads = {"dw": dw,
"db": db}
return grads, cost
# 梯度下降算法
def optimize(w, b, X, Y, num_iterations, learning_rate, print_cost = False):
"""
参数:
w -- 权重数组,维度是 (12288, 1)
b -- 偏置bias
X -- 图片的特征数据,维度是 (12288, 209)
Y -- 图片对应的标签,0或1,0是无猫,1是有猫,维度是(1,209)
num_iterations -- 指定要优化多少次
learning_rate -- 学习步进,是我们用来控制优化步进的参数
print_cost -- 为True时,每优化100次就把成本cost打印出来,以便我们观察成本的变化
返回值:
params -- 优化后的w和b
costs -- 每优化100次,将成本记录下来,成本越小,表示参数越优化
"""
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
# 记录cost
if i % 100 == 0:
costs.append(cost)
if print_cost:
print ("优化%i次后成本是: %f" %(i, cost))
params = {"w": w,
"b": b}
return params, costs
# 预测
def predict(w, b, X):
'''
参数:
w -- 权重数组,维度是 (12288, 1)
b -- 偏置bias
X -- 图片的特征数据,维度是 (12288, 图片张数)
返回值:
Y_prediction -- 对每张图片的预测结果
'''
m = X.shape[1]
Y_prediction = np.zeros((1,m))
# 前向传播
A = sigmoid(np.dot(w.T, X) + b)
# 将得到的小数转化为0-无, 1-有
for i in range(A.shape[1]):
if A[0,i] >= 0.5:
Y_prediction[0,i] = 1
return Y_prediction
# 整个训练模型
def model(X_train, Y_train, X_test, Y_test, num_iterations = 2000, learning_rate = 0.5, print_cost = False):
"""
参数:
X_train -- 训练图片,维度是(12288, 209)
Y_train -- 训练图片对应的标签,维度是 (1, 209)
X_test -- 测试图片,维度是(12288, 50)
Y_test -- 测试图片对应的标签,维度是 (1, 50)
num_iterations -- 需要训练/优化多少次
learning_rate -- 学习步进,是我们用来控制优化步进的参数
print_cost -- 为True时,每优化100次就把成本cost打印出来,以便我们观察成本的变化
返回值:
d -- 返回一些信息
"""
# 初始化待训练的参数
w, b = initialize_with_zeros(X_train.shape[0])
# 使用训练数据来训练/优化参数
parameters, costs = optimize(w, b, X_train, Y_train, num_iterations, learning_rate, print_cost)
# 从字典中分别取出训练好的w和b
w = parameters["w"]
b = parameters["b"]
# 使用训练好的w和b来分别对训练图片和测试图片进行预测
Y_prediction_train = predict(w, b, X_train)
Y_prediction_test = predict(w, b, X_test)
# 打印出预测的准确率
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_prediction_train" : Y_prediction_train,
"w" : w,
"b" : b,
"learning_rate" : learning_rate,
"num_iterations": num_iterations}
return d
# 调用上面的模型函数对我们最开始加载的数据进行训练
d = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 2000, learning_rate = 0.005, print_cost = True)
# 查看预测的正确与否
index =40
plt.imshow(test_set_x[:,index].reshape((num_px, num_px, 3)))
print ("这张图的标签是 " + str(test_set_y[0,index]) + ", 预测结果是 " + str(int(d["Y_prediction_test"][0,index])))
# 下面我们打印出成本随着训练次数增加时的变化情况。可以很直观的看出,训练次数越多,成本越小,也就是预测结果更精确
costs = np.squeeze(d['costs'])
plt.plot(costs)
plt.ylabel('cost') # 成本
plt.xlabel('iterations (per hundreds)') # 横坐标为训练次数,以100为单位
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 ("学习率为: " + 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 (hundreds)')
legend = plt.legend(loc='upper center', shadow=True)
frame = legend.get_frame()
frame.set_facecolor('0.90')
plt.show()
在不同学习率下训练集和测试集预测的准确率如下表所示: