maxpool

Max Pooling Layer λž€?

Max Pooling LayerλŠ” Convolutional Neural Network(CNN)의 ꡬ성 μš”μ†Œ 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€. CNN은 이미지, μŒμ„± λ˜λŠ” λΉ„λ””μ˜€μ™€ 같은 μž…λ ₯ 데이터λ₯Ό μ²˜λ¦¬ν•  λ•Œ μ‚¬μš©λ©λ‹ˆλ‹€. μ΄μ „μ˜ Convolutional Layerμ—μ„œ μƒμ„±λœ feature map을 λ‹€μš΄ μƒ˜ν”Œλ§ν•˜μ—¬ 곡간 해상도λ₯Ό μ€„μ΄λŠ” 역할을 ν•©λ‹ˆλ‹€. 이λ₯Ό 톡해 λ„€νŠΈμ›Œν¬κ°€ κ³Όμ ν•©λ˜λŠ” 것을 λ°©μ§€ν•˜κ³  μ—°μ‚° 속도λ₯Ό 높일 수 μžˆμŠ΅λ‹ˆλ‹€.

Max Pooling LayerλŠ” 각 feature mapμ—μ„œ κ°€μž₯ 큰 값을 μ„ νƒν•˜μ—¬ 좜λ ₯ν•©λ‹ˆλ‹€. 이λ₯Ό 톡해 feature map의 크기가 쀄어듀고, μ΄λ―Έμ§€μ˜ μœ„μΉ˜ 이동에 λŒ€ν•œ λΆˆλ³€μ„±(invariance)이 μ¦κ°€ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, μ–΄λ–€ 이미지 λ‚΄μ—μ„œ 개의 얼꡴이 μžˆμ„ λ•Œ, 개의 μœ„μΉ˜κ°€ λ‹€λ₯΄λ”라도 Max Pooling LayerλŠ” 개의 νŠΉμ§•μ„ μΈμ‹ν•˜λ„λ‘ λ„μ™€μ€λ‹ˆλ‹€.

일반적으둜, Max Pooling LayerλŠ” 2x2의 μœˆλ„μš°μ™€ 2의 μŠ€νŠΈλΌμ΄λ“œ(stride)λ₯Ό μ‚¬μš©ν•˜μ—¬ μž‘λ™ν•©λ‹ˆλ‹€. μ΄λŠ” μž…λ ₯ feature map을 2배둜 λ‹€μš΄μƒ˜ν”Œλ§ν•˜μ—¬ 크기λ₯Ό μ€„μž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μœˆλ„μš° 크기와 μŠ€νŠΈλΌμ΄λ“œ ν¬κΈ°λŠ” λ¬Έμ œμ— 따라 λ‹€λ₯Ό 수 μžˆμŠ΅λ‹ˆλ‹€. Max Pooling LayerλŠ” ν•™μŠ΅ κ°€λŠ₯ν•œ 맀개 λ³€μˆ˜κ°€ μ—†κΈ° λ•Œλ¬Έμ—, λ„€νŠΈμ›Œν¬ νŒŒλΌλ―Έν„° 수λ₯Ό 쀄이고 과적합을 λ°©μ§€ν•˜λŠ” 데 도움이 λ©λ‹ˆλ‹€.

make_maxpool_layer

maxpool_layer make_maxpool_layer(int batch, int h, int w, int c, int size, int stride, int padding)
{
    maxpool_layer l = {0};
    l.type = MAXPOOL;
    l.batch = batch;
    l.h = h;
    l.w = w;
    l.c = c;
    l.pad = padding;
    l.out_w = (w + padding - size)/stride + 1;
    l.out_h = (h + padding - size)/stride + 1;
    l.out_c = c;
    l.outputs = l.out_h * l.out_w * l.out_c;
    l.inputs = h*w*c;
    l.size = size;
    l.stride = stride;
    int output_size = l.out_h * l.out_w * l.out_c * batch;
    l.indexes = calloc(output_size, sizeof(int));
    l.output =  calloc(output_size, sizeof(float));
    l.delta =   calloc(output_size, sizeof(float));
    l.forward = forward_maxpool_layer;
    l.backward = backward_maxpool_layer;

    fprintf(stderr, "max          %d x %d / %d  %4d x%4d x%4d   ->  %4d x%4d x%4d\n", size, size, stride, w, h, c, l.out_w, l.out_h, l.out_c);
    return l;
}

