logistic分类图片中是否包含猫
numpy :是用Python进行科学计算的基本软件包。
h5py:是与H5文件中存储的数据集进行交互的常用软件包。
matplotlib:是一个著名的库,用于在Python中绘制图表。
lr_utils :在本文的资料包里,一个加载资料包里面的数据的简单功能的库。
import numpy as np
import matplotlib.pyplot as plt
#是与H5文件中存储的数据集进行交互的常用软件包
import h5py
from lr_utils import load_dataset
观察数据集
train_set_x_orig , train_set_y , test_set_x_orig , test_set_y , classes = load_dataset()
train_set_x_orig.shape,train_set_y.shape
(209, 64, 64, 3) ,(1,209)
classes
array([b’non-cat’, b’cat’], dtype=’|S7’)
index = 25
plt.imshow(train_set_x_orig[index])
print("y="+str(train_set_y[0, index])+“it is a ”+classes[np.squeeze(train_set_y[0, index])].decode("utf-8")+"picture")
y = [1], it’s a ‘cat’ picture.
把维度为(64,64,3)的numpy数组(图片像素)重新构造为(64 x 64 x 3,1)的数组
train_set_x=train_set_x_orig.reshape(train_set_x_orig.shape[0],-1).T #(64*64*3,209)
test_set_x=test_set_x_orig.reshape(test_set_x_orig.shape[0],-1).T #(64*64*3,50)
为了表示彩色图像,必须为每个像素指定红色,绿色和蓝色通道(RGB),因此像素值实际上是从0到255范围内的三个数字的向量。机器学习中一个常见的预处理步骤是对数据集进行居中和标准化,这意味着可以减去每个示例中整个numpy数组的平均值,然后将每个示例除以整个numpy数组的标准偏差。
但对于图片数据集,它更简单,更方便,几乎可以将数据集的每一行除以255(像素通道的最大值),因为在RGB中不存在比255大的数据,所以我们可以放心的除以255,让标准化的数据位于[0,1]之间,现在标准化我们的数据集:
train_set_x=train_set_x/255
test_set_x=test_set_x/255
建立神经网络的主要步骤是:
定义模型结构(例如输入特征的数量)
初始化模型的参数
循环:
- 计算当前损失(正向传播)
- 计算当前梯度(反向传播)
- 更新参数(梯度下降)
def sigmoid(z):
return 1/(1+np.exp(-z))
初始化参数
def initialize(dim):
w=np.zeros((1,dim))
b=0
return w,b
计算正向传播和反向传播
def propagation(w,b,x,y):
#不能在这里面加initialize函数,因为这样每次循环w和b都不变,起不到更新的效果
z=w@x+b
a=sigmoid(z)
cost=-1/m*(np.sum(y*np.log(a)+(1-y)*np.log(1-a)))
dz=a-y
dw=1/m*(x@dz.T)
db=1/m*(np.sum(dz))
grads={
'dw':dw
'db':db
}
return cost,grads
利用梯度下降更新参数
def optimize(w,b,x,y,iters,lr,print_cost=False):
costs=[]
for i in range(iters):
cost,grads=propagation(w,b,x,y)
dw=grads['dw']
db=grads['db']
#更新w,b的值
w=w-lr*dw
b=b-lr*db
if i%1000==0:
costs.append(cost)
if print_cost and i%1000==0:
print("第%d次更新后,cost是%f" %(i,cost))
params={
'w':w,
'b':b
}
grads = {
"dw": dw,
"db": db
}
return costs,params,grads
预测y的值
def predict(params,x):
m=x.shape[1]
w=params['w']
b=params['b']
a=sigmoid(w@x+b)
y_pre=np.zeros((1,m))
for i in range(m):
if a[0,i]<0.5:
y_pre[0,i]=0
else:
y_pre[0,i]=1
return y_pre
def model(X_train , Y_train , X_test , Y_test,iters=2000,lr=0.5,print_cost = False):
#初始化参数
w,b=initialize(X_train.shape[0])
costs,params,grads=optimize(w,b,X_train,Y_train,iters,lr,print_cost=False)
y_pre_train=predict(params,X_train)
y_pre_test=predict(params,X_test)
print('train accuracy:{} %'.format(np.mean(y_pre_train==Y_train)*100))
print('test accuracy:{} %'.format(np.mean(y_pre_test==Y_test)*100))
d = {
"costs":costs,
"y_pre_test":y_pre_test,
"y_pre_train": y_pre_train,
"w" : w,
"b" : b,
"lr" : lr,
"iters": iters
}
return d
d=model(train_set_x, train_set_y, test_set_x, test_set_y, iters = 2000, lr = 0.005, print_cost = True)
训练集比测试集准确率高很多,可能是过拟合了。
我们画出cost的学习曲线来观察
costs=d['costs']
plt.plot(costs)
plt.ylabel('cost')
plt.xlabel('iterations (per hundreds)')
plt.title("Learning rate =0.005")
plt.show()
调节学习速率的值,观察准确率的变化情况
lr=[0.01,0.001,0.0001]
for i in lr:
d=model(train_set_x, train_set_y, test_set_x, test_set_y, iters = 2000, lr = i, print_cost = False)
print("---------------------------------")
调节学习速率的值,观察cost的变化情况
for i in lr:
d = model(train_set_x, train_set_y, test_set_x, test_set_y, iters = 1500, lr = i, print_cost = False)
costs=d['costs']
plt.plot(costs,label=str(d['lr']))
plt.ylabel('cost')
plt.xlabel('iterations')
legend = plt.legend(loc='upper right', shadow=False)
plt.show()
使用自己的图片来测试模型的准确率
import skimage.io as io
from PIL import Image
image='images/my_image.jpg'
img=io.imread(image)
img.shape
(1276, 1920, 3)
#改变图像大小为64*64并且隐藏归一化到0-255区间的操作
my_image=np.array(Image.fromarray(img).resize((64,64))) #(64, 64, 3)
#调整大小代入模型中
my_image=my_image.reshape(12288,1)
my_predicted_image = predict(d["w"], d["b"], my_image)
my_predicted_image
array([[0.]])
说明这张图片里面没有猫