深度学习中的目标识别

2023-11-16

 博主简介

博主是一名大二学生,主攻人工智能研究。感谢让我们在CSDN相遇,博主致力于在这里分享关于人工智能,c++,Python,爬虫等方面知识的分享。 如果有需要的小伙伴可以关注博主,博主会继续更新的,如果有错误之处,大家可以指正。

专栏简介:   本专栏主要研究计算机视觉,涉及算法,案例实践,网络模型等知识。包括一些常用的数据处理算法,也会介绍很多的Python第三方库。如果需要,点击这里订阅专栏   。

给大家分享一个我很喜欢的一句话:“每天多努力一点,不为别的,只为日后,能够多一些选择,选择舒心的日子,选择自己喜欢的人!”


目录

编辑前言

​编辑目标识别的概念

​编辑神经网络的使用 

​编辑构建数据集的方法

编辑搭建神经网络

编辑训练及效果评估

​编辑解决过拟合

​编辑数据增强

​编辑迁移学习


前言

前面我们介绍了深度学习中的神经网络,那么本届我们就开始正式的进入深度学习中了,前面我们介绍过计算机视觉的四大任务:目标识别、目标检测、目标跟踪和目标分割。其中最基础的就是目标识别,几乎所有的计算机视觉的知识都是在目标识别问题上构建的,也就是说目标识别问题构成了整个计算机视觉的地基,如果我们不能解决识别问题,就无法建造我们的计算机视觉大厦。

本章,我们就通过一个项目实战来全面认识目标识别。本节我们用到的数据集:数据集下载

目标识别的概念

目标识别的概念在前面我们就已经介绍过了,计算机视觉之所以叫做计算机视觉,这是用为这是基于计算机,模仿人类视觉的一种概念模型。但是计算机始终计算机,它并不能像人一样直接分别出物体,而是对物体进行标记。比如说,我们对一堆照片进行识别的时候,里面的猫识别成功后标记为1,如果是狗就标记为2.也就是他的识别是已经规划好的数据,并不能随机应变。

其次,计算机输出的是物体类别的概率,例如,第一类的概率为0.9,第二类的概率为0.1,最后取最大概率对应的类别进行输出,这与人类识别物体是不同的,从这方面可以看出,计算机是非常严谨的,应为他不会认为某一个类别的概率为100%。

由于计算机对于每一类都输出概率,就出现了一个引申概念:top k准确率,顾名思义就是将输出概率最大的k个类别输出,只要猜对其中的一个,就认为计算机猜对了,这在目标识别的评价中很常见,因为一张图片中往往有多个目标,而标签只有一个,所以简单的才一次决定输赢是不合理的,k的值由类别的数量决定,一般取5~10.

神经网络的使用 

构建数据集的方法

在进行神经网络的学习中,数据集的使用是非常重要的,在这个过程中,我们可以使用开源的数据集,也可以自己创建数据集。下面我们准备对猫狗大战数据集进行使用。

(1)、将图片构建成同样的大小,这是用与一般的卷积神经网络需要输入图片的大小固定。

(2)、对每张图片构建数据标签,对于猫狗大战,图片猫标记为0,图片狗标记为1.

(3)、将数据集分为训练集和测试集,一般比例为4:1,或5:1.为了防止过拟合,我们需要在训练集上训练,之后再测试集测试,当训练集和测试集最终表现差不多的时候,我们就可以认为模型没有过拟合,而最终的结果也需要使用测试集上的准确率。

(4)、分批次,对于深度学习,我们一般使用小批次梯度下降算法,所以我们需要确定每个批次图片的数量,数量需要更具我们的CPU或GPU的内存来决定,一般取64或129张图片为一个批次。

(5)、随机打乱训练集的图片顺序,为了提升训练结果,每训练完一遍数据集后,我们需要对数据集进行随机打乱顺序,确保每个批次输入的图片都是完全随机的,否则很容易陷入局部极值。

来吧,展示,上代码:

