我正在尝试在Keras中实现Subpixel向上卷积层。我可以毫无问题地训练模型并保存。但是我无法加载该模型。我总是会得到尺寸错误的错误。
唯一可行的方法是保存权重,创建新模型,然后加载权重。但这并不是理想的,因为优化器会重置,因此很难恢复训练。
import keras
import numpy as np
import tensorflow as tf
class Subpixel(keras.layers.Conv2D):
def __init__(self,
filters,
kernel_size,
scale,
padding='valid',
data_format='channels_last',
strides=(1, 1),
activation=None,
use_bias=True,
kernel_initializer='he_normal',
bias_initializer='zeros',
kernel_regularizer=None,
bias_regularizer=None,
activity_regularizer=None,
kernel_constraint=None,
bias_constraint=None,
**kwargs):
super().__init__(
filters=scale * scale * filters,
kernel_size=kernel_size,
strides=strides,
padding=padding,
data_format=data_format,
activation=activation,
use_bias=use_bias,
kernel_initializer=kernel_initializer,
bias_initializer=bias_initializer,
kernel_regularizer=kernel_regularizer,
bias_regularizer=bias_regularizer,
activity_regularizer=activity_regularizer,
kernel_constraint=kernel_constraint,
bias_constraint=bias_constraint,
**kwargs)
self.scale = scale
self.data_format = data_format
def call(self, inputs):
return tf.depth_to_space(super().call(inputs), self.scale)
def compute_output_shape(self, input_shape):
if self.data_format == 'channels_first':
b, k, r, c = super().compute_output_shape(input_shape)
return b, k // (self.scale ** 2), r * self.scale, c * self.scale
else:
b, r, c, k = super().compute_output_shape(input_shape)
return b, r * self.scale, c * self.scale, k // (self.scale ** 2)
def get_config(self):
config = super(keras.layers.Conv2D, self).get_config()
config['filters'] = int(config['filters'] / self.scale * self.scale)
config['scale'] = self.scale
return config
X = np.random.rand(100, 2, 2, 1)
y = np.random.rand(100, 4, 4, 1)
inputs = keras.layers.Input(shape=(2, 2, 1))
x = Subpixel(4, 4, 2, padding='same')(inputs)
output = keras.layers.Dense(1, activation='sigmoid')(x)
model = keras.models.Model(inputs, output)
model.compile(optimizer='sgd',
loss='mean_absolute_error',
metrics=[])
model.fit(X, y)
model.save('foo.h5')
foo = keras.models.load_model('foo.h5', custom_objects={'Subpixel': Subpixel})
似乎重量文件中的形状与加载的体系结构之间存在冲突。在加载的模型上,内核形状不正确。它应为4,4,1,16时为4,4,1,64。输出如下:
self = TensorShape([Dimension(4), Dimension(4), Dimension(1), Dimension(64)])
other = TensorShape([Dimension(4), Dimension(4), Dimension(1), Dimension(16)])
def assert_is_compatible_with(self, other):
"""Raises exception if `self` and `other` do not represent the same shape.
This method can be used to assert that there exists a shape that both
`self` and `other` represent.
Args:
other: Another TensorShape.
Raises:
ValueError: If `self` and `other` do not represent the same shape.
"""
if not self.is_compatible_with(other):
> raise ValueError("Shapes %s and %s are incompatible" % (self, other))
E ValueError: Shapes (4, 4, 1, 64) and (4, 4, 1, 16) are incompatible
答案 0 :(得分:0)
极其愚蠢的错误。该行:
config['filters'] = int(config['filters'] / self.scale * self.scale)
应该是:
config['filters'] = int(config['filters'] / (self.scale * self.scale))
否则,在序列化图层时,将保存错误的过滤器输入参数。基本上我对运算符的优先级感到困惑。
答案 1 :(得分:0)
我有类似的错误,但这不是由错误或错别字引起的。相反,我在TensorFlow中遇到了一个错误,并设法通过在重新安装最新版本之前先卸载tensorflow软件包来解决该问题。
因此
pip uninstall tensorflow-gpu
pip uninstall tensorflow-cpu
pip uninstall tensorflow
pip install --upgrade tensorflow
是我的把戏。