ν•¨μˆ˜ 이름: make_maxpool_layer

μž…λ ₯:

  • batch: int ν˜•νƒœμ˜ 배치 크기

  • h: int ν˜•νƒœμ˜ μž…λ ₯ 이미지 높이

  • w: int ν˜•νƒœμ˜ μž…λ ₯ 이미지 λ„ˆλΉ„

  • c: int ν˜•νƒœμ˜ μž…λ ₯ 이미지 채널 수

  • size: int ν˜•νƒœμ˜ λ§₯μŠ€ν’€λ§ ν•„ν„° 크기

  • stride: int ν˜•νƒœμ˜ λ§₯μŠ€ν’€λ§ μŠ€νŠΈλΌμ΄λ“œ 크기

  • padding: int ν˜•νƒœμ˜ νŒ¨λ”© 크기

λ™μž‘:

  • λ§₯μŠ€ν’€λ§ λ ˆμ΄μ–΄λ₯Ό μƒμ„±ν•˜κ³  μ΄ˆκΈ°ν™”ν•œ λ’€ λ°˜ν™˜ν•œλ‹€.

  • 좜λ ₯ 크기λ₯Ό κ³„μ‚°ν•˜κ³ , λ©”λͺ¨λ¦¬λ₯Ό λ™μ μœΌλ‘œ ν• λ‹Ήν•˜μ—¬ μ΄ˆκΈ°ν™”ν•˜λ©°, μˆœμ „νŒŒμ™€ μ—­μ „νŒŒ ν•¨μˆ˜λ₯Ό μ„€μ •ν•œλ‹€.

μ„€λͺ…:

  • l: maxpool_layer ꡬ쑰체 λ³€μˆ˜

  • l.type: λ ˆμ΄μ–΄ νƒ€μž…μœΌλ‘œ MAXPOOL둜 μ„€μ •

  • l.out_c: 좜λ ₯ 이미지 채널 수둜 μž…λ ₯ 이미지 채널 μˆ˜μ™€ κ°™κ²Œ μ„€μ •

  • l.outputs: 좜λ ₯ μ΄λ―Έμ§€μ˜ 크기(높이xλ„ˆλΉ„x채널 수)둜 좜λ ₯ 크기 계산

  • l.inputs: μž…λ ₯ μ΄λ―Έμ§€μ˜ 크기(높이xλ„ˆλΉ„x채널 수)둜 μž…λ ₯ 크기 계산

  • l.indexes: λ§₯μŠ€ν’€λ§ μ—°μ‚°μ—μ„œ μ΅œλŒ“κ°’ μœ„μΉ˜λ₯Ό κΈ°λ‘ν•˜κΈ° μœ„ν•œ λ°°μ—΄ 동적 ν• λ‹Ή

  • l.output: λ§₯μŠ€ν’€λ§ μ—°μ‚° κ²°κ³Όλ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•œ λ°°μ—΄ 동적 ν• λ‹Ή

  • l.delta: μ—­μ „νŒŒ κ³Όμ •μ—μ„œ κ³„μ‚°λœ κ·Έλž˜λ””μ–ΈνŠΈλ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•œ λ°°μ—΄ 동적 ν• λ‹Ή

  • l.forward: λ§₯μŠ€ν’€λ§ λ ˆμ΄μ–΄μ˜ μˆœμ „νŒŒ μ—°μ‚° ν•¨μˆ˜ 포인터 μ„€μ •

  • l.backward: λ§₯μŠ€ν’€λ§ λ ˆμ΄μ–΄μ˜ μ—­μ „νŒŒ μ—°μ‚° ν•¨μˆ˜ 포인터 μ„€μ •

  • fprintf: λ””λ²„κΉ…μš©μœΌλ‘œ λ§₯μŠ€ν’€λ§ λ ˆμ΄μ–΄μ˜ 크기λ₯Ό 좜λ ₯

forward_maxpool_layer