import tensorflow as tf
import os
#读取数据集并构建数据集
_URL='https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip'
#解压
path_to_zip=tf.keras.utils.get_file('cats_and_dogs.zip',origin=_URL,extract=True)
PATH=os.path.join(os.path.dirname(path_to_zip),'cats_and_dogs_filtered')
#分为训练集和测试集
train_dir=os.path.join(PATH,'train')
validation_dir=os.path.join(PATH,'validation')

#分为猫图片和狗图片
train_cats_dir=os.path.join(train_dir,'cats')
train_dogs_dir=os.path.join(train_dir,'dogs')
validation_cats_dir=os.path.join(validation_dir,'cats')
validation_dogs_dir=os.path.join(validation_dir,'dogs')
#批次大小
batch_size=64
epochs=20
#图片输入大小为150*150
IMG_HEIGHT=150
IMG_WIDTH=150
#从目录生成数据集,shuffle表示随机打乱数据顺序
train_data_gen=tf.keras.preprocessing.image.ImageDataGenerator()
train_data_gentor=train_data_gen.flow_from_directory(batch_size=batch_size,directory=train_dir,
                                                                                   shuffle=True,target_size=(IMG_HEIGHT,IMG_WIDTH),class_mode='binary')
val_data_gen=tf.keras.preprocessing.image.ImageDataGenerator()
val_data_gentor=val_data_gen.flow_from_directory(batch_size=batch_size,directory=validation_dir
                                                                                 ,target_size=(IMG_HEIGHT,IMG_WIDTH),class_mode='binary')

搭建神经网络

接下来我们需要根据图片的大小搭建一个合适的神经网络,对于初学者,建议使用10层左右的神经网络。一般来说,只对神经网络的第一层和最后一层有输入和输出大小的限制。例如,第一层的输入需要图片的形状,而最后一层的输出需要为物体类别数量。

第一层:3x3卷积层,32个输出通道,输入形状为图片的形状:150x150x3,填充1个像素,激活函数为relu()。

第二层:2x2的最大池化层。

第三层:3x3的卷积层,64个输出通道,填充一个像素,激活函数为relu()。

第四层:2x2的最大池化层。

第五层:3x3的卷积层,64个输出通道,填充一个像素,激活函数为relu()。

第六层:2x2的最大池化层。

第七层:输出为256维的全连接层,激活函数为relu()。

第八层:输出为1维的全连接层,激活函数为sigmoid()。


#搭建神经网络
#每一行代表神经网络的一层
model=tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(32,3,padding='same',activation='relu',input_shape=(IMG_HEIGHT,IMG_WIDTH,3)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(64,3,padding='same',activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(64,3,padding='same',activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(256,activation='relu'),
    tf.keras.layers.Dense(1,'sigmoid')
])

训练及效果评估

为了防止可能出现错误,我们先不要再整个数据机上训练,而是在小规模的数据集上训练,保证模型可以在小规模数据集上过拟合,进而使用整个数据集。

接下来就可以训练了,我们需要选择优化器,一般来说Adam优化器可以解决大部分问题,损失函数我们一般选择交叉熵损失,在本例中我们使用二分类交叉熵。训练过程中我们可以美国一定部署把当前损失和准确率记录下来,以此来判断模型训练的效果。当我们发现损失函数不再下降时应该即时停止训练。


#训练
#编译模型,输入优化器,损失函数,训练过程需要保存的特征
model.compile(optimizer='adam',
              loss='binary_crossentropy',
              metrics=['accuracy'])
#训练
history=model.fit_generator(
    train_data_gen,
    steps_per_epoch=100//batch_size, #每轮的步数
    epochs=epochs,
    validation_data=val_data_gen,
    validation_steps=100//batch_size
)

解决过拟合

当我们使用的数据集比较小的时候,就需要用一定的方法防止过拟合。所以可以通过减小模型参数来解决过拟合问题。


model1=tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(32,3,padding='same',activation='relu',input_shape=(IMG_HEIGHT,IMG_WIDTH,3)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(32,3,padding='same',activation='relu'),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128,activation='relu'),
    tf.keras.layers.Dense(1,activation='sigmoid')
])

