convolutional_layer

Convolutional Layer 란?

Convolution은 합성곱으로 2가지 연산을 사용합니다.

  • 각 원소끼리 곱합니다. (element wise multiplication)

  • 각 원소를 더합니다.

이해를 돕기위해 그림으로 살펴보겠습니다. 아래 그림과 같이 각 원소를 곱하고 합한 값을 활성화 함수를 통과하여 최종적으로 값을 만듭니다.(아래 그림은 활성화 함수를 생략한 그림입니다.)

Convolutional Layer는 Feature Maps과 Filters의 Convolution 연산을 통해 그 다음 Feature Maps을 만들어 내는 작업을 반복합니다. 여기서 filters가 학습 파라미터 입니다.

입력 이미지 -> Filters(kernel) -> Feature Maps(Channels) -> Filters(kernel) -> Feature Maps(Channels) -> ...

Convolutional Layer는 설정 가능한 파라미터가 있습니다.

  • stride : filter가 움직이는 간격입니다.

  • padding : Feature Map의 테두리 부분의 정보 손실을 줄이기 위해서 테두리를 특정한 값(보통 0)으로 채워 넣는 방법입니다. padding은 몇개의 테두리를 채울지에 대한 값입니다.

  • filter의 수(가중치의 수) : k×k×C1×C2k \times k \times C_1 \times C_2

  • W2=W1k+2×paddingstridew+1W_2 = \frac{W_1 - k + 2 \times padding}{stride_w} + 1

  • H2=H1k+2×paddingstrideh+1H_2 = \frac{H_1 - k + 2 \times padding}{stride_h} + 1

Convolutional Layer 역전파는 쉽게 표현하는 경우 아래 그림과 같습니다.

output을 계산하기 위해서 각자의 id를 가지고 있는 weight가 사용된 곳을 보시면 이해하기 쉽습니다. 예를 들어서 w11w_11h11,h12,h21,h22h_11, h_12, h_21, h_22를 연산하는데 각각 사용되었기 때문에 이들의 미분 값의 합으로 최종적으로 업데이트 할 기울기를 만듭니다. 역전파는 Layer 따로 따로 간단하게 어떻게 동작하는지를 전부 살펴보고 마지막에 보면 더 쉬운거 같습니다.


forward_convolutional_layer

함수 이름: forward_convolutional_layer

입력:

  • convolutional_layer l: 컨볼루션 레이어 구조체

  • network net: 네트워크 구조체

동작:

  • 컨볼루션 연산을 수행하여 l.output에 결과값을 저장

  • 배치 정규화를 사용하는 경우, forward_batchnorm_layer 함수를 호출하여 배치 정규화를 수행

  • 활성화 함수를 수행하여 l.output을 업데이트

  • 이진 컨볼루션 또는 XNOR-Networks를 사용하는 경우, swap_binary 함수를 호출하여 가중치와 입력값을 이진화

설명:

  • 컨볼루션 레이어에 대한 forward 연산을 수행하는 함수이다.

  • l.weights, l.biases, l.activation 등 컨볼루션 레이어의 필수 구성 요소들을 사용하여 입력값을 컨볼루션 연산하여 출력값을 계산한다.

  • 컨볼루션 연산을 수행하기 위해 입력값을 이미지를 columns로 변환한다.

  • l.batch_normalize가 true인 경우, forward_batchnorm_layer 함수를 호출하여 배치 정규화를 수행한다.

  • activate_array 함수를 사용하여 활성화 함수를 수행하여 l.output을 업데이트한다.

  • l.binary 또는 l.xnor가 true인 경우, swap_binary 함수를 호출하여 가중치와 입력값을 이진화한다.

backward_convolutional_layer

함수 이름: backward_convolutional_layer

입력:

  • convolutional_layer l: 컨볼루션 레이어 구조체

  • network net: 네트워크 구조체