void forward_maxpool_layer(const maxpool_layer l, network net) { 
    int b,i,j,k,m,n; 
    int w_offset = -l.pad/2; 
    int h_offset = -l.pad/2;
    int h = l.out_h;
    int w = l.out_w;
    int c = l.c;
    
    for(b = 0; b < l.batch; ++b){
        for(k = 0; k < c; ++k){
            for(i = 0; i < h; ++i){
                for(j = 0; j < w; ++j){
                    int out_index = j + w*(i + h*(k + c*b));
                    float max = -FLT_MAX;
                    int max_i = -1;
                    for(n = 0; n < l.size; ++n){
                        for(m = 0; m < l.size; ++m){
                            int cur_h = h_offset + i*l.stride + n;
                            int cur_w = w_offset + j*l.stride + m;
                            int index = cur_w + l.w*(cur_h + l.h*(k + b*l.c));
                            int valid = (cur_h >= 0 && cur_h < l.h &&
                                         cur_w >= 0 && cur_w < l.w);
                            float val = (valid != 0) ? net.input[index] : -FLT_MAX;
                            max_i = (val > max) ? index : max_i;
                            max   = (val > max) ? val   : max;
                        }
                    }
                    l.output[out_index] = max;
                    l.indexes[out_index] = max_i;
                }
            }
        }
    }
}

ν•¨μˆ˜ 이름: forward_maxpool_layer

μž…λ ₯:

  • const maxpool_layer l: Max pooling λ ˆμ΄μ–΄λ₯Ό λ‚˜νƒ€λ‚΄λŠ” ꡬ쑰체

  • network net: 신경망 ꡬ쑰λ₯Ό λ‚˜νƒ€λ‚΄λŠ” ꡬ쑰체

λ™μž‘:

  • μ£Όμ–΄μ§„ Max pooling λ ˆμ΄μ–΄ ꡬ쑰체 lκ³Ό 신경망 ꡬ쑰체 netλ₯Ό μ‚¬μš©ν•˜μ—¬ Max pooling λ ˆμ΄μ–΄λ₯Ό μˆœμ „νŒŒν•˜λŠ” ν•¨μˆ˜μ΄λ‹€. 이 ν•¨μˆ˜λŠ” μž…λ ₯κ°’μ—μ„œ Max pooling 연산을 μˆ˜ν–‰ν•˜μ—¬ 좜λ ₯값을 κ³„μ‚°ν•œλ‹€. Max pooling 연산은 각 μœˆλ„μš° λ‚΄μ˜ μ΅œλŒ“κ°’μ„ μ°Ύμ•„ 좜λ ₯κ°’μœΌλ‘œ μ‚¬μš©ν•œλ‹€.