第二种方法是增加正则化项,常用的为L1和L2正则化方法。在神经网络中我们一般用L2正则化方法,我们需要调整权重系数,有一个神奇的值0.0005,此值可以作为大部分问题的权重系数。


model=tf.keras.Sequential([
    tf.keras.layers.Conv2D(32,3,padding='same',activation='relu',input_shape=(IMG_HEIGHT,IMG_WIDTH,3),kernel_regularizer=tf.keras.regularizers.l2(l=0.0005)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(64,3,padding='same',activation='relu',input_shape=(IMG_HEIGHT,IMG_WIDTH,3),kernel_regularizer=tf.keras.regularizers.l2(l=0.0005)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Conv2D(64,3,padding='same',activation='relu',input_shape=(IMG_HEIGHT,IMG_WIDTH,3),kernel_regularizer=tf.keras.regularizers.l2(l=0.0005)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(256,activation='relu',kernel_regularizer=tf.keras.regularizers.l2(l=0.0005)),
    tf.keras.layers.Dense(1,activation='sigmoid',kernel_regularizer=tf.keras.regularizers.l2(l=0.0005))
])

第三种方法是加入Dropout层,Dropout层的原理在前面已经讲过,一般来说Dropout层的效果比前两个更好,我们需要调整删除神经元的概率,一般设为0.5.


#增加Dropout层
model=tf.keras.Sequential([
    tf.keras.layers.Conv2D(32,3,padding='same',activation='relu',input_shape=(IMG_HEIGHT,IMG_WIDTH,3)),
    tf.keras.layers.MaxPooling2D(),
    tf.keras.layers.Dropout(0.5), #设置Dropout层
    tf.keras.layers.Conv2D(64,3,padding='same',activation='relu'),
    tf.keras.layers.Dropout(0.5), #Dropout层
    tf.keras.layers.Conv2D(64,3,padding='same',activation='relu'),
    tf.keras.layers.MaxPooling2D(), #池化层
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(256,activation='relu'), #全连接层
    tf.keras.layers.Dropout(0.5),
    tf.keras.layers.Dense(1,activation='sigmoid')

])

当然,我们可以把前几个方法结合在一起,组成一个最佳的模型,最后,对于深度学习,还有一个非常重要的超参数,就是学习效率。一般来说,我么可以从0.001开始调整,当学习率太高时,我们难以得到高精度的结果;当学习率太小时,训练时间很长。



#调整学习率
#学习率先用0.001训练
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),loss='sparse_categorical_crossentropy',metrics=['accuracy'])
#学习率调小为原来的1/10
model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.0001),loss='sparse_categorical_crossentropy',metrics=['accuracy'])

数据增强

果我们使用的数据非常少,那么我们得到的数据就不会很准确。这时候就需要数据增强,其实说简单点,就是将数据集增多,例如你有2000张图片,我们可以翻转,变色等方式改变图片,以此达到增加数据。在之后的训练中,每轮如果还是用2000张图片进行训练,但是每一轮的图片都是不同的。经过了随机变换,得到的数据模型会更加准确。


#随即水平反转
image_gen=tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255,horizontal_flip=True)
#随机竖直翻转
image_gen=tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255,vertical_flip=True)
#随即旋转
image_gen=tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255,rotation_range=45)
#随即缩放,zoom_range在0~1表示图片缩放比例范围[1-zoom_range,1+zoom_range]
image_gen=tf.keras.preprocessing.image.ImageDataGenerator(rescale=1./255,zoom_range=0.5)
#全部应用
image_gen_train=tf.keras.preprocessing.image.ImageDataGenerator(
    rescale=1./255,
    rotation_range=45,
    width_shift_range=.15,
    height_shift_range=.15,
    horizontal_flip=True,
    vertical_flip=True,
    zoom_range=0.5
)

迁移学习

迁移学习是什么?

