在 Tensorflow 2.0 中是不是有更简单的方法来执行模型层?
Posted
技术标签:
【中文标题】在 Tensorflow 2.0 中是不是有更简单的方法来执行模型层?【英文标题】:Are there easier ways to excute model's layers in Tensorflow 2.0?在 Tensorflow 2.0 中是否有更简单的方法来执行模型层? 【发布时间】:2020-12-27 11:59:27 【问题描述】:假设我使用 Tensorflow 2.0 中的 Keras 子类化 API 制作了一个自定义模型,如下所示。
class MyModel(Model):
def __init__(self):
super(MyModel, self).__init__()
self.conv1 = Conv2D(32, 3, activation='relu')
self.flatten = Flatten()
self.d1 = Dense(128, activation='relu')
self.d2 = Dense(10, activation='softmax')
def call(self, x):
x = self.conv1(x)
x = self.flatten(x)
x = self.d1(x)
return self.d2(x)
model = MyModel()
如果层数不多,写类的'def call'也没那么烦。
我只需要像上面那样写下 3~4 行图层。
但是如果层数增加 50~60 甚至更高呢?
我必须输入所有这些图层吗?不知道有没有更好的方法?
期待您的回答。提前谢谢!
【问题讨论】:
我没有密切关注TF,但上次看到Keras,有Sequential
。没有了吗?
@dedObed 它还有Sequential
。感谢您的评论!
【参考方案1】:
您可以创建一个循环来一次创建多个层,然后使用 for 循环调用它们。
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
import tensorflow as tf
from functools import partial
x = tf.random.uniform((5, 2), 0, 1)
class MyModel(tf.keras.Model):
def __init__(self):
super(MyModel, self).__init__()
dense_layer = partial(tf.keras.layers.Dense, units=3, activation='relu')
self.layer_list = [dense_layer(name=f'layer_i') for i in range(3)]
self.out = tf.keras.layers.Dense(1, activation='sigmoid')
def call(self, x, training=None, **kwargs):
for layer in self.layer_list:
x = layer(x)
x = self.out(x)
return x
model = MyModel()
model.build(input_shape=(5, 2))
print(list(map(lambda x: x.name, model.layer_list)))
['layer_0', 'layer_1', 'layer_2']
model(x)
<tf.Tensor: shape=(5, 1), dtype=float32, numpy=
array([[0.51850706],
[0.5285746 ],
[0.51396513],
[0.5171388 ],
[0.50938624]], dtype=float32)>
有些架构会重复自己(例如,连续多次的卷积层和最大池化层),因此您可以创建返回多个层的函数,然后使用循环来创建其中的许多层。为避免重复所有内容,我使用了functools.partial,它使用默认参数创建了一个可调用对象。
import os
os.environ['CUDA_VISIBLE_DEVICES'] = '-1'
import tensorflow as tf
from functools import partial
x = tf.random.uniform((5, 256, 256, 3), 0, 1)
def conv_block(units):
conv = partial(tf.keras.layers.Conv2D, kernel_size=(3, 3), activation='relu')
pool = partial(tf.keras.layers.MaxPooling2D, pool_size=(2, 2))
layer_dict =
'conv1': conv(units),
'pool1': pool(),
'conv2': conv(units*2),
'pool2': pool(),
'conv3': conv(units*3)
return layer_dict
class MyModel(tf.keras.Model):
def __init__(self):
super(MyModel, self).__init__()
self.block_list = [conv_block(i) for i in range(1, 3)]
self.flat = tf.keras.layers.Flatten()
self.out = tf.keras.layers.Dense(1, activation='sigmoid')
def call(self, x, training=None, **kwargs):
for block in self.block_list:
for layer in block.values():
x = layer(x)
x = self.flat(x)
x = self.out(x)
return x
model = MyModel()
model.build(input_shape=(5, 256, 256, 3))
model(x)
<tf.Tensor: shape=(5, 1), dtype=float32, numpy=
array([[0.48275623],
[0.48887327],
[0.49217385],
[0.48883903],
[0.48933515]], dtype=float32)>
如你所见,我生成了两次这个块:
model.layers
[<tensorflow.python.keras.layers.convolutional.Conv2D at 0x1b404f47b08>,
<tensorflow.python.keras.layers.convolutional.Conv2D at 0x1b40be6cb48>,
<tensorflow.python.keras.layers.convolutional.Conv2D at 0x1b40d6eab88>,
<tensorflow.python.keras.layers.pooling.MaxPooling2D at 0x1b40be6cb08>,
<tensorflow.python.keras.layers.pooling.MaxPooling2D at 0x1b40d6ddc08>,
<tensorflow.python.keras.layers.convolutional.Conv2D at 0x1b40d6f2188>,
<tensorflow.python.keras.layers.convolutional.Conv2D at 0x1b40d6f2bc8>,
<tensorflow.python.keras.layers.convolutional.Conv2D at 0x1b40d6f0648>,
<tensorflow.python.keras.layers.pooling.MaxPooling2D at 0x1b40d6f2748>,
<tensorflow.python.keras.layers.pooling.MaxPooling2D at 0x1b40d6f01c8>,
<tensorflow.python.keras.layers.core.Flatten at 0x1b40d6f8cc8>,
<tensorflow.python.keras.layers.core.Dense at 0x1b40d6ee248>]
【讨论】:
这与我正在寻找的答案有点接近。谢谢!【参考方案2】:在 TF 2.0 中创建类更容易与 Pytorch 和其他深度学习框架竞争。但是,如果您的模型是顺序的,将层堆叠在一起,您仍然可以通过 example 应用它。
对于需要执行多个输出的模型,像SSD或YOLO这样的并行计算,像类一样全面编写更好,或者您可以通过将多个输入和多个输出传递给模型来直接使用Model(example)
【讨论】:
但我建议您应该坚持使用类继承模型以进行进一步的高级开发 你为什么这么认为? 对于更高的模型,您需要一次声明多个并行模型。当您编写顺序时,它会很容易但过于庞大。这就是为什么 Pytorch 非常受欢迎的原因。有时间你应该试试 哦,我明白了。再次感谢您的建议! 我可能是错的,但我根本不明白这如何回答这个问题......以上是关于在 Tensorflow 2.0 中是不是有更简单的方法来执行模型层?的主要内容,如果未能解决你的问题,请参考以下文章
Anaconda 安装 TensorFlow 1.15 而不是 2.0
tensorflow 2.0中是不是有mtcnn人脸检测的实现?
在 Tensorflow 2.0 中的简单 LSTM 层之上添加注意力