B站吴恩达深度学习视频笔记(1-14)——实战3:识别猫图

前言

还记得在前几节课中吴恩达老师讲述如何识别一张图片,以及电脑识别图片的原理吗?这篇笔记中就会用到之前笔记1-14除了机器学习框架以外几乎所有的知识,来完成入门阶段终极实战——识别猫图。

我们即将使用逻辑回归搭建一个简单的单层神将网络,并实现猫图的识别。
本篇中的单层神经网络在训练集与测试集上分别获得了 100% 与 70% 的正确率。

数据导入

使用的数据是著名的catvnoncat数据集,数据集已经被处理成了标准的h5文件,只需要导入就可以了,这里我们另写了一个导入使用的py文件,所以只需要调用一下语句,即可完成数据导入:

from lr_utils import load_dataset
train_X_orig, train_Y, test_X_orig, test_Y, classes = load_dataset()

其中 load_dataset 就将数据进行了导入,如果你好奇数据是怎么导入的,在文章末尾我会把代码放出来让你查看导入数据的细节。

不过目前为止你并不需要关心数据是怎么导入的,以及数据来源是什么,因为这些都不是本篇的重点。你要关注内容的应该是神经网络在编程中到底是如何实现的,当你真正实现了你的神经网络之后,只需要将数据按照你的网络需要进行格式处理并输入就行了。在本篇当中你直接将数据下载下来并使用上面的一行代码导入进行使用即可。

导入数据后的第一件事情,应该关心数据的存储结构,下面几行代码输出了训练集输入(train_set_x_orig)、训练集输出(train_set_y)、测试集输入(test_set_x_orig)及测试集输出(test_set_y)的形状。

print ("Shape of train_set_x_orig: " + str(train_X_orig.shape))
print ("Shape of train_set_y: " + str(train_Y.shape))
print ("Shape of test_set_x_orig: " + str(test_X_orig.shape))
print ("Shape of test_set_y: " + str(test_Y.shape))

输出结果是:
在这里插入图片描述
由此不难获得几点信息:

  1. 训练集中有209个训练元素;测试集中有50个测试元素。
  2. 训练集和测试集的图像宽高均为 64×64

而 3L代表的是 RGB 三通道。如果对图像在计算机当中的存储形式有所了解的话,应该对 RGB

RGB 不陌生,电脑屏幕上的所有颜色,都由这红色绿色蓝色三种色光按照不同的比例混合而成。

数据处理

在前面已经完成了数据集的导入,并且查看了训练集当中的两个样本图像及对应的图像标注。但是这些数据目前为止还不方便我们使用,下面看一看如何将其调整为合适的格式。

对于单个训练样本而言,所有的输入按照列矩阵的形式传入网络,即输入 x
x 的是 nx×1 维的矩阵,但是一幅 64×64 图像的在数据集中是以 64×64×3 的矩阵形状进行存储的,为了满足神经网络的输入格式,在 Python 中可以使用 reshape 函数改变矩阵的形状,对于一个形状为 (a,b,c,d) 的矩阵 M1M1​ 而言,通过 M1.reshape(M1.shape[0],−1).T 就可以将其转换为形状为 (b×c×d,a)的矩阵了。

其中第一项参数 M1.shape[0]表示的就是 M1​ 原来的第一维长度 a,第二项参数 −1表示将后面的所有维度堆叠成一个维度,这样就得到了一个形为 (a,b×c×d)的矩阵,再通过".T"进行转置,就得到了 a个列矩阵堆叠得到的“向量化矩阵”。

使用这个方法就可以对数据集中的图像数据进行降维处理了:

train_set_x_flatten = train_X_orig.reshape(train_X_orig.shape[0],-1).T
test_set_x_flatten = test_X_orig.reshape(test_X_orig.shape[0],-1).T
print ("Shape of train_set_x_flatten: " + str(train_set_x_flatten.shape))
print ("Value of test_set_x_flatten: " + str(test_set_x_flatten))

输出结果:
在这里插入图片描述
其中按列看,每一列代表一个样本图像的所有 RGB 数值,共有209个训练样本,因此 train_set_x_flatten 有209列。

数字 12288 是 RGB 全部铺平的数值总量

因为图片是 64×64 的,因此 R、G、B各有 64×64=4096个值,RGB 共三层4096×3=12288

单个样本的RGB颜色值在 flatten 当中应该是这样存放的:

在这里插入图片描述至此,我们完成了数据集的格式化处理,即 图1-3 中左侧RGB图像到右侧输入层的转换。

