Category Archives: AI

训练一个跑在嵌入式环境的YOLOv4模型检测人,猫,狗

By | May 31, 2020

2020年4月,Alexey Bochkovskiy在他的Github放出了YOLO检测模型的第四个版本:YOLOv4,比YOLOv3计算量变化不大的前提下,大幅提升了算法效果,在MS COCO数据集上mAP@0.5从33%提升到43.5%。 官方提供训练好的权重文件大小为246MB,提供了80类物体的检测,在PC上通过CPU运行608×608尺寸推理的耗时则达到了2秒多,要在嵌入式环境运行完全无法达到实时性能要求。如果我们只关心某几类物体,能否进行一些优化呢? 我挑选了三类目标:人、猫、狗进行实验。在MS COCO 2017数据集上训练一个可以在VisionSeed(1T FP16算力)上实时运行的YOLOv4-nano模型。 MS COCO 2017包含80类不同的目标框标注,训练集和验证集图片数量如下: 123456+——-+——–+——–+——+——+—–+ |       |  all   | person | cat  | dog  | … | +——-+——–+——–+——+——+—–+ | train | 118287 |  64115 | 4114 | 4385 | … | | val   |   5000 |   2693 |  184 |  177… Read More »

Category: AI

在Ubuntu 18.04上安装深度学习训练环境

By | May 5, 2020

0x00:前传 去年底又入了一台DELL,这次是因为需要GPU训模型,正好Nvidia出了基于Turing核心的GTX-1660Ti用于笔记本,比2060少了Tensor Core,但显存一样是6G,想想Tensor Core的意义在于FP16加速训练,但半精度训练配置比较繁琐,暂时不折腾也罢,于是6799入了这台Dell-G3-3590游戏本,被我装上Ubuntu训模型,训练速度比CPU快了20~30倍,大概有V100单卡的50%,而价格只及V100的1/10,非常适合用来学习。 第一次折腾CUDA,实现了CUDA9和CUDA10共存,能同时支持下面两个环境,把安装过程记录一下。 tensorflow-gpu 1.9:CUDA9 + cuDNN 7.0 darknet:CUDA10 + cuDNN 7.5 0x01:理论 CUDA分为两个部分,内核态的驱动(.ko)和用户态的动态链接库(.so)。CUDA的内核态驱动是高版本兼容低版本。而一般说的CUDA9或者CUDA10是指用户态动态链接库的版本,跨版本不兼容,因此,理论上只需要安装一个高版本的内核态驱动,然后通过将CUDA的用户态库安装到不同目录中来达到多版本共存目的。 内核态的驱动版本号一般是3xx.mm或4xx.mm,例如,现在最新的是440.64,在Ubuntu下,由nvidia-driver-4xx和它的依赖包提供。 用户态的动态链接库,其实是一系列的功能库组成的集合,例如cudart, cublas, curand, cufft等,由cuda-libraries-10-0和它的依赖包提供。 还有一个部分,是CUDA内核函数编译器(此内核并非操作系统内核,应该是源于filer的kernel概念,这里指运行在GPU中的算子),由cuda-compiler-10-0和它的依赖包提供。如果需要运行自定义的CUDA kernel函数,就需要安装这个包,例如编译darknet就需要它。 0x02:现状 Ubuntu有两个源提供CUDA驱动和库,一个是Ubuntu的官方源,另一个是Nvidia提供的源。Nvidia源比较新,并且提供了CUDA各个版本共存的机制,所以经过一番尝试后,最终选择了Nvidia源。 0x03:安装CUDA内核态的驱动和CUDA10 在新立得包管理器(synaptic)中,打开“设置”->“软件库”->“其他软件”,点击“添加”,分别添加下面两个Nvidia源,然后关闭并自动刷新: 12deb http://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64 / deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64 / 如果是手动编辑/etc/apt/source.list并遇到如下错误: 1W: GPG error: https://developer.download.nvidia.cn/compute/machine-learning/repos/ubuntu1804/x86_64  Release: The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY F60F4B3D7FA2AF80 可通过命令自动添加证书:… Read More »

Category: AI

TensorFlow中Batch Normalization的两个大坑

By | October 5, 2019

尝试用Inception和MobileNet训练一个二分类模型,折腾了几天,发现MobileNet很难收敛,而Inception训练虽然收敛,但测试时结果却很糟糕。 最后排查下来,只要在测试时把is_training设为True,看起来就正常了,但只要is_training是False,结果就不对。 很容易就排查到了一个问题,从零构建的代码使用如下的方式创建优化器(实际上是错误的): 1    self.train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(self.loss, global_step=self.global_steps) Inception和MobileNet使用的Batch Normalization层需要在训练时统计mini batch的均值和方差并进行滑动更新;在推理时是不进行统计和更新的,而是使用训练时统计好的值。这就要求训练时要进行额外的操作,正确的写法是这样: 123    extra_update_ops = tf.get_collection(tf.GraphKeys.UPDATE_OPS)     with tf.control_dependencies(extra_update_ops):         self.train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(self.loss, global_step=self.global_steps) 让人意外的是,改正了这个问题后,测试不收敛的问题还是一直萦绕着,虽然多个链接都说按照上面修改后,is_training为False就没问题了[1] [2],但我面临的情况并非如此。 现在的现象仍然是:训练逐渐趋于收敛(accuracy > 0.99),但测试时却是非常奇怪的结果(accuracy 约等于 0.5),而且对任何输入图片,都输出固定的结果,比如[0.503, 0.497] 左图:训练收敛 右图:测试不收敛 在slim.mobilenet源码中,is_training只出现了4次,除影响bn层外,还影响了dropout层,通过对照实验很快排除了dropout层,问题锁定在了bn层。bn层有很多参数,其中一个decay参数是控制统计滑动平均的保留率,在mobilenet和inception的实现中,对应于batch_norm_decay,它的默认值为0.9997,逼近速度非常慢,如果我们训练集很小,训练次数也只很少(几千次)的话,均值和方差几乎没有得到更新!奇怪的是,只有很少的文章提到了这个问题[3] 12    with slim.arg_scope(mobilenet_v1.mobilenet_v1_arg_scope(batch_norm_decay=0.95)):         self.prediction, ep = mobilenet_v1.mobilenet_v1(xs_reshaped, num_class, dropout_keep_prob=self.keep_prob, is_training=self.is_trainning,… Read More »

Category: AI