Pruning 사전 지식
실습에 들어가기 전 사전 지식을 정리해두자.
Matrix Sparsity
희소행렬 : 행렬의 대부분의 요소가 0인 행렬
Sparsity = 전체 중 0의 비율 (Density = 1 - Sparsity )
1 | 2 | 1 |
5 | 0 | 0 |
1 | 2 | 0 |
Dense 행렬
Sparsity = 3 / 9 = 33.33%
Dense = 6 / 9 = 66.67%
1 | 0 | 0 |
0 | 0 | 0 |
1 | 0 | 0 |
Sparsity 행렬
Sparsity = 7 / 9 = 77.78%
Dense = 6 / 9 = 22.22%
위와 같은 행렬에 대해 말한 이유는 Unstructured pruning은 Structured pruning과는 다르게 파라미터 값을 0으로 바꾸는 방식이다.
여전히 0을 저장하고 있고(공간 절감 X), 0을 곱하고 있기(시간 절감 X) 때문에 이 방식으로는 계산속도가 빨라지지 않는다.
즉, 시간 복잡도와 공간 복잡도가 해결되지 않는다.
때문에 해결책이 붙어야 하며 이는 크게 2개가 있다.
(1) Sparsity가 심한 경우 : Sparsity Matrix Representation
0이 아닌 값들을 기억하는 것이라고 보면 된다.
여기서는 좌표값(row, col)과 실제값, 이렇게 3가지를 하나로 저장한다.
1 | 0 | 0 |
0 | 0 | 0 |
1 | 0 | 0 |
위와 같은 행렬이 있을 때
좌측 상단에 있는 1의 값에 대해 (row, col, value) = (0, 0, 1)로 저장
좌측 하단에 있는 1의 값에 대해 (row, col, value) = (2, 0, 1)로 저장
이는 메모리와 연산 효율을 높일 수 있다.
메모리 효율에 대해 잠깐 알아보자.
일반적인 N X M 행렬은 NM 만큼의 메모리가 필요하다.
Sparse 행렬의 필요 메모리 =최대 3K (K는 0이 아닌 값의 개수)
Sparse = K / NM 이므로, Sparsity가 1 / 3 미만일 때 더 효율적이다.
위 3 X 3 행렬을 예시로 들자면, 원래 9의 메모리가 필요했는데, 3 X 2 = 6 으로 절감한 걸 확인할 수 있다.
(2) Sparsity가 적당한 경우 : 전용 하드웨어 사용
곱셈을 수행하기 전, 행렬 안에 어떤 값이 0인지 파악하는 작업을 거친다. (이 과정에서 오버헤드가 발생한다.)
이후 해당 위치를 스킵해서 계산되도록 조정한다.
Sensitivity Analysis (민감도 분석)
Pruning Ratio : 파라미터를 얼마나 제거할지의 비율
- Local : 레이어 별로 동일하게 일정 비율을 제거
- 동일한 비율이라서 Uniform Shrink라고도 한다.
더 좋은 방법은 레이어별로 비율을 다르게 설정하기가 될 수 있다.
이 방법이 필요한 경우
우리가 쓰는 네트워크가 복잡하거나 / 층별로 처리 방법이 상이한 모델의 경우 많이 사용한다.
각 레이어의 특성을 반엉 :
- 민감도가 높은 부분은 덜 pruning
- 민감도가 낮은 부분은 더 pruning
이는 각 레이어의 pruning 비율을 설정하는 것으로 중요도를 측정하게 된다.
pruning을 얼마나 진행했을 때, 성능이 얼마나 떨어지는지 분석하는 방법이다.(실험을 통해서 설정하는)
Sensitivity 측정
파라미터 / 레이어의 민감도 : 파라미터 혹은 레이어마다 조금씩 제거해보고 각각이 pruning 되었을 때 성능저하가 얼마나 되는지 측정
일반적으로는 가장 앞 부분 레이어가 민감하다. (입력을 직접적으로 처리하는 부분과 맞닿아 있어서)
일반적으로는 뒷 부분 레이어가 덜 민감하다. (인터렉션이 많이 이뤄진 상태라서 중복된 정보들을 많이 갖고 있는 레이어들이 있을 수 있다.)
Sensitivity Analysis는 오래 걸리는 작업이기 때문에 주로 분석용으로 사용한다.
(측정 한 번에 pruning 전체 과정 1번 만큼의 iteration이 소요되므로)
단! 모델 구조가 같고 데이터만 다른 경우, 한번 계산해둔 비율은 재사용이 어느 정도 가능하다.