AI学习实习元旦小结
作者:互联网
跟大多数大学生一样,我从大一开始学习编程,但却没有局限于课堂知识。有着极强的自学和动手能力,通过课外资源学习了更多编程技能,并通过目标驱动去解决问题:因为在学校要提交电子版作业,习惯手写作业的他就尝试学习OCR技术来达到目的,又因为在这个项目中发现了图像质量不高等不足,我开始试图分析和优化项目,也因此让他获得了超出原本要解决的问题的更多技术能力和项目经验。
在计算成像过程中,我们可以使用光的偏振原理与电机对偏振片的控制来完成去雾、去雨等图像处理操作,而现在我们可以使用以CNNs为代表的深度学习方法通过软件计算直接得到去雾、去雨结果。
一方面,深度学习方法能够通过强大的图像后处理能力,间接降低光电系统中其他部分的开发难度;另一方面,在已知相机参数的情况下,深度学习方法可以通过强大的拟合能力取得比传统方法更好的成像结果。这也是为什么我现在的技能和兴趣有很大部分偏向AI。
我开始接触编程是在大一上“计算机导论”课程。我们的老师鼓励学生自学相关知识,于是我就在B站上搜索相关资料进行学习。在听完老师的C语言课程之后,就投向了其他编程语言入门课,比如JavaScript、Cpp。
后来在学校社团的影响下,学习了Python,同时在学长的带领下学习计算机视觉、计算机图形学相关的内容,深入学习了JS、TS、WebGL相关的技术,也尝试过拿Unity做CG。我个人认为,学习编程最重要的是实打实地看或者敲优质的代码,最好以解决生活中实际需求为导向。
当时正值疫情期间,老师要求提交电子版作业,而我习惯了手写笔记。为了不把时间浪费在码字上,我开始学习OCR相关的知识。在学长的建议下,我先后学习了CS231n、吴恩达深度学习等入门课程,也接触了MSER、PSENet等文本检测方法。
到了大二下学期,我发现该项目几个难点,拍摄的图像质量不高,手写公式识别精度较低,以及如何能在端侧完成CNN的计算。第一个是专业相关,第二个除了CRNN+CTC外好像没有更好的处理方案,而第三个看起来更有挑战性,与专业也有一定关联,我就把重心放在了部署上。这也间接促使我加入公司实习做TVM前端支持相关的工作。
由于我现在的主要学习方向是底层视觉和模型部署,所以未来更想做ISP、高光谱相机相关的工作。毕竟,用自己参与制作的相机去定格万千世界,成就感不是一般的高。
在参与这种相对比较大型的开源项目之前,我自己写过一些小项目,一般与low-level vision相关,比如超分的经典算法、一些较新论文的复现。还有一些硬件相关,比如stm32的LCD、ADDA驱动、深度学习模型在FPGA端的部署,在做FPGA模型部署的时有听说过TVM,在看到开源之夏有相关项目后便果断提交了申请。
不过发生了一个小插曲,开源之夏系统没有把我录进去。可能受到我极强的参与该项目的意向的影响,公司领导在跟我聊过后同意我进去实习,然后开始了时长两个月的实习。
在实习的两个月,最直观的感受就是对小白极其友好。刚开始,老大结合他自己写的tvm-learn给我梳理了一遍项目代码实现的基本流程,并给我制订了一个非常详细的周计划。配置服务器环境的时候发现git push不到远程,前辈给我一通排查后,结果发现是我没有开新分支的权限。
工作第一个周的任务是熟悉公司的API,我参考之前用PyTorch编写的Transformer,实现了公司版本版本的Transformer。
公司的开发进度很快且开发过程具有较高的不确定性。第二周,我正式投入到给TVM添加公司前端的工作中,最开始告诉我可以模仿PyTorch转TVM Relay IR的方法,PyTorch的做法是将模型转为静态的Torchsrcipt形式,用来获取每一个计算节点的形状与数据类型。但当时公司并未提供动静转换的接口,我打算先使用lazy模式去做一个能用的转换脚本。
公司 eager模式与PyTorch相似,而公司 lazy模型与TensorFlow更为类似。受益于之前对TensorFlow和PyTorch都有一定了解,在快速熟悉相关API后,我用公司 lazy的接口在第一个月完成了lazy版本的公司转TVM Relay IR工作。
这个工作本质上就是将公司模型进行解体,经过转换后重新组装成Relay IR。其中比较大的问题有两个,一个是有些节点会有多个输入输出,解析的时候一不小心就会出现找不到节点的情况,另一个是节点命名问题,Relay IR组装时依赖节点命名,一开始的方案是将路径与命名组合起来,这样可以确保节点名可以作为节点的唯一标识,但是这会导致graph输出的时候很不好看,一个节点名字长的没边。
其中,第一个问题通过长时间的细致排查后解决,第二个问题在nn.Graph动静转换接口出来后,在翻看源码时发现nn.Graph有一套自己的节点命名规则,于是我根据这个规则修改了命名问题,使得转换后TVM Relay IR节点名字与nn.Graph保持一致。关于算子转换的工作,更多的是Ctrl CV,需要注意的是节点input的顺序问题,需要避免出现被除数与除数搞反的情况。
在完成这项任务后,我收到了公司已经大致完成动静转换接口的消息。于是,我又用大致一周的时间用当时正在开发中的nn.Graph完成了公司 eager转TVM Relay IR的工作。后面的工作主要围绕着编写相关的示例与文档,丰富相关实例并不断新增op。
开发过程中也发生过一些比较憨的问题。我在转换脚本中大量运用了正在开发中的非public方法,这导致在nn.Graph repr方法的输出删去了INPUT和OUTPUT节点后,之前编写公司转TVM Realy IR的代码就无法正常运行。最后给公司主仓库添加nn.Graph与TVM转换相关的测试时,由于对unittest的不熟悉,CI挂了很多次,负责nn.Graph工作的许啸宇给我讲了unittest相关的操作并指出来很多test脚本中的细节错误。
一个工程的实现严重依赖团队内每个人的配合,而不是不管团队内其他人的工作。项目模块之间相互高度连接,不能实现功能后就双腿一蹬。其实实习过程中主体工作不是很难,这段经历带给我的更多是工程能力上的提高,让我主要体验了下Ctrl CV工程师的日常生活(误)。
感谢公司和在公司认识的诸位大佬,也希望公司能早日做成使用体验最好的深度学习框架。我也准备带着我们实验室的小伙伴为公司多做些力所能及的工作,如果你对深度学习框架也感兴趣,欢迎参与其中,共同进步。
标签:学习,nn,AI,Graph,IR,TVM,实习,小结,节点 来源: https://www.cnblogs.com/emmaty/p/15757115.html