Record something about DL

2023-05-16

这篇文章算是DL实践杂谈吧,主要是想把自己模型调优和复现算法遇到的一些坑总结一下(里面的一行字可能是我当时花费了一周甚至更长时间得到的总结),希望能对读者有所帮助。

一、熟悉数据

模型是数据的浓缩版----Andrew NG的二八定律,即80%的数据+20%的=更好的AI

​ 对于新上手的一任务来说,需要熟悉你的数据。拿检测任务来说,可以写个可视化代码查看标注是否合理,查看一下待检测物体的大小分布情况(例如anchor的预设),查看一下图片大小,查看类别分布情况(例如是否有极端的分布)等等。

二、算法选型

​ 在接到一个新领域的新任务时,需要调研相关领域算法,对该领域的发展有个大概的了解,掌握一些关键算法(比如历年的SOTA)的思路。虽然调研需要花费一些时间,但是这样在算法选型上可以少做一些实验,性价比是很高的。站在他们的肩膀上就好了。

​ 不太可取的思路:

  1. 在指标上太钻牛角尖。有些算法工程师遇到指标在自己数据集效果不太好的情况时,立马换别的算法,或者立马换个backbone,或者立马换个loss去做实验。(需要认真分析为什么效果不好,是自己训练有问题,还是当前数据不太适合该算法,是评测指标不合理,还是评测指标实现有问题。)
  2. 不进行相关调研,直接上SOTA算法。这样做会有一些不太理想的问题,比如SOTA可能没有针对自己场景的数据做优化,比如当前任务是小目标居多(通过分析数据得到),虽然SOTA的总的mAP很高,但是small mAP比之前算法还低,那就要慎用 。比如SOTA用的是很重的网络,但是任务是速度快,或者速度与效果兼顾,那也应该慎用。

三、基于已有实现来优化算法

​ 对于某个任务在选择好合适的算法以后,如果有相应的效果比较好的开源实现,最好用开源项目进行算法的复现。

​ 这样做的目的:

  1. 更方便深入的理解算法的具体细节,比如可能代码在文章没有提到的某些层上偷摸的加了一个shift操作,比如文章提到的一些trick代码根本没有实现,比如代码用了额外的数据训练但文章没有提到,比如文章描述的数据增强方式与代码的实现不一样等。(这些可能发生在开源复现者没有“一比一”复现论文的情况,也可能发生在论文作者自己没有实现的情况)

  2. 能快速掌握算法的基础性能,比如复现算法大概的运行速度(特别是文章没给出的时候)和达到的效果

  3. 不用自己做一些无用功。要知道重写和调试一份新的模型不仅费时费力,可能还因为文章没有写清楚一些细节,导致你几乎无法复现到相应的结果。

​ 利用开源项目已复现的算法(这里复现不是完全能与代码作者或者文章作者结果一致,可能是数据增强,随机种子导致结果有偏差,但已获取到八九不离十的结果)来改进模型可以有下面几点思路:

  1. 代码是否实现了文章一些涨点的trick,如果没有可以尝试
  2. 文章一般会分析实验结果,后面会有作者自己的一些观点,他们可能会说明为什么有些情况文章的算法效果较差
  3. 有些文章会写他们将来可能的工作,这也是一个改进思路
  4. 需要可视化查看实验结果(特别是跑自己的数据集),结果可能与作者在公开数据集展示出的问题不一样,分析效果差的原因

四、从0复现算法

​ 复现算法是一个比较大的工程,这里的大工程不只是指代码多或者工作量大,而是没有一个基础版,导致引入的不可控因素太多调试困难,比如数据接口是否有问题,模型是否搭建正确,训练方式是否存在问题。

​ 在复现算法或者优化算法是比较头疼的是一切训练正常,loss曲线比你想象的还好看,训练了一年后(just kidding, maybe longer),测试一下发现效果奇差无比,都不好意思说是自己写的代码。一年就过去了。

