算法图解里面的代码是什么代码啊_如何复现一篇paper的算法代码?

531d2316f0a93f31085945827b04cca9.png
目前正在复现一篇paper的代码,工作还没有完成,这里作为自己的经验总结。

首先必须得说,复现他人的程序实在是迫不得已的事情。要么源码无法要到,要么就是不符合自己的编程习惯或者输入输出不能够对应得上。通过paper去复现代码虽然相对可靠,但是也难免有作者并没有提及的细节处理地方,所以预先要做好充分的心理准备。前路漫漫~~~


精读paper,梳理算法流程及输入输出

准备开始动手前,一定要精读paper,至少是要精度算法设计部分。这里如果作者阐述很详细,采用伪码表或者算法流程图来表达,那么就会方便很多。

0aaae8d2924159f71bcdde4385f571e7.png
伪码展示示意

我目前的习惯是,先把整篇论文的算法流程搞清楚,看每个子函数的时候,第一遍至少将子函数的输入输出搞懂(因为paper上的思路有时并不是阅读一遍就能够搞懂),这样一遍流程下来,就可以把整篇论文的框架梳理出来。

9018eee2d60ec860032824037fa8fb19.png
算法的整体流程图

根据整体的算法流程图,就可以把子函数纳入其中,有点纲举目张的感觉。

在这里插一句,我其实也是算法编程的小白,经验仅作参考 ‍

设计数据结构,并详细记录

在第一步完成之后,我梳理了程序中常用的参数的数据结构(当然,在这里应该反观第一步,需要把重要的数据及其使用记录下来)。有的数据类型比较复杂,根据不同的编程语言需要设计不同的结构,比如C++中的vector/struct,Matlab中的cell等等。

我个人感觉,数据结构的定义非常重要,因为后序程序的运行会经常调用需要用到的数据,也会将结果,存储在对应的位置。而且,数据结构的定义也需要有清晰的文字记录。之前在阅读他人程序的时候,因为数据的定义不清楚,只能采用猜测+调试的方法最终搞明白,确实花费了太多的时间。在做项目的过程中,软件设计也需要一份清晰的输入输出、以及中间数据的定义,这也是从中学习到的方法。

所以这次我对数据进行了一个有记录的定义,至少保证我自己能够看懂,而且遇到问题的时候我可以查询、检验。

f4446c7885b3243fcc874a1d53db5310.png
数据定义的记录

不过在算法实现的过程中,我发现,数据的定义在预先设想和程序具体实现时是有差异的。所以需要至少2个版本,预先设计的版本和实际程序实现的版本,在程序实现的过程中,发现需要调整数据格式的,需要及时进行修改,并详细记录下来。在本次实现中,cell数据最多有4层,最大的单独数据存储量达到了1.53GB。


程序实现,从前至后,由简入难,测试校验,细致莫烦

然后就是程序的具体实现过程了,现在工作还在进行中,只能记录一些零散的经验……

1)按照程序的流程来编写代码,整体的框架列出来,然后先把数据输入的部分整理好。这样做的好处在于,后面的程序可以有正确格式的输入,就可以在每写完一个函数之后进行详细的测试;

2)每一段函数 / 每个子函数 写完之后都需要进行详细测试!因为程序中除了逻辑错误,还会出现书写错误,如果书写错误没有导致逻辑问题,也是将数据导向了另一个位置,那么后序调试起来真的会崩溃的!!!所以应该在写完一段程序之后,单步运行查看数据的结果是否正确,写完一个函数之后,需要对函数的功能进行测试,同时考虑可能出现的意外情况,先在注释中记录下来。Matlab实现程序时,可以单独建一个测试脚本。

2020-07-04

------未完待续------


程序复现的工作在继续开展,碰到一个较难的点,还没有想清楚怎么实现,所以也就先来再继续总结一下经验。

关于为什么要先阅读paper的算法框架,再梳理输入输出及Local数据的格式,今天又有了一点新的认识。

数据的结构如何组织,与程序具体实现的方式也有关系。例如:for循环的判据是什么,就会直接对数据的组织结构产生影响。所以在熟悉程序框架的时候,不仅要看到有哪些数据要进行结构的梳理,还需要尽量根据程序实现的方式,构想出更为合理的数据结构。

ca88ab90868f5f98a5c9863e25f847af.png
数据结构与程序实现方式

如上图所示,一个子函数的程序实现其实有不同的方式,这里的一个结构就比较复杂,第一轮循环中采用 target → task → position的三重循环,来进行判断,随后又对计算结果按照orbit 来进行组织,这对数据的结构就提出了比较高的要求,同时,复现的时候也容易被数据的格式搞得心烦意乱。但是数据的格式一旦出错,程序运行就肯定是错误的!!

而数据的格式一旦设计好之后,后序的程序的代码实现以及测试都会方便很多,我个人的体会:前期数据格式没有确定的时候,感觉复现的工作很难推进,畏难情绪也很大,等数据格式确定之后,程序的实现以及测试在2-3天内就取得了飞速的进展,至少完成到70%的过程中困难都不大。可见这项工作的进展也并不是按照线性模式来前进和完成的。


一些小的Tips

对于要复现代码的paper,我的习惯是把文章打印出来。采用知云PDF阅读器可以实现快速翻译,局部放大也可以查看得很清晰,不过对于算法前后功能对照查看的时候就显得有些捉襟见肘,即使水平拆分也不能获得整个纸质版paper拿在手中,能够掌握全局的感觉。

另外,尤其是对于算法中比较复杂和困难的部分,这些地方一般与前后环节有不少的交集,同时本身理解和实现起来难度较大,对于这些部分的反复研读、分析、做笔记和思考,有纸质版的论文确实会方便很多。

