PyTorch流水账与基于Torch的Waifu2x代码分析
开始
1.nn.PixelShuffle
这个函数从名字上看,和ShufflePlanes
好像。(https://github.com/XuecaiHu/Meta-SR-Pytorch/blob/master/model/common.py)
2.字面上,bias是偏差的意思。
bias(
tensor
) - 卷积的偏置系数,大小是(out_channel
)
3.现在的libtorch模型读入文件已经解决,而Torch模型的Json与t7的关系虽尚未明白,但具体内容人类可读,已经看了大概。
现在的任务是明白网络内容,网络结构保存了什么信息。
模型保存的内容
- 网络的结构和模型参数
- 只保存网络的模型参数
在waifu2x的appendix/arch/cunet.txt
中是网络结构的描述。虽然我还不知道这仅仅是个文档性能的描述,还是确是导入了代码中…看上去只是一个描述(我不觉得会专门写一段代码,去匹配这样的文字``->`)。
扫盲
4.Waifu2x中vgg_7 -> cunet?
5.话说waifu-caffe中的cNet是代表什么啊,莫不就是cunet?
6.一个灵魂发问,这些代码,抛开实用化的接口,不就是在搭网络吗?
所以我现在学这些代码,除了我耽误之急要用的模型和前向传播相关,余下的核心,不就是怎么搭网络吗。
7.Torch的函数
SpatialZeroPadding()
waifu2x 项目结构分析
appendix (附录 -> 所以
cunet.txt
果然只是说明文件)arch: descripte network for torch (only has two files for cunet)
caffe_prototxt: prototxt is for caffee, and has a .py file for making cunet.
Generate prototxt of waifu2x’s cunet/upcunet arch. Training is not possible.
其余是markdown说明和.sh文件
assets
看名字是和网站相关的,里面的文件也是html、css、js三剑客,不用管
cache
顾名思义,里面也没有内容
data
同样没有内容,不知道这是什么套路
image_generators
- dots (字面上是点)
Only has a gen.lua file, which has this code. So it’s for generating images. However, I can’t understand the meanings of dots.
But ever, this is for cmd…So…I can ignore it now?
1
2cmd:text("dot image generator")
image.save(path.join(opt.o, i .. ".png"), img)images
Using for description, although some images aren’t used in readme, yet they all seems to used to show the networks.
layer_outputs folder
Other images and .sh file
lib
Seem to build the newtwork, such as
srcnn.lua
, which is decripted the SRCNN?看了一下w2nn.Lua,感觉Lua这门语言,有点…简单得过分了,调用其他文件,用类似这样的写法,还是在代码的结尾
1
require 'Print'
models
models
tools
在这里看到了
export_model.Lua
,这应该能解答我对模型内容的疑惑。emmm,
export_model.Lua
开篇第一句就是1
-- adapted from https://github.com/marcan/cl-waifu2x
这是什么意思,cl-waifu2x明明是建立在waifu2x基础上的OpenCL支持项目。(其实..在Lua里这是注释的意思)
在代码结尾有好看的东西
1
2cmd:option("-i", "input.t7", 'Specify the input torch model')
cmd:option("-o", "output.json", 'Specify the output json file')这话说的是,进去t7,出来json。依此分析,文件名
export
的含义,并不是把Torch用的模型输出成t7,而是把导出的t7模型转换成json。也就是说,t7和json的内容,是一致的。(顺带一提,看这Lua写的命令行构建代码,真是简洁啊。之前看av1的rust命令行构建代码,虽然不能说比C++更复杂,但也挺长的。)
webgen
For web app, can ignore it.
Single Files
- convert_data.lua -> 似乎是图片预处理的过程
- install_lua_modules.sh -> 安装依赖
- train.lua
- waifu2x.lua
- web.lua
- Dockerfile
- Other Files
综上分析,与核心处理相关的代码,位于lib
文件夹(描述网络)和主文件(调用)下,核心代码并不是很多,甚至让我觉得,比Caffe版还要简洁一点。
回到保存的模型
由上面的代码分析,并且去看了历史提交,发现json版的模型文件在初始提交中并没有,而是稍晚时添加的,同时添加了上面的export_model.lua
。(虽然初始代码还没有像现在这样构建命令行,但意思是一样的)
1 |
|
所以先前的判断是没错的,json模型和t7模型就是一致的。json模型是为了“跨框架”而准备的,使预测/前向传播不限于Torch(+CUDA)的框架。
当然,json模型下那一堆小数(与t7模型中整齐的模型参数形成了对比),应该是转换过程中近似计算导致的。这应该很好理解,在Torch下的函数别的地方没有,那只能把数值算出来,用类似查表的方式提供给其他框架。
比如Waifu2x-convert,在modelHandler.hpp/.cpp
就用下面的语句读取json模型的内容(借助picojson)
1 |
|
所以可以推测,用json模型会比用t7模型(以及直接由t7转向其他框架模型,如由t7转向pt)精度低?
所以延伸一下,我不能偷懒(或者说瞎折腾),把json模型喂给PyTorch,而还是要借助低版本PyTorch完成从t7到pt的模型转换。但忘了在哪看到了,说PyTorch的C++前端没有明显提速、甚至慢于Python前端,很大程度是因为读取pt模型拖慢了速度。那我能否使用json模型实现精度换速度?
…有想法,但我目前还是按套路出牌吧…
进一步说模型
各版本模型情况
版本 | 主体文件 | 辅助文件 | hash一致 |
---|---|---|---|
Waifu2x | json/t7 | / | √ |
Waifu2x-caffe | json | prototxt | √ |
VapourSynth-Waifu2x-caffe | json.caffemodel | protobin | × |
关于t7转pt
这个别想了,用目前查到的convert_torch.py
,因为模型结构的原因,没法转cunet的模型,其他的没试(其实在两天前,周五的时候,就在某篇博文上读到过,convert_torch.py
不是万能的,今天更是在Github issues上看到了作者类似的回复)。所以Waifu2x-caffe直接用的json模型。
不过话说回来,json模型是怎么转成caffe的caffemodel的?(这样转是为了提高读入速度吗?)
而我从来没注意过Waifu2x-caffe和VapourSynth版代码的区别,读这两种不同格式的模型(json/caffemodel),代码上总归得有点区别吧。
下一步的模型转换计划
所以对于写libtorch,要么想办法手动读入json模型,要么…onnx?
在Waifu2x-PyTorch版中,作者自定义了函数load_pre_train_weights()
用以加载json模型,所以我可以直接拿来用了?
但Waifu2x-PyTorch的Readme中有句话很让人在意。
Model inference (32 fp only) can run in cpu only.
像只做预测的VapourSynth-Waifu2x-caffe、ncnn版是在GPU中运行的。这里只能在CPU中运行,这是一个可改进的地方。
Whatever,现在情况已经明了了,基于不重复造轮子的原则和我什么不会的实际情况,我完全可以在现有Waifu2x-PyTorch的基础上,去写libtorch的前向计算。至于是写出独立项目,还是基于VapourSynth,这个可以后续再考虑。