동작:

  1. activation function의 gradient를 계산한다.

  2. batch normalization이 적용되었다면 batch normalization의 gradient를 계산하고, 그렇지 않으면 bias의 gradient를 계산한다.

  3. 각 배치에 대해, 각 그룹에서 gradient와 weight를 곱해 weight update를 계산한다.

  4. 이미지를 columns로 변환하여, 각 그룹에서 weight와 gradient를 곱해 input delta를 계산한다.

  5. columns을 이미지로 변환하여 input delta를 저장한다.

설명:

  • convolutional layer에서는 이미지와 weight를 컨볼루션 연산하여 output feature map을 계산하고, 이후 activation function을 적용한다.

  • 역전파에서는 output feature map의 gradient를 계산하고, 이를 이용하여 input delta와 weight update를 계산한다.

  • 이때, gradient와 weight를 곱해 weight update를 계산할 때는 해당 그룹의 weight를 모두 사용하며, 각 그룹마다 input delta를 계산하여 누적하여 저장한다.

  • 이후, columns를 이미지로 변환하여 input delta를 계산한다.

  • 만약 batch normalization이 적용된 convolutional layer라면, 이전 layer에서 전달받은 error를 이용하여 batch normalization의 gradient를 계산하고, 이를 이용하여 gamma와 beta를 업데이트한다.

update_convolutional_layer

함수 이름: update_convolutional_layer

입력:

  • convolutional_layer l: 업데이트할 convolutional layer 구조체

  • update_args a: 업데이트에 필요한 인자들을 담은 구조체. learning_rate, momentum, decay, batch 값을 가짐

동작:

  • Convolutional layer의 bias와 weight를 업데이트함

  • learning_rate, momentum, decay, batch 값을 사용하여 업데이트에 필요한 계산 수행

설명:

  • axpy_cpu 함수를 사용하여 bias와 scale을 업데이트 함. axpy_cpu 함수는 y = a*x + y 연산을 수행함

  • scal_cpu 함수를 사용하여 momentum을 적용함. scal_cpu 함수는 벡터의 모든 원소에 스칼라 값을 곱해줌

  • weight의 경우 decay를 적용하고, axpy_cpu 함수를 사용하여 weight를 업데이트 함. 이때 batch 값을 사용하여 mini-batch gradient descent를 수행함

resize_convolutional_layer

함수 이름: resize_convolutional_layer

입력:

  • convolutional_layer *l: 크기를 조절할 컨볼루션 레이어

  • int w: 조절할 가로 크기

  • int h: 조절할 세로 크기

동작:

  • 주어진 가로 크기와 세로 크기에 따라 컨볼루션 레이어의 크기를 조정합니다.

  • 이때, 출력 크기(out_w, out_h)도 계산하고, 컨볼루션 레이어의 출력, 델타, x, x_norm, workspace의 크기를 새로운 크기에 맞게 재할당합니다.

설명:

  • 컨볼루션 레이어의 크기를 조절하는 함수입니다.

  • 입력으로 주어진 컨볼루션 레이어의 가로와 세로 크기를 주어진 w와 h 값으로 각각 바꾸어주며, 출력 크기(out_w, out_h)도 이에 맞게 다시 계산합니다.

  • 그리고 출력, 델타, x, x_norm, workspace의 크기를 새로운 크기에 맞게 realloc 함수를 사용하여 재할당합니다.

  • 이때, batch_normalize가 사용되는 경우에는 x와 x_norm도 재할당합니다.

  • 마지막으로 workspace_size를 get_workspace_size 함수를 통해 다시 계산하여 저장합니다.

make_convolutional_layer

함수 이름: make_convolutional_layer

입력:

  • batch: 배치 크기

  • h: 입력 이미지의 높이

  • w: 입력 이미지의 너비

  • c: 입력 이미지의 채널 수

  • n: 필터 개수

  • groups: 그룹 수

  • size: 필터 크기

  • stride: 스트라이드

  • padding: 패딩 크기

  • activation: 활성화 함수

  • batch_normalize: 배치 정규화 여부

  • binary: 이진화 여부

  • xnor: XNOR 여부

  • adam: Adam 옵티마이저 사용 여부

