__index__返回非int(类型为NoneType):使用张量动态形状创建自定义层



我正在编写一个自定义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)

最新更新