In the following two examples,that are all use the subclassing to construct the same model.Some strange problem occur about reused layers.the one can`t reused all layers,the another can`t reused a part of layers,such as Convolution,BatchNormization,but can reused the Activation layer.
why?
tensorflow version: 2.0.0
1. use the existing layers in tensorflow .
the all layers can`t be reused,such as convolution,BatchNormailzation,Activation.
In the following code,when I change 'conv2' to 'conv' or change 'bn2' to 'bn' or 'ac2' to 'ac' in call function , the error is threw.
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
from tensorflow.keras.layers import Conv2D, BatchNormalization, ReLU
class Models(tf.keras.Model):
def __init__(self):
super().__init__()
self.conv = Conv2D(16, (3, 3), padding='same')
self.bn = BatchNormalization()
self.ac = ReLU()
self.conv2 = Conv2D(32, (3, 3), padding='same')
self.bn2 = BatchNormalization()
self.ac2 = ReLU()
def call(self, x, **kwargs):
x = self.conv(x)
x = self.bn(x)
x = self.ac(x)
x = self.conv2(x)
x = self.bn2(x)
x = self.ac2(x)
return x
m = Models()
m.build(input_shape=(2, 8, 8, 3))
m.summary()
some error are threw,when resue layer,such as:
- reuse BatchNormalization layer:
ValueError: Input 0 of layer batch_normalization is incompatible with the layer: expected axis 3 of input shape to have value 16 but received input with shape [2, 8, 8, 32]
- reuse Convlution layer:
ValueError: Input 0 of layer conv2d is incompatible with the layer: expected axis -1 of input shape to have value 3 but received input with shape [2, 8, 8, 16]
- reuse Activation layer:
ValueError: You tried to call `count_params` on re_lu_1, but the layer isn't built. You can build it manually via: `re_lu_1.build(batch_input_shape)`.
2. use the customized layers extended from tensorflow .
In the following code,the result of reused convolution/BactchNorization layers are silmilar to previous code,but the Activation layer can reused!
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'
import tensorflow as tf
from tensorflow.keras import layers
class DoubleConv(layers.Layer):
def __init__(self, mid_kernel_numbers, out_kernel_number):
"""
初始化含有两个卷积的卷积块
:param mid_kernel_numbers: 中间特征图的通道数
:param out_kernel_number: 输出特征图的通道数
"""
super().__init__()
self.conv1 = layers.Conv2D(mid_kernel_numbers, (3, 3), padding='same')
self.conv2 = layers.Conv2D(out_kernel_number, (3, 3), padding='same')
self.bn = layers.BatchNormalization()
self.bn2 = layers.BatchNormalization()
self.ac = layers.ReLU()
self.ac2 = layers.ReLU()
def call(self, input, **kwargs):
"""正向传播"""
x = self.conv1(input)
x = self.bn(x)
x = self.ac(x)
x = self.conv2(x)
x = self.bn2(x)
x = self.ac2(x)
return x
class Model(tf.keras.Model):
def __init__(self):
"""
构建模型的类
"""
super().__init__()
# 初始化卷积块
self.block = DoubleConv(16, 32)
def call(self, x, **kwargs):
x = self.block(x)
return x
m = Model()
m.build(input_shape=(2, 8, 8, 3))
m.summary()
some error are threw,when resue layer,such as:
- reuse BatchNormalization layer:
ValueError: Input 0 of layer batch_normalization is incompatible with the layer: expected axis 3 of input shape to have value 16 but received input with shape [2, 8, 8, 32]
- reuse Convlution layer:
AttributeError: 'DoubleConv' object has no attribute 'conv'
There are two possibilities for my guess:
the one is relate to layer`s name.the other is relate to parameters.the activation layer not need parameters. But these can`t explain why there are difference.