将模型内的张量流操作列表自动转换为 ListWrapper

Eyp*_*ros 5 python keras tensorflow

我正在检查 tf.keras 代码,发现在自定义 model.Model 实例内部时,tf分配给self变量的每个操作列表都会自动转换为ListWrapper对象。此功能的示例如代码所示:

from tensorflow.keras import models
from tensorflow.keras import layers
from tensorflow.keras import initializers


class CustomModel(models.Model):
    def __init__(self, width, depth, **kwargs):
        super(CustomModel, self).__init__(**kwargs)
        self.width = width
        options = {
            'kernel_size': 3,
            'strides': 1,
            'padding': 'same',
            'kernel_initializer': initializers.RandomNormal(mean=0.0, stddev=0.01, seed=None)
        }
        self.convs = [layers.Conv2D(filters=width, bias_initializer='zeros', name='convs_{}'.format(i), **options)
                      for i in range(depth)]
        self.conv = layers.Conv2D(filters=width, bias_initializer='zeros', name='conv_{}'.format(0), **options)
        self.conv2 = [layers.Conv2D(filters=width, bias_initializer='zeros', name='conv_{}'.format(0), **options)]

        self.depth = depth
Run Code Online (Sandbox Code Playgroud)

如果检查的话(例如在调试器中):

type(self.convs)
Run Code Online (Sandbox Code Playgroud)

tensorflow.python.training.tracking.data_structs.ListWrapper

type(self.conv)
Run Code Online (Sandbox Code Playgroud)

张量流.python.keras.layers.卷积.Conv2D

type(self.conv2)
Run Code Online (Sandbox Code Playgroud)

tensorflow.python.training.tracking.data_structs.ListWrapper

可以看出,是self.convsand self.conv2areListWrapper而不是 list。相反,如果该类不继承自Model

class CustomModel2(object):
    def __init__(self, width, depth, **kwargs):
        # super(CustomModel, self).__init__(**kwargs)
        self.width = width
        options = {
            'kernel_size': 3,
            'strides': 1,
            'padding': 'same',
            'kernel_initializer': initializers.RandomNormal(mean=0.0, stddev=0.01, seed=None)
        }
        self.convs = [layers.Conv2D(filters=width, bias_initializer='zeros', name='convs_{}'.format(i), **options)
                      for i in range(depth)]
        self.conv = layers.Conv2D(filters=width, bias_initializer='zeros', name='conv_{}'.format(0), **options)
        self.conv2 = [layers.Conv2D(filters=width, bias_initializer='zeros', name='conv_{}'.format(0), **options)]

        self.depth = depth
Run Code Online (Sandbox Code Playgroud)

创建通常的列表:

type(self.convs)
Run Code Online (Sandbox Code Playgroud)

列表

type(self.conv)
Run Code Online (Sandbox Code Playgroud)

张量流.python.keras.layers.卷积.Conv2D

type(self.conv2)
Run Code Online (Sandbox Code Playgroud)

列表

所以,我的问题是为什么会发生这种情况?使用列表比使用列表有什么优点ListWrapper?另外,我该如何使用这种类型?for例如,我知道我可以通过循环访问其成员。还有其他我应该了解的属性吗?

这里有一个类似的问题,但问题和答案都不令我满意。