Keras与tf.keras:TensorFlow 2.0有什么区别?

  在本教程的第一部分中,我们将讨论Keras和TensorFlow之间相互交织的历史,包括他们共同的受欢迎程度如何相互滋养,相互促进和滋养,使我们走向今天。
  然后,我将讨论为什么您应该在以后的所有深度学习项目和实验中都使用tf.keras。
  接下来,我将讨论“计算后端”的概念,以及TensorFlow的流行度如何使其成为Keras最流行的后端,从而为Keras集成到TensorFlow的tf.keras子模块中铺平了道路。
  最后,我们将讨论作为Keras用户应关注的一些最受欢迎的TensorFlow 2.0功能,包括:会话和渴望执行自动区分模型和层子类化更好的多GPU /分布式培训支持TensorFlow 2.0中包含完整的功能。由TensorFlow Lite(用于移动和嵌入式设备)和TensorFlow Extended组成的生态系统,用于开发生产机器学习管道(用于部署生产模型)。
  让我们开始吧!

Keras和TensorFlow之间的纠缠关系

在这里插入图片描述
  在TensorFlow 2.0中,您应该使用tf.keras而不是单独的Keras软件包。
  理解Keras和TensorFlow之间复杂而纠缠的关系就像聆听两个高中情侣的爱情故事,他们开始约会,分手并最终找到了自己的路,这很长,很详尽,有时甚至是矛盾的。我们不会为您回忆完整的爱情故事,而是会回顾CliffsNotes:

  • Keras最初是由Google AI开发人员/研究员Francois Chollet创建和开发的。
  • Francois于2015年3月27日提交了Keras的第一个版本并将其发布到他的GitHub。
  • 最初,Francois开发了Keras来促进他自己的研究和实验。
  • 但是,随着深度学习的普及爆炸,由于其易于使用的API,许多开发人员,程序员和机器学习从业者蜂拥至Keras。
  • 那时,没有太多的深度学习库可供使用-热门的库包括Torch,Theano和Caffe。
    • 这些库的问题在于,这就像试图编写程序集/ C ++来执行您的实验一样—繁琐,耗时且效率低下。
    • 另一方面,Keras非常易于使用,这使得研究人员和开发人员可以更快地迭代他们的实验。
  • 为了训练自己的自定义神经网络,Keras需要一个后端。
    • 后端是一个计算引擎-它构建网络图/拓扑,运行优化器并执行实际的数字运算。
    • 要了解后端的概念,请考虑从头开始构建网站。在这里,您可以使用PHP编程语言和SQL数据库。您的SQL数据库是您的后端。您可以使用MySQL,PostgreSQL或SQL Server作为数据库。但是,用于与数据库交互的PHP代码不会更改(当然,前提是您使用的是某种抽象数据库层的MVC范例)。本质上,PHP并不关心使用哪个数据库,只要它符合PHP的规则即可。
    • Keras也是如此。您可以将后端视为数据库,将Keras视为用于访问数据库的编程语言。您可以交换任何您喜欢的后端,只要它遵守某些规则,您的代码就不必更改。
    • 因此,您可以将Keras视为一组简化了深度学习的抽象(请注意:尽管Keras始终启用快速原型制作,但对于研究人员来说不够灵活。TensorFlow2.0对此进行了更改-在以后的内容中将对此进行详细介绍)。
  • 最初,Keras的默认后端是Theano,直到v1.1.0为止都是默认的。
  • 同时,Google发布了TensorFlow,这是一个用于机器学习和训练神经网络的符号数学库。
    • Keras开始支持TensorFlow作为后端,但缓慢但可以肯定的是,TensorFlow成为最受欢迎的后端,因此从Keras v1.1.0版本开始,TensorFlow成为默认的后端。
  • 从定义上讲,一旦TensorFlow成为Keras的默认后端,TensorFlow和Keras的使用量就会一起增长-如果没有TensorFlow,就无法拥有Keras,并且如果在系统上安装了Keras,那么您还将安装TensorFlow。
  • 同样,TensorFlow用户越来越被高级Keras API的简单性吸引。
  • TensorFlow v1.10.0中引入了tf.keras子模块,这是将Keras直接集成在TensorFlow包本身中的第一步。
    • tf.keras软件包与您将通过pip安装的keras软件包分开(即pip install keras)。
    • 原始的keras软件包不包含在tensorflow中以确保兼容性,因此它们都可以有机地发展。
  • 但是,现在情况正在发生变化-当Google在2019年6月发布TensorFlow 2.0时,他们宣布Keras现在是TensorFlow的官方高级API,可以快速,轻松地进行模型设计和训练。
  • 在Keras 2.3.0发行版中,Francois表示:
    • 这是Keras的首个发行版,使keras软件包与tf.keras同步。
    • 这是Keras的最终发行版,它将支持多个后端(即Theano,CNTK等)。
    • 最重要的是,所有深度学习从业人员都应将其代码切换到TensorFlow 2.0和tf.keras软件包。
    • 原始的keras软件包仍将收到错误修复,但是继续前进,您应该使用tf.keras。

  如您所知,Keras和TensorFlow之间的历史悠久,复​​杂且交织在一起。但是,作为Keras用户,对您来说最重要的收获是,您应该在将来的项目中使用TensorFlow 2.0和tf.keras。

