人工智能系列实验(一)——用于识别猫的二分类单层神经网络

本文主要是介绍人工智能系列实验(一)——用于识别猫的二分类单层神经网络,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本实验利用Python,搭建了一个用于识别猫的单神经元神经网络,最终实现在测试集上的准确率在70%以上。

实验环境: python中numpy、matplotlib、h5py和skimage库

import numpy as np
import matplotlib.pyplot as plt  # 用于画图
import h5py  # 用于加载训练数据集
import skimage.transform as tf  # 用于缩放图片

训练样本: 209张64*64的带标签图片

测试样本: 50张64*64的带标签图片

关于本实验中所用数据集完整代码详见:
https://github.com/PPPerry/AI_projects/tree/main/1.cats_identification

构建的神经网络模型如下:

在这里插入图片描述

基于该神经网络模型,代码实现如下:

首先,对数据集数据进行预处理。

def load_dataset():"""加载数据集数据:return: 训练数据与测试数据的相关参数"""train_dataset = h5py.File("datasets/train_catvnoncat.h5", "r")train_set_x_orig = np.array(train_dataset["train_set_x"][:])  # 提取训练数据的特征数据,格式为(样本数, 图片宽, 图片长, 3个RGB通道)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"][:])  # 提取标签,1代表是猫,0代表不是猫train_set_y_orig = train_set_y_orig.reshape((1, train_set_y_orig.shape[0]))  # 统一类别数组格式为(1, 样本数)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, classestrain_set_x_orig,  train_set_y, test_set_x_orig, test_set_y, classes = load_dataset()  # 加载数据集数据m_train = train_set_x_orig.shape[0]  # 训练样本数
m_test = test_set_x_orig.shape[0]  # 测试样本数
num_px = test_set_x_orig.shape[1]  # 正方形图片的长/宽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).Ttrain_set_x = train_set_x_flatten/255.  # 标准化处理,使所有值都在[0, 1]范围内
test_set_x = test_set_x_flatten/255.

其次,构造神经网络中用到的相应函数。
其中,前向传播的公式为
A = σ ( w T X + b ) = ( a ( 1 ) , a ( 2 ) , ⋯ , a ( m − 1 ) , a ( m ) ) J = − 1 m ∑ i = 1 m l o g ( a ( i ) ) + ( 1 − y ( i ) ) l o g ( 1 − a ( i ) ) \begin{array}{c} A=\sigma(w^TX+b)=(a^{(1)},a^{(2)},\cdots,a^{(m-1)},a^{(m)})\\ \\ J = -\frac{1}{m}\sum^m_{i=1}log(a^{(i)})+(1-y^{(i)})log(1-a^{(i)}) \end{array} A=σ(wTX+b)=(a(1),a(2),,a(m1),a(m))J=m1i=1mlog(a(i))+(1y(i))log(1a(i))
反向传播的公式为
∂ J ∂ w = 1 m X ( A − Y ) T ∂ J ∂ b = 1 m ∑ i = 1 m ( a ( i ) − y ( i ) ) \begin{array}{c} \frac{\partial J}{\partial w} = \frac{1}{m}X(A-Y)^T\\ \\ \frac{\partial J}{\partial b} = \frac{1}{m}\sum^m_{i=1}(a^{(i)}-y^{(i)}) \end{array} wJ=m1X(AY)TbJ=m1i=1m(a(i)y(i))

def sigmoid(z):"""sigmod函数实现:param z: 数值或一个numpy数组:return: [0, 1]范围数值"""s = 1 / (1 + np.exp(-z))return sdef initialize_with_zeros(dim):"""初始化权重数组w和偏置b为0:param dim: 权重值的数量:return:w: 权重数组b: 偏置bias"""w = np.zeros((dim, 1))b = 0return w, bdef propagate(w, b, X, Y):"""实现正向传播和反向传播,分别计算出成本与梯度:param w: 权重数组:param b: 偏置:param X: 图片的特征数据:param Y: 图片的标签数据:return:cost: 成本dw: w的梯度db:b的梯度"""m = X.shape[1]# 前向传播A = sigmoid(np.dot(w.T, X) + b)cost = -np.sum(Y * np.log(A) + (1 - Y) * np.log(1 - A)) / m# 反向传播dZ = A - Ydw = np.dot(X, dZ.T) / mdb = np.sum(dZ) / m# 梯度保存在字典中grads = {"dw": dw,"db": db}return grads, costdef optimize(w, b, X, Y, num_iterations, learning_rate, print_cost=False):"""梯度下降算法更新参数:param w: 权重数组:param b: 偏置bias:param X: 图片的特征数据:param Y: 图片的标签数据:param num_iterations: 优化迭代次数:param learning_rate: 学习率:param print_cost: 为真时,每迭代100次,打印一次成本:return:params: 优化后的w和bcosts: 每迭代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 * dwb = b - learning_rate * db# 记录成本变化if i % 100 == 0:costs.append(cost)if print_cost:print("优化%d次后成本是:%f" % (i, cost))params = {"w": w,"b": b}return params, costsdef predict(w, b, X):"""预测函数,判断是否为猫:param w: 权重数组:param b: 偏置bias:param X: 图片的特征数据:return:Y_predicition: 预测是否为猫,返回值为0或1p: 预测为猫的概率"""m = X.shape[1]Y_prediction = np.zeros((1, m))p = sigmoid(np.dot(w.T, X) + b)for i in range(p.shape[1]):if p[0, i] >= 0.5:Y_prediction[0, i] = 1return Y_prediction, p

