as_strided: размер шага связывания (шаги conv2d) с параметром шагов as_strided.

Я обнаружил, что для создания (X - x + 1, Y - y + 1) патчей размером (x,y) из (X,Y) с шагом 1 изображение требует, чтобы мы задавали параметр шага как img.strides * 2 или img.strides + img.strides. Я не знаю, как они быстро вычисляют это, зная "нет". шагов в conv2d

Но что мне делать, чтобы получить ((X-x)/stride)+1, ((Y-y)/stride)+1 патчей одного размера из изображения того же размера с шагом stride?


Из этого SO ответ с небольшим изменением, с каналами и количеством изображений, размещенных впереди

def patchify(img, patch_shape):
    a,b,X, Y = img.shape                # a images and b channels
    x, y = patch_shape
    shape = (a, b, X - x + 1, Y - y + 1, x, y)
    a_str, b_str, X_str, Y_str = img.strides
    strides = (a_str, b_str, X_str, Y_str, X_str, Y_str)
    return np.lib.stride_tricks.as_strided(img, shape=shape, strides=strides)

Я вижу, что он создает скользящее окно с размером (x, y) и шагом 1 (перемещение на 1 пиксель вправо и перемещение на 1 пиксель вниз). У меня возникли проблемы с соотнесением параметра шагов, который использует as_strided, и шагов, которые мы обычно используем для conv2d.

Как добавить параметр в приведенную выше функцию, которая вычисляет параметр as_strided шагов?

def patchify(img, patch_shape, stride):    # stride=stepsize in conv2d eg: 1,2,3,...
    a,b,X,Y = img.shape                    # a images and b channels
    x, y = patch_shape
    shape = (a,b,((X-x)/stride)+1, ((Y-y)/stride)+1, x, y)
    strides = ???                          # strides for as_strided
    return np.lib.stride_tricks.as_strided(img, shape=shape, strides=strides)

изображение 4d (a, b, X, Y)

  • a=количество изображений,
  • b=количество каналов,
  • (X,Y) = ширина и высота

Примечание. Под stride in conv2d я подразумеваю stepsize К сожалению, это также называется шагом.

Примечание 2. Поскольку stepsize обычно будет одинаковым по обеим осям, в предоставленном коде я указал только один параметр, однако использовал его для обоих измерений.

Детская площадка: что нужно для strides здесь. У меня он работает для stepsize=1 здесь. Я заметил, что это может не работать по ссылке, но работает при вставке в новую игровую площадку.

Это должно дать четкое представление о том, что мне нужно:

[[ 0.5488135   0.71518937  0.60276338  0.54488318]
 [ 0.4236548   0.64589411  0.43758721  0.891773  ]
 [ 0.96366276  0.38344152  0.79172504  0.52889492]
 [ 0.56804456  0.92559664  0.07103606  0.0871293 ]]

# patch_size = 2x2
# stride = 1,1

[[[[ 0.5488135   0.71518937]
   [ 0.4236548   0.64589411]]

  [[ 0.71518937  0.60276338]
   [ 0.64589411  0.43758721]]

  [[ 0.60276338  0.54488318]
   [ 0.43758721  0.891773  ]]]


 [[[ 0.4236548   0.64589411]
   [ 0.96366276  0.38344152]]

  [[ 0.64589411  0.43758721]
   [ 0.38344152  0.79172504]]

  [[ 0.43758721  0.891773  ]
   [ 0.79172504  0.52889492]]]


 [[[ 0.96366276  0.38344152]
   [ 0.56804456  0.92559664]]

  [[ 0.38344152  0.79172504]
   [ 0.92559664  0.07103606]]

  [[ 0.79172504  0.52889492]
   [ 0.07103606  0.0871293 ]]]]

# stride = 2,2

[[[[[[ 0.5488135   0.71518937]
     [ 0.4236548   0.64589411]]

    [[ 0.60276338  0.54488318]
     [ 0.43758721  0.891773  ]]]


   [[[ 0.96366276  0.38344152]
     [ 0.56804456  0.92559664]]

    [[ 0.79172504  0.52889492]
     [ 0.07103606  0.0871293 ]]]]]]

# stride = 2,1

[[[[ 0.5488135   0.71518937]
   [ 0.4236548   0.64589411]]

  [[ 0.71518937  0.60276338]
   [ 0.64589411  0.43758721]]

  [[ 0.60276338  0.54488318]
   [ 0.43758721  0.891773  ]]]

 [[[ 0.96366276  0.38344152]
   [ 0.56804456  0.92559664]]

  [[ 0.38344152  0.79172504]
   [ 0.92559664  0.07103606]]

  [[ 0.79172504  0.52889492]
   [ 0.07103606  0.0871293 ]]]]