μ„€λͺ…:

  • 이 ν•¨μˆ˜λŠ” Max pooling λ ˆμ΄μ–΄μ—μ„œ μ‚¬μš©λ˜λŠ” forward propagation ν•¨μˆ˜μ΄λ‹€. μž…λ ₯κ°’μœΌλ‘œλŠ” Max pooling λ ˆμ΄μ–΄λ₯Ό λ‚˜νƒ€λ‚΄λŠ” ꡬ쑰체 lκ³Ό 신경망 ꡬ쑰체 net이 μ£Όμ–΄μ§„λ‹€. Max pooling λ ˆμ΄μ–΄μ˜ 좜λ ₯값은 ꡬ쑰체 l의 output 배열에 μ €μž₯λœλ‹€. Max pooling λ ˆμ΄μ–΄μ˜ 좜λ ₯값을 κ³„μ‚°ν•˜κΈ° μœ„ν•΄, μž…λ ₯κ°’μ—μ„œ Max pooling 연산을 μˆ˜ν–‰ν•˜λŠ”λ°, 이λ₯Ό μœ„ν•΄ μž…λ ₯κ°’μ—μ„œ μœˆλ„μš°λ₯Ό μ΄λ™ν•˜λ©΄μ„œ 각 μœˆλ„μš° λ‚΄μ˜ μ΅œλŒ“κ°’μ„ μ°Ύμ•„ 좜λ ₯κ°’μœΌλ‘œ μ‚¬μš©ν•œλ‹€.

  • 이 ν•¨μˆ˜λŠ” μž…λ ₯κ°’μ˜ 배치 크기 l.batch, 좜λ ₯κ°’μ˜ 높이 l.out_h, 좜λ ₯κ°’μ˜ λ„ˆλΉ„ l.out_w, 채널 수 l.c, νŒ¨λ”© 크기 l.pad, μŠ€νŠΈλΌμ΄λ“œ 크기 l.stride, μœˆλ„μš° 크기 l.size λ“±μ˜ 정보λ₯Ό μ‚¬μš©ν•œλ‹€. 이 ν•¨μˆ˜μ—μ„œλŠ” μž…λ ₯κ°’μ—μ„œ μœˆλ„μš°λ₯Ό μ΄λ™ν•˜λ©΄μ„œ 각 μœˆλ„μš° λ‚΄μ˜ μ΅œλŒ“κ°’μ„ μ°Ύκ³ , ꡬ쑰체 l의 output 배열에 μ €μž₯ν•œλ‹€. μ΅œλŒ“κ°’μ˜ μœ„μΉ˜ 정보λ₯Ό μ €μž₯ν•˜κΈ° μœ„ν•΄ ꡬ쑰체 l의 indexes 배열도 ν•¨κ»˜ μ—…λ°μ΄νŠΈν•œλ‹€.

  • 이 ν•¨μˆ˜λŠ” for문을 μ‚¬μš©ν•˜μ—¬ μž…λ ₯κ°’μ˜ λͺ¨λ“  μœ„μΉ˜μ— λŒ€ν•΄ Max pooling 연산을 μˆ˜ν–‰ν•œλ‹€. κ΅¬μ²΄μ μœΌλ‘œλŠ” μž…λ ₯κ°’μ˜ λ°°μΉ˜λ³„λ‘œ, μ±„λ„λ³„λ‘œ, 좜λ ₯κ°’μ˜ μœ„μΉ˜λ³„λ‘œ μž…λ ₯κ°’μ—μ„œ μœˆλ„μš°λ₯Ό μ΄λ™ν•˜λ©΄μ„œ μ΅œλŒ“κ°’μ„ μ°ΎλŠ”λ‹€. μž…λ ₯κ°’μ—μ„œ μœˆλ„μš°λ₯Ό μ΄λ™ν•˜κΈ° μœ„ν•΄ h_offsetκ³Ό w_offset을 μ‚¬μš©ν•˜λ©°, 이 값은 νŒ¨λ”© 정보와 μŠ€νŠΈλΌμ΄λ“œ 정보λ₯Ό μ΄μš©ν•˜μ—¬ κ³„μ‚°λœλ‹€. μ΅œλŒ“κ°’μ„ 찾을 λ•ŒλŠ” μœˆλ„μš° λ‚΄μ˜ λͺ¨λ“  κ°’κ³Ό λΉ„κ΅ν•˜λ©΄μ„œ μ΅œλŒ“κ°’κ³Ό μ΅œλŒ“κ°’μ˜ μœ„μΉ˜λ₯Ό μ°ΎλŠ”λ‹€. μ΅œλŒ“κ°’μ€ 좜λ ₯κ°’μœΌλ‘œ μ‚¬μš©λ˜λ©°, μ΅œλŒ“κ°’μ˜ μœ„μΉ˜ μ •λ³΄λŠ” indexes 배열에 μ €μž₯λœλ‹€.

  • λ§ˆμ§€λ§‰μœΌλ‘œ, 이 ν•¨μˆ˜λŠ” μž…λ ₯κ°’κ³Ό 좜λ ₯κ°’μ˜ λ©”λͺ¨λ¦¬ ν• λ‹Ή 및 ν•΄μ œ 등을 μˆ˜ν–‰ν•œλ‹€.

backward_maxpool_layer

void backward_maxpool_layer(const maxpool_layer l, network net)
{
    int i;
    int h = l.out_h;
    int w = l.out_w;
    int c = l.c;
    for(i = 0; i < h*w*c*l.batch; ++i){
        int index = l.indexes[i];
        net.delta[index] += l.delta[i];
    }
}