동작:

  • 입력 이미지와 필터를 합성곱 연산하여 출력을 계산하는 합성곱 레이어를 생성합니다.

  • 필요한 메모리를 동적 할당합니다.

  • 가중치(weight)와 편향(bias)을 초기화합니다.

  • 활성화 함수, 배치 정규화, 이진화, XNOR, Adam 옵티마이저를 사용하는 경우 필요한 메모리와 변수를 할당하고 초기화합니다.

  • 생성된 레이어의 출력 크기와 필요한 메모리 크기를 계산합니다.

  • 생성된 레이어와 연관된 함수 포인터를 설정합니다.

  • 생성된 레이어를 반환합니다.

설명:

  • 이 함수는 입력 이미지와 필터의 합성곱 연산을 수행하는 합성곱 레이어를 생성하는 함수입니다.

  • 입력으로 받은 파라미터를 사용하여 필요한 메모리를 동적 할당하고 초기화합니다.

  • 필터(weight)는 랜덤한 값으로 초기화하며, Xavier 초기화 방법을 사용합니다.

  • 활성화 함수는 ReLU, LeakyReLU, linear 함수를 사용할 수 있습니다.

  • 배치 정규화는 입력 데이터의 배치 단위로 정규화를 수행하여 학습을 안정화시키는 방법입니다.

  • 이진화는 모델의 가중치를 이진 형태로 변환하여 모델의 크기를 줄이고 연산 속도를 높이는 방법입니다.

  • XNOR는 이진화된 가중치와 이진화된 입력을 사용하여 합성곱 연산을 수행하는 방법으로, 이진화보다 더 큰 모델 압축과 빠른 연산 속도를 제공합니다.

  • Adam 옵티마이저는 경사 하강법을 사용하는 옵티마이저 중 하나로, 모멘텀과 RMSProp을 결합한 방법입니다. 학습 속도를 자동으로 조절하여 더 빠르게 수렴하는 특징이 있습니다.

denormalize_convolutional_layer

함수 이름: denormalize_convolutional_layer

입력:

  • convolutional_layer l: denormalization이 필요한 convolutional layer

동작:

  • batch normalization을 적용한 convolutional layer를 denormalize 함

  • convolutional layer의 weights, biases, scales, rolling_mean, rolling_variance 값을 수정함

설명:

  • batch normalization은 데이터의 분포를 조절해 학습을 안정화시키는 기술이다.

  • 학습 과정에서 이전 미니배치의 평균과 분산을 이용해 현재 미니배치의 데이터를 normalize한다.

  • 하지만, 학습이 끝난 모델을 사용할 때는 이전 미니배치의 평균과 분산 대신 전체 데이터셋의 평균과 분산을 이용해 denormalize해야 한다.

  • 이 함수는 그 역할을 수행하는 함수이다.

  • 각 채널마다 denormalize에 필요한 값을 계산하고, weights와 biases 값을 수정한다.

  • scales 값은 1로, rolling_mean과 rolling_variance 값은 0과 1로 초기화한다.

add_bias

함수 이름: add_bias

입력:

  • output: float 형식의 출력 값 포인터

  • biases: float 형식의 bias 값 포인터

  • batch: int 형식의 batch 크기

  • n: int 형식의 필터 개수

  • size: int 형식의 출력 값 크기

동작:

  • 출력 값에 bias 값을 더함

  • 출력 값의 크기는 batch x n x size

설명:

  • 각 필터마다 bias 값을 더해주는 함수

  • 출력 값의 각 요소에 biases[i] 값을 더해줌으로써 bias 값을 적용함

  • 출력 값의 크기는 batch x n x size 이므로, 반복문을 통해 각 요소에 biases[i] 값을 더해줌

scale_bias

함수 이름: scale_bias

입력:

  • float *output: 출력값 포인터

  • float *scales: 스케일값 포인터

  • int batch: 배치 크기

  • int n: 출력 채널 수

  • int size: 출력값 크기 (가로, 세로)

동작:

  • 각 배치별로 출력값(output)의 각 채널에 대해, scales 배열의 해당 채널 값으로 출력값을 스케일링(scale)합니다.