在这里插入图片描述
不过,imshow()显示图像时对double型是认为在01范围内,因此再将颜色值全部除以255将值转换到01。

train_set_x = 1.0*train_set_x_flatten/255
test_set_x = 1.0*test_set_x_flatten/255
print ("Shape of train_set_x: " + str(train_set_x.shape))
print ("Value of test_set_x: " + str(test_set_x))

输出结果:
在这里插入图片描述
现在,整个数据集的输入数据都已经处理好了放在矩阵 train_set_x 与 test_set_x 当中,形式如下:

在这里插入图片描述
如果你有些忘记了上面这个矩阵的行数、列数及每一个角标的意义的话,请回看上一篇向量化的第一节,里面有详细的解释,不过结合矩阵的角标你应该很好理解了。

至此,训练和测试数据都有了并且都规范好了,正式开始搭建你的神经网络吧!

搭建神经网络

numpy 是 Python 的一种开源的数值计算扩展,这种工具可用来存储和处理大型矩阵,在上一篇向量化当中所记录的是如何将 Logistic 回归向量化,即将循环代码转换为矩阵计算的形式,而 numpy 就可以帮助你实现矩阵的相关计算。

例如现在将定义一个函数 sigmoid 用于计算所有输入样本 z 值的 σ 函数值:

# sigmoid 函数

def sigmoid(z):
    a = 1./(1+np.exp(-z))
    return a

np.exp 是 numpy 提供的求自然指数的函数,对如输入参数为矩阵的时候,会对矩阵中的所有元素求自然指数,如果不使用 numpy 的话,你就要写一个大的 for 循环来遍历所有的数据并计算了,在上一篇中你已经看到了 for 循环的效率是很低的,这就是使用 numpy 的必要性,即向量化计算的落地实现。

初始化参数

下面定义的函数 initialize_parameters 用于初始化参数 w和 b,传入输入的维数,返回一个值为 0 的 b 及对应维数的 w。

np.zeros((a,b))# 用于生成一个形状为 a×ba×b 的零矩阵。
# Initialize parameters

def initialize_parameters(dim):
    w = np.zeros(shape=(dim, 1), dtype=np.float32)
    b = 0
    
    return w, b

向前/后传播

下面定义的函数 propagate 将完成一次向前传播与向后传播。

np.sum(M)#是 numpy 中的求和函数,可以对矩阵按行/列进行堆叠求和,参数 axis = 1 时表示按行求和。
np.dot(M1,M2)#是 numpy 中的点乘函数,用于对两个矩阵做点乘运算。
def propagate(w, b, X, Y):
    
    m = X.shape[1]
    
    # 向前传播
    A = sigmoid(np.dot(w.T,X) + b)
    
    cost = (-1./m) * np.sum((Y*np.log(A) + (1-Y)*np.log(1-A)), axis = 1) # axis = 1 代表按行求和
    
    # 向后传播
    dw = (1./m)*np.dot(X, ((A-Y).T))
    db = (1./m)*np.sum(A-Y, axis = 1)
    
    cost = np.squeeze(cost) # trans cost from matrix 1x1 into a real number
    
    return dw, db, cost

梯度下降

下面的函数 optimized 将实现梯度下降,参数 train_times 和 learning_rate 分别用于设定训练次数及学习率。变量 costs 用于记录参数 w
w、bb 对应的成本函数值,每训练100次记录一次成本,用于后期绘制 costs 关于训练次数的变化图像,以了解模型的学习情况。

def optimized(w, b, X, Y, train_times, learning_rate):
    
    costs = []
    
    for i in range(train_times):
        
        dw, db, cost = propagate(w, b, X, Y)

        # 参数迭代
        w = w - learning_rate * dw
        b = b - learning_rate * db
        
        # 记录成本函数
        if i%100 == 0:
            costs.append(cost)
        
    return w, b, costs

输入预测

下面的函数 predict 用于输入预测,其实也就是计算一次向前传播,得到输出结果就是预测值。

def predict(w, b, X):
    
    m = X.shape[1]
    Y_prediction = np.zeros((1,m))
    
	# 确保矩阵维数匹配
    w = w.reshape(X.shape[0], 1)
    
	# 计算 Logistic 回归
    A = sigmoid(np.dot(w.T, X) + b)
	
	# 如果结果大于0.5,打上标签"1",反之记录为"0"
    for i in range(A.shape[1]):
        if A[0, i] > 0.5:
            Y_prediction[0, i] = 1
        else:
            Y_prediction[0, i] = 0
    
	# 确保一下矩阵维数正确
    assert(Y_prediction.shape == (1,m))
    
    return Y_prediction    

模型封装

