因此,我目前正在学习如何使用子类化在TensorFlow中创建模型.根据本教程,以下代码片段应该可以完美运行:

#Defining the class
class FeatureExtractor(Layer):
    def __init__(self):
        super().__init__()

        self.conv_1 = Conv2D(filters = 6, kernel_size = 4, padding = "valid", activation = "relu")
        self.batchnorm_1 = BatchNormalization()
        self.maxpool_1 = MaxPool2D(pool_size = 2, strides=2)

        self.conv_2 = Conv2D(filters = 16, kernel_size = 4, padding = "valid", activation = "relu")
        self.batchnorm_2 = BatchNormalization()
        self.maxpool_2 = MaxPool2D(pool_size = 2, strides=2)


    def call(self, x):
        x = self.conv_1(x)
        x = self.batchnorm_1(x)
        x = self.maxpool_1(x)

        x = self.conv_2(x)
        x = self.batchnorm_2(x)
        x = self.maxpool_2(x)

        return x

#Calling and using the class
feature_extractor = FeatureExtractor()

func_input = Input(shape=(IMG_SIZE, IMG_SIZE, 3), name="Input_Image")

x = feature_extractor(func_input)

而且它确实运行得无懈可击.但后来我意识到,在__init__()中,BatchNormalization()MaxPool2D()看起来是一样的,但被定义了两次,而不是被重复使用,所以我做了一些研究和asked on Stackoverflow,得出了when layers are called in 104, they adapt to the dimension of the input, and then keep that dimension for later calls的结论,这阻止了这些层能够被重复使用.

但正如Fynn在我的previous question中指出的那样,maxpool个成员实际上可以重复使用,而batchnorm个成员不能.那么,一些层适应输入的维度(比如batchnorm),而另一些不适应(比如maxpool)?或者是这些层的某个属性导致了这种行为?(我可以在文档中查找)

推荐答案

一般来说,有些层有参数,这些参数不能被重用,除非在某些边缘情况下,但它们可能不应该被重用.在这个具体的例子中,批处理规范化具有可学习的betagamma参数,以及用于推理的不可训练的参数(如果这对您没有任何意义,我建议您详细查看批处理规范是如何工作的).

现在,一个层对象只有一组参数,如果要重复使用该对象,相同的参数将应用于多个位置.请考虑以下几点:

self.conv_1 = Conv2D(filters = 6, kernel_size = 4, padding = "valid", activation = "relu")
self.batchnorm = BatchNormalization()
self.maxpool_1 = MaxPool2D(pool_size = 2, strides=2)

self.conv_2 = Conv2D(filters = 16, kernel_size = 4, padding = "valid", activation = "relu")
self.maxpool_2 = MaxPool2D(pool_size = 2, strides=2)

并假设在both个卷积之后将使用batchnorm.在这个例子中,batchnorm将被构建为具有6个beta/gamma,因为这是第一层中的过滤器的数量;try 将其重新用于第二层将不起作用,因为它具有16个过滤器,需要16个beta/gamma.这就是为什么只创建一个batchnorm层是行不通的.

以下代码应实际运行:

self.conv_1 = Conv2D(filters = 16, kernel_size = 4, padding = "valid", activation = "relu")
self.batchnorm = BatchNormalization()
self.maxpool_1 = MaxPool2D(pool_size = 2, strides=2)

self.conv_2 = Conv2D(filters = 16, kernel_size = 4, padding = "valid", activation = "relu")
self.maxpool_2 = MaxPool2D(pool_size = 2, strides=2)

我将其更改为两个卷积都使用16个滤光片.然而,这将在两个层之后重复使用same Beta/Gamma(因为我们使用相同的BatchNorm对象),这可能不是一个好主意.

对于MaxPool来说,这不是问题,因为它没有任何参数.具有相同窗口大小和步长的池化对于任何输入都是相同的.

Python相关问答推荐

比较2 PD.数组的令人惊讶的结果

带条件计算最小值

对整个 pyramid 进行分组与对 pyramid 列子集进行分组

当从Docker的--env-file参数读取Python中的环境变量时,每个\n都会添加一个\'.如何没有额外的?

对象的`__call__`方法的setattr在Python中不起作用'

Pandas DataFrame中行之间的差异

形状弃用警告与组合多边形和多边形如何解决

有没有一种ONE—LINER的方法给一个框架的每一行一个由整数和字符串组成的唯一id?

joblib:无法从父目录的另一个子文件夹加载转储模型

计算天数

如何使用SentenceTransformers创建矢量嵌入?

在matplotlib中使用不同大小的标记顶部添加批注

Cython无法识别Numpy类型

递归函数修饰器

仅使用预先计算的排序获取排序元素

如何将返回引用的函数与pybind11绑定?

如何获取包含`try`外部堆栈的`__traceback__`属性的异常

我怎么才能用拉夫分拣呢?

高效地计算数字数组中三行上三个点之间的Angular

如何将验证器应用于PYDANC2中的EACHY_ITEM?