DeepLearning学习笔记【1】:基于逻辑回归的图像二分类

本文详细介绍了逻辑回归在深度学习中的应用,包括数据预处理、模型构建、训练过程中的正向传播和反向传播,以及使用梯度下降法优化参数。作者通过吴恩达的课程实例,展示了如何使用逻辑回归进行图像二分类,并通过学习曲线和准确率评估模型性能。
摘要由CSDN通过智能技术生成

本文为笔者学习吴恩达深度学习课程的学习笔记,仅作学习参考使用。
在吴恩达第二周课程中,编程作业为使用逻辑回归进行图像二分类,判断一张图片是否为猫。本文基于这种情景对基于逻辑回归的图像二分类问题进行讨论。
本文代码改编自博主何宽的这篇文章,稍有改动意在使代码更加简洁,让读者更容易将其与网课所讲的原理相联系。

模型训练的技术路线

深度学习中模型训练通常包含以下步骤:

  1. 数据准备:读取样本数据集(通常包含train集和test集)和预处理;
  2. 模型初始化:将模型(函数)的参数初始化为极小的数或零;
  3. 正向传播:模型对给定输入做出预测(将输入代入函数);
  4. 计算损失:损失函数反映模型的预测与真实标签的差异,损失越小越好;
  5. 反向传播:计算梯度等,用于参数更新;
  6. 参数更新:通常使用梯度下降法,更新模型的参数,使损失可以更小;
  7. 迭代:重复正向传播、计算损失、反向传播和参数更新步骤,直到模型损失足够小或达到一定的迭代次数;
  8. 评估:通过绘制学习曲线、Loss曲线或分析混淆矩阵等评估模型的效果。

逻辑回归

逻辑回归模型通过Sigmoid函数将线性回归的输出映射到0和1之间,其输出可以被解释为属于某类的概率。
就是说,逻辑回归的目的是得到一个形如下的一个函数来进行预测分类:
  A = σ ( Z ) = 1 1 + e − Z = 1 1 + e − ω X + b \ A=\sigma (Z)=\frac{1}{1+{{e}^{-Z}}}=\frac{1}{1+{{e}^{-\omega X+b}}}  A=σ(Z)=1+eZ1=1+eωX+b1
其中A可解释为“图片是猫图的概率”。
而这个函数(Sigmoid)对应的损失函数(Cost function)如下,损失函数越小越好:
  J ( w , b ) = − 1 m ∑ i = 1 m [ y ( i ) log ⁡ ( a ( i ) ) + ( 1 − y ( i ) ) log ⁡ ( 1 − a ( i ) ) ] \ J(w, b) = -\frac{1}{m} \sum_{i=1}^{m} [y^{(i)} \log(a^{(i)}) + (1 - y^{(i)}) \log(1 - a^{(i)})]  J(w,b)=m1i=1m[y(i)log(a(i))+(1y(i))log(1a(i))]

代码实现

事先说明笔者的一个观点,在这里涉及一些库函数的使用,即使你不了解这些库函数也完全没有关系,因为随便一个GPT都写得出来,记忆库函数的使用是没有意义的,重要的是了解以下代码中的深度学习工作模式和原理,知道我们每步要做什么是最重要的

  1. 导入所需要的库
import numpy as np
import matplotlib.pyplot as plt
import h5py
  1. 从文件导入数据集,其包含有:
    训练集图像 train_set_x_orig :209张64x64的图像
    训练集标签 train_set_y_orig :训练集的图像对应的分类值【0 | 1】
    测试集图像 test_set_x_orig :50张64x64的图像
    测试集标签 test_set_y_orig : 测试集的图像对应的分类值【0 | 1】
    classes : bytes类型的两个字符串数据:[b’non-cat’ b’cat’]