在前面我们已经将模型的主体即向前传播向后传播和梯度下降都模块化地完成了,接下来把这些步骤拼接在一起得到最终的模型吧!

def TestMyModel(X_train, Y_train, X_test, Y_test, train_times = 100, learning_rate = 0.005):
    
    # 初始化参数
    w, b = initialize_parameters(X_train.shape[0])
    
    # 开始梯度下降训练
    w, b, costs = optimized(w, b, X_train, Y_train, train_times, learning_rate)
    
    # 训练完成,测试一下效果
    Y_prediction_train = predict(w, b, X_train)
    Y_prediction_test = predict(w, b, X_test)
    
    # 输出效果
    print("Accuracy on train_set: " + str(100 - np.mean(np.abs(Y_prediction_train-Y_train)) * 100) + "%")
    print("Accuracy on test_set: " + str(100 - np.mean(np.abs(Y_prediction_test-Y_test)) * 100) + "%")
    print(Y_prediction_test)
    return w, b, costs, Y_prediction_test

数据集测试

至此,你已经完成了一个单层神经网络的构建,让我们来测试一下效果吧!

w, b, costs, Y_prediction_test = TestMyModel(train_set_x, train_set_y, test_set_x, test_set_y, 2000, 0.002)
plot_costs = np.squeeze(costs)
plt.plot(plot_costs)

输出结果:
在这里插入图片描述可以看到,对于学习率 0.002,训练2000次可以在训练集与测试集上分别得到 100% 与 70% 的正确率!这对于一个如此简单的单层神经网络来说已经算是不错了。

总结

到这里,深度学习的第一阶段正式告一段落,在网上找了一位博主的框架图,这里粘来用一下,正好可以表示最近学习的总体框架。
在这里插入图片描述首先整体的第一周的课程是神经“网路”,对,通向神经网络的基础的网络,其中讲解了内容模块包括:

二分分类

二分类问题简单来说就是1和0的问题,也就是著名的cat 和 noncat问题,这个处理是靠图片输入,然后计算机整合处理矩阵输入,使用网络初等感知机进行输出,这是一个典型的判别网络模型

逻辑回归

逻辑回归问题,如果说二分类问题是分类问题的话,那么这个可以简单地理解成为回归问题,对的,网络模型中基本上使用的最多的也就是分类问题(人脸识别,手写体识别,猫识别)和回归问题(房价预估),在这里你要了解到的是逻辑回归使用了最大似然估计,定义逻辑回归函数和成本函数后,利用梯度下降进行损失最小化

梯度下降

梯度下降这一部分就是讲解了梯度为何下降的,要清楚理解其中的权重更新,学习率,还有前后向的求导方法,可是梯度下降并不仅仅是这个一个简单的流程就能解决各种各样复杂的问题,还有很多前辈们优化的方法,比如权重衰减,学习率衰减等,这个在后面会讲到。

向量化

量化,这一部分其实是在教我们如何在硬件的基础上更好的加快训练速度和思维空间逻辑思考,它可以让我们一次训练多样本,更简单和更高效的完成训练目标。但是python的numpy这一个模块还是有必要去好好看下的,这也算是一个建议了,希望下去好好努力下。

  • 8
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
吴恩达logistic regression算法可以用于识别的数据集。在机器学习中,logistic regression是一种用于解决二分类问题的方法。对于识别问题来说,我们可以将图像视为特征矩阵,每个像素点的数值可以作为该特征的值。而标签则表示图像是否为。 首先,我们需要将图像数据集按照一定比例划分为训练集和测试集。训练集用于训练模型,而测试集用来评估模型的性能。 接下来,我们将每个像素点的数值作为特征,构建特征矩阵。同时,对于每个图像,我们需要将标签转化为对应的二分类标签,例如1表示是,0表示不是。 然后,我们使用logistic regression算法对训练集进行训练。训练过程中,算法会根据特征矩阵和对应的标签进行优化,找到最优的权重和偏置,以最大化模型的预测能力。 最后,我们使用训练好的模型对测试集进行预测,并与测试集的真实标签进行比较,计算模型的准确率等评估指标,来评估模型的性能。 需要注意的是,为了提高模型的性能,我们可以采取一些预处理步骤,例如特征缩放和特征选择等。此外,还可以使用正则化方法来避免过拟合问题。 总之,通过吴恩达logistic regression算法,我们可以构建一个用于识别的模型,并对其性能进行评估和优化。这个模型可以应用于各种需要识别的场景,如图像分类和目标检测等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

nine_mink

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

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

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

打赏作者

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

抵扣说明:

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

余额充值