【深度学习】聊聊Keras的特点及其与其他框架的关系
共 7576字,需浏览 16分钟
·
2021-08-01 03:03
导读:独立的Keras和内置的Keras有什么不一样吗?我又该选择哪一种呢?
现在说到开发深度学习模型,都先做个二选一:是工程能力更强的Tensorflow?还是语法更加Pythonic的Pytorch?当然还有一些其它框架,远没成气候。不过聊着聊着,有时候会蹦出一个新词,叫Keras。如果你去网上一查,发现这个Keras也是个Python的深度学习包,热度也很高。
这就很容易让初学者疑惑了,而更容易疑惑的还在后头:这个Keras好像又和Tensorflow存在某种关系,有人说得先安装Tensorflow才能使用Keras,也有人说Keras是个独立的包直接安装就好。真是越发叫人摸不着头脑。
今天我们就来捋一捋这个听起来错综复杂的Keras。
现在Python下的深度学习包也不少了,叫什么名字一点不重要,我们先来看看用Keras做深度学习有什么优势。吴恩达在介绍深度学习的时候说过一句话,他说他喜欢神经网络能够像搭乐高积木一样搭起一款模型。
这个说法很形象。玩过乐高的都知道,乐高就是很多圆的、方的各种形状的小部件,单拿一块出来啥也不是,但是一旦把这些小部件组合起来,就可以搭建成许多意想不到的东西,小到巴掌大小的平板车,大到真人大小的钢铁侠模型都可以用乐高拼起来。
Keras就是可以用乐高的方式搭建出深度学习模型。
我们说深度学习也是神经网络,那比传统的神经网络模型好在哪里呢?好就好在多了很多好用的部件,譬如说池化层,譬如说LSTM,我们可以根据不同的任务目标,把各种部件像拼乐高一样组合起来,就可以搭建出一款好用的深度学习模型。
不过,理想很丰满,现实很骨感。Tensorflow就不用说了,语法怎么看怎么别扭,Pytorch在这方面要好太多,可是对于新手,特别是许多主要从事科研工作,此前没有太多编程基础的新手来说,用起来还是存在一些困难。
先来看一段用Pytorch搭建神经网络模型的代码:
device="cuda"iftorch.cuda.is_available()else"cpu"
classNeuralNetwork(nn.Module):
def __init__(self):
super(NeuralNetwork,self).__init__()
self.flatten=nn.Flatten()
self.linear_relu_stack=nn.Sequential(
nn.Linear(28*28,512),
nn.ReLU(),
nn.Linear(512,10),
nn.Softmax()
)
defforward(self,x):
x=self.flatten(x)
logits=self.linear_relu_stack(x)
returnlogits
model=NeuralNetwork().to(device)
这是个两层的基本模型。熟悉编程的同学应该一眼就能看出来,这里用到了一些面向对象的知识,对于不了解相关背景的同学来说其实不太好读。而这仅仅只是用Pytorch搭建模型的部分,搭建好了模型还得训练,这部分通常会另外定义一个函数:
deftrain(dataloader,model,loss_fn,optimizer):
size=len(dataloader.dataset)
forbatch,(X,y)inenumerate(dataloader):
X,y=X.to(device),y.to(device)
# Compute prediction error
pred=model(X)
loss=loss_fn(pred,y)
# Backpropagation
optimizer.zero_grad()
loss.backward()
optimizer.step()
ifbatch%100==0:
loss,current=loss.item(),batch*len(X)
然后写个for循环,把参数都填好,最后将前面的model传进去才能使用。客观地评价,Pytorch确实很Pythonic,真的是用Python的方式来写深度学习。不过,对于不熟悉Python也不在乎Pythonic,只想搭建深度学习模型的同学来说,这种写法还是觉得绕了一点,至少,和前面说的“搭乐高积木”还是很有距离。
同样的模型用Keras来写,就像多了。拢共分三步:
第一步,声明个模型:
model = models.Sequential()
第二步,把部件像乐高那样拼起来。两层的神经网络,那就用两个部件:
model.add(keras.layers.Dense(512, activation=keras.activations.relu, input_dim=28*28))
model.add(keras.layers.Dense(10, activation=keras.activations.softmax))
拼接就是“add”,拼两个部件那就add两次。Keras还支持一种更简洁的写法,可以将神经网络的各个层(Layer)全都写进一个List里,然后直接放进Sequential里面,连add都省了。有机会我们再展开聊聊。
到这里模型就已经算搭好了,可以用summary查看模型结构了。不过,别忘了搭好了模型还得训练,那就再加一句:
model.compile(loss='categorical_crossentropy',optimizer='sgd',metrics=['accuracy'])
齐活。怎么用呢?和ScikitLearn一样,只要把X和y传进去,然后fit就可以了:
model.fit(X,y)
多说一句,我们在Pytorch也看到了Sequential,这还是从Keras借鉴过去的,早期Pytorch搭建神经网络模型的语法还要更Pythonic一点。
前面我们已经看到使用Keras搭建深度学习模型的优点,那就是高度抽象,将各种不同的深度学习部件都封装成一个个组件,我们根本不需要了解部件内部的实现细节,只需要根据需要把它们像乐高积木一样逐一装配起来,一个符合需要的深度学习模型就搭建好了。
就我自己的感受,用Keras搭建深度学习模型感觉更像写配置文件,俗称“填表格”,需要什么只要在对应的地方填写就好了,不需要再花很多时间和一些编程特性打交道。这个特点很贴合现在一个很重要的思想,叫“开箱即用”。
当然,高度封装是优点也是缺点。既然是“封装”,那许多内部的底层的东西自然就不会暴露出来,从另一个角度来看,就是可操控性降低了,用很多人的说法就是,Keras不如Pytorch“灵活”。
我专门去找了一下,哪怕到了现在,网上对于Keras还是Pytorch的争论照样很多,我倒是觉得这场漫长争论最后也不会有一个公认的结果,究竟是选择Keras还是Pytorch,关键不是工具本身,而是使用工具的人的需求。如果你希望利用现有的深度学习部件快速搭建出可用的深度学习模型,Keras自然是你的首选。
好了,介绍完Keras的功能,那Keras究竟和Tensorflow是什么关系呢?
Keras是一个前端,需要其它深度学习框架提供后端支撑,而Tensorflow是其中之一,也是Keras当前默认的后端。
不过这是后话。Keras最开始的后端不是Tensorflow,而是Theano。这是怎么回事?Theano又是个啥?这事说来话长,我们长话短说。
在深度学习热起来,又还没这么热的时候,当时的研究人员使用的既不是Tensorflow也不是Pytorch,那时这俩框架估计还没立项,但当时也有不少框架,知名度高的有Caffe、Torch,Torch采用的是Lua语言,现在听到的不多,不过在当年也是以一己之力撑起半个圈的神奇角色,今天的PyTorch就是Torch的精神续作,名字的意思就是Python版的Torch。
还有一款用得很多的,叫Theano。这个框架现在已经停更了,估计知道的人不多,但当年非常热,Theano最早应该算是一款数学工具,填补了一大片空白,加上有Yoshua Bengio,Ian Goodfellow等大神的加持,当时在业界就是爆款。
Theano热到什么地步?当年我学习深度学习别人推荐的就是这款框架。当然这没啥说服力,不过大家如果去找一找,在大概16、17年的时候,深度学习圈也有个日经的问题,问的就是深度学习框架究竟该选Theano还是Tensorflow。
从某种意义上说,Theano和Tensorflow确实有很多相像的地方,特别是在用户体验一言难尽这一点上,这俩可谓是不分伯仲,相信经历过那个时代的同学一定都很赞同。
本来深度学习就是很新的东西,需要陡峭的学习曲线,而现在Theano的学习曲线搞不好还要更陡峭,面对这一对劝退组合,大家能怎办呢?于是,Keras就出来了。
Keras刚出来的时候,大家真的是惊为天人,哪怕是放在今天,使用Keras仍然是一件很愉悦的事。所以,Keras+Theano很快就成为那个时期深度学习研究人员的推荐配置。
这并不是说二者在设计水平上差别明显。底层是有底层的包袱的,要让框架能够跑起来,就必须得包含许多看着碍事但必须要有的东西,而高度封装的“高级API”则可以抛开这些包袱,将注意力集中在“更高级”的方面。
我不知道深度学习框架这种前端和后端的分法是不是从Keras开始的,不过最开始的时候,大家应该都是使用一套框架搭模型,只不过随着深度学习的铺开,有些人注重模型本身的开发,而有些人则注重模型的使用,需求有了分化,于是就有了前端和后端的划分。现在这种划分已经很普遍,除了Keras,还有知名的FastAI,这是Pytorch的前端。
不过,从技术的角度说,Keras只是一层蒙皮,把Theano丑陋磨人的地方给统统包起来,但实际发挥作用的还是Theano。这种做法自然也会带来一些新问题,大家关注度比较高的主要有两个,第一个就是前面所说的高度封装带来“灵活性”降低的问题。这个我们前面已经进行了讨论,主要看使用需要,在很多场景下,好用易用会更受关注。
第二个问题则是性能问题。Keras毕竟是在Theano之上又加了一层皮,不可避免地带来额外的性能损耗,这也是当时很令人纠结的地方,毕竟深度学习本身就很耗性能。不过还是那句话:没有绝对的正确。只有使用需要,许多人还是选择了牺牲性能,来换取使用体验的明显提升。
这就是Keras最开始的故事。Keras不仅好用,而且从工程的角度说,Keras也是一个优秀的前端,非常注意另一种灵活性:Keras不但支持Theano,也支持其它主流的深度学习框架作为后端,譬如谷歌的Tensorflow、微软的CNTK 、亚马逊的MXnet,不过无论从工程能力和用户规模来说,Tensorflow都远比其它框架热门,加上Tensorflow同样得了Theano的那种病,Keras+Tensorflow成为现在深度学习的标配也就理所当然。
最后说说Keras和Tensorflow的关系。有人说要使用Keras,必须先安装Tensorflow,这话也对也不对。
Keras最开始是以独立第三方库的形式出现,支持很多种后端,而默认是Theano。当时要使用Keras,至少需要做两件事,首先安装好一个后端,譬如Theano或者Tensorflow,然后安装Keras。都完成以后,就可以import keras来使用。
后来Tensorflow凭借工程优势逐渐取代了Theano的位置,但糟糕的用户体验很快又成为Tensorflow的短板,在大家都没得选的时候,也只能私下吐吐槽,但Pytorch出来以后,大家就开始用脚投票了。
Tensorflow很着急,也推出了许多解决方案,结果许多不同的设计逻辑混杂在一起,反而显得更加不伦不类了。这时Keras+Tensorflow也逐渐成为标配,既然已经有现成的解决方案何必从头再造轮子,于是双方一拍即合,成为官方钦定CP。
Tensorflow应该是从2.X版本开始内置Keras,也就是说,Keras正式成为Tensorflow底下的一个包,安装好Tensorflow之后,可以通过from tensorflow import keras直接使用,无需额外单独下载。不过Keras也并没有放弃独立性,大家同样可以继续单独安装Keras。
那这就有一个问题了,独立的Keras和内置的Keras有什么不一样吗?我又该选择哪一种呢?
这是个困扰了不少人的问题。官方的回答是:大同小异,Keras的主体功能是相同的,也就是无论是import keras,还是from tensorflow import keras,绝大部分代码应该是可以完全相同的。单从“高级API”的角度来说,两者并无不同。
那还有没有区别呢?有区别,区别在部分特性功能。Keras成为Tensorflow内置包以后,地位不一样了,自然也有一些“特供”能力,对于Tensorflow自身的一些特色功能提供额外的支撑。譬如说eager execution模式,这是Tensorflow被Pytorch打疼以后推出来的东西,涉及许多Tensorflow内部机制,如果需要操作相关对象,必须使用内置的Keras。此外还有支持TPU、支持tf.data等等特性,都是和Tensorflow密切相关的。
Keras近期还有一个新闻,说“Keras正式从Tensorflow的代码库剥离”。这是什么意思?Keras和Tensorflow分家了吗?不是的,正如字面上的意思,是代码剥离,,也就是Keras的代码不在混在Tensorflow的代码里面,有了自己独立的代码库。
从维护的角度看,代码独立以后,Keras的维护工作就更加容易,只需要管理Keras自己这部分,不需要再去和Tensorflow的代码掺和在一起了,举个简单例子,以后想要测试Keras,就只需要单独编译Keras就行,不必再去编译庞大又关系不大的Tensorflow了,节省了大量的时间。
那和Tensorflow在关系方面有什么变化吗?没有任何变化,Tensorflow依然是Keras的娘家,用官方的介绍就是,“Keras is a deep learning API written in Python, running on top ofthe machine learning platform TensorFlow.”
作者:莫凡,网名木羊同学。娱乐向机器学习解说选手,《机器学习算法的数学解析与Python实现》作者,前沿技术发展观潮者,擅长高冷技术的“白菜化”解说,微信公众号“睡前机器学习”,个人知乎号“木羊”。
推荐阅读
(点击标题可跳转阅读)
老铁,三连支持一下,好吗?↓↓↓