설명:

  • 이 함수는 출력값(output)에 대해 각 채널에 대한 스케일링 작업을 수행하는 함수입니다.

  • 배치(batch) 크기만큼의 데이터를 처리하며, 각 배치에 대해 출력값(output)의 n개 채널에 대해 스케일링 작업을 수행합니다.

  • 출력값(output)은 배치, 채널, 가로, 세로의 4차원 배열 구조로 이루어져 있으며, 스케일(scales)도 출력 채널 수(n)만큼의 1차원 배열로 주어집니다.

  • 이 함수는 각 배치(b), 채널(i), 가로(j), 세로(k)에 대한 반복문을 수행하며, 출력값(output)의 (b*n+i)*size+j 위치에 해당하는 값을 스케일(scales) 배열의 i번째 값으로 곱해주는 작업을 수행합니다.

  • 이렇게 스케일링된 값을 출력값(output)에 저장합니다.

backward_bias

함수 이름: backward_bias

입력:

  • bias_updates: 각 레이어의 편향(bias) 업데이트 값을 저장할 배열

  • delta: 각 뉴런의 오차 값(error) 배열

  • batch: 미니배치(batch) 크기

  • n: 레이어 내 뉴런 개수

  • size: 뉴런이 가지고 있는 입력(input) 데이터 크기

동작:

  • 이 함수는 convolutional neural network에서 편향(bias) 업데이트를 계산합니다.

  • delta는 현재 레이어의 뉴런에서의 오차 값입니다.

  • bias_updates 배열은 각 레이어의 편향 값을 업데이트할 때 사용됩니다.

설명:

  • 이 함수는 미니배치(batch) 내의 모든 뉴런에 대해 bias_updates 배열에 대한 업데이트 값을 계산합니다.

  • 먼저 for문을 이용하여 batch 내 각 뉴런에 대한 bias_updates 값을 계산합니다.

  • 그리고 sum_array 함수를 사용하여 delta 배열의 해당 뉴런의 오차 값을 계산하고, bias_updates 배열에 더합니다.

  • 따라서 이 함수는 backward propagation 과정에서 편향 업데이트를 수행합니다.

swap_binary

함수 이름: swap_binary

입력:

  • convolutional_layer *l: convolutional_layer 구조체 포인터

동작:

  • 이 함수는 convolutional layer의 가중치(weights)와 binary weights를 교환(swap)합니다.

설명:

  • 이 함수는 convolutional layer의 가중치를 binary weights로 교환합니다.

  • 이는 forward pass에서 기존의 가중치를 사용하여 연산을 수행하는 대신, 이진 형태의 가중치(binary weights)를 사용하여 더욱 빠르게 연산을 수행할 수 있도록 하기 위한 것입니다.

  • 이 함수에서는 포인터를 사용하여 가중치와 binary weights를 교환합니다.

binarize_weights

함수 이름: binarize_weights

입력:

  • float *weights: 이진화할 가중치 배열

  • int n: 가중치의 채널 수

  • int size: 가중치의 크기

  • float *binary: 이진화된 가중치를 저장할 배열

동작:

  • 주어진 가중치 배열(weights)을 이진화하여 이진화된 가중치(binary)를 계산합니다.

  • 이진화된 가중치는 각 가중치의 절댓값 평균(mean)으로 계산됩니다.

  • 가중치 값이 평균보다 크면 이진화된 가중치 값은 평균이고, 작으면 -평균입니다.

설명:

  • Convolutional neural network에서 이진화된 가중치는 더 적은 메모리 공간을 차지하고 빠른 연산이 가능하여 모델의 실행 속도를 향상시키는 데 도움을 줍니다.

  • 이진화된 가중치를 사용하면 계산 복잡도를 줄이는 동시에 정확도를 유지할 수 있습니다.

binarize_cpu

함수 이름: binarize_cpu

입력:

  • input: float 형태의 1차원 배열

  • n: input 배열의 길이

  • binary: float 형태의 1차원 배열

동작:

  • input 배열의 요소를 0을 기준으로 1 또는 -1로 이진화하여 binary 배열에 저장함.