ν•¨μˆ˜ 이름: backward_maxpool_layer

μž…λ ₯:

  • maxpool_layer l (maxpool λ ˆμ΄μ–΄ ꡬ쑰체)

  • network net (λ‰΄λŸ΄ λ„€νŠΈμ›Œν¬ ꡬ쑰체)

λ™μž‘:

  • maxpool λ ˆμ΄μ–΄μ˜ μ—­μ „νŒŒλ₯Ό μˆ˜ν–‰ν•˜μ—¬, λ‰΄λŸ΄ λ„€νŠΈμ›Œν¬μ˜ delta 값을 μ—…λ°μ΄νŠΈν•œλ‹€.

  • μ—­μ „νŒŒ μˆ˜ν–‰μ„ μœ„ν•΄, maxpool λ ˆμ΄μ–΄μ—μ„œ μ‚¬μš©λœ max 값을 κ°€μ§€λŠ” μ›μ†Œλ“€μ˜ 인덱슀λ₯Ό l.indexes 배열에 μ €μž₯ν•΄ λ†“μ•˜μœΌλ©°, 이λ₯Ό μ΄μš©ν•˜μ—¬ delta 값을 ν•΄λ‹Ή 인덱슀의 μ›μ†Œμ— 더해쀀닀.

μ„€λͺ…:

  • μž…λ ₯으둜 λ“€μ–΄μ˜¨ maxpool λ ˆμ΄μ–΄ ꡬ쑰체 lκ³Ό λ‰΄λŸ΄ λ„€νŠΈμ›Œν¬ ꡬ쑰체 net을 μ΄μš©ν•˜μ—¬, maxpool λ ˆμ΄μ–΄μ˜ μ—­μ „νŒŒλ₯Ό μˆ˜ν–‰ν•œλ‹€.

  • l.indexes λ°°μ—΄μ—λŠ” max 값을 κ°€μ§€λŠ” μ›μ†Œλ“€μ˜ μΈλ±μŠ€κ°€ μ €μž₯λ˜μ–΄ μžˆμœΌλ―€λ‘œ, 이λ₯Ό μ΄μš©ν•˜μ—¬ net.delta λ°°μ—΄μ˜ ν•΄λ‹Ή 인덱슀의 μ›μ†Œμ— l.delta λ°°μ—΄μ˜ 값을 더해쀀닀.

  • μ΄λ ‡κ²Œ ν•˜λ©΄, maxpool λ ˆμ΄μ–΄λ‘œ μ „λ‹¬λœ 델타 값이 이전 λ ˆμ΄μ–΄λ‘œ μ—­μ „νŒŒλ˜λ©°, λ„€νŠΈμ›Œν¬μ˜ ν•™μŠ΅μ΄ 이루어진닀.

get_maxpool_image

image get_maxpool_image(maxpool_layer l)
{
    int h = l.out_h;
    int w = l.out_w;
    int c = l.c;
    return float_to_image(w,h,c,l.output);
}

ν•¨μˆ˜ 이름: get_maxpool_image

μž…λ ₯:

  • maxpool_layer ꡬ쑰체 l

λ™μž‘:

  • max pooling λ ˆμ΄μ–΄μ˜ 좜λ ₯값을 이미지 ν˜•νƒœλ‘œ λ³€ν™˜ν•˜μ—¬ λ°˜ν™˜ν•©λ‹ˆλ‹€.

μ„€λͺ…:

  • max pooling λ ˆμ΄μ–΄μ˜ 좜λ ₯값을 νŠΉμ • 크기의 μ΄λ―Έμ§€λ‘œ λ³€ν™˜ν•œ ν›„, float_to_image ν•¨μˆ˜λ₯Ό μ΄μš©ν•˜μ—¬ image ν˜•νƒœλ‘œ λ³€ν™˜ν•˜μ—¬ λ°˜ν™˜ν•©λ‹ˆλ‹€.

  • 좜λ ₯값을 이미지 ν˜•νƒœλ‘œ λ³€ν™˜ν•˜λŠ” μ΄μœ λŠ” 이미지λ₯Ό μ‹œκ°ν™”ν•˜μ—¬ max pooling λ ˆμ΄μ–΄κ°€ μ–΄λ–€ μž‘μ—…μ„ μˆ˜ν–‰ν•˜λŠ”μ§€ μ‰½κ²Œ 이해할 수 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

