问题描述
在下面的两个示例中,它们都使用子类来构造相同的模型。关于重用的层会出现一些奇怪的问题。一个层不能重用所有层,另一个不能重用一部分层,例如卷积,批处理规范化,但可以重用激活层。
为什么?
tensorflow版本:2.0.0
1。使用tensorflow中的现有层。
所有层都无法重用,例如卷积,批处理或激活。
在以下代码中,当我在调用函数中将“ conv2”更改为“ conv”或将“ bn2”更改为“ bn”或将“ ac2”更改为“ ac”时,就会抛出错误。
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,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,3))
m.summary()
在恢复图层时会抛出一些错误,例如:
- 重新使用Batchnormalization层:
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,32]
- 重复使用污染层:
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,16]
- 重用激活层:
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。使用从tensorflow扩展的自定义层。
在下面的代码中,重用的卷积/ Bactchnorization层的结果与以前的代码完全相同,但是激活层可以重用!
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,padding='same')
self.conv2 = layers.Conv2D(out_kernel_number,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,**kwargs):
x = self.block(x)
return x
m = Model()
m.build(input_shape=(2,3))
m.summary()
在恢复图层时会抛出一些错误,例如:
- 重新使用Batchnormalization层:
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,32]
- 重复使用污染层:
AttributeError: 'DoubleConv' object has no attribute 'conv'
我的猜测有两种可能性:
一个与层的名称有关,另一个与参数有关。激活层不需要参数。 但是这些无法解释为什么存在差异。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)