2017-02-11 11 views
2

Я прочитал бумагу Xception (есть описание Keras Model для описания NN), и речь идет о раздельных свертках. Я пытался понять, как точно они рассчитаны. Вместо того, чтобы оставлять это для неточных слов, я включил ниже приведенный ниже фрагмент псевдокода, который суммирует мое понимание. Карты кода из полнометражных карт 18x18x728 в виде 18x18x1024 один:Как рассчитать разделимые свертки в документе Xception?

XSIZE = 18; 
YSIZE = 18; 
ZSIZE = 728; 
ZSIXE2 = 1024; 

float mapin[XSIZE][YSIZE][ZSIZE]; // Input map 
float imap[XSIZE][YSIZE][ZSIZE2]; // Intermediate map 
float mapout[XSIZE][YSIZE][ZSIZE2]; // Output map 

float wz[ZSIZE][ZSIZE2]; // Weights for 1x1 convs 
float wxy[3][3][ZSIZE2]; // Weights for 3x3 convs 

// Apply 1x1 convs 
for(y=0;y<YSIZE;y++) 
    for(x=0;x<XSIZE;x++) 
    for(o=0;o<ZSIZE2;o++){ 
     s=0.0; 
     for(z=0;z<ZSIZE;z++) 
     s+=mapin[x][y][z]*wz[z][o]; 
     imap[x][y][o]=s; 
    } 

// Apply 2D 3x3 convs 
for(o=0;o<ZSIZE2;o++) 
    for(y=0y<YSIZE;y++) 
    for(x=0;x<XSIZE;x++){ 
     s=0.0; 
     for(i=-1;i<2;i++) 
     for(j=-1;j<2;j++) 
      s+=imap[x+j][y+i][o]*wxy[j+1][i+1][o]; // This value is 0 if falls off the edge 
     mapout[x][y][o]=s; 
    } 

Правильно ли это? Если нет, можете ли вы предложить исправления, аналогично написанные на C или псевдо-C?

спасибо, что заранее.

ответ

0

Я нашел tf.nn.separable_conv2d в Tensorflow, который делает именно это. Поэтому я построил очень простой граф и с помощью случайных чисел попытался получить код выше, чтобы он соответствовал результату. Правильный код:

XSIZE = 18; 
YSIZE = 18; 
ZSIZE = 728; 
ZSIXE2 = 1024; 

float mapin[XSIZE][YSIZE][ZSIZE]; // Input map 
float imap[XSIZE][YSIZE][ZSIZE]; // Intermediate map 
float mapout[XSIZE][YSIZE][ZSIZE2]; // Output map 

float wxy[3][3][ZSIZE]; // Weights for 3x3 convs 
float wz[ZSIZE][ZSIZE2]; // Weights for 1x1 convs 


// Apply 2D 3x3 convs 
for(o=0;o<ZSIZE;o++) 
    for(y=0y<YSIZE;y++) 
    for(x=0;x<XSIZE;x++){ 
     s=0.0; 
     for(i=-1;i<2;i++) 
     for(j=-1;j<2;j++) 
      s+=mapin[x+j][y+i][o]*wxy[j+1][i+1][o]; // This value is 0 if falls off the edge 
     imap[x][y][o]=s; 
    } 

// Apply 1x1 convs 
for(y=0;y<YSIZE;y++) 
    for(x=0;x<XSIZE;x++) 
    for(o=0;o<ZSIZE2;o++){ 
     s=0.0; 
     for(z=0;z<ZSIZE;z++) 
     s+=imap[x][y][z]*wz[z][o]; 
     mapout[x][y][o]=s; 
    } 

Главное отличие состоит в том, чтобы выполнялись две группы сверток. К моему удивлению, заказ важен даже тогда, когда ZSIZE == ZSIZE2.