我正在编写一个定制的Keras层(使用Lamba层)以实现随机下采样(在[1]中引入)。基本上是图片中显示的内容: stochastic_downsampling
问题在于,用于循环的张量的形状(“ 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)
我对Tensorflow的经验不多,所以也许解决方案是基本的,但是如何为给定的每个张量形状使我的层“动态”?我还尝试给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
答案 0 :(得分:0)
对于任何可能对此有所困扰的人:我移至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)