설명:

  • 이진화란, 입력값을 0과 1 또는 -1과 1과 같은 이진수 형태로 바꾸는 작업을 의미함.

  • 이 함수에서는 입력된 input 배열의 요소를 0을 기준으로 1 또는 -1로 이진화하여 binary 배열에 저장함.

  • 이진화된 값은 다음과 같은 조건문으로 결정됨:

    • input[i] > 0 이면, binary[i] = 1

    • input[i] <= 0 이면, binary[i] = -1

binarize_input

함수 이름: binarize_input

입력:

  • float *input: 이진화할 입력 배열

  • int n: 입력 배열의 채널 수

  • int size: 입력 배열의 크기 (가로 또는 세로 한 변의 길이)

  • float *binary: 이진화된 값을 저장할 출력 배열

동작:

  • 입력 배열을 이진화하여 출력 배열에 저장합니다.

설명:

  • 입력 배열의 각 채널과 위치에 대해 평균값을 계산하고, 입력 값이 평균보다 크면 1, 작으면 -1을 출력 배열에 저장합니다.

  • 평균값은 각 채널과 위치마다 다르게 계산됩니다.

convolutional_out_height

함수 이름: convolutional_out_height

입력:

  • convolutional_layer l: 합성곱 레이어 구조체

동작:

  • 합성곱 레이어의 입력 이미지 높이(l.h), 패딩 크기(l.pad), 필터 크기(l.size), 및 스트라이드 크기(l.stride)를 고려하여 출력 이미지 높이를 계산한다.

설명:

  • 합성곱 레이어에서 필터와 입력 이미지의 합성곱 연산을 수행하면 출력 이미지가 생성된다.

  • 이때, 출력 이미지의 높이를 계산하는 함수이다.

  • 합성곱 레이어 구조체에서 입력 이미지의 높이(l.h), 패딩 크기(l.pad), 필터 크기(l.size), 및 스트라이드 크기(l.stride)를 이용하여 출력 이미지의 높이를 계산하고 반환한다.

convolutional_out_width

함수 이름: convolutional_out_width

입력:

  • convolutional_layer l: 컨볼루션 레이어 구조체

동작:

  • 입력 이미지의 너비, 패딩, 스트라이드, 필터 크기를 고려하여 컨볼루션 레이어의 출력 너비를 계산한다.

설명:

  • 컨볼루션 레이어의 출력 너비를 반환하는 함수이다.

  • 입력 이미지의 너비, 패딩, 스트라이드, 필터 크기를 고려하여 컨볼루션 레이어의 출력 너비를 계산하고 반환한다.

  • 출력 너비는 아래의 공식을 따른다: (입력 너비 + 2 x 패딩 - 필터 크기) / 스트라이드 + 1

get_convolutional_image

함수 이름: get_convolutional_image

입력:

  • convolutional_layer 구조체

동작:

  • convolutional_layer의 출력을 float_to_image 함수를 사용하여 image 구조체로 변환

설명:

  • convolutional_layer의 출력을 이미지 형식으로 변환하여 반환하는 함수이다.

  • 반환된 이미지는 float_to_image 함수를 사용하여 변환된다.

get_convolutional_delta

함수 이름: get_convolutional_delta

입력:

  • convolutional_layer 구조체

동작:

  • convolutional_layer 구조체 내 delta 배열을 out_w, out_h, out_c 크기의 이미지 구조체 형태로 변환

설명:

  • convolutional_layer 구조체 내 delta 배열은 해당 층에서 역전파(backpropagation)를 통해 계산된 출력 값의 오차 값을 저장하고 있다.

  • 이 함수는 해당 delta 배열을 이미지 형태로 변환하여 반환한다.

  • 이 때, 변환된 이미지의 크기는 해당 층의 출력 값 크기(out_w, out_h, out_c)와 동일하다.

get_convolutional_weight

함수 이름: get_convolutional_weight

입력:

  • convolutional_layer l: 컨볼루션 레이어 구조체

  • int i: 가져올 가중치의 인덱스

동작:

  • 컨볼루션 레이어에서 i번째 가중치의 크기를 이용하여 float_to_image 함수를 호출해 가중치 이미지를 생성한다.