​ 这里有下面一些建议:

  1. 尽量测试每一个细节,从数据接口,模型,到loss输出,到最终的评测代码。保证每个部分都可控。
  2. 测试数据接口,从单进程,batch为1开始,方便打印数值进行对比。
  3. 不要随意的去随机,尽量保证问题可以复现比如先不要加入随机数据增强,模型的随机种子固定。
  4. 用少量的数据,这样可以快速的做实验,也可以让模型快速过拟合。模型能过拟合可以大概确定模型是可以学到点什么的。
  5. 尽量按照原文来复现,在复现前,先不要过多的添加自己独特的想法。比如训练参数,模型backbone,数据增强方式等等先按照文章来。不清楚的点可以尝试email作者或者寻找相关圈子讨论。
  6. 日志打印全,比如解loss为nan的情况,需要知道是forward的导致还是bp导致。

五、一些或许有用的训练建议

  1. 保证数据是可靠的
  2. 有预训练模型最好用上
  3. 通常学习率参数小于1e-5基本没啥用了,比如cosine或者step操作,最后的学习率到1e-5就好了。当然特殊任务不一样
  4. bn在训练时记得打开更新(特别是tf的小伙伴,容易漏),不然可能出现的问题是训练时loss下降很快,测试感觉模型就没收敛
  5. sgd是很棒的,但是实验用adam或许收敛速度更好
  6. 如果想要很好的压榨出一个算法的性能,请先保证当前模型能到达相应的性能再去压榨。而不是盲目的换模块,疯狂调参,那样可能只是浪费时间
  7. 不要太相信自己的调参技术,在没有一个较好的baseline情况下,调参不会有质的飞跃(除非是之前参数造成了某种bug)
  8. 数据小时,使用了预训练模型记得固定前几层的模型参数,还可以用小点的学习率
  9. loss balance有时候很有用
  10. 重复训练可能可以提升点数,将一个模型训练好后,用训练好的模型做预训练模型载入,继续用同一套参数训练。有点像CyclicLR
  11. DL没有像机器学习有那么多公式支撑,很多都是make sense就做个实验来验证,所以尽量多阅读论文,看看别人的实验,这样就可以减少不必要的实验
  12. 这篇文章是为了分享自己的一些心得,希望读者能用得上,如果有严重错误还请告知,不想误导他人

视频算法QQ交流群:657626967

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

