2016-10-08 4 views
0

나는 결과를 커피 결과와 비교하기 위해 스스로 컨볼 루션 함수를 작성하려고했습니다. 데모 프로그램을 실행하는 동안 아래쪽 및 위쪽 blob 데이터와 가중치를 사용했습니다. 나는 추출 된 자료가 정확하다는 것을 확신한다. 여기에 작성한 회선 테스트 코드가 있지만 결과는 다릅니다. 이 예에서는 64 개의 입력 기능 맵과 64 개의 출력 기능 맵이 있고 3x3 커널을 사용합니다. 이 프로그램은 64 개 파일에서 최하위 데이터를 읽고, 64x64 3x3 커널 및 가중치에 대한 가중치 및 바이어스를 읽고 컨볼 루션을 수행하고 최상위 데이터를 64 개 파일에 저장합니다. 아주 간단한 프로그램 .. 만약 내가 어떤 사람이라도 실수를 발견하고 알려 주시면 감사하겠습니다.컨볼 루션 결과가 카페의 컨볼 루션 결과와 다릅니다

// written by Chan Kim for simple convolution test 

/* 
layer 2 type Convolution num_bottoms 1 num_tops 1 
layer 2 bottom 0 shape "1 64 600 800 (30720000)" 
layer 2 top 0 shape = "1 64 600 800 (30720000)" 
layer 2 kernel_size = 3 
bottom size : 4*64*600*800 = 0x7530000 Bytes 
top size : 4*64*600*800 = 0x7530000 Bytes 
kernel size : 4*3*3*64*64 = 0x24000 Bytes 
in word size, bottom : 0x1d4c000 kernel : 0x9000 Words 
*/ 

#include <stdio.h> 
#define NUM_IFM 64 
#define NUM_OFM 64 
#define HEIGHT 600 
#define WIDTH 800 
#define K 3 // 3x3 kernel 
float bottom[1][NUM_IFM][HEIGHT][WIDTH]; 
float top[1][NUM_IFM][HEIGHT][WIDTH]; 
float weights[NUM_OFM][NUM_IFM][K][K]; 
float bias[NUM_OFM]; 
float conv[1][NUM_IFM][HEIGHT][WIDTH]; // result 
char str[80]; 
float kern[K][K]; 
float in_square[K][K]; 
float sum; 


#define layer 2 // for test 

