行者知趣
框架是一种抽象。而抽象非常重要。
本质上,深度学习是在操作大量的浮点矩阵。但是,如果你在实现深度学习的时候,思考层次在矩阵乘法之类的上面,那这个层级太低了。
比如说,利用Keras搭一个深度学习模型,可能花不了一刻钟:
from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
model.add(Dense(units=64, activation='relu', input_dim=100))
model.add(Dense(units=10, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='sgd', metrics=['accuracy'])
model.fit(x_train, y_train, epochs=5, batch_size=32)
我们看到,使用框架,不仅写起来快,而且可读性很好。
上面的代码中,我们用了两个密集(Dense)层(也就是全连接的层):
- 第一层:输入维度100,神经元64个,激活函数ReLU
- 第二层:神经元10个,激活函数softmax
然后是编译模型,损失函数选交叉熵,优化用SGD(随机梯度下降),评估指标是精确度。
最后拟合训练数据,epoch为5,batch size为32.
如果我们不用框架,从头写起,一刻钟也许刚刚写好ReLU和softmax的定义。等我们把网络架构、损失函数、优化方法什么一一实现,可能已经过去一周了,而且我们自己实现的性能还不一定好。
然后,别人看我们的代码,密密麻麻的几千行,看起来也累。这都是抽象层次太低的缘故。
当然,另一方面,“框架”其实也“框”住了我们。上面的代码中,有一个`model.compile`的语句。这背后其实很有深义。我们需要先定义一个模型,然后编译,然后再运行。这是因为Keras基于TensorFlow,而TensorFlow是一个define-and-run的框架,不支持动态图模型。如果我们使用PyTorch、MXNet这样支持动态图模型的框架,就可以使用动态图模型,在运行中动态调整模型,也就是所谓define-by-run。(其实TensorFlow去年引入了贪婪执行模式,最近刚刚又推出了Swift For TensorFlow这样的研究项目,不过总的来说,TensorFlow的define-by-run模式还处于试验阶段。)
结一下,深度学习框架为我们提供了高层抽象,大大提升了开发效率,另一方面,也可能限制我们的思路,这个算是负作用吧。
论智
根据github上的star数量开看,目前市场占有率是:
tensorflow>keras>caffe>pytorch>Theano
tensorflow偏底层,对理解深度学习的模型设计有点用。我们熟知的AlphaGo就是构建在tensorflow上。keras更上层,是搭建在Theano、tensorflow和CNTK之上的,所以使用起来比较简单,缺点是不够灵活,因为毕竟它是在别人的基础上构建的。caffe算是深度学习早期发展最好的框架了,现在很多实验室还都偏向使用caffe,因为caffe不管是在训练阶段和投入到生产中运算速度都比较快。但是在研发迭代中因为修改会比较多的牵扯到c++和cuda编程,所以也是不够灵活易用的,它主要在计算机视觉方面表现比较好。然后pytorch,pytorch是今年或者去年年末才发布的,现在冲到第四的位置是很厉害,它和tensorflow相比一个很大的优势是它是动态神经网络。Theano是非常老牌的,它更适合数值计算优化。
如果新手入手学习,推荐tensorflow、keras和pytorch。