__index__ вернул не-int (тип NoneType): используйте тензорную динамику c для создания пользовательского слоя - PullRequest
1 голос
/ 04 марта 2020

Я пишу пользовательский слой Keras (используя слой Lamba) для достижения стохастической c понижающей дискретизации (представленной в [1]). Это в основном то, что показано на изображении: stochastic_downsampling

Проблема в том, что форма тензора, используемого для l oop, переменной '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, поэтому, возможно, решение имеет базовый c, но как я могу сделать свой слой "Dynami c" для каждого заданного тензора? Я также пытаюсь дать N значение stati c, передающее значение 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. и Варшней А. (2017). Объемная сегментация с использованием сверточных нейронных сетей с ограниченными данными обучения. В 2017 году IEEE Международная конференция по обработке изображений (ICIP), стр. 590–594.

Заранее большое спасибо за вашу помощь! : DD

1 Ответ

0 голосов
/ 11 марта 2020

Для тех, кто может застрять: я перешел на 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...