在以后的所有项目中开始使用tf.keras

在这里插入图片描述
  2019年9月17日,Keras v2.3.0正式发布-在发行版Francois Chollet(Keras的创建者和首席维护者)中指出:“Keras v2.3.0是Keras的第一个版本,它使keras与tf.keras同步。它将是支持TensorFlow以外的后端(例如Theano,CNTK等)的最后一个主要版本,最重要的是,深度学习从业人员
应该开始转向TensorFlow 2.0和tf.keras软件包”

TensorFlow 2.0中的会话和eager execution

在这里插入图片描述

  是一种处理动态计算图的Python方式。 TensorFlow 2.0支持即时执行(PyTorch也是如此)。
您可以利用TensorFlow 2.0和tf.keras的热切执行和会话。
  使用tf.keras中的Keras API的TensorFlow 1.10+用户将熟悉创建会话以训练其模型:

with tf.Session() as session:
	session.run(tf.global_variables_initializer())
	session.run(tf.tables_initializer())
	model.fit(X_train, y_train, validation_data=(X_valid, y_valid),
		epochs=10, batch_size=64)

  创建Session对象并要求提前构建整个模型图有点麻烦,因此TensorFlow 2.0引入了Eager Execution的概念,从而将代码简化为:

model.fit(X_train, y_train, validation_data=(X_valid, y_valid),
	epochs=10, batch_size=64)

  Eager Execution的好处是不必构建整个模型图。取而代之的是,将立即评估操作,从而更轻松地开始构建模型(以及调试模型)。有关Eager执行的更多详细信息,包括如何与TensorFlow 2.0一起使用,请参阅本文。而且,如果您想比较“Eager Execution”与“Session”及其对训练模型速度的影响,请参阅此页面

Automatic differentiation and GradientTape with TensorFlow 2.0

在这里插入图片描述
  如果您是需要实施自定义图层或损失函数的研究人员,那么您可能不喜欢TensorFlow 1.x(理应如此)。至少可以说,TensorFlow 1.x的自定义实现很笨拙-仍有很多不足之处。随着TensorFlow 2.0版本的开始变化,现在实现您自己的自定义损失要容易得多。变得更容易的一种方法是通过自动区分和GradientTape实施。
  要利用GradientTape,我们要做的就是实现我们的模型架构:

# Define our model architecture
model = tf.keras.Sequential([
    tf.keras.layers.Dropout(rate=0.2, input_shape=X.shape[1:]),
    tf.keras.layers.Dense(units=64, activation='relu'),
    tf.keras.layers.Dropout(rate=0.2),
    tf.keras.layers.Dense(units=1, activation='sigmoid')
])

  定义损失函数和优化器:

# Define loss and optimizer
loss_func = tf.keras.losses.BinaryCrossentropy()
optimizer = tf.keras.optimizers.Adam()

  创建负责执行单个批处理更新的函数:

def train_loop(features, labels):
    # Define the GradientTape context
    with tf.GradientTape() as tape:
        # Get the probabilities
        predictions = model(features)
        # Calculate the loss
        loss = loss_func(labels, predictions)
    # Get the gradients
    gradients = tape.gradient(loss, model.trainable_variables)
    # Update the weights
    optimizer.apply_gradients(zip(gradients, model.trainable_variables))
    return loss

  然后训练模型:

