python - 在 Tensorflow 2.0 中是否有更简单的方法来执行模型的层?
问题描述
假设我在 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 甚至更高呢?
我必须输入所有这些图层吗?难道没有更好的方法我不知道吗?
我期待你的答案。先感谢您!
解决方案
您可以创建一个循环来一次创建多个层,然后使用 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>]
推荐阅读
- c# - 如何使用 EF Core 仅加载第一个相关数据
- google-cloud-platform - 如何创建 SSLEngine 以连接到任何 https 网站,特别是谷歌云运行?
- python - python numpy:ValueError:形状(14,)和(404,14)未对齐:14(dim 0)!= 404(dim 0)
- php - PHP SOAP 请求未填充 XML 参数
- javascript - 未捕获的类型错误:无法读取未定义的属性“事务”,内容库
- c - 如何在 C 中为 getch() 函数定义某个时间?
- python - 获取 AttributeError:模块 'django.db.models' 在 Django 1.11 中没有属性 'UniqueConstraint'
- mongodb - MongoDB Map-Reduce:需要合并到所有其他匹配条件的文档中?
- angular - Angular - 在应用程序组件中获取路由数据
- c# - Why the value of "count" is showig 1 instead of 2?