我正在编写一个自定义Keras层(使用Lamba层(来实现随机下采样(在[1]中介绍(。这基本上就是图像中出现的内容:随机_下采样
问题是,用于循环的张量的形状,即"N"变量,在使用时返回以下错误:
Creating the network . . .
Traceback (most recent call last):
File "/data2/dfranco/experimentosTFM/FIBSEM_EPFL/scripts/order_by_id/script_id_2000.py", line 553, in <module>
optimizer=optimizer, lr=learning_rate_value)
File "/data2/dfranco/experimentosTFM/FIBSEM_EPFL/scripts/order_by_id/../cheng_2017/asymmetric_unet.py", line 70, in asymmetric_U_Net
t_downsmp_layer=t_downsmp_layer)
File "/data2/dfranco/experimentosTFM/FIBSEM_EPFL/scripts/order_by_id/../cheng_2017/asymmetric_unet.py", line 147, in encode_block
'batch_size':batch_size})(inp_layer)
File "/home/dfranco/anaconda3/envs/baseTFM/lib/python3.6/site-packages/keras/engine/base_layer.py", line 457, in __call__
output = self.call(inputs, **kwargs)
File "/home/dfranco/anaconda3/envs/baseTFM/lib/python3.6/site-packages/keras/layers/core.py", line 687, in call
return self.function(inputs, **arguments)
File "/data2/dfranco/experimentosTFM/FIBSEM_EPFL/scripts/order_by_id/../cheng_2017/asymmetric_unet.py", line 218, in sto_downsampling2d
a = np.array([ [ [(c_rows[i], c_cols[j]) for j in range(sv_w*elem)] for i in range(sv_h*elem) ] for j in range(N) ])
TypeError: __index__ returned non-int (type NoneType)
我对张量流没有太多经验,所以也许解决方案是基本的,但是,我如何使我的层对给定的每个张量形状都是"动态的"?我也试图给N
一个静态值,传递batch_size
值作为自变量,但如果使用的训练数据不能被批次大小整除,训练过程就会崩溃,我的意思是,当它生成余数时,余数会生成最后一批比N的图像少的图像。
我的代码是:
def encode_block(inp_layer, channels, t_downsmp_layer=4, downsample=False):
if downsample == True:
shortcut_padded = Lambda(
sto_downsampling2d,
arguments={'t':t_downsmp_layer})(inp_layer)
shortcut_padded = Conv2D(1, (1, 1), activation=None) (shortcut_padded)
else:
shortcut_padded = Lambda(
pad_depth, arguments={'desired_channels':channels})(inp_layer)
x = BatchNormalization()(inp_layer)
x = PReLU() (x)
if downsample == True:
x = Conv2D(channels, (3, 3), activation=None, strides=(2, 2),
kernel_initializer='he_normal', padding='same') (x)
else:
#x = Conv2D(channels, (3, 3), activation=None,
# kernel_initializer='he_normal', padding='same') (x)
# Factorized kernels
x = Conv2D(channels, (1, 3), activation=None,
kernel_initializer='he_normal', padding='same') (x)
x = Conv2D(channels, (3, 1), activation=None,
kernel_initializer='he_normal', padding='same') (x)
x = Dropout(0.1)(x)
x = BatchNormalization()(x)
x = PReLU() (x)
x = Conv2D(channels, (3, 3), activation=None,
kernel_initializer='he_normal', padding='same') (x)
x = Add()([shortcut_padded, x])
return x
def sto_downsampling2d(x, t=4):
N = x.shape[0]
H = x.shape[1]
W = x.shape[2]
C = x.shape[3]
sv_h = int(H//t)
sv_w = int(W//t)
elem = int(t/2)
# Select random rows and columns
c_rows = np.zeros((sv_h*elem), dtype=np.int32)
c_cols = np.zeros((sv_w*elem), dtype=np.int32)
for i in range(0, sv_h*elem, elem):
nums = np.sort(np.random.choice(t, elem, replace=False))
for j in range(elem):
c_rows[i+j] = nums[j] + int(i/elem)*t
for i in range(0, sv_w*elem, elem):
nums = np.sort(np.random.choice(t, elem, replace=False))
for j in range(elem):
c_cols[i+j] = nums[j] + int(i/elem)*t
tc_rows = tf.constant(c_rows, dtype=tf.int32)
tc_cols = tf.constant(c_cols, dtype=tf.int32)
a = np.array([ [ [(c_rows[i], c_cols[j]) for j in range(sv_w*elem)] for i in range(sv_h*elem) ] for j in range(N) ])
ta = tf.constant(a, dtype=tf.int32)
ta = tf.transpose(tf.stack([ta for i in range(C)]), [1, 2, 3, 0, 4])
ta = tf.pad(ta, [[0,0], [0,0], [0,0], [0,0], [ 1, 1 ]])
return tf.gather_nd(x, ta)
[1] Cheng,H.-C.和Varshney,A.(2017(。体积分割使用训练数据有限的卷积神经网络。2017年IEEE国际图像处理会议(ICIP(,第590–594页。
提前非常感谢您的帮助!:DD
对于任何可能遇到这种情况的人:我转到Tensorflow 2.1,我可以将这个N
变量与None进行比较,作为if N is None:
,这在我运行的TF(1.12(的早期版本中是无法做到的。实际上,maxpooling层不会被执行,因为在训练时间N
会有一个值,但这个技巧有助于避免这个错误。
这是修改后的功能代码:
def sto_downsampling2d(x, t=4):
N = x.shape[0]
H = x.shape[1]
W = x.shape[2]
C = x.shape[3]
sv_h = int(H//t)
sv_w = int(W//t)
elem = int(t/2)
# Select random rows and columns
c_rows = np.zeros((sv_h*elem), dtype=np.int32)
c_cols = np.zeros((sv_w*elem), dtype=np.int32)
for i in range(0, sv_h*elem, elem):
nums = np.sort(np.random.choice(t, elem, replace=False))
for j in range(elem):
c_rows[i+j] = nums[j] + int(i/elem)*t
for i in range(0, sv_w*elem, elem):
nums = np.sort(np.random.choice(t, elem, replace=False))
for j in range(elem):
c_cols[i+j] = nums[j] + int(i/elem)*t
tc_rows = tensorflow.constant(c_rows, dtype=tensorflow.int32)
tc_cols = tensorflow.constant(c_cols, dtype=tensorflow.int32)
if N is None:
x = MaxPooling2D((2, 2)) (x)
return x
else:
a = np.array([ [ [(c_rows[i], c_cols[j]) for j in range(sv_w*elem)] for i in range(sv_h*elem) ] for j in range(N) ])
ta = tf.constant(a, dtype=tf.int32)
ta = tf.transpose(tf.stack([ta for i in range(C)]), [1, 2, 3, 0, 4])
ta = tf.pad(ta, [[0,0], [0,0], [0,0], [0,0], [ 1, 1 ]])
return tf.gather_nd(x, ta)