DarkNet 시리즈 - Upsample Layer
upsample_layer
Upsample Layer란?
Upsample Layer는 Feature Maps의 크기를 키우는 Layer입니다.
upsample_layer.c
forward_upsample_layer
1
2
3
4
5
6
7
8
9
void forward_upsample_layer(const layer l, network net)
{
fill_cpu(l.outputs*l.batch, 0, l.output, 1);
if(l.reverse){
upsample_cpu(l.output, l.out_w, l.out_h, l.c, l.batch, l.stride, 0, l.scale, net.input);
}else{
upsample_cpu(net.input, l.w, l.h, l.c, l.batch, l.stride, 1, l.scale, l.output);
}
}
함수 이름: forward_upsample_layer
입력:
- l: layer 구조체
- net: network 구조체
동작:
- 업샘플링 레이어를 전방향 패스(forward pass)로 처리하는 함수입니다.
- 입력 이미지를 업샘플링하여 출력값을 계산합니다. 이때, 출력값은 l.output에 저장됩니다.
설명:
- fill_cpu() 함수는 l.output을 0으로 초기화합니다.
- l.reverse가 참(True)일 경우, upsample_cpu() 함수를 사용하여 l.output에 업샘플링된 이미지를 저장합니다. 이때, 입력 이미지는 net.input입니다.
- l.reverse가 거짓(False)일 경우, upsample_cpu() 함수를 사용하여 net.input 이미지를 업샘플링하여 l.output에 저장합니다. 이때, 출력 크기는 l.w, l.h로 설정되어 있습니다.
- 최종적으로, 출력값은 l.output에 저장됩니다.
backward_upsample_layer
1
2
3
4
5
6
7
8
void backward_upsample_layer(const layer l, network net)
{
if(l.reverse){
upsample_cpu(l.delta, l.out_w, l.out_h, l.c, l.batch, l.stride, 1, l.scale, net.delta);
}else{
upsample_cpu(net.delta, l.w, l.h, l.c, l.batch, l.stride, 0, l.scale, l.delta);
}
}
함수 이름: backward_upsample_layer
입력:
- l: layer 구조체
- net: network 구조체
동작:
- 업샘플링 레이어의 역전파(backward pass) 연산을 수행합니다.
- 입력값으로는 l과 net을 받으며, l은 현재 레이어의 정보와 이전 레이어의 출력값에 대한 정보를 담고 있으며, net은 전체 네트워크에 대한 정보를 담고 있습니다.
- 업샘플링 레이어는 입력값의 크기를 늘리는 작업을 수행하는데, 이를 역전파 할 때는 이전 레이어의 delta 값을 현재 레이어의 크기에 맞게 축소(upsample)하여 전달합니다. 이 과정에서 scale 값을 사용하여 크기를 조절합니다.
설명:
- 이 함수는 Darknet 딥러닝 프레임워크의 업샘플링 레이어에 대한 역전파 연산을 담당합니다.
- Darknet에서는 입력값의 크기를 늘리는 작업을 수행하는 데에 업샘플링 레이어를 사용하며, 이 레이어의 출력값은 다음 레이어의 입력값으로 사용됩니다. 따라서 이전 레이어의 delta 값을 현재 레이어의 크기에 맞게 축소하여 전달해야 합니다.
- 이를 위해 upsample_cpu() 함수를 사용하며, 이 함수에서는 입력값의 크기를 늘리는 작업을 수행합니다.
- scale 값을 사용하여 크기를 조절하며, reverse 값이 1인 경우에는 이전 레이어의 delta 값을 축소하여 전달하고, 0인 경우에는 net에서 이전 레이어의 delta 값을 가져와서 크기를 늘린 후 현재 레이어의 delta 값으로 사용합니다.
resize_upsample_layer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void resize_upsample_layer(layer *l, int w, int h)
{
l->w = w;
l->h = h;
l->out_w = w*l->stride;
l->out_h = h*l->stride;
if(l->reverse){
l->out_w = w/l->stride;
l->out_h = h/l->stride;
}
l->outputs = l->out_w*l->out_h*l->out_c;
l->inputs = l->h*l->w*l->c;
l->delta = realloc(l->delta, l->outputs*l->batch*sizeof(float));
l->output = realloc(l->output, l->outputs*l->batch*sizeof(float));
}
함수 이름: resize_upsample_layer
입력:
- layer *l: upsample 레이어의 포인터
- int w: upsample 레이어의 출력 이미지 가로 길이
- int h: upsample 레이어의 출력 이미지 세로 길이
동작:
- upsample 레이어의 출력 이미지 가로, 세로 길이를 조절하는 함수이다.
- 입력으로 받은 가로, 세로 길이로 레이어의 가로, 세로 길이를 업데이트하고, 이를 기반으로 출력 이미지 가로, 세로 길이를 다시 계산한다.
- 만약 레이어가 reverse 모드이면 출력 이미지 가로, 세로 길이는 입력 이미지 가로, 세로 길이에 stride를 나눈 값이 되고, outputs 값도 이에 맞게 계산된다.
- 그리고 레이어의 입력 채널 수에 맞게 outputs 값을 계산한다. 마지막으로 delta와 output을 업데이트한다.
설명:
- upsample 레이어는 입력 이미지를 확대하는 역할을 한다. 이 함수는 upsample 레이어의 출력 이미지 가로, 세로 길이를 조정하는 함수이다.
- 이 함수는 l->w와 l->h를 입력으로 받은 가로, 세로 길이로 변경하고, 이를 기반으로 l->out_w와 l->out_h를 다시 계산한다.
- 이때, l->out_w와 l->out_h는 upsample 레이어의 출력 이미지의 가로, 세로 길이이다.
- 만약 upsample 레이어가 reverse 모드이면, l->out_w와 l->out_h는 입력 이미지의 가로, 세로 길이에 stride를 나눈 값이 된다.
- 그리고 l->outputs 값도 이에 맞게 계산된다. l->outputs는 upsample 레이어의 출력 채널 수에 맞게 출력 이미지의 픽셀 수를 나타낸다.
- 마지막으로 delta와 output을 업데이트하여 메모리를 할당한다.
make_upsample_layer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
layer make_upsample_layer(int batch, int w, int h, int c, int stride)
{
layer l = {0};
l.type = UPSAMPLE;
l.batch = batch;
l.w = w;
l.h = h;
l.c = c;
l.out_w = w*stride;
l.out_h = h*stride;
l.out_c = c;
if(stride < 0){
stride = -stride;
l.reverse=1;
l.out_w = w/stride;
l.out_h = h/stride;
}
l.stride = stride;
l.outputs = l.out_w*l.out_h*l.out_c;
l.inputs = l.w*l.h*l.c;
l.delta = calloc(l.outputs*batch, sizeof(float));
l.output = calloc(l.outputs*batch, sizeof(float));;
l.forward = forward_upsample_layer;
l.backward = backward_upsample_layer;
if(l.reverse) fprintf(stderr, "downsample %2dx %4d x%4d x%4d -> %4d x%4d x%4d\n", stride, w, h, c, l.out_w, l.out_h, l.out_c);
else fprintf(stderr, "upsample %2dx %4d x%4d x%4d -> %4d x%4d x%4d\n", stride, w, h, c, l.out_w, l.out_h, l.out_c);
return l;
}
함수 이름: make_upsample_layer
입력:
- batch: int 형식의 배치 크기
- w: int 형식의 입력 너비
- h: int 형식의 입력 높이
- c: int 형식의 입력 채널 수
- stride: int 형식의 업샘플링 배율 또는 다운샘플링 배율(음수)
동작:
- 입력으로 받은 batch, w, h, c, stride 값을 사용하여 upsample 레이어를 생성한다.
- stride 값이 음수인 경우 다운샘플링으로 동작한다.
- 레이어의 출력 크기(out_w, out_h, out_c)와 출력 요소 수(outputs)를 계산한다.
- 레이어의 입력 요소 수(inputs), 델타(delta), 출력(output)을 메모리에 할당하고, 0으로 초기화한다.
- 업샘플링 레이어의 forward와 backward 함수를 설정한다.
- 업샘플링 레이어의 정보를 출력한다.
설명:
- 업샘플링 레이어를 만드는 함수이다.
- 이 함수에서 생성된 레이어는 입력 이미지를 upsample 또는 downsample하여 출력하는 역할을 한다.
- 입력 이미지의 크기를 키우는 upsample과 크기를 줄이는 downsample이 있다.
- 이 함수에서는 stride 값을 이용하여 upsample과 downsample을 구분하고, 역전파 함수에서 해당 연산을 처리한다.
- 레이어의 출력 크기는 입력 크기와 stride 값에 따라 결정된다.
- 이 함수에서는 메모리 할당과 초기화를 수행하고, forward와 backward 함수를 설정하는 작업을 한다.
This post is licensed under CC BY 4.0 by the author.