get_maxpool_delta

image get_maxpool_delta(maxpool_layer l)
{
    int h = l.out_h;
    int w = l.out_w;
    int c = l.c;
    return float_to_image(w,h,c,l.delta);
}

ν•¨μˆ˜ 이름: get_maxpool_delta

μž…λ ₯:

  • maxpool_layer l (maxpool λ ˆμ΄μ–΄ ꡬ쑰체)

λ™μž‘:

  • μž…λ ₯으둜 받은 maxpool λ ˆμ΄μ–΄μ˜ 좜λ ₯값에 λŒ€ν•œ delta 값을 κ°€μ§€κ³  μƒˆλ‘œμš΄ 이미지λ₯Ό μƒμ„±ν•˜μ—¬ λ°˜ν™˜ν•©λ‹ˆλ‹€.

  • μƒμ„±λœ μ΄λ―Έμ§€λŠ” float_to_image ν•¨μˆ˜λ₯Ό 톡해 float ν˜•μ‹μœΌλ‘œ λ³€ν™˜λ©λ‹ˆλ‹€.

μ„€λͺ…:

  • maxpool λ ˆμ΄μ–΄λŠ” μž…λ ₯ 이미지λ₯Ό μ΅œλŒ€κ°’ 풀링 연산을 톡해 μΆ•μ†Œν•œ ν›„ 좜λ ₯값을 μƒμ„±ν•©λ‹ˆλ‹€.

  • μ΄λ•Œ, 손싀 ν•¨μˆ˜μ˜ μ—­μ „νŒŒλ₯Ό μœ„ν•΄ 이전 λ ˆμ΄μ–΄μ—μ„œ μ „λ‹¬λœ delta 값을 maxpool λ ˆμ΄μ–΄μ—μ„œλ„ κ·ΈλŒ€λ‘œ 전달해야 ν•©λ‹ˆλ‹€.

  • 이 ν•¨μˆ˜λŠ” μ΄λŸ¬ν•œ delta 값을 μ΄μš©ν•˜μ—¬ μƒˆλ‘œμš΄ 이미지λ₯Ό μƒμ„±ν•˜κ³  λ°˜ν™˜ν•©λ‹ˆλ‹€. μ΄λ•Œ, μƒμ„±λœ μ΄λ―Έμ§€μ˜ λ„ˆλΉ„, 높이, 채널 μˆ˜λŠ” maxpool λ ˆμ΄μ–΄μ˜ 좜λ ₯κ°’κ³Ό λ™μΌν•©λ‹ˆλ‹€.

resize_maxpool_layer

void resize_maxpool_layer(maxpool_layer *l, int w, int h)
{
    l->h = h;
    l->w = w;
    l->inputs = h*w*l->c;

    l->out_w = (w + l->pad - l->size)/l->stride + 1;
    l->out_h = (h + l->pad - l->size)/l->stride + 1;
    l->outputs = l->out_w * l->out_h * l->c;
    int output_size = l->outputs * l->batch;

    l->indexes = realloc(l->indexes, output_size * sizeof(int));
    l->output = realloc(l->output, output_size * sizeof(float));
    l->delta = realloc(l->delta, output_size * sizeof(float));
}

ν•¨μˆ˜ 이름: resize_maxpool_layer μž…λ ₯:

  • maxpool_layer *l : maxpool λ ˆμ΄μ–΄ ꡬ쑰체 포인터

  • int w : λ³€κ²½ν•  λ„ˆλΉ„

  • int h : λ³€κ²½ν•  높이