설명:

  • 컨볼루션 레이어에서 i번째 가중치의 값을 이용하여 해당 가중치를 시각화할 수 있는 이미지를 생성한다.

  • 생성된 이미지는 float_to_image 함수를 이용하여 생성되며, 이미지의 크기는 가중치의 크기와 동일하다.

rgbgr_weights

함수 이름: rgbgr_weights

입력:

  • convolutional_layer l: 컨볼루션 레이어

동작:

  • 각 컨볼루션 레이어의 가중치 이미지를 가져온다.

  • 이미지의 채널이 3인 경우, rgbgr_image 함수를 사용하여 RGB 이미지를 BGR 이미지로 변환한다.

  • 모든 가중치 이미지에 대해 위 동작을 수행한다.

설명:

  • 이 함수는 컨볼루션 레이어의 가중치 이미지를 BGR 채널 순서로 변환하는 기능을 수행한다.

  • 컬러 이미지에서는 색상 채널의 순서가 RGB가 일반적이지만, OpenCV 라이브러리에서는 BGR 채널 순서를 사용하므로 이러한 변환이 필요하다.

  • 이 함수는 주로 딥러닝 모델을 OpenCV와 같은 라이브러리에서 사용할 때 유용하게 사용된다. 하위 설명:

  • for 문에서 i 변수를 초기화하고, l.n만큼 반복한다.

  • get_convolutional_weight 함수를 사용하여 i번째 가중치 이미지를 가져온다.

  • 이미지의 채널이 3인 경우에만 rgbgr_image 함수를 사용하여 이미지를 변환한다.

rescale_weights

함수 이름: rescale_weights

입력:

  • convolutional_layer l : rescale할 레이어

  • float scale : 가중치를 곱할 스케일 값

  • float trans : 편향(bias) 값을 조절할 값

동작:

  • convolutional layer에서 가중치(weight)를 가져와서 이미지를 rescale하고, 이미지의 총 합(sum)을 구한 후, 편향(bias) 값을 trans만큼 더해줌

설명:

  • convolutional_layer l에서 가중치(weight) 이미지를 가져와서 이미지의 채널 수(c)가 3일 때(rescale하고자 하는 이미지가 RGB 이미지일 때), 이미지를 scale 값만큼 곱해줌

  • 이미지의 모든 픽셀 값의 합(sum)을 구함

  • l.biases[i]에 sum * trans 값을 더해줌으로써, 편향(bias) 값을 trans만큼 더해줌

get_weights

함수 이름: get_weights

입력:

  • convolutional_layer l: 합성곱 레이어 객체

동작:

  • 합성곱 레이어의 가중치를 가져와서, 가중치 이미지들을 생성

  • 생성된 가중치 이미지들을 정규화(normalize)

  • 가중치 이미지들을 반환

설명:

  • 함수는 입력으로 받은 합성곱 레이어의 가중치를 가져와 가중치 이미지들을 생성하고, 생성된 가중치 이미지들을 정규화(normalize)합니다.

  • 정규화(normalize)란, 이미지 픽셀 값들을 0과 1사이의 값으로 조정하는 것을 말합니다.

  • 생성된 가중치 이미지들은 포인터 배열로 반환됩니다.

visualize_convolutional_layer

함수 이름: visualize_convolutional_layer

입력:

  • convolutional_layer l: 시각화할 합성곱 레이어

  • char *window: 시각화할 윈도우 이름

  • image *prev_weights: 이전 가중치 이미지 포인터

동작:

  • 합성곱 레이어의 가중치 이미지와 출력 이미지를 시각화하고,

  • 시각화된 가중치 이미지를 반환한다.

설명:

  • convolutional_layer 구조체에 저장된 가중치 값들을 이미지로 변환한다.

  • 변환된 이미지들을 윈도우에 시각화하여 보여준다.

  • 합성곱 레이어의 출력 이미지를 이미지 collapse를 통해 한 장으로 만들어서 보여준다.

  • 반환되는 single_weights 포인터는 가중치 이미지를 담고 있는 이미지 배열이다.

Last updated

Was this helpful?