这几天进入实验室后,开始阅读实验室学姐的一份代码。刚到手的时候像一个烫手的山芋,不知道从哪里下手,而将整个项目的代码阅读完之后,发现在这个过程中能学到很多东西。于是便想将整个过程记录下来,便于学习。
在阅读前不能傻乎乎的埋头就开始一行一行读。首先应该先对代码进行分块。粗略的说,可以分成四块:
- 数据加载和预处理
- 神经网络实现
- 训练网络
- 其他(工具,配置文件,过程记录等)
数据加载和预处理
训练神经网络最重要的就是数据。数据预处理包括下面几点:
实现一个
Dataset
加载自己的数据
为了使用DataLoader
加载数据。我们需要自己实现一个Dataset
对数据处理。对数据的一些预处理,如:裁剪、拉伸、旋转、镜像等处理,都是在这个模块中实现。在看这个模块的时候主要看下面几个函数:__init__(self,prams)
:初始化函数,prams
是用户自己传入的参数,像文件路径啊,裁剪时图片的大小呀之类的。主要是对用到的变量初始化。__getitem__(self, index)
:DataLoader
通过调用Dataset
的这个函数来读取数据,其中index
是指调用哪个数据。一般在这个函数调用处理数据的函数,返回值是data
和label
。__len__(self)
:返回数据集中一共有多少个数据。
对数据的预处理
在一些项目中,并不是直接把数据(图片)送到神经网络中训练,通常要对其处理,像裁剪、拉伸、上采样、下采样、随机旋转图片、随机旋转RGB
通道、随机镜像等。这些方法一般放在Dataset
中实现,或者实现一个data_util
专门处理这些。
神经网络实现
神经网络这一块没有什么好说的,一般都是根据论文给的结构实现的。但是一定要多看看一些经典的或者复杂的神经网络是怎样实现的,比如:Resnet,Unet,Fast-RNN等这些不同领域典型网络的实现。
训练网络
训练网络部分的代码也比较复杂,因为这里面涉及到配置加载,断点保存等。看这部分代码的时候,首先找几行重要的代码。在这几行代码之间穿插着作者实现的其他代码。首先我们先找到train
函数,如果代码里面有evaluate
和predict
函数,都是差不多的。
1 | def train(param_set): |
上述代码中,白色代码一般是固定的写法,位置也是类似,可以通过这些白色代码定位,从而对整个代码有全局的理解。
其他
剩下的代码都可以归结到其他中,一般都是工具类、配置文件、过程记录、日志打印等。
- 过程记录
过程记录部分,目前见的比较多的是tensorboardX
,使用tensorboardX
来记录loss
等,或者对网络结构进行可视化 - 配置文件
配置文件方面,目前见到的工具有:fire
和configparser
这两个库。 - 日志打印
日志打印一般使用重定向流,讲数据输出到terminal
或者log
文件中。
总体来说,当拿到一份代码后,首先对其有总体的把握,阅读起来就变得容易许多。同时可以根据自己的需求只阅读不同部分的代码。比如只关注数据的预处理,那就看Dataset
相关的部分代码;只关注网络结构,那就看network
部分的代码;只是想将代码运行起来,那就只看配置文件和训练网络部分的代码。