我正在尝试使用tf.keras构建SegNet,但是在使用tf.keras.layers.UpSampling时遇到了一些问题。我不知道如何获取maxpooling的mask(index)并将其用于tf.keras.layers.UpSampling。
我已经在https://github.com/tensorflow/tensorflow/blob/r1.12/tensorflow/python/keras/layers/convolutional.py中看到了tf.keras.layers.UpSampling的代码 似乎没有此功能的实现。
然后我尝试找到一些替代方法,并且在 https://github.com/ykamikawa/tf-keras-SegNet/blob/master/layers.py
我通过简单的测试尝试了此方法,但遇到了一些问题。代码如下:
from tensorflow.keras.layers import Layer
import tensorflow as tf
class MaxPoolingWithArgmax2D(Layer):
def __init__(
self,
pool_size=(2, 2),
strides=(2, 2),
padding='same',
**kwargs):
super(MaxPoolingWithArgmax2D, self).__init__(**kwargs)
self.padding = padding
self.pool_size = pool_size
self.strides = strides
def call(self, inputs, **kwargs):
padding = self.padding
pool_size = self.pool_size
strides = self.strides
ksize = [1, pool_size[0], pool_size[1], 1]
padding = padding.upper()
strides = [1, strides[0], strides[1], 1]
output, argmax = tf.nn.max_pool_with_argmax(
inputs,
ksize=ksize,
strides=strides,
padding=padding)
argmax = tf.cast(argmax, tf.float32)
return [output, argmax]
def compute_output_shape(self, input_shape):
ratio = (1, 2, 2, 1)
output_shape = [
dim//ratio[idx]
if dim is not None else None
for idx, dim in enumerate(input_shape)]
output_shape = tuple(output_shape)
return [output_shape, output_shape]
def compute_mask(self, inputs, mask=None):
return 2 * [None]
class MaxUnpooling2D(Layer):
def __init__(self, size=(2, 2), **kwargs):
super(MaxUnpooling2D, self).__init__(**kwargs)
self.size = size
def call(self, inputs, output_shape=None):
updates, mask = inputs[0], inputs[1]
with tf.variable_scope(self.name):
mask = tf.cast(mask, tf.int32)
# input_shape = tf.shape(updates, out_type='int32')
input_shape = updates.shape
# calculation new shape
if output_shape is None:
output_shape = (
input_shape[0],
input_shape[1]*self.size[0],
input_shape[2]*self.size[1],
input_shape[3])
self.output_shape1 = output_shape
# calculation indices for batch, height, width and feature maps
one_like_mask = tf.ones_like(mask, dtype='int32')
batch_shape = tf.concat(
[[input_shape[0]], [1], [1], [1]],
axis=0)
batch_range = tf.reshape(
tf.range(output_shape[0], dtype='int32'),
shape=batch_shape)
b = one_like_mask * batch_range
y = (mask // (output_shape[2] * output_shape[3]))
x = (mask // output_shape[3]) % output_shape[2]
feature_range = tf.range(output_shape[3], dtype='int32')
f = one_like_mask * feature_range
# transpose indices & reshape update values to one dimension
updates_size = tf.size(updates)
indices = tf.transpose(tf.reshape(
tf.stack([b, y, x, f]),
[4, updates_size]))
values = tf.reshape(updates, [updates_size])
ret = tf.scatter_nd(indices, values, output_shape)
return ret
def compute_output_shape(self, input_shape):
mask_shape = input_shape[1]
return (
mask_shape[0],
mask_shape[1]*self.size[0],
mask_shape[2]*self.size[1],
mask_shape[3]
)
def segmet(channels_in,channels_out):
inputs = tf.keras.layers.Input(shape=(None,None,channels_in))
outputs,mask = MaxPoolingWithArgmax2D()(inputs)
outputs = MaxUnpooling2D()([outputs,mask])
model = tf.keras.models.Model(inputs,outputs,name='segnet')
return model
if __name__ is '__main__':
model = segmet(3,6)
我遇到如下错误:
回溯(最近通话最近一次):
文件“”,第1行,在 runfile('C:/Users/WWW/Desktop/untitled0.py',wdir ='C:/ Users / WWW / Desktop')
文件 “ C:\ Soft \ Anaconda3 \ lib \ site-packages \ spyder \ utils \ site \ sitecustomize.py”, 运行文件中的第710行 execfile(文件名,命名空间)
文件 “ C:\ Soft \ Anaconda3 \ lib \ site-packages \ spyder \ utils \ site \ sitecustomize.py”, 第101行,在execfile中 exec(compile(f.read(),文件名,'exec'),命名空间)
文件“ C:/Users/WWW/Desktop/untitled0.py”,第108行,在 型号= segmet(3,6)
segmet中的文件“ C:/Users/WWW/Desktop/untitled0.py”,第102行 输出= MaxUnpooling2D()([输出,掩码])
文件 “ C:\ Soft \ Anaconda3 \ lib \ site-packages \ tensorflow \ python \ keras \ engine \ base_layer.py”, 第757行,在致电中 输出= self.call(输入,* args,** kwargs)
通话中文件“ C:/Users/WWW/Desktop/untitled0.py”,第69行 轴= 0)
文件 “ C:\ Soft \ Anaconda3 \ lib \ site-packages \ tensorflow \ python \ ops \ array_ops.py”, 1124行,在concat 返回gen_array_ops.concat_v2(values = values,axis = axis,name = name)
文件 “ C:\ Soft \ Anaconda3 \ lib \ site-packages \ tensorflow \ python \ ops \ gen_array_ops.py”, concat_v2中的第1202行 “ ConcatV2”,值=值,轴=轴,名称=名称)
文件 “ C:\ Soft \ Anaconda3 \ lib \ site-packages \ tensorflow \ python \ framework \ op_def_library.py”, _apply_op_helper中的第483行 引发TypeError(“%s都不全。”%前缀)
TypeError:传递给“ ConcatV2” Op的“值”的列表中的张量具有 类型[,int32,int32,int32]不 全部匹配。
因为tf.keras模型中的输入没有固定大小。因此,以上代码中的output_shape为[None,None,None,3]。诸如tf.concat和tf.reshape之类的函数无法处理“无”。然后,张量流给出一个错误。我知道为什么会发生错误,但是我不知道如何解决它。
有人可以帮助我吗?谢谢。