在代码实现过程中,通过Git托管代码可以方便地记录自己每天工作的内容和进度,既可以方便、安全地保存自己的工作,也可以使每一步工作可以溯源,最后回过头来还像保存的棋谱一样可以复盘,从中总结经验,是一个很不错的工具。

44444bdf843b160ba0e24b84ad0755cb.png

磨刀不误砍柴工,谋定而后动,做的过程中阶段性地总结经验教训,这样才能逐渐进步。

2020-07-05

------未完待续(下一次记录:如何解决一部分较难的算法)------


面对复杂算法设计,应当怎么办?一些经验和体会……

好久没有更新了!因为前一段时间在进行代码实现的时候遇到了各种Bug,是我始料未及的。也让我心情焦虑郁闷了比较长的一段时间,也没有心思来记录这个过程。现在情况稍稍有些缓解,所以先腾出手来进行一下总结。

(1)中间有一次和师兄交流,原paper的一些程序流程问题没有搞清楚,但当时我已经开始复现那部分代码了,师兄指出我这种行为的错误之处:在程序没有完全弄清楚之前,不要动手去复现,即使写出来了,还很可能是错误的,后面甚至需要花费更长的时间进行修改!!!所以一定要清楚理解:磨刀不误砍柴工!

(2)关于阅读代码时应当注意的问题(这一点体会太深刻了):

因为阅读伪码时不够细致(没有逐行进行分析+思考),自己存在很多的疑问,列出了一系列的不能理解的问题,和程序实现过程中面临的问题,导致自己对其代码理解不正确,还以为是对方写的有问题(对于正式发表的paper,以后这种念头真的是可以打消了)!

这个时候,能有人进行沟通真的很关键!这倒并不完全是能力的问题,很大程度上心态会产生影响,孤军奋战的感觉其实相当不好受,自己身后没有依靠,心中的力量耗尽的时候,就容易想到放弃,或者一段时间的怠惰——对于像我这种自身动力不是很足的人来说,真的是这样。

姜还是老的辣,通过逐行地对代码进行分析解读,之前产生的不理解的问题就迎刃而解了,完全是理解上的误区造成的。

(3)有问题要及时沟通。这次复现代码的过程中,还很有幸地与论文原作者进行了一次简单的十几分钟的沟通。虽然时间很短,但是就能够将自己对于算法的种种问题全部解决掉。

414090edb31b10fe36fcdc8d6715ba14.png
讨论提前准备的问题思路

在请教之前,一定要充分准备!探讨的过程可以让自己对内容认识得更加清晰准确,另外也许会有科研方法上的启发。

(4)一个惨痛的教训!!!对于sophisticated算法部分,一定要在精神状态极佳的时候去实现,不能拖着自己满满不情愿的心情来“完成任务”!

因为一些原因,这个比较困难的算法的主要部分反而是在精神状态不太好、注意力不够集中的情况下完成的,这给后续的测试造成了极大的影响!

因为在困顿的时候,所能考虑的仅是算法流程的实现,但是对于算法性能的完备方面,却根本没有精力去思考了。

具体来说,复杂的算法牵涉的变量和子函数尤其多,大量的精力需要用来考虑变量引用格式的准确性、函数接口输入输出的正确性、函数流程实现的正确性。因为这是核心算法,甚至可能整个算法的framework都是为了这一步的操作而设计的。

所以这个部分对精力的集中程度、思维的缜密程度、考虑问题的全面程度的要求是最高的!而我,就败在了对问题考虑的全面性上了!

在程序实现的过程中,有的参数设定为某值,但可能为0,也可能为空,针对不同的数据类型,索引的范围可能溢出,以及一些逻辑判断可能是不合逻辑的……这些问题在后面的测试过程中层出不穷,而我在写程序的时候根本就没有考虑到这种情况,我把这种问题称之为算法的完备性不好——在此场景下可以解决问题,换一个场景就会出现Bug。(当然,这个问题肯定有非常多的人都曾经遇到过,以后还需要多与其他人沟通探讨)

(5)其实无论做什么事情,心态都会起到非常重要的作用,好的心态起正面作用,坏的心态则会让事情变得很糟糕。

盲目的对于算法实现的自信是千万要不得的。没有得到结果之前,谁也无法预料求解的结果会是怎样的。对于科研工作者而言,一定要对最终实现的结果有一个客观的面对心态,以及冷静的处理方式。否则,学习和培养的过程就不能称之为合格了。

5c7da230597ce25fc02f71aa46a037e7.png

(待续)

2020年07月14日

Gatys et al. (2016) proposed an algorithm for style transfer, which can generate an image that combines the content of one image and the style of another image. The algorithm is based on the neural style transfer technique, which uses a pre-trained convolutional neural network (CNN) to extract the content and style features from the input images. In this algorithm, the content and style features are extracted from the content and style images respectively using the VGG-19 network. The content features are extracted from the output of one of the convolutional layers in the network, while the style features are extracted from the correlations between the feature maps of different layers. The Gram matrix is used to measure these correlations. The optimization process involves minimizing a loss function that consists of three components: the content loss, the style loss, and the total variation loss. The content loss measures the difference between the content features of the generated image and the content image. The style loss measures the difference between the style features of the generated image and the style image. The total variation loss is used to smooth the image and reduce noise. The optimization is performed using gradient descent, where the gradient of the loss function with respect to the generated image is computed and used to update the image. The process is repeated until the loss function converges. The code for this algorithm is available online, and it is implemented using the TensorFlow library. It involves loading the pre-trained VGG-19 network, extracting the content and style features, computing the loss function, and optimizing the generated image using gradient descent. The code also includes various parameters that can be adjusted, such as the weight of the content and style loss, the number of iterations, and the learning rate.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值