DarkNet 시리즈 - Route Layer
route_layer
forward_route_layer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void forward_route_layer(const route_layer l, network net)
{
int i, j;
int offset = 0;
for(i = 0; i < l.n; ++i){
int index = l.input_layers[i];
float *input = net.layers[index].output;
int input_size = l.input_sizes[i];
for(j = 0; j < l.batch; ++j){
copy_cpu(input_size, input + j*input_size, 1, l.output + offset + j*l.outputs, 1);
}
offset += input_size;
}
}
함수 이름: forward_route_layer
입력:
- const route_layer l: route layer 구조체
- network net: neural network 구조체
동작:
- 입력으로 받은 neural network의 route layer를 순전파(forward propagation) 진행
- route layer에 연결된 모든 input layer의 출력을 하나로 이어붙여(l.output) 반환
설명:
- l.input_layers: route layer와 연결된 input layer의 인덱스를 저장하는 int 배열
- l.input_sizes: route layer와 연결된 input layer의 출력 크기를 저장하는 int 배열
- l.batch: mini-batch 크기
- l.outputs: route layer 출력의 크기
- 각 input layer의 출력을 mini-batch 단위로 이어붙여서 route layer의 출력을 만듦
- copy_cpu 함수: OpenBLAS 라이브러리 함수로, 배열의 복사를 수행함
backward_route_layer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void backward_route_layer(const route_layer l, network net)
{
int i, j;
int offset = 0;
for(i = 0; i < l.n; ++i){
int index = l.input_layers[i];
float *delta = net.layers[index].delta;
int input_size = l.input_sizes[i];
for(j = 0; j < l.batch; ++j){
axpy_cpu(input_size, 1, l.delta + offset + j*l.outputs, 1, delta + j*input_size, 1);
}
offset += input_size;
}
}
함수 이름: backward_route_layer
입력:
- route_layer l: route_layer 구조체
- network net: 네트워크 구조체
동작:
- route_layer의 역전파를 수행함
- route_layer에 입력된 레이어들의 delta 값을 계산하여 더함
설명:
- route_layer는 여러 입력 레이어들의 출력을 합침(concatenate)으로써 이전 레이어의 출력을 다음 레이어의 입력으로 사용할 수 있도록 함
- 따라서, route_layer의 입력으로 사용된 모든 레이어들의 delta 값을 계산해야 함
- 이를 위해, route_layer에 입력된 레이어들의 delta 값을 더해줌
- offset 변수는 입력 레이어들의 출력이 route_layer의 출력에 어디서부터 복사되는지를 나타내는 인덱스 역할을 함
resize_route_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
void resize_route_layer(route_layer *l, network *net)
{
int i;
layer first = net->layers[l->input_layers[0]];
l->out_w = first.out_w;
l->out_h = first.out_h;
l->out_c = first.out_c;
l->outputs = first.outputs;
l->input_sizes[0] = first.outputs;
for(i = 1; i < l->n; ++i){
int index = l->input_layers[i];
layer next = net->layers[index];
l->outputs += next.outputs;
l->input_sizes[i] = next.outputs;
if(next.out_w == first.out_w && next.out_h == first.out_h){
l->out_c += next.out_c;
}else{
printf("%d %d, %d %d\n", next.out_w, next.out_h, first.out_w, first.out_h);
l->out_h = l->out_w = l->out_c = 0;
}
}
l->inputs = l->outputs;
l->delta = realloc(l->delta, l->outputs*l->batch*sizeof(float));
l->output = realloc(l->output, l->outputs*l->batch*sizeof(float));
}
함수 이름: resize_route_layer
입력:
- route_layer *l (route_layer 구조체 포인터)
- network *net (network 구조체 포인터)
동작:
- route_layer 구조체의 출력 크기와 입력 크기를 업데이트하고 메모리를 재할당한다.
- 입력 레이어 중 첫 번째 레이어의 출력 크기를 사용하여 route_layer의 출력 크기 및 출력 채널 수를 초기화한다.
- 그런 다음 나머지 입력 레이어를 확인하고 출력 크기를 누적한다.
- 모든 입력 레이어의 출력 크기가 같은 경우 출력 채널 수를 증가시킨다.
- 그렇지 않은 경우 출력 크기와 출력 채널 수를 0으로 설정한다. 마지막으로 메모리를 재할당한다.
설명:
- route_layer는 입력 레이어에서 여러 출력을 결합하는 데 사용되는 레이어이다.
- 이 함수는 route_layer의 출력 크기와 입력 크기를 업데이트하고 메모리를 재할당하는 데 사용된다.
- 또한 입력 레이어의 출력 크기가 다른 경우 경고 메시지를 출력한다.
- 이 함수는 네트워크에서 route_layer를 다시 크기 조정해야 할 때 호출된다.
make_route_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
route_layer make_route_layer(int batch, int n, int *input_layers, int *input_sizes)
{
fprintf(stderr,"route ");
route_layer l = {0};
l.type = ROUTE;
l.batch = batch;
l.n = n;
l.input_layers = input_layers;
l.input_sizes = input_sizes;
int i;
int outputs = 0;
for(i = 0; i < n; ++i){
fprintf(stderr," %d", input_layers[i]);
outputs += input_sizes[i];
}
fprintf(stderr, "\n");
l.outputs = outputs;
l.inputs = outputs;
l.delta = calloc(outputs*batch, sizeof(float));
l.output = calloc(outputs*batch, sizeof(float));;
l.forward = forward_route_layer;
l.backward = backward_route_layer;
return l;
}
함수 이름: make_route_layer
입력:
- batch: int형, 배치 크기
- n: int형, 이전 레이어의 개수
- input_layers: int형 배열, 이전 레이어의 인덱스를 저장한 배열
- input_sizes: int형 배열, 이전 레이어의 출력 크기를 저장한 배열
동작:
- 입력으로 받은 정보를 바탕으로 route 레이어를 생성하고 초기화한다.
- 출력값과 입력값의 크기를 계산하고, delta와 output 메모리를 동적 할당한다. forward와 backward 함수를 할당하고 생성된 레이어를 반환한다.
설명:
- make_route_layer 함수는 입력으로 받은 정보를 바탕으로 route 레이어를 생성하고 초기화하는 함수이다. 이 함수는 생성된 route_layer 구조체를 반환한다.
- 배치 크기(batch), 이전 레이어의 개수(n), 이전 레이어의 인덱스(input_layers), 이전 레이어의 출력 크기(input_sizes)를 인자로 받는다.
- 출력값과 입력값의 크기를 계산하고, delta와 output 메모리를 동적 할당한다. forward와 backward 함수를 할당하고 생성된 레이어를 반환한다.
- route_layer 구조체를 초기화하기 위해 다음 필드를 설정한다.
- type: ROUTE
- batch: 입력으로 받은 배치 크기(batch)
- n: 입력으로 받은 이전 레이어의 개수(n)
- input_layers: 입력으로 받은 이전 레이어의 인덱스(input_layers)
- input_sizes: 입력으로 받은 이전 레이어의 출력 크기(input_sizes)
- outputs: 이전 레이어의 출력 크기를 모두 합한 값
- inputs: 이전 레이어의 출력 크기를 모두 합한 값
- delta: 크기가 outputs * batch인 0으로 초기화된 float형 배열
- output: 크기가 outputs * batch인 0으로 초기화된 float형 배열
- forward: forward_route_layer 함수의 포인터
- backward: backward_route_layer 함수의 포인터
- 마지막으로 생성된 route_layer 구조체를 반환한다.
This post is licensed under CC BY 4.0 by the author.