# Train the model
def train_model():
    start = time.time()
    for epoch in range(10):
        for step, (x, y) in enumerate(dataset):
            loss = train_loop(x, y)
            print('Epoch %d: last batch loss = %.4f' % (epoch, float(loss)))
    print("It took {} seconds".format(time.time() - start))
# Initiate training
train_model()

  GradientTape魔术为我们在后台处理差异化处理,使处理自定义损失和图层变得更加容易。
说到自定义层和模型实现,一定要参考下一节。

Model and layer subclassing in TensorFlow 2.0

  TensorFlow 2.0和tf.keras为我们提供了三种单独的方法来实现我们自己的自定义模型:

  • Sequential
  • Function
  • Subclassing

  Sequential和Functional范例都已经在Keras中存在很长时间了,但是对于许多深度学习从业者来说,Subclass功能仍然是未知的。
  我将在下周针对这三种方法进行专门的教程,但是暂时,让我们看一下如何使用(1)TensorFlow 2.0,(2)tf基于开创性的LeNet架构实现简单的CNN。
keras,以及(3)模型子类化功能:

class LeNet(tf.keras.Model):
    def __init__(self):
        super(LeNet, self).__init__()
        self.conv2d_1 = tf.keras.layers.Conv2D(filters=6, 
                           kernel_size=(3, 3), activation='relu', 
                           input_shape=(32,32,1))
        self.average_pool = tf.keras.layers.AveragePooling2D()
        self.conv2d_2 = tf.keras.layers.Conv2D(filters=16, 
                           kernel_size=(3, 3), activation='relu')
        self.flatten = tf.keras.layers.Flatten()
        self.fc_1 = tf.keras.layers.Dense(120, activation='relu')
        self.fc_2 = tf.keras.layers.Dense(84, activation='relu')
        self.out = tf.keras.layers.Dense(10, activation='softmax')
        
    def call(self, input):
        x = self.conv2d_1(input)
        x = self.average_pool(x)
        x = self.conv2d_2(x)
        x = self.average_pool(x)
        x = self.flatten(x)
        x = self.fc_2(self.fc_1(x))
        return self.out(x)
    
lenet = LeNet()

  注意LeNet类是Model的子类。LeNet的构造函数(即init)定义了模型内部的每个单独层。
然后,call方法将执行前向传递,使您可以根据需要自定义前向传递。使用模型子类化的好处是您的模型:

  • 变得完全可定制。
  • 使您能够实施和利用自己的自定义损失实现。

  而且,由于您的体系结构继承了Model类,因此您仍然可以调用.fit()、. compile()和.evaluate()之类的方法,从而维护易于使用(且熟悉)的Keras API。
  如果您想了解有关LeNet的更多信息,可以参考上一篇文章

TensorFlow 2.0引入了更好的多GPU和分布式训练支持

在这里插入图片描述
  TensorFlow 2.0和tf.keras通过其MirroredStrategy提供更好的多GPU和分布式训练。引用TensorFlow 2.0文档,“ MirroredStrategy支持在一台机器上的多个GPU上的同步分布式训练”。如果要使用多台计算机(每台计算机可能具有多个GPU),则应查看MultiWorkerMirroredStrategy。或者,如果您使用Google的云进行训练,请查看TPUStrategy。不过,现在,假设您位于一台具有多个GPU的机器上,并且想要确保所有GPU都用于训练。
您可以先创建MirroredStrategy来完成此操作:

strategy = tf.distribute.MirroredStrategy()
print ('Number of devices: {}'.format(strategy.num_replicas_in_sync))

  然后,您需要声明您的模型架构,并在策略范围内对其进行编译:

# Call the distribution scope context manager
with strategy.scope():
    # Define a model to fit the above data
    model = tf.keras.Sequential([
        tf.keras.layers.Dropout(rate=0.2, input_shape=X.shape[1:]),
        tf.keras.layers.Dense(units=64, activation='relu'),
        tf.keras.layers.Dropout(rate=0.2),
        tf.keras.layers.Dense(units=1, activation='sigmoid')
    ])
    
    # Compile the model
    model.compile(loss='binary_crossentropy',
                optimizer='adam',
                metrics=['accuracy'])

然后从那里可以调用.fit来训练模型:

# Train the model
model.fit(X, y, epochs=5)

如果您的机器具有多个GPU,TensorFlow将为您处理多GPU训练。

翻译自:https://www.pyimagesearch.com/2019/10/21/keras-vs-tf-keras-whats-the-difference-in-tensorflow-2-0/

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值