深度学习入门篇--手把手教你用 TensorFlow 训练模型

2023-05-16

欢迎大家前往腾讯云技术社区,获取更多腾讯海量技术实践干货哦~

作者:付越

导语

Tensorflow在更新1.0版本之后多了很多新功能,其中放出了很多用tf框架写的深度网络结构(github.com/tensorflow/… ),大大降低了开发难度,利用现成的网络结构,无论fine-tuning还是重新训练方便了不少。最近笔者终于跑通TensorFlow Object Detection API的ssd_mobilenet_v1模型,这里记录下如何完整跑通数据准备到模型使用的整个过程,相信对自己和一些同学能有所帮助。

Object Detection API提供了5种网络结构的预训练的权重,全部是用COCO数据集进行训练,这五种模型分别是SSD+mobilenet、SSD+inception_v2、R-FCN+resnet101、faster RCNN+resnet101、faster RCNN+inception+resnet101。各个模型的精度和计算所需时间如下。下面及介绍下如何使用Object Detection去训练自己的模型。

这里TensorFlow的安装就不再说明了,网上的教程一大把,大家可以找到很详尽的安装TensorFlow的文档。

训练前准备:

使用protobuf来配置模型和训练参数,所以API正常使用必须先编译protobuf库,这里可以下载直接编译好的pb库(github.com/google/prot… ),解压压缩包后,把protoc加入到环境变量中:

$ cd tensorflow/models

