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?