def load_dataset():
    train_dataset = h5py.File('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('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"][:]) 
    
    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
  1. 对数据集进行预处理:展平 & 归一化
def pretreat(train_set_x_orig, test_set_x_orig):
    
    # 把每个样本的特征化成列向量
    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

    # 归一化
    train_set_x = train_set_x_flatten / 255
    test_set_x = test_set_x_flatten / 255
    
    return train_set_x, test_set_x

经过展平和归一化:(括号代表shape)
train_set_x_orig(209, 64, 64, 3)变成了train_set_x(12288, 209)
test_set_x_orig(50, 64, 64, 3) 变成了test_set_x(12288, 50)

  1. 定义sigmoid函数方便后续使用:
def sigmoid(z):
    s = 1 / (1 + np.exp(-z))
    return s
  1. 定义优化函数:
    正向传播: 计算预测概率A和损失函数J;
    反向传播: 计算梯度(dw, db);
    梯度下降: 优化权重w和偏置b:
def optimize(w , b , X , Y , num_iterations , learning_rate):

    # m为样本数量
    m = X.shape[1]
    costs = []
    # 迭代次数num_iterations即循环次数
    for i in range(num_iterations):
        # 计算当前参数下的梯度和成本
        # 正向传播
        A = sigmoid(np.dot(w.T,X) + b) #计算激活函数的输出(预测概率 A)
        cost = (- 1 / m) * np.sum(Y * np.log(A) + (1 - Y) * (np.log(1 - A))) #计算成本 J

        # 反向传播
        # 省略 dz = A - Y
        dw = (1 / m) * np.dot(X, (A - Y).T) #请参考视频中的偏导公式。
        db = (1 / m) * np.sum(A - Y) #请参考视频中的偏导公式。
        
        # 梯度下降:更新权重w和偏置b       
        w = w - learning_rate * dw
        b = b - learning_rate * db

        # 每100次迭代记录一次成本并打印,用于分析模型的收敛过程
        if i % 100 == 0:
            costs.append(cost)
            print("迭代的次数: %i , 误差值: %f" % (i,cost))

    params  = {
                "w" : w,
                "b" : b }
    grads = {
            "dw": dw,
            "db": db } 
    return (params , grads , costs)
  1. 使用以上函数我们足以训练一个可用的模型,但训练完毕后,我们需要科学地看一下我们训练出来的模型效果如何,故编写下面的函数使用我们训练的模型对图片集进行预测判断:
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
    #使用断言
    assert(Y_prediction.shape == (1,m))

    return Y_prediction
  1. 将以上函数集成为一个model函数,使用model函数便可以完成模型训练的完整过程:
def model(X_train , Y_train , X_test , Y_test , num_iterations = 2000 , learning_rate = 0.5):
    # 初始化w向量和b
    w , b = initialize_with_zeros(X_train.shape[0])
    # 
    params , grads , costs = optimize(w , b , X_train , Y_train,num_iterations , learning_rate )

    # 从字典“参数”中检索参数w和b
    w , b = params["w"] , params["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
  1. 相关函数定义完毕,我们便可以用简单的代码实现基于逻辑回归的图像二分类:
# 加载数据集
train_set_x_orig , train_set_y , test_set_x_orig , test_set_y , classes = load_dataset()
# 预处理数据集
train_set_x, test_set_x = pretreat(train_set_x_orig, test_set_x_orig)

# 代入model函数
d = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations = 2100, learning_rate = 0.005)

# 绘制图
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()

代码最终运行结果

GPT总结的关键学习点:

数据预处理:我们学习了如何从文件中导入数据集,以及如何对数据集进行预处理,包括展平和归一化,使其适用于模型训练。
模型构建:通过定义Sigmoid函数和损失函数,我们掌握了逻辑回归模型的基本构成。
训练过程:我们详细了解了模型训练的各个步骤,特别是正向传播和反向传播的原理,以及如何使用梯度下降法进行参数更新。
模型评估:通过绘制学习曲线和计算训练集与测试集的准确率,我们学会了如何评估模型的性能。

  • 28
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mugen_n

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值