其实说的简单点就是借用别人的模型来进行训练自己的任务,优点就是速度快,效果好。就比如说,书本上的知识很详细,很多,但是理解起来可能没那么快,但是如果有一个人给你讲解,那是不是就很快能理解。也就是吸收别人的东西。

迁移学习主要有两种方法:第一种叫微调(Fine Tune),顾名思义就是对已经训练好的模型进行细微的调整,一般我们会调整整个模型的最后几层;

第二种方法叫作加层,就是在模型最后增加几层,然后对这几个层进行训练即可。

下面我借用ResNet50模型来简单的介绍一下如何使用迁移学习:



#选则基础模型
base_model=tf.keras.applications.ResNet50(weights='imagenet')
base_model.summary()
#将基础模型的参数设置为不可训练
base_model.trainable=False
#加层
prediction_layer1=tf.keras.layers.Dense(128,activation='relu')
prediction_layer2=tf.keras.layers.Dense(1,activation='sigmoid')
model=tf.keras.Sequential([
    base_model,
    prediction_layer1,
    prediction_layer2
])
#微调
fine_tune_at=150
for layer in base_model.layers[fine_tune_at:]:
    layer.trainable=True
base_model.summary()
prediction_layer=tf.keras.layers.Dense(1,activation='sigmoid')
model=tf.keras.Sequential([
    base_model,
    prediction_layer
])

 

 

好了,这里我们已经初步认识了如何搭建自己的神经网络和数据集以及一些啥=常规的方法,下一节我们就开始学习神经网络中的视觉了。拜拜了你嘞!

点赞加关注不迷路

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

深度学习中的目标识别 的相关文章

