当前位置: 首页 > 科技观察

Keras还是TensorFlow?程序员应该如何选择深度学习框架?

时间:2023-03-21 20:54:46 科技观察

深度学习发展迅猛,但是近两年涌现的很多深度学习框架让初学者无所适从。如谷歌的TensorFlow、亚马逊的MXN??et、Facebook的PyTorch、Theano、Caffe、CNTK、Chainer、百度的PaddlePaddle、DSSTNE、DyNet、BigDL、Neon等。其中,TensorFlow是最著名的深度学习生产环境框架。它具有非常强大的生态系统支持。但是,与其他框架相比,TensorFlow也有其缺点,如速度慢、使用困难等。Keras建立在TensorFlow的基础上,提供了简单易用的API接口,非常适合初学者。2017年1月,随着Keras作者、谷歌AI研究员FrancoisChollet发布消息,Keras成为第一个加入TensorFlow核心的高级框架,Keras从此成为Tensorflow的默认API。“那么,我应该在我的项目中使用Keras还是TensorFlow?Keras和TensorFlow哪个更好?我应该花时间研究TensorFlow还是Keras?”在一次与包括工程师在内的深度学习研究人员、从业者的讨论中,《DeepLearningforComputerVisionwithPython》一书的作者AdrianRosebrock听到了他们的困惑。就Keras和TensorFlow而言,Rosebrock认为开发人员更应该关心的是,当Keras真正被完全采用并集成到TensorFlow中时,他们可以:使用Keras易于使用的界面定义模型。如果您需要特定于TensorFlow的功能,或者需要实现Keras不支持但TensorFlow支持的自定义功能,请调用TensorFlow。他的建议是从Keras开始,然后下载TensorFlow以获得您可能需要的任何特定功能。在文中,Rosebrock展示了如何使用Keras训练神经网络,以及如何使用直接内置在TensorFlow库中的Keras+TensorFlow集成(带有自定义函数)来训练模型。正文从这里开始:▌比较Keras和TensorFlow毫无意义多年前,深度学习领域的研究人员、开发人员和工程师经常不得不做出一些选择:我应该选择易于使用但难以定制的Keras吗?图书馆?或者我应该使用更难的TensorFlowAPI并编写大量代码?(更不用说一个不太容易使用的API。)如果你被“我应该使用Keras还是TensorFlow”的问题困扰,你可以退后一步,看看这实际上是一个错误的问题,因为你可以选择两者同时使用。我将使用基于TensorFlow的标准keras模块和tf.keras模块来实现卷积神经网络(CNN)。然后,在示例数据集上训练这些CNN,并检查结果,您会发现Keras和TensorFlow可以和谐共存。虽然TensorFlow早在一年多前就宣布将Keras纳入TensorFlow的正式版,但令我惊讶的是,很多深度学习开发者仍然没有意识到他们可以通过Keras的tf.keras子模块来调用它。更重要的是,Keras和TensorFlow是无缝连接的,我们可以直接将TensorFlow的源代码写入Keras模型中。将Keras与TensorFlow相结合具有双赢的效果:您可以使用Keras提供的简单、原生的API来创建您自己的模型。Keras的API和scikit-learn的类似,堪称机器学习的优质API。Keras的API是模块化的、基于Python的,并且非常易于使用。当您需要实现自定义层或更复杂的损失函数时,您可以深入研究TensorFlow并将代码与Keras模型自动集成。▌Keras通过tf.keras模块内置到TensorFlow可以看到,我们通过引入TensorFlow(tf)并调用tf.keras来表明Keras实际上是Pythonshell中TensorFlow的一部分。tf.keras中的Keras允许我们使用标准的Keras包来获得一个简单的前馈神经网络,如下所示:接下来,基于TensorFlow的一部分——tf.keras子模块,实现相同的网络:然而,这样做意味着你必须使用tf.keras?那么现在放弃使用标准的Keras包了吗?当然不是!Keras仍然是一个库,与TensorFlow分开,独立运行,因此两者未来仍有可能分开;然而,我们知道谷歌官方同时支持Keras和TensorFlow,分离似乎极不可能发生。但关键是:如果你更喜欢只在Keras上编程,那就去做吧,而且你总是可以这样做。但如果你是TensorFlow用户,你应该开始考虑KerasAPI,因为:它是基于TensorFlow创建的它更易于使用当你需要使用纯TensorFlow实现特定性能或功能时,它可以直接在你的Keras中使用。▌示例数据集CIFAR-10数据集有10个类别,我们用这个数据集来说明本文的观点。为简单起见,我们在CIFAR-10数据集上训练两个独立的卷积神经网络(CNN),解决方案如下:方法一:以TensorFlow为后端的Keras模型方法二:使用tf.keras中的Keras子模块引入时,我还将展示如何将自定义TensorFlow代码写入您的Keras模型。CIFAR-10数据集包括10个独立的类别、50,000张训练图像和10,000张测试图像。▌项目结构我们可以在终端使用tree命令查看项目结构:pyimagesearch模块包含在与web入口相关的下载中。它不能通过pip安装,但包含在“下载”之后的结果中。我们先回顾一下本模块中两个重要的Python文件:minivggnetkeras.py:该文件基于Keras实现的MiniVGGNet网络,是一种基于VGGNet的深度学习模型。minivggnettf.py:该文件是基于TensorFlow+Keras(如tf.keras)实现的MiniVGGNet网络。项目根目录包含两个Python文件:train_network_keras.py:用Keras实现的训练脚本;train_network_tf.py:TensorFlow+Keras实现所需的训练脚本,与前者基本相同;但我们仍然会解释它并标记差异。每个脚本都会生成自己的训练精度和损失曲线:plot_keras.pngplot_tf.png接下来介绍基于Keras和TensorFlow+Keras(tf.keras)实现的MiniVGGNet网络及其训练过程。▌用Keras训练神经网络在Keras中实现的一个miniVGGNet卷积神经网络结构训练我们网络的第一步是在Keras中搭建网络的架构。如果您已经熟悉在Keras中训练神经网络的基础知识,那么让我们开始吧(如果您还不熟悉,请参阅相关介绍文章)。相关链接:https://www.pyimagesearch.com/2018/09/10/keras-tutorial-how-to-get-started-with-keras-deep-learning-and-python/首先,打开minivggnetkeras.py文件并插入以下代码:通过导入一系列所需的Keras库来构建模型。然后,定义一个MiniVGGNetKeras类:我们在第12行定义了build方法,定义了inputShape和输入参数。我们假设顺序是通道最后,所以inputShape参数中的最后一个值应该对应于深度值。让我们开始定义卷积神经网络的主要结构:从上面的代码可以观察到我们堆叠了一系列的卷积(conv2D)、ReLU激活函数和批量归一化层(batchnormalization)来减少卷积操作后的空间维度.此外,我们还使用了dropout技术来防止模型的过拟合现象。图层类型和相关术语可以参考之前的Keras教程https://www.pyimagesearch.com/2018/09/10/keras-tutorial-how-to-get-started-with-keras-deep-learning-and-python/如果想深入学习,推荐《DeepLearningforComputerVisionwithPython》这本书https://www.pyimagesearch.com/deep-learning-computer-vision-python-book/然后,连接fullLayer(FC)被添加到网络结构中,代码如下:我们将FC层和Softmax分类器添加到网络中。然后我们定义神经网络模型并将其返回给调用函数。我们现在已经在Keras中实现了CNN模型的定义。接下来,我们创建用于训练模型的程序脚本。打开train_network_keras.py文件并插入以下代码:我们首先在代码的第2-13行导入模型训练所需的包。需要注意的一点:在第3行,我们将Matplotlib的后端设置为Agg,这样我们就可以将训练图保存为图像文件。在第6行,我们导入了MiniVGGNetKeras类。我们使用scikit-learn库中的LabelBinarizer方法进行one-hot编码,并使用其classification_report方法打印出分类准确率统计信息(分别对应第7行和第8行)。我们在第10行导入训练所需的数据库。如何使用自定义数据集,请参考https://www.pyimagesearch.com/2018/09/10/keras-tutorial-how-to-get-started-with-keras-deep-learning-and-python/https://www.pyimagesearch.com/2018/04/16/keras-and-convolutional-neural-networks-cnns/此外,我们解析命令行参数(输出--plot路径)。接下来,我们加载CIFAR-10数据集并对标签进行编码。代码如下:在第24和25行,我们加载并提取了训练和测试所需的数据,同时在第26和27行,对数据进行了浮点+标度的转换。第30-36行我们对标签进行编码并初始化真实的标签名称。模型定义和数据集导入工作已经完成。现在我们可以开始训练我们的模型了,代码如下:第40-46行,我们设置了训练过程中需要的一些参数和模型优化方法。然后在第47-50行,我们使用MiniVGGNetKeras.build方法初始化我们的模型并编译它。最后,模型的训练过程从第54行和第55行开始。接下来,我们评估网络模型并生成结果图:这里我们在测试数据上评估我们的模型并生成分类报告。最后,我们整合评估结果并导出结果图。请注意,通常在这里我们会序列化并导出我们的模型,以便我们可以在图像或视频处理脚本中使用它,但我们不会在本教程中介绍它。如果你想运行上面的脚本,请务必下载本文的源代码。然后,通过打开终端并执行以下命令,可以使用Keras实现神经网络:在我计算机的CPU上运行每个训练周期仅需5分钟多一点。训练结果如下:用Keras实现的神经网络模型,以及用Matplotlib绘制的训练过程的accuracy/loss曲线从上面终端的输出可以看出,我们的模型达到了75%的准确率。虽然这不是最先进的模型,但它可以比随机猜测(1/10)做得更好。与较小的神经网络相比,我们模型的结果实际上非常好!此外,正如我们在图6的输出中看到的那样,我们的模型没有过度拟合。▌使用Tensorflow和tf.keras训练神经网络模型使用tf.keras(TensorFlow内置模块)构建的MiniVGGNetCNN架构与我们直接使用Keras构建的模型是一样的。这里为了演示,我把激活函数改了一下,其他结构都是一样的。上面我们已经能够使用Keras库实现和训练一个简单的CNN模型。接下来,我们要做的是:1.学习如何使用TensorFlow中的tf.keras模块实现相同的网络架构2.在我们的Keras模型中包含一个TensorFlow激活函数,这在Keras中没有实现。接下来,让我们开始吧。首先打开minivggnettf.py文件,我们要实现TensorFlow版本的MiniVGGNet模型,代码如下:在这个.py文件中,注意第2行我们需要导入需要的tensorflow依赖库,tensorflow附带tf.keras子模块,其中包含我们可以直接调用的所有Keras函数。在模型定义中,我使用了Lambda层,代码中用黄色高亮显示,可以用来插入自定义激活函数CRELU(ConcatenatedReLUs),激活函数CRELU是Shang等人开发的。在论文《UnderstandingandImprovingConvolutionalNeuralNetwork》中提出。CRELU激活函数在Keras中没有对应的实现,但是在TensorFlow中有。您可以在TensorFlow中的tf.keras模块中使用一行代码将CRELU函数添加到我们的Keras模型中。还要注意:CRELU函数有两个输出,一个正ReLU和一个负ReLU,它们是串联的。对于x的正值,CRELU函数的返回值为[x,0];对于x的负值,CRELU函数的返回值为[0,x]。关于这个功能的详细介绍可以在Shang等人的论文中找到。接下来,我们将使用TensorFlow+Keras来定义训练MiniVGGNetTF模型的程序。打开train_network_tf.py并插入以下代码:在第2-12行,我们导入训练过程所需的依赖项。与我们之前的Keras版本的训练脚本相比,唯一的变化是我们将MiniVGGNetTF类和tensorflow作为tf导入,而不是使用Keras。第15-18行是我们的命令行参数解析部分。和之前一样,我们在第23行加载模型训练所需的数据。脚本的其余部分与之前Keras版本的训练过程相同,提取并分离训练和测试数据并对我们的标签进行编码。接下来开始训练我们的模型,代码如下:第39-54行与Keras版本的训练过程不同,我们用黄色高亮显示,其余相同。在第58-73行,我们根据测试数据评估我们的模型并绘制最终结果。如您所见,我们只是改变了使用的方法(使用tf.keras)并实现了几乎相同的训练过程。然后,打开一个终端,执行如下命令使用tensorflow+tf.keras训练一个神经网络模型:训练完成后,可以得到类似上图的训练结果图:NeuralnetworkmodelimplementedwithTensorflow+tf.keras,给Matplotlib画出了训练过程的accuracy/loss曲线。可以看出,我们将原来的RELU激活函数替换为CRELU,获得了76%的准确率;然而,1%的准确率提升可能是由于网络中权重的随机初始化导致的,还需要交叉验证实验来进一步证明CRELU激活函数是否确实可以提高模型的准确率。当然,原始精度不是本节的重点。相反,更需要我们关注的是如何将标准的Keras激活函数替换为Keras模型内部的TensorFlow激活函数!或者,您可以使用自定义激活函数、损失/成本函数或层来执行上述相同的操作。▌总结今天的文章,我们主要讨论了以下关于Keras和TensorFlow的问题:我的项目应该用Keras还是TensorFlow?TensorFlow比Keras好吗?我应该花时间学习TensorFlow还是Keras?最终,我们发现试图在Keras和TensorFlow之间做出选择变得越来越无关紧要。Keras库已通过tf.keras模块直接集成到TensorFlow中。从本质上讲,您可以通过易于使用的KerasAPI对您的模型和训练过程进行编码,然后在纯TensorFlow中进行自定义实现。所以,如果你正准备开始学习深度学习,或者想知道你的下一个项目应该是“Keras还是TensorFlow?”是时候了,我给你的建议很简单:从不说话开始!在您的Python项目中键入importkeras或importtensorflowastf(以便您可以访问tf.keras)并开始使用。TensorFlow可以直接集成到您的模型和训练过程中,因此您可以直接在您的项目中使用TensorFlow或Keras,而不是比较特性、功能或易用性。▌读者提问有读者提出了尖锐的问题:根据以上和我的理解,很多开发者还在纠结什么是Keras和TensorFlow。我可能对它们知之甚少,但我仍然希望提出一些澄清的问题:其中之一,将一个视为计算引擎而将另一个视为一种工具包是否正确?如果是这样,我猜TensorFlow是工具包而Keras是计算后端?第二个是你也提到了TensorFlow和Caffe的整合,但是Caffe为了支持Keras已经放弃了。你能分享一下你为什么这样做吗?是因为Caffe不再可用,还是因为Keras的功能更多了?对此,AdrianRosebrock回应:是的,Keras本身依赖于TensorFlow、Theano、CNTK等后端来执行实际计算。Caffe仍然存在,只是其他功能已被纳入Caffe2。TensorFlow从来都不是Caffe的一部分。我们仍然使用Caffe,尤其是研究人员。但从业者,尤其是Python从业者,更喜欢编程友好的库,例如TensorFlow、Keras、PyTorch或mxnet。您对此有何疑问或意见?欢迎留言。