吴恩达神经网络课后作业_逻辑回归_猫的识别

案例:猫的二分类

数据集:train_catvnoncat.h5 、 test_catvnoncat.h5

逻辑回归、梯度下降


目录
1.使用h5py加载数据
2.查看数据信息 (以字典的方式提取)
3.提取图片以及标签(包含随机可视化一个样本)
4. 前向传播
5. 优化部分(梯度下降)
6. 预测、准确率
7. 不同学习率的比较


与之前作业的比较

1、使用 h5py 来读取图像文件,每一个图像为 28*28 像素,每一个像素作为一个特征,要把 四维的数组(209, 64, 64, 3),预处理为二维数组(12288,209)
2、机器学习中,我们用pandas读取数据时,每一行为一个样本(m,n),现在每一行为一个特征(n,m),以便对应公式 w.T @ X + b
3、(把损失函数、梯度下降、预测函数 整合到 一个模型中,便于保存),我看了一些大神的作业确实是那么做的,但实际上,我并没有做。


import h5py
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

1.使用h5py加载数据

data_train = h5py.File('train_catvnoncat.h5', 'r')
data_test = h5py.File('test_catvnoncat.h5', 'r')

2.查看数据信息

for key in data_train.keys():
    print(data_train[key].name) # 打印每一个 key 的名字
    # print(data_train[key].shape)  
    # print(data_train[key].value)
/list_classes
/train_set_x
/train_set_y
for key in data_test.keys():
    print(data_test[key].name) # 打印每一个 key 的名字
    # print(data_train[key].shape)  
    # print(data_train[key].value)
/list_classes
/test_set_x
/test_set_y

3.提取图片以及标签

3.1 提取训练集数据,并转化为np二维数组

x_train = data_train['train_set_x']

# 可视化一个样本
num = np.random.randint(209)
plt.imshow(x_train[num,:])

# print(type(x_train))  # <class 'h5py._hl.dataset.Dataset'>  # 原始的维数 (209, 64, 64, 3)
x_train = np.array(x_train).reshape((209,-1)).T
# type(x_train)  # numpy.ndarray
y_train = np.array(data_train['train_set_y'])
y_train = y_train.reshape((-1,1)).T
print(x_train.shape, y_train.shape)
(12288, 209) (1, 209)

吴恩达神经网络课后作业_逻辑回归_猫的识别

3.2 提取测试集数据,并转化为np二维数组

x_test = np.array(data_test['test_set_x']).reshape((50,-1)).T
y_test = np.array(data_test['test_set_y']).reshape((-1,1)).T
print(x_test.shape, y_test.shape)
(12288, 50) (1, 50)

3.3 数据归一化

x_train = x_train / 255
x_test = x_test / 255
print(x_train.shape,x_test.shape)
(12288, 209) (12288, 50)

4. 前向传播

**函数\损失函数\梯度公式
def sigmoid(z):
    return 1/(1+np.exp(-z))
# 初始化 w,b
n = x_train.shape[0]
w = np.zeros((n,1))
b = 0
w.shape
(12288, 1)
def propagate(w,b,X,y):
    m = X.shape[1]
    A = sigmoid(np.dot(w.T, X) + b)  # 加权求和以及**函数映射
    cost = -(1.0 / m) * np.sum(y * np.log(A) + (1 - y) * np.log(1 - A))  # 代价函数

    dw = (1.0 / m) * np.dot(X, (A - y).T)
    db = (1.0 / m) * np.sum(A - y)
    grands = {'dw': dw,
              'db': db}

    return grands, cost
#     m = X.shape[1]
#     Z = w.T @ X + b
#     A = sigmoid(Z)
#     inner = y * np.log(A) + (1-y) * np.log(1-A)
#     cost = - np.sum(inner)/ m
    
#     dw = (1.0 / m) * np.dot(X, (A - y).T)
#     db = (1.0 / m) * np.sum(A - y)
    
#     grands = {'dw': dw,
#               'db': db}

5. 优化部分

梯度下降

def optimize(w, b, X, y, learning_rate, num_iterations, print_cost):
    costs = []

    for i in range(num_iterations):

        grands, cost = propagate(w, b, X, y)

        dw = grands["dw"]
        db = grands["db"]

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

        if i % 100 == 0:
            costs.append(cost)
            if print_cost:
                print("Cost after iteration %i: %f" % (i, cost))

    params = {"w": w,
              "b": b}

    grands = {"dw": dw,
              "db": db}

    return params, grands, costs


6. 预测\准确率

def predict(w,b,X):
    Z = w.T @ X + b
    A = sigmoid(Z)
    m = X.shape[1]
    y_pred = np.zeros((1,m))
    
    for i in range(m):
        if A[:,i] > 0.5:
            y_pred[:,i] = 1
        else:
            y_pred[:,i] = 0
    return y_pred
learning_rate = 0.005 
num_iterations = 2000

params, grands, costs = optimize(w, b, x_train, y_train, learning_rate, num_iterations,print_cost=False)
print(costs)

w = params['w']
b = params['b']

y_pred_train = predict(w, b, x_train)
y_pred_test = predict(w, b, x_test)

print('train accrate', np.mean(y_pred_train == y_train) * 100, '%')  # 准确率
print('test accrate', np.mean(y_pred_test == y_test) * 100, '%')
[0.6931471805599453, 0.5845083636993086, 0.46694904094655476, 0.37600686694802077, 0.3314632893282513, 0.30327306747438293, 0.2798795865826048, 0.26004213692587574, 0.24294068467796623, 0.22800422256726066, 0.21481951378449635, 0.20307819060644985, 0.1925442771670686, 0.18303333796883503, 0.17439859438448876, 0.16652139705400335, 0.15930451829756614, 0.15266732471296504, 0.1465422350398234, 0.14087207570310162]
train accrate 99.04306220095694 %
test accrate 70.0 %
plt.plot(costs)
plt.ylabel('cost')
plt.xlabel('iterations (per hundreds)')
plt.show()

吴恩达神经网络课后作业_逻辑回归_猫的识别

7 学习率的比较

# 比较 学习率 0.01/0.001/0.0001
learning_rate = [0.01, 0.001, 0.0001]

for i in learning_rate:
    print('learning_rate=', i)
    
    w = np.zeros((n,1))
    b = 0
    
    # 优化
    params, grands, costs = optimize(w, b, x_train, y_train,learning_rate=i, num_iterations=2000,print_cost=False)
    
    # 预测
    w = params['w']
    b = params['b']

    y_pred_train = predict(w, b, x_train)
    y_pred_test = predict(w, b, x_test)
    
    # 评分
    print('train accrate', np.mean(y_pred_train == y_train) * 100, '%')  # 准确率
    print('test accrate', np.mean(y_pred_test == y_test) * 100, '%')
    
    # 可视化
    print('-' * 30)
    plt.plot(costs, label=str(i))
    plt.ylabel('cost')
    plt.xlabel('iterations (per hundreds)')
    plt.legend()
    plt.show()
learning_rate= 0.01
train accrate 99.52153110047847 %
test accrate 70.0 %
------------------------------

吴恩达神经网络课后作业_逻辑回归_猫的识别

learning_rate= 0.001
train accrate 91.38755980861244 %
test accrate 68.0 %
------------------------------

吴恩达神经网络课后作业_逻辑回归_猫的识别

learning_rate= 0.0001
train accrate 71.29186602870813 %
test accrate 40.0 %
------------------------------

吴恩达神经网络课后作业_逻辑回归_猫的识别