λ™μž‘:

  • μž…λ ₯받은 maxpool λ ˆμ΄μ–΄ ꡬ쑰체 포인터(*l)의 w와 h ν•„λ“œλ₯Ό μž…λ ₯받은 κ°’μœΌλ‘œ λ³€κ²½ν•˜κ³ , 그에 따라 λ‹€λ₯Έ ν•„λ“œλ“€λ„ μƒˆλ‘œ κ³„μ‚°ν•˜μ—¬ μ—…λ°μ΄νŠΈν•œλ‹€. μƒˆλ‘­κ²Œ κ³„μ‚°λœ ν•„λ“œλ“€μ€ λ‹€μŒκ³Ό κ°™λ‹€:

  • inputs : μž…λ ₯ 이미지 λ°μ΄ν„°μ˜ 총 개수(h * w * c)

  • out_w : 좜λ ₯ μ΄λ―Έμ§€μ˜ λ„ˆλΉ„

  • out_h : 좜λ ₯ μ΄λ―Έμ§€μ˜ 높이

  • outputs : 좜λ ₯ 이미지 λ°μ΄ν„°μ˜ 총 개수(out_w * out_h * c)

  • indexes : 좜λ ₯κ°’ 쀑 μ΅œλŒ“κ°’μ˜ μœ„μΉ˜λ₯Ό μ €μž₯ν•˜λŠ” 배열을 output_size 크기둜 μž¬ν• λ‹Ήν•œλ‹€.

  • output : 좜λ ₯값을 μ €μž₯ν•˜λŠ” 배열을 output_size 크기둜 μž¬ν• λ‹Ήν•œλ‹€.

  • delta : 좜λ ₯값에 λŒ€ν•œ λ―ΈλΆ„κ°’(gradient)을 μ €μž₯ν•˜λŠ” 배열을 output_size 크기둜 μž¬ν• λ‹Ήν•œλ‹€.

μ„€λͺ…:

  • 이 ν•¨μˆ˜λŠ” maxpool λ ˆμ΄μ–΄μ˜ 크기λ₯Ό μ‘°μ •ν•˜κΈ° μœ„ν•œ ν•¨μˆ˜μ΄λ‹€.

  • μž…λ ₯받은 maxpool λ ˆμ΄μ–΄ ꡬ쑰체 포인터(*l)의 w와 h ν•„λ“œλ₯Ό λ³€κ²½ν•œ λ’€, 이 값에 따라 λ‹€λ₯Έ ν•„λ“œλ“€λ„ μ—…λ°μ΄νŠΈν•œλ‹€. 이 λ•Œ, maxpool λ ˆμ΄μ–΄λŠ” μž…λ ₯ μ΄λ―Έμ§€μ—μ„œ stride와 sizeλ₯Ό 기반으둜 μ΅œλŒ“κ°’μ„ μΆ”μΆœν•˜μ—¬ 좜λ ₯ 이미지λ₯Ό μƒμ„±ν•˜λŠ” λ ˆμ΄μ–΄μ΄λ‹€.

  • 이 ν•¨μˆ˜μ—μ„œλŠ” μž…λ ₯ 이미지 λ°μ΄ν„°μ˜ 총 개수(inputs), 좜λ ₯ μ΄λ―Έμ§€μ˜ λ„ˆλΉ„(out_w)와 높이(out_h), 좜λ ₯ 이미지 λ°μ΄ν„°μ˜ 총 개수(outputs)λ₯Ό μƒˆλ‘­κ²Œ κ³„μ‚°ν•œλ‹€.

  • λ˜ν•œ, 좜λ ₯κ°’ 쀑 μ΅œλŒ“κ°’μ˜ μœ„μΉ˜λ₯Ό μ €μž₯ν•˜λŠ” λ°°μ—΄(indexes), 좜λ ₯값을 μ €μž₯ν•˜λŠ” λ°°μ—΄(output), 그리고 좜λ ₯값에 λŒ€ν•œ λ―ΈλΆ„κ°’(gradient)을 μ €μž₯ν•˜λŠ” λ°°μ—΄(delta)을 μž¬ν• λ‹Ήν•œλ‹€.

  • μ΄λ ‡κ²Œ ν•„μš”ν•œ ν•„λ“œλ“€μ„ μƒˆλ‘­κ²Œ κ³„μ‚°ν•˜κ³  μž¬ν• λ‹Ήν•¨μœΌλ‘œμ¨, maxpool λ ˆμ΄μ–΄μ˜ 크기λ₯Ό μ‘°μ •ν•  수 μžˆλ‹€.

Last updated

Was this helpful?