随机推荐

  • 3D游戏编程与设计作业——游戏智能

    一 作业要求 坦克对战游戏AI设计 从商店下载游戏 Kawaii Tank 或 其他坦克模型 构建AI对战坦克 具体要求 使用 感知 思考 行为 模型 建模 AI 坦克 场景中要放置一些障碍阻挡对手视线 坦克要放置一个矩阵包围盒触发器 保证
  • 如何解决Exception in thread “main” java.sql.SQLException: Statement.executeUpdate() or Statement.execute

    场景 黑马程序员javaweb基础教程 视频jdbc快速入门时出现的报错 问题描述 Exception in thread main java sql SQLException Statement executeUpdate or Stat
  • late_initcall和module_init

    late initcall和module init 分类 linux驱动程序设计 2012 11 04 15 14 3680人阅读 评论 0 收藏 举报 所有的 init函数在区段 initcall init中还保存了一份函数指针 在初始化
  • unittest+ddt自动化测试相关知识点

    unittest是Python单元测试框架 主要分为 测试用例TestCase 一个完整的测试流程 测试套件TestSuite 多个测试用例集合在一起 执行 结果呈现TextTestRunner 用例运行和结果呈现 结果呈现常用HtmlTe
  • 环境配置tips

    一 MySQL在Linux下数据库名 表名 列名 别名大小写规则是这样的 1 数据库名与表名是严格区分大小写的 2 表的别名是严格区分大小写的 3 列名与列的别名在所有的情况下均是忽略大小写的 4 变量名也是严格区分大小写的 修改不区分大小
  • OpenWrt系统无法进入Luci解决办法之一

    当在OpenWrt系统重启后 打开Luci后台时有时可能会遇到以下错误报告 usr lib lua luci dispatcher lua 577 bad argument 1 to pairs table expected got nil
  • cocos2d-x 4.0 版本修改点

    转自 https discuss cocos2d x org t cocos2d x v4 0 released 48487 Features support metal on iOS macOS use CMake for all pla
  • vue : 无法加载文件 \Node.js\node_global\vue.ps1。未对文件 \Node.js\node_global\vue.ps1 进行数字签名。无法在当前系统上运行该脚本。

    vue 无法加载文件 D Node js node global vue ps1 未对文件 D Node js node global vue ps1 进行数字签名 无法在当前系统上运行该脚本 最近在使用powershell下使用 vue
  • pandas的行列获取/pandas iloc和loc的使用/如何获取pandas的行和列

    Pandas行和列的获取 由于平时没有系统的学习pandas 导致在实际应用过程中 对于获取df中的行和列经常出现问题 于是总结一下 供自己以后参考 参考的书籍在线版链接 利用 Python 进行数据分析 第 2 版 0 查看手册 请当你看
  • 深度学习之基于VGG16与ResNet50实现鸟类识别

    鸟类识别在之前做过 但是效果特别差 而且ResNet50的效果直接差到爆炸 这次利用VGG16与ResNet50的官方模型进行鸟类识别 1 导入库 import tensorflow as tf import numpy as np imp
  • ubuntu安装/查看已安装包的方法

    自己折腾ubuntu安装包来着 发现一篇文章非常实用 将apt get和dpkg等命令的参数讲解非常全面 于是转载过来 中文的比英文的帮助看着还是顺手一点 原文链接 http www cnblogs com forward archive
  • vue 给页面局部加水印和全部加水印

    局部加水印 在公共类js下 新建一个watermask js 代码如下 export default tool js addWaterMark const strArr localStorage getItem loginUserName
  • 图的深度优先遍历(Depth First Search)

    图的深度优先遍历 Depth First Search 基本思想 类似于二叉树的先序遍历 假设图中所有结点均未被访问 从初始结点访问 访问其第一个邻接结点 接着以被访问的邻接结点作为初始结点 访问它的第一个邻接结点 递归的过程 算法步骤 访
  • Cesium快速入门

    Cesium是全世界使用最广泛的3D WebGIS引擎 国内有若干个GIS厂家的3D GIS引擎也是基于Cesium进行开发 随着国家 新基建 数字化 战略的不断发展深化 越来越多的城市数字化项目需要用上3D GIS引擎 对Web端而言 C
  • 简单记录搭建SSM(Spring+Spring MVC+Mybatis)整合

    业务层 View 数据显示 Controller 业务控制 执行成功怎么处理 执行失败怎么处理 Service 业务处理 Model 数据库相关实体类 增删改查 工程搭建 第一步 创建Maven web工程 点击finish创建完毕工程 第
  • C++在路径下新建一个指定名称的文件夹

    在保存数据是 我们希望将新生成的数据单独保存在一个文件夹中 其实我们可以通过程序自动生成一个指定名称的文件夹 存放数据 而不必提前手动新建文件夹并修改名称 代码实现的方法也很简单 但是需要注意的是该方法需要包含windows h头文件 代如
  • 树莓派——制作静态库、动态库

    库的特点 库是可执行代码的二进制形式 即将源代码转换成二进制的源代码 相当于对源代码进行了加密 别人可以看见库使用库 但是看不见库的源代码 2种类型库 静态库 libxxx a 动态库 libxxx so 静态库 在程序执行前就加入到目标程
  • Spring IoC是什么

    IoC是什么 Ioc Inversion of Control 即 控制反转 不是什么技术 而是一种设计思想 在Java开发中 Ioc意味着将你设计好的对象交给容器控制 而不是传统的在你的对象内部直接控制 如何理解好Ioc呢 理解好Ioc的
  • FDTD solutions——TFSF(全场散射场)光源及斜入射

    每天一遍 防止忘记 初始建立仿真文件 1 建立物理结构 几何结构 材料特性 2 定义仿真区域 边界条件 3 设置激励源 光源 4 设置监视器 至少使用一个时间监视器 分析组 只记录需要的数据 运行与仿真 1 运行仿真文件 分布式并行运算 并
  • 深度学习中的目标识别

    博主简介 博主是一名大二学生 主攻人工智能研究 感谢让我们在CSDN相遇 博主致力于在这里分享关于人工智能 c Python 爬虫等方面知识的分享 如果有需要的小伙伴可以关注博主 博主会继续更新的 如果有错误之处 大家可以指正 专栏简介 本