$ protoc object_detection/protos/*.proto --python_out=.复制代码


(我是把protoc加到环境变量中,遇到找不到*.proto文件的报错,后来把protoc.exe放到models/object_detection目录下,重新执行才可以)

然后将models和slim(tf高级框架)加入python环境变量:

PYTHONPATH=$PYTHONPATH:/your/path/to/tensorflow/models:/your/path/to/tensorflow/models/slim复制代码


数据准备:

数据集需要转化成PASCAL VOC结构,API提供了create_pascal_tf_record.py,把VOC结构数据集转换成.record格式。不过我们发现更简单的方式,Datitran提供一种更简单生产.record格式的方法。

首先需要先要标注图像相应标签,这里可以使用labelImg工具。每标注一张样本,即生成一个xml的标注文件。然后,把这些标注的xml文件,按训练集与验证集分别放置到两个目录下,在Datitran提供了xml_to_csv.py脚本。这里只要指定标注的目录名即可。接下来,然后需要我们把对应的csv格式转换成.record格式。

def main():
    # image_path = os.path.join(os.getcwd(), 'annotations')
    image_path = r'D:\training-sets\object-detection\sunglasses\label\test'
    xml_df = xml_to_csv(image_path)
    xml_df.to_csv('sunglasses_test_labels.csv', index=None)
    print('Successfully converted xml to csv.')复制代码


调用generate_tfrecord.py,注意要指定--csv_input与--output_path这两个参数。执行下面命令:

python generate_tfrecord.py --csv_input=sunglasses_test_labels.csv --output_path=sunglass_test.record复制代码


这样就生成了训练及验证用的train.record与test.record。接下来指定标签名称,仿照models/ object_detection/data/ pet_label_map.pbtxt,重新创建一个文件,指定标签名。

item {
  id: 1
  name: 'sunglasses'
}复制代码


训练:

根据自己的需要,选择一款用coco数据集预训练的模型,把前缀model.ckpt放置在待训练的目录,这里meta文件保存了graph和metadata,ckpt保存了网络的weights,这几个文件表示预训练模型的初始状态。

打开ssd_mobilenet_v1_pets.config文件,并做如下修改:

  1. num_classes:修改为自己的classes num

  1. 将所有PATH_TO_BE_CONFIGURED的地方修改为自己之前设置的路径(共5处)

其他参数均保持默认参数。

准备好上述文件后就可以直接调用train文件进行训练。

python object_detection/train.py \
--logtostderr \
--pipeline_config_path= D:/training-sets /data-translate/training/ssd_mobilenet_v1_pets.config \
--train_dir=D:/training-sets/data-translate/training复制代码


TensorBoard监控:

通过tensorboard工具,可以监控训练过程,输入西面指令后,在浏览器输入localhost:6006(默认)即可。

tensorboard --logdir= D:/training-sets/data-translate/training复制代码


这里面有很多指标曲线,甚至有模型网络架构,笔者对于这里面很多指标含义还没有弄明白,不过感觉出TensorBoard这个工具应该是极其强大。不过我们可以通过Total_Loss来看整体训练的情况。

从整体上看,loss曲线确实是收敛的,整体的训练效果还是满意的。另外,TensorFlow还提供了训练过程中利用验证集验证准确性的能力,但是笔者在调用时,仍有些问题,这里暂时就不详细说明了。

Freeze Model模型导出:

查看模型实际的效果前,我们需要把训练的过程文件导出,生产.pb的模型文件。本来,tensorflow/python/tools/freeze_graph.py提供了freeze model的api,但是需要提供输出的final node names(一般是softmax之类的最后一层的激活函数命名),而object detection api提供提供了预训练好的网络,final node name并不好找,所以object_detection目录下还提供了export_inference_graph.py。

python export_inference_graph.py \
--input_type image_tensor
--pipeline_config_path D:/training-sets /data-translate/training/ssd_mobilenet_v1_pets.config \
--trained_checkpoint_prefix D:/training-sets /data-translate/training/ssd_mobilenet_v1_pets.config /model.ckpt-* \
--output_directory D:/training-sets /data-translate/training/result复制代码


导出完成后,在output_directory下,会生成frozen_inference_graph.pb、model.ckpt.data-00000-of-00001、model.ckpt.meta、model.ckpt.data文件。

调用生成模型:

目录下本身有一个调用的例子,稍微改造如下:

import cv2
import numpy as np
import tensorflow as tf
from object_detection.utils import label_map_util
from object_detection.utils import visualization_utils as vis_util


class TOD(object):
    def __init__(self):
        self.PATH_TO_CKPT = r'D:\lib\tf-model\models-master\object_detection\training\frozen_inference_graph.pb'
        self.PATH_TO_LABELS = r'D:\lib\tf-model\models-master\object_detection\training\sunglasses_label_map.pbtxt'
        self.NUM_CLASSES = 1
        self.detection_graph = self._load_model()
        self.category_index = self._load_label_map()

    def _load_model(self):
        detection_graph = tf.Graph()
        with detection_graph.as_default():
            od_graph_def = tf.GraphDef()
            with tf.gfile.GFile(self.PATH_TO_CKPT, 'rb') as fid:
                serialized_graph = fid.read()
                od_graph_def.ParseFromString(serialized_graph)
                tf.import_graph_def(od_graph_def, name='')
        return detection_graph

    def _load_label_map(self):
        label_map = label_map_util.load_labelmap(self.PATH_TO_LABELS)
        categories = label_map_util.convert_label_map_to_categories(label_map,
                                                                    max_num_classes=self.NUM_CLASSES,
                                                                    use_display_name=True)
        category_index = label_map_util.create_category_index(categories)
        return category_index

    def detect(self, image):
        with self.detection_graph.as_default():
            with tf.Session(graph=self.detection_graph) as sess:
                # Expand dimensions since the model expects images to have shape: [1, None, None, 3]
                image_np_expanded = np.expand_dims(image, axis=0)
                image_tensor = self.detection_graph.get_tensor_by_name('image_tensor:0')
                boxes = self.detection_graph.get_tensor_by_name('detection_boxes:0')
                scores = self.detection_graph.get_tensor_by_name('detection_scores:0')
                classes = self.detection_graph.get_tensor_by_name('detection_classes:0')
                num_detections = self.detection_graph.get_tensor_by_name('num_detections:0')
                # Actual detection.
                (boxes, scores, classes, num_detections) = sess.run(
                    [boxes, scores, classes, num_detections],
                    feed_dict={image_tensor: image_np_expanded})
                # Visualization of the results of a detection.
                vis_util.visualize_boxes_and_labels_on_image_array(
                    image,
                    np.squeeze(boxes),
                    np.squeeze(classes).astype(np.int32),
                    np.squeeze(scores),
                    self.category_index,
                    use_normalized_coordinates=True,
                    line_thickness=8)

        cv2.namedWindow("detection", cv2.WINDOW_NORMAL)
        cv2.imshow("detection", image)
        cv2.waitKey(0)

if __name__ == '__main__':
    image = cv2.imread('image.jpg')
    detecotr = TOD()
    detecotr.detect(image)复制代码


下面是一些图片的识别效果:

相关阅读

当强化学习遇见泛函分析

google cloud :穷人也能玩深度学习

[ I am Jarvis ] :聊聊 FaceID 背后的深度学习视觉算法

此文已由作者授权腾讯云技术社区发布,转载请注明文章出处
原文链接:https://cloud.tencent.com/community/article/351424


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

深度学习入门篇--手把手教你用 TensorFlow 训练模型 的相关文章

随机推荐

  • 介绍:成为一名 Jenkins 贡献者的旅程

    转自Jenkins 中文社区 作为一名软件工程师 xff0c 这些年来在我工作过的不同公司里用到过许多开源软件 xff08 包括框架 库 工具等 xff09 然而 xff0c 在此之前我从没有以一名贡献者的身份参与过开源项目 自从我向 Je
  • 国内嵌入式公司比较排名

    随着 ARM内核的应用越来越广泛 xff0c 从手机到电视机 xff0c 从大型工控设备到小型的家电应用 xff0c 都能找到 ARM内核的嵌入式产品 而由此引领了一番全球嵌入式领域火热的变化 xff0c 当然 xff0c 国内的嵌入式领域
  • MYSQL常用操作及python操作MYSQL常用类

    Mysql 常见操作 数据库操作 创建数据库 create database fuzjtest 删除数据库 drop database fuzjtest 查询数据库 show databases 切换数据库 use databas 1231
  • Windows Server 2008的认证监视工具

    管理证书的一个主要目标是获得企业安全的一种高级水平 应当认真对待身份和访问管理问题 在本文中 xff0c 笔者将简要地讨论认证授权 xff0c 然后探讨使用特定的证书监视工具 xff08 如PKIView msc和certutil exe
  • (转)为什么需要正则表达式 by 王珢

    为什么需要正则表达式 by 王垠 学习Unix最开头 xff0c 大家都学过正则表达式 regexp 可是有没有人考虑过我们为什么需要正则表达式 xff1f 正则表达式本来的初衷是用来从无结构的字符串中提取信息 xff0c 殊不知这正好是U
  • 无法启动程序,因为计算机丢失D3DCOMPILER_47.dll 的解决方法

    这个原因应该是windows update在更新的时出现错误导致的 解决方法是安装 KB4019990 更新包 网址如下 xff1a http www catalog update microsoft com Search aspx q 6
  • KNN cosine 余弦相似度计算

    coding utf 8 import collections import numpy as np import os from sklearn neighbors import NearestNeighbors def cos vect
  • sqlserver2017 重装过程中出现“无法找到数据库引擎启动句柄”错误的解决办法...

    sqlserver数据库引擎修改账号名 xff0c 详情参考 xff1a http blog 51cto com djclouds 2089047 utm source 61 oschina app 在SQL Server安装期间 xff0
  • python基本常用语法&函数&数据结构

    1 Python概述 1989年12月 Google工程师 Guido van Rossum为了打发圣诞节假期 开发了ABC语言的后继 并以他自己喜欢的一个情景剧 Monty Python s Flying Circus命名 Python
  • R语言中对文本数据进行主题模型topicmodeling分析

    主题建模 在文本挖掘中 xff0c 我们经常收集一些文档集合 xff0c 例如博客文章或新闻文章 xff0c 我们希望将其分成自然组 xff0c 以便我们可以分别理解它们 主题建模是对这些文档进行无监督分类的一种方法 xff0c 类似于对数
  • NLTK基础基础教程学习笔记(十四)

    对于文本分类 xff0c 最简单的定义就是基于文本内容来对其进行分类 通常情况算法是根据数字 变量特征来写的 先从https archive ics uci edu ml datasets SMS 43 SPam 43 Collection
  • ***故障错误代码列表

    故障错误代码列表 724 IPX 协议无法在此端口拨出 xff0c 因为此计算机是 IPX 路由器 725 IPX 协议无法在此端口拨入 xff0c 因为未安装 IPX 路由器 726 IPX 协议不能同时在一个以上的端口上用于拨出 727
  • 如何下载网页所有资源(附源码)

    nodejs扒取html页面中所有链接资源 前言 xff1a 总有些人 xff0c 想下载一个插件 xff0c 能直接获取浏览器显示页面的所有资源 也就是下载一个其他人的网站 xff0c 但是不想一个个复制链接的内容 xff0c 原因大致有
  • shiro错误:Subject does not have permission [user:select]

    使用的是jdbcRealm xff0c 在数据库中有相应的权限 错误日志 xff1a org apache shiro authz UnauthorizedException Subject does not have permission
  • Google发布SSLv3漏洞简要分析报告

    摘要 xff1a 今天上午 xff0c Google发布了一份关于SSLv3漏洞的简要分析报告 根据Google的说法 xff0c 该漏洞贯穿于所有的SSLv3版本中 xff0c 利用该漏洞 xff0c 黑客可以通过中间人攻击等类似的方式
  • android notification应用

    public void checkConnectionStatusNotification String notificationText Context context String ns 61 Context NOTIFICATION
  • APK动态加载框架 https://github.com/singwhatiwanna/dynamic-load-apk

    https github com singwhatiwanna dynamic load apk 转载于 https www cnblogs com sunfb p 4607624 html
  • ROS学习之package.xml

    目录 概述格式2 xff08 推荐 xff09 基本结构所需标签依赖关系Metapackages附加标签格式1 xff08 遗产 xff09 基本结构所需标签构建 xff0c 运行和测试依赖关系Metapackages附加标签 概述 该软件
  • ESP8266模块接线篇 (正常运行&烧录固件)

    刚拿到这个模块时 xff0c 连上线一会能用 xff0c 一会不能用 xff0c 开始也一直不知道是什么原因 xff0c 后来仔细了解了8266的引脚功能 xff0c 算是解决了这个问题 xff0c 不仅学会了模块正常工作下的调试 xff0
  • 深度学习入门篇--手把手教你用 TensorFlow 训练模型

    欢迎大家前往腾讯云技术社区 xff0c 获取更多腾讯海量技术实践干货哦 作者 xff1a 付越 导语 Tensorflow在更新1 0版本之后多了很多新功能 xff0c 其中放出了很多用tf框架写的深度网络结构 xff08 github c