person Saravanabalagi Ramachandran    schedule 24.11.2017    source источник
comment
Какова форма входного массива?   -  person Divakar    schedule 24.11.2017
comment
Итак, вы ищете неперекрывающиеся патчи, верно? Какой будет форма выходного массива по отношению к форме входного массива?   -  person Divakar    schedule 24.11.2017
comment
Да, я тоже ищу неперекрывающиеся патчи, когда размер patch_size по каждому измерению равен шагу. Но я ищу функцию, которая будет принимать шаги в качестве входных данных, поэтому мы можем указать любой шаг, который в этом случае я бы дал ему так же, как patch_size[0]   -  person Saravanabalagi Ramachandran    schedule 24.11.2017
comment
@Divakar, какие шаги следует предпринять для неперекрывающихся патчей?   -  person Saravanabalagi Ramachandran    schedule 24.11.2017
comment
Я думаю, вы путаете шаги, которые мы получаем от img.strides, и ваш входной параметр stride. Это две разные вещи. Ваш stride, который я чувствую, больше похож на размер шага. Образец дела было бы неплохо, чтобы прояснить ситуацию.   -  person Divakar    schedule 24.11.2017
comment
Вы правы, под шагами в conv2d я подразумеваю размер шага. Я понимаю и вижу их как две разные вещи, но я не знаю, как их связать, например, почему для stepsize=1 мы используем strides=img.strides*2 для 2d-изображений, как указано в первой части вопроса.   -  person Saravanabalagi Ramachandran    schedule 24.11.2017
comment
@Divakar *какой strides вместо as_strided следует указать для неперекрывающихся патчей или stepsize=patch_size в каждом измерении?   -  person Saravanabalagi Ramachandran    schedule 24.11.2017


Ответы (1)


Вот один подход -

def patchify(img, patch_shape, stepsize_x=1, stepsize_y=1): 
    strided = np.lib.stride_tricks.as_strided
    x, y = patch_shape    
    p,q = img.shape[-2:]    
    sp,sq = img.strides[-2:]

    out_shp = img.shape[:-2] + (p-x+1,q-y+1,x,y)
    out_stride = img.strides[:-2] + (sp,sq,sp,sq)

    imgs = strided(img, shape=out_shp, strides=out_stride)
    return imgs[...,::stepsize_x,::stepsize_y,:,:]

Примеры запусков -

1] Вход:

In [156]: np.random.seed(0)

In [157]: img = np.random.randint(11,99,(2,4,4))

In [158]: img
Out[158]: 
array([[[55, 58, 75, 78],
        [78, 20, 94, 32],
        [47, 98, 81, 23],
        [69, 76, 50, 98]],

       [[57, 92, 48, 36],
        [88, 83, 20, 31],
        [91, 80, 90, 58],
        [75, 93, 60, 40]]])

2] Выход - Случай №1:

In [159]: patchify(img, (2,2), stepsize_x=1, stepsize_y=1)[0]
Out[159]: 
array([[[[55, 58],
         [78, 20]],

        [[58, 75],
         [20, 94]],

        [[75, 78],
         [94, 32]]],


       [[[78, 20],
         [47, 98]],

        [[20, 94],
         [98, 81]],

        [[94, 32],
         [81, 23]]],


       [[[47, 98],
         [69, 76]],

        [[98, 81],
         [76, 50]],

        [[81, 23],
         [50, 98]]]])

3] Выход - Случай № 2:

In [160]: patchify(img, (2,2), stepsize_x=2, stepsize_y=1)[0]
Out[160]: 
array([[[[55, 58],
         [78, 20]],

        [[58, 75],
         [20, 94]],

        [[75, 78],
         [94, 32]]],


       [[[47, 98],
         [69, 76]],

        [[98, 81],
         [76, 50]],

        [[81, 23],
         [50, 98]]]])

4] Выход - Случай №3:

In [161]: patchify(img, (2,2), stepsize_x=2, stepsize_y=2)[0]
Out[161]: 
array([[[[55, 58],
         [78, 20]],

        [[75, 78],
         [94, 32]]],


       [[[47, 98],
         [69, 76]],

        [[81, 23],
         [50, 98]]]])
person Divakar    schedule 24.11.2017
comment
возможно, я должен был четко определить размер шага. Я понял из приведенного выше кода. даже для stepsize=1 он не будет перекрываться, и, следовательно, истинный размер шага будет равен 2, что является размером патча. Итак, судя по вашему POV, моя проблема всегда перекрывается, в то время как мы можем вычислить неперекрывающиеся патчи, указав stepsize=patch_size. при условии, что размер патча одинаков в обоих измерениях - person Saravanabalagi Ramachandran; 24.11.2017
comment
@SaravanabalagiRamachandran Мне нужен примерный случай. - person Divakar; 24.11.2017
comment
@SaravanabalagiRamachandran Обновленное решение. - person Divakar; 24.11.2017
comment
Вы также должны опубликовать свое первоначальное предложение на @Divakar, чтобы показать альтернативы и позволить людям сравнить и сопоставить подход с использованием as_strided и без него. - person NaN; 24.11.2017
comment
@NaN Мой первоначальный предполагаемый неперекрывающийся случай, который не будет работать, учитывая изменения и комментарии, сделанные OP после этого, поскольку он был упомянут как перекрывающийся. Итак, заменили все. Я думаю, если кто-то ищет непересекающийся случай, этот оригинальный пост может им помочь, но здесь он больше не применим. - person Divakar; 24.11.2017
comment
поправьте меня, если я ошибаюсь, as_strides спроектирован так, чтобы всегда возвращаться с stepsize=1 (перекрывающимся), и хитрость заключается в том, чтобы отфильтровать те, которые мы хотим, из возвращаемого массива, чтобы получить stepsize›1 - person Saravanabalagi Ramachandran; 24.11.2017
comment
@SaravanabalagiRamachandran Вы поняли. - person Divakar; 24.11.2017