main() 
{ 

FILE *file; 
int ifm_idx; 
int ofm_idx; 
int orix; 
int ocix; 
char c; 
int r; 
int rix, cix; 
char line[80]; 
char *ll; 
float v0, v1, v2, v3, v4, v5, v6, v7; 
int kyi, kxi; 
int orixm, orixp; 
int ocixm, ocixp; 
int kx, ky; 
int i; 

// -------------------------------------------------------- 
// reading blob data from files into blob memory 
// -------------------------------------------------------- 
printf("startnig!\n"); 
for(ifm_idx=0;ifm_idx<NUM_IFM;ifm_idx++) { 
    sprintf(str, "/home/ckim/Neuro/convhw/ext-z840/L%02d_Convolution_B0_FN%03d.txt", layer, ifm_idx); 
    file = fopen(str, "r"); 
    c = fgetc(file); 
    rix = -1; 
    while (c != EOF) { 
     if (c == '#') { 
      ll = fgets(line, 80, file); 
      c = fgetc(file); 
      rix++; 
      cix = 0; 
     } 
     else { 
      r = ungetc(c, file); 
      r = fscanf(file, "%f %f %f %f %f %f %f %f", &v0, &v1, &v2, &v3, &v4, &v5, &v6, &v7); 
      bottom[0][ifm_idx][rix][cix++] = v0; 
      bottom[0][ifm_idx][rix][cix++] = v1; 
      bottom[0][ifm_idx][rix][cix++] = v2; 
      bottom[0][ifm_idx][rix][cix++] = v3; 
      bottom[0][ifm_idx][rix][cix++] = v4; 
      bottom[0][ifm_idx][rix][cix++] = v5; 
      bottom[0][ifm_idx][rix][cix++] = v6; 
      bottom[0][ifm_idx][rix][cix++] = v7; 
      c = fgetc(file); 
     } 
    } 
    printf("file %s read.. \n",str); 
    fclose(file); 
} 

// -------------------------------------------------------- 
// reading weights from files into blob memory 
// -------------------------------------------------------- 
sprintf(str, "/home/ckim/Neuro/convhw/ext1/L%02d_Convolution_Weights.txt", layer); 
file = fopen(str, "r"); 
ll = fgets(line, 80, file); // read the layer config line 
for(ofm_idx = 0; ofm_idx < NUM_OFM; ofm_idx++) { 
//for(ifm_idx = 0; ifm_idx < NUM_IFM; ifm_idx++) { 
    ll = fgets(line, 80, file); // read the line '## For output map ofm_idx' 
    for(ifm_idx = 0; ifm_idx < NUM_IFM; ifm_idx++) { 
    //for(ofm_idx = 0; ofm_idx < NUM_OFM; ofm_idx++) { 
     ll = fgets(line, 80, file); // read the line '## for input map ifm_idx' 
     for(kyi = 0; kyi < K; kyi++) { 
     fscanf(file, "%f %f %f", &v0, &v1, &v2); // K=3 always 
      weights[ofm_idx][ifm_idx][kyi][0] = v0; 
      weights[ofm_idx][ifm_idx][kyi][1] = v1; 
      weights[ofm_idx][ifm_idx][kyi][2] = v2; 
     ll = fgets(line, 80, file); // read off remaining line 
     } 
    } 
    // read bias values 
} 
for(i = 0, ofm_idx = 0; i < NUM_OFM/8; i++){ 
    ll = fgets(line, 80, file); 
    r = fscanf(file, "%f %f %f %f %f %f %f %f", &v0, &v1, &v2, &v3, &v4, &v5, &v6, &v7); 
    bias[ofm_idx++] = v0; 
    bias[ofm_idx++] = v1; 
    bias[ofm_idx++] = v2; 
    bias[ofm_idx++] = v3; 
    bias[ofm_idx++] = v4; 
    bias[ofm_idx++] = v5; 
    bias[ofm_idx++] = v6; 
    bias[ofm_idx++] = v7; 
} 
fclose(file); 

// -------------------------------------------------------- 
// perform convolution 
// -------------------------------------------------------- 
printf("starting convolution..\n"); 
for(ofm_idx = 0; ofm_idx < NUM_OFM; ofm_idx++) { 
    printf("making OFM %d\n", ofm_idx); 
    for(orix = 0; orix < HEIGHT; orix++) { 
     for(ocix = 0; ocix < WIDTH; ocix++) { 

      sum = 0.; // for single point 

      // for each input maps 
      for(ifm_idx = 0; ifm_idx < NUM_IFM; ifm_idx++) { 

       // get kernel 
       kern[0][0] = weights[ofm_idx][ifm_idx][0][0]; 
       kern[0][1] = weights[ofm_idx][ifm_idx][0][1]; 
       kern[0][2] = weights[ofm_idx][ifm_idx][0][2]; 
       kern[1][0] = weights[ofm_idx][ifm_idx][1][0]; 
       kern[1][1] = weights[ofm_idx][ifm_idx][1][1]; 
       kern[1][2] = weights[ofm_idx][ifm_idx][1][2]; 
       kern[2][0] = weights[ofm_idx][ifm_idx][2][0]; 
       kern[2][1] = weights[ofm_idx][ifm_idx][2][1]; 
       kern[2][2] = weights[ofm_idx][ifm_idx][2][2]; 

       // zero-value padding (used in caffe) 
       in_square[0][0] = (orix == 0 ||ocix == 0) ? 0 : bottom[0][ifm_idx][orix][ocix]; 
       in_square[0][1] = (orix == 0) ? 0 : bottom[0][ifm_idx][orix][ocix]; 
       in_square[0][2] = (orix == 0 || ocix == WIDTH-1) ? 0 : bottom[0][ifm_idx][orix][ocix]; 
       in_square[1][0] = (ocix == 0) ? 0 : bottom[0][ifm_idx][orix][ocix]; 
       in_square[1][1] = bottom[0][ifm_idx][orix][ocix]; 
       in_square[1][2] = (ocix == WIDTH-1) ? 0 : bottom[0][ifm_idx][orix][ocix]; 
       in_square[2][0] = (orix == HEIGHT-1 || ocix == 0) ? 0 : bottom[0][ifm_idx][orix][ocix]; 
       in_square[2][1] = (orix == HEIGHT-1) ? 0 : bottom[0][ifm_idx][orix][ocix]; 
       in_square[2][2] = (orix == HEIGHT-1 || ocix == WIDTH-1) ? 0 : bottom[0][ifm_idx][orix][ocix]; 

       // apply kernel 
       for(ky = 0; ky < K; ky++) { 
        for(kx = 0; kx < K; kx++) { 
         sum += in_square[ky][kx]*kern[ky][kx]; 
        } 
       } 

       //// add bias 
       //sum += bias[ifm_idx]; 
      } // ifm_idx 

      // add bias 
      sum += bias[ofm_idx]; 
      // store result 
      conv[0][ofm_idx][orix][ocix] = sum; 
     } // ocix 
    } // orix 

    printf("OFM %d\n", ofm_idx); 
    sprintf(str, "./result/L%02d_Convolution_T0_FN%03d.txt", layer, ofm_idx); 
    file = fopen(str, "w"); 
    printf("writing convolution result to file %s..\n", str); 
    for (rix = 0; rix < HEIGHT; rix++) { 
     fprintf(file, "### kr = %d ##\n", rix); 
     for (cix = 0; cix < WIDTH; cix++) { 
      fprintf(file, "%f ",conv[0][ofm_idx][rix][cix]); 
      if (cix %8 == 7) fprintf(file, "\n"); 
     } 
    } 
    fclose(file); 
} 
printf("Convolution finished\n"); 

업데이트 : 커널을 전치 시도하고, 추출 커널 4 개 조합을 입력 - 출력 관계를 반대했지만, 일치하지 않습니다. 어쩌면 내가 카페 실행에서 값을 추출하는 방식에 뭔가 문제가있을 수 있습니다. 나는 caffe/src/caffe/net.cpp 파일의 convolution layer에서 bottom, top, weight 데이터를 추출하는 방법을 추가했다. 레이어 처리가 완료되면 추출됩니다.

//#define LayerShapeExtract 
//#define BlobExtract 
//#define WeightExtract 
#define LayerExtNum 2 
#define EXT_ALL_LAYERS 0 
int ccc; // for debug 
template <typename Dtype> 
Dtype Net<Dtype>::ForwardFromTo(int start, int end) { 
    CHECK_GE(start, 0); 
    CHECK_LT(end, layers_.size()); 
    Dtype loss = 0; 
    LOG(INFO) << "## : net_input_blobs_.size() : " << net_input_blobs_.size() << std::endl; 
    if (debug_info_) { 
    for (int i = 0; i < net_input_blobs_.size(); ++i) { 
     InputDebugInfo(i); 
    } 
    } 
    for (int i = start; i <= end; ++i) { 
    ccc = i; printf("ccc = %d\n", ccc); // LOG(ERROR) << "Forwarding " << layer_names_[i]; 
    Dtype layer_loss = layers_[i]->Forward(bottom_vecs_[i], top_vecs_[i]); // Layer::Forward 
    loss += layer_loss; 
    if (debug_info_) { ForwardDebugInfo(i); } 

#ifdef LayerShapeExtract 
// -------------------------------- start of shape extract --------------------- 
    FILE *lsfp; 
    lsfp = fopen("ext/layers.txt","w"); 
    fprintf(lsfp, "####### Layer Shape ########\n"); 
    fprintf(lsfp, "start = %d, end = %d\n", start,end); 
    for (int li = start; li <= end; ++li) { 
    fprintf(lsfp, "layer %d type %s num_bottoms %zu num_tops %zu\n", li, layers_[li]->type(), bottom_vecs_[li].size(), top_vecs_[li].size()); 
    for (int bi = 0; bi < bottom_vecs_[li].size(); bi++) { 
     fprintf(lsfp, "layer %d bottom %d shape \"%s\"\n", li, bi, bottom_vecs_[li][bi]->shape_string().c_str()); 
    } 
    for (int ti = 0; ti < top_vecs_[li].size(); ti++) { 
     fprintf(lsfp, "layer %d top %d shape = \"%s\"\n", li, ti, top_vecs_[li][ti]->shape_string().c_str()); 
    } 
    if (strcmp(layers_[li]->type(),"Convolution") == 0) { 
     fprintf(lsfp, "layer %d kernel_size = %d\n", li, layers_[li]->layer_param().convolution_param().kernel_size()); 
    } 
    } 
    fclose(lsfp); 
    //printf("##Net::ForwardFromTo ==> ####### End of Layer Shape ########\n"); 
// -------------------------------- end of shape extract --------------------- 
#endif 

#ifdef BlobExtract 
// -------------------------------- start of blob extract --------------------- 

if (i == LayerExtNum || EXT_ALL_LAYERS) { //print!! 
    char fname[50]; 
    FILE *extfp1; 
    for (int j = 0; j < bottom_vecs_[i].size(); j++) { 

     Blob<Dtype>* bp = bottom_vecs_[i][j]; 
     const Dtype *dptr = bp->cpu_data(); 
    if (bp->shape().size() == 4) { 
     for (int kn = 0; kn < bp->shape()[0]; kn++) { // Blob 
      for (int kd = 0; kd < bp->shape()[1]; kd++) { // Ni 
      sprintf(fname, "ext/L%02d_%s_B%d_FN%03d.txt", 
        i,layers_[i]->type(),j,kd); 
      extfp1 = fopen(fname,"w"); 
      for (int kr = 0; kr < bp->shape()[2]; kr++) { // Ny 
       fprintf(extfp1, "### kr = %d ##\n", kr); 
       for (int kc = 0; kc < bp->shape()[3]; kc++) { // Nx 
        fprintf(extfp1, "%f ",*dptr++); 
        if (kc %8 == 7 || kc == bp->shape()[3]-1) fprintf(extfp1, "\n"); 
       } 
      } 
      fclose(extfp1); 
      } 
     } 
    } // if size 4 
    else if (bp->shape().size() == 2) { 
     for (int kn = 0; kn < bp->shape()[0]; kn++) { // Blob 
      sprintf(fname, "ext/L%02d_%s_B%d_FN%03d.txt", 
       i,layers_[i]->type(),j,kn); 
      extfp1 = fopen(fname,"w"); 
      for (int kd = 0; kd < bp->shape()[1]; kd++) { // Ni 
        fprintf(extfp1, "%f ",*dptr++); 
        if (kd %8 == 7 || kd == bp->shape()[1]-1) fprintf(extfp1, "\n"); 
      } 
      fclose(extfp1); 
     } 
    } // if size 2 
    else { 
     printf("BSS != 4 or 2, i = %d, j = %d, sz = %zd\n",i,j,bp->shape().size()); 
    } 
    } // for j 

    for (int j = 0; j < top_vecs_[i].size(); j++) { 

     Blob<Dtype>* tp = top_vecs_[i][j]; 
     const Dtype *dptr = tp->cpu_data(); 
    if (tp->shape().size() == 4) { // Blob 
     for (int kn = 0; kn < tp->shape()[0]; kn++) { // Blob 
      for (int kd = 0; kd < tp->shape()[1]; kd++) { // Ni 
      sprintf(fname, "ext/L%02d_%s_T%d_FN%03d.txt", 
        i,layers_[i]->type(),j,kd); 
      extfp1 = fopen(fname,"w"); 
      for (int kr = 0; kr < tp->shape()[2]; kr++) { // Ny 
       fprintf(extfp1, "### kr = %d ##\n", kr); 
       for (int kc = 0; kc < tp->shape()[3]; kc++) { // Nx 
        fprintf(extfp1, "%f ",*dptr++); 
        if (kc %8 == 7 || kc == tp->shape()[3]-1) fprintf(extfp1, "\n"); 
       } 
      } 
      fclose(extfp1); 
      } 
     } 
    } // if size 4 
    else if (tp->shape().size() == 2) { 
     for (int kn = 0; kn < tp->shape()[0]; kn++) { // Blob 
      sprintf(fname, "ext/L%02d_%s_T%d_FN%03d.txt", 
       i,layers_[i]->type(),j,kn); 
      extfp1 = fopen(fname,"w"); 
      for (int kd = 0; kd < tp->shape()[1]; kd++) { // Ni 
        fprintf(extfp1, "%f ",*dptr++); 
        if (kd %8 == 7) fprintf(extfp1, "\n"); 
      } 
      fclose(extfp1); 
     } 
    } // if size 2 
    else { 
     printf("BSS != 4 or 2, i = %d, j = %d, sz = %zd\n",i,j,tp->shape().size()); 
    } 
    } // for j 
} // print!! 
// -------------------------------- end of blob extract --------------------- 
#endif 

#ifdef WeightExtract 
// -------------------------------- start of weight extract --------------------- 
if (i == LayerExtNum || EXT_ALL_LAYERS) { //print!! 
    char fname[50]; 
    FILE *extfp1; 
    printf("#*#* Ext layer type = %s\n", layers_[i]->type()); 
    if (strcmp(layers_[i]->type(),"Convolution") == 0){ 
     printf("It's Convolution Layer!\n"); 
     vector<shared_ptr<Blob<Dtype> > >& lyr_blobs = layers_[i]->blobs(); 
     // Layer 
     printf("layer blob size = %zd\n", lyr_blobs.size()); 
     //const LayerParameter& lyr_param = layers()[i]->layer_param(); // vector shared_ptr Layer 
     printf("lyr_blobs.size() = %zd\n", lyr_blobs.size()); 
     printf("lyr_blobs[0].shape = %s\n", lyr_blobs[0]->shape_string().c_str()); 
     printf("lyr_blobs[1].shape = %s\n", lyr_blobs[1]->shape_string().c_str()); // Blob 
     Blob<Dtype> *wp = lyr_blobs[0].get(); // weight // shared_ptr 
     Blob<Dtype> *bp = lyr_blobs[1].get(); // bias 
     printf("No Ni ky kx = %d %d %d %d\n", wp->shape()[0], wp->shape()[1], wp->shape()[2], wp->shape()[3]); // Blob 
     printf("Nb = %d\n", bp->shape()[0]); 
     int No = wp->shape()[0]; 
     int Ni = wp->shape()[1]; 
     int Ky = wp->shape()[2]; 
     int Kx = wp->shape()[3]; 
     int Nb = bp->shape()[0]; 
     const Dtype *wptr = wp->cpu_data(); 
     const Dtype *bptr = bp->cpu_data(); 
     // save weights first 
     sprintf(fname, "ext/L%02d_%s_Weights.txt",i,layers_[i]->type()); 
     extfp1 = fopen(fname, "w"); 
     fprintf(extfp1, "## Layer 0 Conv Weights (No = %d, Ni = %d, Ky = %d, Kx = %d, Nb = %d\n", No, Ni, Ky, Kx, Nb); 
     for (int n = 0; n < No; n++){ 
      fprintf(extfp1, "## For output map %d ##\n", n); 
      for (int c = 0; c < Ni; c++){ 
       fprintf(extfp1, "## for input map %d ##\n", c); 
       for (int y = 0; y < Ky; y++) { 
        for (int x = 0; x < Kx; x++) { 
         fprintf(extfp1, "%f ", *wptr++); 
        } 
        fprintf(extfp1, "\n"); 
       } 
       fprintf(extfp1, "\n"); 
      } 
     } 
     fprintf(extfp1, "## Bias values for outputs ##\n"); 
     for (int n = 0; n < No; n++){ 
      fprintf(extfp1, "%f ",*bptr++); 
      if (n % 8 == 7) fprintf(extfp1, "\n"); 
     } 
     fclose(extfp1); 
    } 
} // print!! 
// -------------------------------- end of weight extract --------------------- 
#endif 
    } 
    return loss; 
} 

ADD : 나는 PY-빠른 rcnn 코드에서 온 VGG_ILSVRC_16_layers에 출마했습니다. 데이터를 추출한 레이어 I의 매개 변수는 다음과 같습니다. :

layer { 
    name: "conv1_2" 
    type: "Convolution" 
    bottom: "conv1_1" 
    top: "conv1_2" 
    convolution_param { 
    num_output: 64 
    pad: 1 kernel_size: 3 
    } 
} 

ADD : 중재자가 고정 코드를 삭제 했으므로 여기 kerne weight의 고정 코드를 추가합니다.

for(ofm_idx = 0; ofm_idx < NUM_OFM; ofm_idx++) { 
    ll = fgets(line, 80, file); // read the line '## For output map ofm_idx' 
    for(ifm_idx = 0; ifm_idx < NUM_IFM; ifm_idx++) { 

     ll = fgets(line, 80, file); // read the line '## for input map ifm_idx' 
     for(kyi = 0; kyi < K; kyi++) { 
     fscanf(file, "%f %f %f\n", &v0, &v1, &v2); // K=3 always 

      weights[ofm_idx][ifm_idx][kyi][0] = v0; 
      weights[ofm_idx][ifm_idx][kyi][1] = v1; 
      weights[ofm_idx][ifm_idx][kyi][2] = v2; 
     } 
    } 
    // read bias values 
} 
+0

당신이'Convolution' 층 매개 변수를 업로드 할 수 prototxt에 사용됩니까? – Dale

+0

@DaleSong 레이어 매개 변수를 업로드했습니다. VGG16에서는 그 레이어에서 하단 및 상단 크기가 동일합니다. 패드 == 1, 스트라이드 == 1. –

+0

@DaleSong 출력 인덱스 대신 이동 된 src 인덱스를 사용하여 응답을 시도하고 응답으로 답장을 시도했습니다. 나는 여전히 올바른 결과를 얻을 수 없습니다. 시간이 있다면, 당신이나 다른 누군가가 문제를 찾을 수 있기를 바랍니다. 감사! –

답변

0

나는 버그가 회선을 수행 할 때 하단의 데이터를 (입력)를 가져 오는에있다 생각하고, 올바른 코드가 있어야한다 :

//bottom data index for convolution 
int src_r, src_c; 
//pads and strides along row and column 
int row_pad = 1, col_pad = 1, row_stride = 1, col_stride = 1; 
for(ofm_idx = 0; ofm_idx < NUM_OFM; ofm_idx++) { 
    for(orix = 0; orix < HEIGHT; orix++) { 
    for(ocix = 0; ocix < WIDTH; ocix++) { 
     sum = 0.; 
     for(ifm_idx = 0; ifm_idx < NUM_IFM; ifm_idx++) { 
     ... 
     // zero-value padding (used in caffe) 
     //The right indexing for bottom data, 
     //your original code is wrong here 
     src_r= orix * row_stride - row_pad; 
     src_c= ocix * col_stride - col_pad; 
     in_square[0][0] = (src_r < 0 || src_c < 0 || 
          src_r >= HEIGHT || src_c >= WIDTH) ? 
          0 : bottom[0][ifm_idx][src_r][src_c]; 
     in_square[0][1] = (src_r < 0 || src_c + 1 < 0 || 
          src_r >= HEIGHT || src_c + 1 >= WIDTH) ? 
          0 : bottom[0][ifm_idx][src_r][src_c + 1]; 
     in_square[0][2] = (src_r < 0 || src_c + 2 < 0 || 
          src_r >= HEIGHT || src_c + 2 >= WIDTH) ? 
          0 : bottom[0][ifm_idx][src_r][src_c + 2]; 
     in_square[1][0] = (src_r + 1 < 0 || src_c < 0 || 
          src_r + 1 >= HEIGHT || src_c >= WIDTH) ? 
          0 : bottom[0][ifm_idx][src_r + 1][src_c]; 
     in_square[1][1] = (src_r + 1 < 0 || src_c + 1 < 0 || 
          src_r + 1 >= HEIGHT || src_c + 1 >= WIDTH) ? 
          0 : bottom[0][ifm_idx][src_r + 1][src_c + 1]; 
     in_square[1][2] = (src_r + 1 < 0 || src_c + 2 < 0 || 
          src_r + 1 >= HEIGHT || src_c + 2 >= WIDTH) ? 
          0 : bottom[0][ifm_idx][src_r + 1][src_c + 2]; 
     in_square[2][0] = (src_r + 2 < 0 || src_c < 0 || 
          src_r + 2 >= HEIGHT || src_c >= WIDTH) ? 
          0 : bottom[0][ifm_idx][src_r + 2][src_c]; 
     in_square[2][1] = (src_r + 2 < 0 || src_c + 1 < 0 || 
          src_r + 2 >= HEIGHT || src_c + 1 >= WIDTH) ? 
          0 : bottom[0][ifm_idx][src_r + 2][src_c + 1]; 
     in_square[2][2] = (src_r + 2 < 0 || src_c + 2 < 0 || 
          src_r + 2 >= HEIGHT || src_c + 2 >= WIDTH) ? 
          0 : bottom[0][ifm_idx][src_r + 2][src_c + 2]; 

     //apply kernel 
     ... 
     } 
    } 
    } 
} 
+1

안녕하세요, 버그를 발견했습니다. 커널 무게를 읽는 중이었습니다. 나는 다시 한번 점검 했어야했다. 내 대답을 참조하십시오. 내가 너에게 버그를 찾는 걸 도왔 기 때문에 너에게 경계를 줬어. 고맙습니다! –

0

하단을 전치시키면서 뒤집은 다음 비교해보십시오. (또는 트랜스 콘볼 루션 커널)

+0

고마워, 나는 그걸 시도하지 않았다. 나중에 시간이 있으면 다시 시도해 보겠습니다. –

+0

안녕하세요, 전 커널 전치와 커널 featuremap 색인 정의를 시도했습니다 (먼저 출력을 시도한 후 첫 번째 출력은 마지막 순서대로 입력 함). 조합. 여전히 일치하지 않습니다. 내 BLOB 추출 코드를 넣었 어. 잘못된 것이 있는지 내 코드를 살펴볼 시간이 있으면 좋겠다. 감사! –

+0

카페에서 컨볼 루션을 수행하기 위해 트랜스 포즈를 할 필요가 없습니다. – Dale

관련 문제