Record something about DL 的相关文章

  • C语言关键字_record

    重要关键字 涉及流程和单数据类型的关键字 xff0c 功能一般都比较简单 xff0c 在使用过程中很快就会熟悉 下列关键字相对前者来说 xff0c 功能较多 xff0c 值得好好学习 extern 实现外部链接 修饰符extern用在变量或
  • about:blank_关于Blank –什么是:blank意味着什么,您应该摆脱它吗?

    about blank Have you ever tried to go to a web page and instead see 34 about blank 34 displayed in the address bar where
  • ros数据集录制:rosbag record

    1 查看话题 查看topic列表 xff1a rostopic list 打印topic内容 xff1a rostopic echo topic xff12 话题录制rosbag record 用于在ros系统中录取系统中其他ros节点发出
  • Record: My CMakeLists

    1 设置需要的最小版本的cmake cmake minimum required VERSION 3 10 2 定义生成的项目名 project perceive tracking 3 1 设置cmake参数 set CMAKE CXX F
  • 【VCU】详解S19文件(S-record)

    目录 1 概述 2 S record格式 3 S record类型 4 S19文件示例 5 校验和计算示例 6 参考 1 概述 Motorola S record是由Motorola创建的一种文件格式 xff0c 它以 ASCII十六进制
  • 我在记录时崩溃:“所需条件为假:format.sampleRate == hwFormat.sampleRate”afterweb rtc 调用

    我的记录工作正常 但问题是在 WebRTC 调用之后 我崩溃了 所需条件为 false format sampleRate hwFormat sampleRate 这是我开始崩溃和 installTap 的方式 func startReco
  • Haskell Esqueleto 将列子集投影到自定义记录列表

    在所有的例子中我都看到了结果埃斯克莱托被投影到元组列表中或实体记录 例如 previousLogItems lt select from li gt do orderBy desc li LogItemId limit 10 return
  • 如何在chrome中停止由chrome.tabCapture API启动的捕获媒体流

    我正在开发一个 chrome 扩展 我使用chrome tabCapture用于从 Chrome 浏览器的选项卡捕获流并使用以下命令记录流的 APIMediaStreamRecorder js 我可以使用 mediaRecorder sto
  • Postgres 函数结束循环并返回错误

    我尝试创建这个函数 但系统返回 循环错误 并且我不知道如何同时返回 3 个变量 我很努力地想弄清楚这个问题 但我没有在任何地方找到答案 CREATE OR REPLACE FUNCTION conta relatos fator norma
  • 在 Android 中录制声音并读取振幅

    我正在尝试制作一个应用程序 记录声音一秒钟 然后从记录的声音中读取最大幅度 这是我到目前为止所拥有的 但我的应用程序崩溃了 我不明白为什么 这是我的第二个活动 我在按下 记录 按钮后从第一个活动中调用该活动 该应用程序在我的模拟器和手机上崩
  • 使用 fastxml.jackson 将 JSON 解析为 Java 记录

    根据设计 Java 记录不能从另一个对象继承 请参阅为什么Java记录不支持继承 所以我想知道实现以下目标的最佳方法是什么 鉴于我的 JSON 数据包含具有一些通用数据 独特数据的对象 例如 类型 宽度和高度适用于所有形状 但根据类型 它们
  • Java 录制/混合两个音频流

    我有一个java应用程序 它记录来自混音器的音频并将其存储在字节数组中 或将其保存到文件中 我需要的是同时从两个混音器获取音频 并将其保存到音频文件 我正在尝试使用 wav 问题是我可以获得两个字节数组 但不知道如何合并它们 合并 我并不是
  • 使用 ODP.NET 从 PL/SQL 函数获取 RECORD,无需接触 PL/SQL 代码

    标题非常不言自明 从 C 应用程序 使用 ODP NET 我尝试调用一个 PL SQL 函数 该函数返回的不是一个简单的值 而是一条记录 不幸的是 我无权添加或更改 PL SQL 代码 因此尝试将函数包装在另一个返回不同类型的函数中对我来说
  • Erlang Mnesia - 非法记录信息

    我试图有一个函数来确保我需要的表已经创建 如果没有创建它 这是示例 ensure table exists Table MnesiaTables Nodes gt case lists member Table MnesiaTables o
  • erlang 是否以任何巧妙的方式实现记录复制和修改?

    given record foo a b c 我做了这样的事情 Thing foo a 1 2 b 3 4 c 5 6 Thing1 Thing foo a 7 8 从语义角度来看 Thing 和 Thing1 是唯一的实体 然而 从语言实
  • 记录列表上的SML功能

    我试图声明一个函数 该函数将元组内的记录列表作为参数 但语法并不像我希望的那样直观 这就是我想做的 type Player id int privateStack int list fun foo id x xs Player player
  • 用python检测并记录声音

    我正在使用这个程序在 python 中录制声音 在 Python 中检测和录制音频 https stackoverflow com questions 892199 detect record audio in python 892293
  • 循环记录的列

    我需要循环类型RECORD按键 索引排列的项目 就像我可以使用其他编程语言中的数组结构来做到这一点 例如 DECLARE data1 record data2 text BEGIN FOR data1 IN SELECT FROM some
  • Delphi - 按名称调用记录方法

    我为我的应用程序编写了一种脚本语言 我的目标是能够在脚本中发布来自 delphi 的任何类型 我使用 rtti 来自动执行此任务 对于任何实例类型 例如类 我使用以下代码从脚本查找并调用方法 var Info TRttiType Meth
  • 如何录制屏幕并保存为gif动画? [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 有这样的软件吗 尝试这个名为 Cropper 的免费工具 无限帧 将输出设置为动画 Gif http cropper codeplex com htt

随机推荐