我是去年工作后开始接触TensorFlow的,彼时,人工智能大潮刚刚启幕,Caffe正当其时;然而,Google推出了TensorFlow。依据其时相关行业的研究者以及社区的强烈反响,和很多人一样,我认为这会是一个影响未来的东西,而我若想进入这一行业,TensorFlow不可错过。 但对于当时的我,学习TensorFlow又谈何容易?系统需要Linux,使用最多的是Ubuntu,但我对其一无所知;使用TensorFlow,最匹配的语言是Python,但我对其最多只是知道个名字;了解TensorFlow的应用自然需要对机器学习、深度学习比较熟悉,可我当时不过仅仅看过寥寥几篇相关论文;而我们用TensorFlow,最终是在应用在图像处理上,但我对图像处理的理解尚停留在PS上。 知难而退固然是一种智慧,可是与我又谈何人工智能的大潮和未来?无奈之下,迎难而上,终于还是慢慢的在踩过无数坑之后一步步地入门上路了。其后就在网上看到一些TensorFlow用起来很溜的大神为TensorFlow项目做了诸多贡献,贡献了很多代码,成了TensorFlow的Contributor;而部门主管也曾在跟我们聊天时提及,有机会好好研读一下TensorFlow的代码,如果能Contribe to TensorFlow,自然会对以后的职业推进有不小帮助。但这高高在上的TensorFlow Contributor于我,却不过是天方夜谭,莫说可望而不可及,甚至连想都不敢想啊。 但机缘巧合,终究在我用TensorFlow做深度学习的开发而过了十来个月的时候,机会来了。 我们使用TensorFlow做进行的研究主要涉及医学影像的处理,而我们所处理的医学影像主要是CT序列,不同于普通的图像处理,这是一个3D数据。具体说来,普通图像是二维的3通道RGB图像(即128*128*3);而CT序列是三维的单通道灰度图像(即128*128*128*1)。这样,在很多既有的面向普通图像处理的框架和模型中,2D图像处理的功能实现的都已经淋漓尽致,但3D图像处理方面的功能则可能偶有遗漏。 一个很明显的例子就是TensorFlow框架中的一个高层封装——slim,其主要面对的就是图像处理,因此TensorFlow的models中的很多示例,为方便实现,以及实现和代码的简便性,多使用了这个封装,比如经典的ResNet。而因为这些模型面对的主要还是2D普通图像,所以我们在3D的医学影像上无法使用。而且,在我试图将其修改为3D医学影像可以处理的过程中,却发现slim尚未将TensorFlow的3D操作进行封装,比如3D卷积、反卷积,等等。 最初在16年年底发现这些问题的时候,我并没有想到去做,一方面是自己并没有这个时间;另一方面也考虑到自己水平的欠缺,从来没敢去想过这些事情。而且,彼时我使用比较简单的深度模型已经能够较好地完成任务,所以对尝试更多模型的需求也并不迫切,因此将更多模型修改为3D可用的需求也不迫切,所以,slim没有3D就没有呗,反正我也没那么需要。 可年后在一些项目的推进中,最初的简单模型已经很显乏力,而我在尝试新的模型的过程中,多次遇到slim没有3D功能的问题而多次碰壁。而且在尝试阅读slim的2D封装的代码时,发现原来根本就是很简单的事情。所以,我自然就着手实施。 其实过程中还是碰到了不少问题,最典型的就是,开始前我甚至都不知道GitHub怎么使用,诸如最简单的Pull Request、Push、Pull、Commit等等,我一点都不了解,更不用说后来在提交过程中碰到的rebase、revert了。当然,这些东西无非在使用中学习一下,即使出了什么问题,大不了也就是删了重新clone一份去重做一下而已。 而整个commit过程中最让我后悔的则是,我的行动和进度都太慢了。slim的conv3d_transpose封装需要用到tensorflow.layers里面的conv3d_transpose,而当时,这个东西还并不存在,因此,我一并使用tensorflow.nn.conv3d_transpose进行了封装实现。然而遗憾的是,在我提交PR之后几天,我才突然发现,有一个老外,已经在不到一个月之前提交了PR,在tensorflow.layers里进行了封装。只是当时,这个PR尚在review的过程中。所以后来才不得不rebase和revert。 还好slim中这些我commit的东西没有其他人做,而终于在经过漫长的两个月的反复修改和提交、不停学习与改进之后,PR最后被Merge到了TensorFlow中。 具体来说,就是这么几个东西:
tensorflow.contrib.slim.conv3d
tensorflow.contrib.slim.avg_pool3d
tensorflow.contrib.slim.max_pool3d
tensorflow.contrib.slim.conv3d_transpose
谨此纪念!