最终,组合以上函数,构建出最终的神经网络模型函数。

def model(X_train, Y_train, X_test, Y_test, num_iterations=2001, learning_rate=0.5, print_cost=False):"""最终的神经网络模型函数:param X_train: 训练样本的特征数据:param Y_train: 训练样本的标签数据:param X_test: 测试样本的特征数据:param Y_test: 测试样本的标签数据:param num_iterations: 优化迭代次数:param learning_rate: 学习率:param print_cost: 为真时,每迭代100次,打印一次成本:return: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 = parameters["w"]b = parameters["b"]Y_prediction_train, p_train = predict(w, b, X_train)Y_prediction_test, p_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,"p_train": p_train,"p_test": p_test}return d

现在调用上面的模型函数对我们最开始加载的数据进行训练。

d = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations=2001, learning_rate=0.005, print_cost=True)

输出:优化2000次后的成本是0.1356。对训练数据的准确率为99%左右,对测试数据的准确率为70%左右。
在这里插入图片描述

试验模型预测功能:

  1. 查看训练集和测试集中图片及其对应的预测结果
def show_predict(index, prediction=np.hstack((d["Y_prediction_train"], d["Y_prediction_test"])),data=np.hstack((train_set_x, test_set_x)), origin=np.hstack((train_set_y, test_set_y)),px=num_px, p=np.hstack((d["p_train"], d["p_test"]))):if index >= prediction.shape[1]:print("index超出数据范围")returnplt.imshow(data[:, index].reshape((px, px, 3)))plt.show()print("这张图的标签是" + str(origin[0, index]) + ",预测分类是" + str(int(prediction[0, index])) + ",预测概率是" + str(p[0, index]))return

以第19张图片为例:
在这里插入图片描述
输出:这张图的标签是1,预测分类是1,预测概率是0.93。

  1. 查看自己输入的图片及其对应的预测结果
# 预测自己的图片
# 在同目录下创建一个文件夹images,把你的任意图片改名成my_image1.jpg后放入文件夹
my_image = "my_image1.jpg"image = np.array(plt.imread(my_image))
my_image = tf.resize(image, (num_px, num_px), mode='reflect').reshape((1, num_px*num_px*3)).T
my_prediction, my_p = predict(d["w"], d["b"], my_image)plt.imshow(image)
plt.show()
print("预测分类是" + str(int(my_prediction[0, 0])) + ",预测概率是" + str(my_p[0, 0]))

以下图为例:
在这里插入图片描述
输出:预测分类是1,预测概率是0.89。

进一步实验得到的结论:

  1. 成本随迭代次数增加时的变化情况
# 绘制成本随迭代次数增加时的变化情况
costs = np.squeeze(d['costs'])  # 将表示向量的数组转换为秩为1的数组,便于matplotlib库函数画图
plt.plot(costs)
plt.ylabel('cost')
plt.xlabel('iterations (per hundreds)')
plt.title("Learning rate =" + str(d["learning_rate"]))
plt.show()

在这里插入图片描述
结论:训练次数越多,成本越小,预测结果越精确。

  1. 不同学习率下成本随迭代次数增加时的变化情况
# 绘制在不同学习率下成本随迭代次数增加时的变化情况
learning_rates = [0.01, 0.001, 0.0001]
models = {}
for i in learning_rates:models[str(i)] = model(train_set_x, train_set_y, test_set_x, test_set_y, num_iterations=2001, learning_rate=i,print_cost=False)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 (per hundreds)')
legend = plt.legend(loc='upper right', shadow=True)
plt.show()

在这里插入图片描述
结论:选择一个正确的学习率很重要,不一定越大越好。设置不合理,神经网络有可能永远都不能下降到损失函数的最小值处;相反,设置合理,可以使神经网络的收敛达到很好的效果。

结束语:

  1. 实验过程中,一定要搞清楚变量的维度,否则做数据处理、写数组操作时会容易出现问题。
  2. 数据集、图片等需要和代码在同一目录下。
  3. 本实验几乎基于纯Python的numpy库函数进行神经网络模型的搭建,没有使用任何机器学习框架,重在理解数学原理及意义。在后续的实验中,我会对TensorFlow等经典框架进行学习与运用。
  4. 相关代码可能会不断更新改进,以github中的代码为准。
  5. 这是我在系统学习人工智能中实现的第一个人工智能程序,后续还会不断更新系列实验。写博客以督促自己不能总摸鱼233,希望自己能在神经网络这条路上走的尽可能远一些。

这篇关于人工智能系列实验(一)——用于识别猫的二分类单层神经网络的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/323291

相关文章

人工智能机器学习算法总结神经网络算法(前向及反向传播)

1.定义,意义和优缺点 定义: 神经网络算法是一种模仿人类大脑神经元之间连接方式的机器学习算法。通过多层神经元的组合和激活函数的非线性转换,神经网络能够学习数据的特征和模式,实现对复杂数据的建模和预测。(我们可以借助人类的神经元模型来更好的帮助我们理解该算法的本质,不过这里需要说明的是,虽然名字是神经网络,并且结构等等也是借鉴了神经网络,但其原型以及算法本质上还和生物层面的神经网络运行原理存在

雨量传感器的分类和选型建议

物理原理分类 机械降雨量计(雨量桶):最早使用的降雨量传感器,通过漏斗收集雨水并记录。主要用于长期降雨统计,故障率较低。电容式降雨量传感器:基于两个电极之间的电容变化来计算降雨量。当降雨时,水滴堵住电极空间,改变电容值,从而计算降雨量。超声波式降雨量传感器:利用超声波的反射来计算降雨量。适用于大降雨量的场合。激光雷达式降雨量传感器:利用激光技术测量雨滴的速度、大小和形状等参数,并计算降雨量。主

时间服务器中,适用于国内的 NTP 服务器地址,可用于时间同步或 Android 加速 GPS 定位

NTP 是什么?   NTP 是网络时间协议(Network Time Protocol),它用来同步网络设备【如计算机、手机】的时间的协议。 NTP 实现什么目的?   目的很简单,就是为了提供准确时间。因为我们的手表、设备等,经常会时间跑着跑着就有误差,或快或慢的少几秒,时间长了甚至误差过分钟。 NTP 服务器列表 最常见、熟知的就是 www.pool.ntp.org/zo

JavaWeb系列二十: jQuery的DOM操作 下

jQuery的DOM操作 CSS-DOM操作多选框案例页面加载完毕触发方法作业布置jQuery获取选中复选框的值jQuery控制checkbox被选中jQuery控制(全选/全不选/反选)jQuery动态添加删除用户 CSS-DOM操作 获取和设置元素的样式属性: css()获取和设置元素透明度: opacity属性获取和设置元素高度, 宽度: height(), widt

python实现最简单循环神经网络(RNNs)

Recurrent Neural Networks(RNNs) 的模型: 上图中红色部分是输入向量。文本、单词、数据都是输入,在网络里都以向量的形式进行表示。 绿色部分是隐藏向量。是加工处理过程。 蓝色部分是输出向量。 python代码表示如下: rnn = RNN()y = rnn.step(x) # x为输入向量,y为输出向量 RNNs神经网络由神经元组成, python

人工智能做音乐

0 别人做的音乐demo https://yun.baidu.com/share/link?shareid=1799925478&uk=840708891 1 为什么人工智能能做音乐? 最下面蓝色的部分是你输入的音乐。 从上图可以看出,input是一个个的点,然后通过input来相互结合生成灰色的点,经过几层的连接之后,最后的Output就是新生成的音乐,也就是黄色的点。 把黄色的点

基于CTPN(tensorflow)+CRNN(pytorch)+CTC的不定长文本检测和识别

转发来源:https://swift.ctolib.com/ooooverflow-chinese-ocr.html chinese-ocr 基于CTPN(tensorflow)+CRNN(pytorch)+CTC的不定长文本检测和识别 环境部署 sh setup.sh 使用环境: python 3.6 + tensorflow 1.10 +pytorch 0.4.1 注:CPU环境

百度OCR识别结构结构化处理视频

https://edu.csdn.net/course/detail/10506

气象站的种类和应用范围可以根据不同的分类标准进行详细的划分和描述

气象站的种类和应用范围可以根据不同的分类标准进行详细的划分和描述。以下是从不同角度对气象站的种类和应用范围的介绍: 一、气象站的种类 根据用途和安装环境分类: 农业气象站:专为农业生产服务,监测土壤温度、湿度等参数,为农业生产提供科学依据。交通气象站:用于公路、铁路、机场等交通场所的气象监测,提供实时气象数据以支持交通运营和调度。林业气象站:监测林区风速、湿度、温度等气象要素,为林区保护和

C语言入门系列:探秘二级指针与多级指针的奇妙世界

文章目录 一,指针的回忆杀1,指针的概念2,指针的声明和赋值3,指针的使用3.1 直接给指针变量赋值3.2 通过*运算符读写指针指向的内存3.2.1 读3.2.2 写 二,二级指针详解1,定义2,示例说明3,二级指针与一级指针、普通变量的关系3.1,与一级指针的关系3.2,与普通变量的关系,示例说明 4,二级指针的常见用途5,二级指针扩展到多级指针 小结 C语言的学习之旅中,二级