作者:十方,一品炼丹师
你真的会读论文吗?
Do you really known how to read papers?
十方一开始就给大家提了一个非常犀利的问题,这个问题从十方刚开始读论文,就不断问自己了。如果你毫不犹豫的回答了会!那这篇可以跳过了,可以多关注一元写的前沿论文笔记。如果你犹豫了,或者就是想好奇看看十方到底要说啥,那么往下看。
看论文的经典状态如下:
其实,也不会啥都没学会,论文毕竟是英文的,至少提高了英语阅读能力不是。严肃点说,看完论文会有以下几种状态:
你是哪种状态?
先说下看的一知半解的状态,这个对很多初学者而言,是经常出现的情况。先说下为什么会出现这种状态,就像我们在上大学前,会学数学、语文这种基础学科,然后开始接触专业课,看到很多公式就不会茫然。读论文也一样,不是说你可以直接读最新的论文。BERT本质用的是Transformer的Encoder,而预训练的思想,来自很多论文,比如ELMO,GPT。Attention呢?很早在LSTM的encoder-decoder架构中就用到了,其实attention最早是用在cv领域的,就不往下再扩展了,没有这些背景知识,可以说直接看一篇巨佬的论文是没有任何意义的,只是去浪费时间(十方表示也浪费过大量时间)。
再说下第2个状态,这个状态就很有意思了。看论文点到为止,知道有个什么模型,效果很好,解决了问题。然后去github搜复现(比如deepctr就封装的很好),readme写的很清楚,输入数据格式是什么样,直接调用(可能用于比赛),做个愉快的调包侠。其实这个状态是优于上一个状态的,实践是认识发展的动力。比如我们从出生开始,不是先学会文字的语法才去学说话的,十方之前也喜欢看论文去github上找复现代码,去跑跑看。当然,这个状态不能持续太久,在你实践能力很强后,这种状态对你未来而言,就不能有任何提升了。
再说下第3个状态,当你完全能看懂论文,比如transformer,为啥attention要做scale,预训练样本如何构造,transormer在处理不同任务的区别是什么等等细节的时候,这是个非常好的状态,建议大家这个时候,可以好好看看源码,十方看完bert这篇论文的时候,就仔仔细细看完了bert的源码。
最后再说一种状态,这些往往就是大佬了,能够在只有论文,和tensorflow官方文档的情况下,复现论文,或者融合论文中部分模型优化点,去优化现有模型。很多时候可能不需要达到这种状态,看各位需求了。
因为每个人情况不一样,其实还有些其他状态。十方建议大家看完论文,最好总结下,自己究竟学到了什么。非常重要的是,如果你是一个初学者,建议多阅读巨佬的著作,而不是直接看论文,每本书都会介绍很多经典的模型,并给出该模型出自的论文,大家结合着书去翻阅论文,这样效率才是最高的。
到底应该怎么读论文呢?
Echoes Of The Rainbow
大家一般看论文的方式,是哪种呢?大多数人喜欢从公众号,知乎,CSDN等去看论文。首先不用面对烦人的英文,其次就是往往公众号等平台中已经把论文的要点,模型的结构做了详细的解读。直接读别人写的论文分享是一种快速阅读论文的方式,但是毕竟作者能力层次不齐(主要是写作能力),可能有时候你没看懂仅仅是作者漏写了部分要点导致的,比如之前就有朋友吐槽过十方写的DR,他直接指出十方没有写模型的上线方式,导致他又去翻论文,问同事。十方看了下确实没写,即使十方十分清楚应该怎么上线,因为十方假定了读者自己在读完分享后能够自己领悟上线方式。所以十方希望大家把公众号的论文分享,尽可能当作一个摘要去看,当你发现一篇论文对你非常重要或者让你非常感兴趣,去读原文吧,一篇一两千字的公众号文章是说不完很多细节的。
关于复现论文
Echoes Of The Rainbow
首先说下复现论文是一件非常有意思的事,当你完全领悟一篇论文的各个要点时,每个人都有能力去复现论文,不需要依赖于github的分享,或者等着某个开源平台去开源。为什么要去复现?因为在调用一个开源模型上,你不会比任何人更优秀,毕竟每个人都可以用deepctr。那么为什么比赛很多大佬能拿冠亚呢?我们看很多top方案的时候,发现或多或少都对模型进行了各种调整。如果仅仅把开源当作一个黑盒来用,你就只能在挖特征上努力了,而对于图像,nlp等比赛,给你挖特征的机会并不多。
那么应该怎么复现论文,其实论文中已经教你怎么复现了。我拿最经典的deepfm举例,很多博客或者知乎,都给了这张图:
从这张图,我们都知道FM Layer把每个Fields映射成embedding,然后求点积,最后线性加权。好像很简单,如何复现呢?难道是这样(伪代码):
# 省略FM Layer的bias
def FM_Layer(dense_embs):
dot_list = []
for i in range(len(dense_embs)):
for j in range(i + 1, len(dense_embs)):
dot_list.append(dot(dense_embs[i], dense_embs[j]))
return dot_list
这在tensorflow中咋写,还要写两个for循环?论文中给了下式:
熟悉FM模型的肯定能第一时间想到化简公式:
然后,复现就简单了:
class FM_Block(layers.Layer):
# better add drop-out after this block
def __init__(self, **kwargs):
super(FM_Block, self).__init__(**kwargs)
def build(self,input_shape):
# input_shape must be in (None, Fields Num, K)
super(FM_Block,self).build(input_shape) # 相当于设置self.built = True
def call(self, inputs):
# sum square part 上图公式第一项
summed_features_emb = tf.reduce_sum(inputs, 1) # None * K
summed_features_emb_square = tf.square(summed_features_emb) # None * K
# square sum part 上图公式第二项
squared_features_emb = tf.square(inputs)
squared_sum_features_emb = tf.reduce_sum(squared_features_emb, 1) # None * K
# second order 1/2 (第一项 - 第二项)
y_second_order = 0.5 * tf.subtract(self.summed_features_emb_square, self.squared_sum_features_emb) # None * K
return y_second_order
def get_config(self):
config = super(FM_Block, self).get_config()
config.update({})
return config
看多很多复现代码,你会发现,很多推荐模型相关的代码并不难,有很多复现技巧隐藏在论文公式中。
结语
Echoes Of The Rainbow
说了这么多,十方还是希望大家在阅读论文中,能真正学到东西的。十方后面会出一系列“保姆”级的论文复现文章,旨在帮助大家能独立复现很多论文。