《Yacht Dice》는 여러 명이 플레이하는 주사위 게임입니다. 플레이어는 우선 주사위를 $5$개 굴립니다. 이후 원하는 주사위를 고정시킨 뒤, 남은 주사위를 다시 굴리는 일을 두 번 이하로 할 수 있습니다. 그렇게 주사위를 굴려 나온 값들의 조합으로 아래 족보에서 이전까지 선택하지 않은 하나를 선택해 점수를 기록합니다.
Ones: $1$이 나온 주사위의 눈 수의 총합.
Twos: $2$가 나온 주사위의 눈 수의 총합.
Threes: $3$이 나온 주사위의 눈 수의 총합.
Fours: $4$가 나온 주사위의 눈 수의 총합.
Fives: $5$가 나온 주사위의 눈 수의 총합.
Sixes: $6$이 나온 주사위의 눈 수의 총합.
Four of a Kind: 동일한 주사위 눈이 $4$개 이상**이라면, 동일한 주사위 눈 $4$개의 총합. 아니라면 $0$점.
Full House: 주사위 눈이 정확히 두 종류로 이루어져 있고 한 종류는 $3$개, 다른 종류는 $2$개일 때, 주사위 눈 $5$개의 총합. 아니라면 $0$점.
Little Straight: 주사위 눈이 $1$, $2$, $3$, $4$, $5$의 조합이라면, 즉 $1$에서 $5$까지의 눈이 한 번씩 등장했다면 $30$점, 아니라면 $0$점.
Big Straight: 주사위 눈이 $2$, $3$, $4$, $5$, $6$의 조합이라면, 즉 $2$에서 $6$까지의 눈이 한 번씩 등장했다면 $30$점, 아니라면 $0$점.
Yacht: 동일한 주사위 눈이 $5$개라면 $50$점, 아니라면 $0$점.
Choice: 모든 주사위 눈의 총합.
모든 플레이어의 모든 족보가 사용되면 게임이 끝납니다.
지금은 한별이 차례입니다. 한별이는 첫 번째로 굴린 주사위의 조합에서 세 개의 주사위를 고정하고 나머지 두 개의 주사위를 다시 굴려야 하는 상황입니다. 이 상황에서 나올 수 있는 점수의 최댓값은 얼마일까요?
입력
첫 번째 줄에는 이미 선택한 족보를 의미하는 $12$글자의 문자열이 주어집니다. 문자열의 모든 글자는 Y 또는 N이며, 글자들 중 적어도 하나는 Y입니다.
$1$번째 글자가 Y라면 Ones를 선택할 수 있습니다. 마찬가지로 $6$번째 글자까지 같은 규칙이 적용되어, $6$번째 글자가 Y라면 Sixes를 선택할 수 있습니다.
$7$번째 글자가 Y라면 Four of a Kind를 선택할 수 있습니다.
$8$번째 글자가 Y라면 Full House를 선택할 수 있습니다.
$9$번째 글자가 Y라면 Little Straight를 선택할 수 있습니다.
$10$번째 글자가 Y라면 Big Straight를 선택할 수 있습니다.
$11$번째 글자가 Y라면 Yacht를 선택할 수 있습니다.
$12$번째 글자가 Y라면 Choice를 선택할 수 있습니다.
각각의 경우에서 글자가 N이라면 해당하는 족보를 이미 선택하여 다시 선택할 수 없음을 의미합니다.
두 번째 줄에는 한별이가 첫 번째로 굴린 조합에서 고정한 주사위들의 눈의 수를 나타내는 $1$과 $6$ 사이의 정수 $3$개가 공백으로 구분되어 주어집니다.
출력
한별이가 얻을 수 있는 점수의 최댓값을 출력합니다.
풀이
compute_score 함수
이 함수는 주사위 조합과 선택한 족보에 따라 점수를 계산합니다.
def compute_score(dice, category_idx):
dice: 5개의 주사위 눈을 담은 리스트
category_idx: 0-11 사이의 정수로, 선택한 족보를 나타냄
함수는 각 족보 유형에 따라 다른 로직을 적용합니다.
Ones부터 Sixes까지 (인덱스 0-5)
if 0 <= category_idx <= 5: # Ones to Sixes
target = category_idx + 1
return sum(d for d in dice if d == target)
category_idx + 1이 찾고자 하는 주사위 눈 값
해당 값과 일치하는 주사위 눈들의 합을 반환
Four of a Kind (인덱스 6)
elif category_idx == 6: # Four of a Kind
for value in range(1, 7):
if dice.count(value) >= 4:
return value * 4
return 0
같은 눈이 4개 이상인 경우, 그 눈 × 4를 반환
없으면 0점을 반환
Full House (인덱스 7)
elif category_idx == 7: # Full House
counts = {}
for d in dice:
counts[d] = counts.get(d, 0) + 1
values = list(counts.values())
if len(counts) == 2 and (3 in values and 2 in values):
return sum(dice)
return 0
주사위 눈의 등장 횟수를 딕셔너리에 저장
딕셔너리의 길이가 2(두 종류의 눈만 있음)이고, 한 종류는 3번, 다른 종류는 2번 등장한다면 모든 주사위의 합을 반환
조건을 만족하지 않으면, 0점을 반환
Little Straight (인덱스 8)
elif category_idx == 8: # Little Straight
if sorted(dice) == [1, 2, 3, 4, 5]:
return 30
return 0
주사위 눈이 1부터 5까지 모두 있으면 30점을 반환
아니면 0점을 반환
Big Straight (인덱스 9)
elif category_idx == 9: # Big Straight
if sorted(dice) == [2, 3, 4, 5, 6]:
return 30
return 0
- 모든 주사위 눈이 같으면(집합의 크기가 1이면) 50점을 반환
- 아니면 0점을 반환
<br>
**Choice (인덱스 11)**:
```python
elif category_idx == 11: # Choice
return sum(dice)
모든 주사위 눈의 합을 반환
시간 복잡도 분석
남은 두 주사위를 굴리는 경우의 수: 6 × 6 = 36
각 경우마다 최대 12개의 족보를 확인: 36 × 12 = 432
각 족보마다 점수 계산은 O(1) 또는 O(n) 시간이 소요됨 (여기서 n은 주사위 개수 5, 상수 취급 가능)
따라서 전체 시간 복잡도는 O(36 × 12 × 5) = O(2160) = O(1)
예제 검증
def test_examples():
# 예제 1
example1_available = "YYYYYYYYYYYN"
example1_fixed = [1, 5, 6]
available_categories1 = [i for i in range(12) if example1_available[i] == 'Y']
max_score1 = 0
best_dice1 = []
best_category1 = -1
for d1 in range(1, 7):
for d2 in range(1, 7):
current_dice = example1_fixed.copy() + [d1, d2]
for category in available_categories1:
score = compute_score(current_dice, category)
if score > max_score1:
max_score1 = score
best_dice1 = current_dice
best_category1 = category
print(f"예제 1 최대 점수: {max_score1}")
print(f"최적 주사위: {best_dice1}, 사용 족보: {best_category1}")
# 예제 테스트
test_examples()
전체 코드
# 25204 문자열 정렬
def compute_score(dice, category_idx):
if 0 <= category_idx <= 5: # Ones to Sixes
target = category_idx + 1
return sum(d for d in dice if d == target)
elif category_idx == 6: # Four of a Kind
for value in range(1, 7):
if dice.count(value) >= 4:
return value * 4
return 0
elif category_idx == 7: # Full House
counts = {}
for d in dice:
counts[d] = counts.get(d, 0) + 1
values = list(counts.values())
if len(counts) == 2 and (3 in values and 2 in values):
return sum(dice)
return 0
elif category_idx == 8: # Little Straight
if sorted(dice) == [1, 2, 3, 4, 5]:
return 30
return 0
elif category_idx == 9: # Big Straight
if sorted(dice) == [2, 3, 4, 5, 6]:
return 30
return 0
elif category_idx == 10: # Yacht
if len(set(dice)) == 1:
return 50
return 0
elif category_idx == 11: # Choice
return sum(dice)
return 0
def solve():
# 선택 가능한 족보 읽기
available = input().strip()
available_categories = [i for i in range(12) if available[i] == 'Y']
# Y가 있는 위치의 인덱스를 리스트에 저장
# 고정된 주사위 읽기
fixed_dice = list(map(int, input().strip().split()))
max_score = 0
# 남은 두 주사위의 모든 경우의 수 시뮬레이션 (1-6, 1-6) => 36가지 모두 확인
for d1 in range(1, 7):
for d2 in range(1, 7):
current_dice = fixed_dice.copy() + [d1, d2]
# 각 선택 가능한 족보에 대한 점수 계산
for category in available_categories:
score = compute_score(current_dice, category)
max_score = max(max_score, score)
return max_score
print(solve())
문자열은 영문 알파벳 이외에도 붙임표 ('-')가 들어가는 경우가 있기 때문에 처리가 까다롭다. 이 문제에 한해, 서로 다른 두 문자열 $X$, $Y$의 "사전식" 순서는 아래 규칙에 따라 정한다:
$X$가 $Y$의 접두사인 (prefix) 경우 $X$가 $Y$보다 앞선다. 반대로, $Y$가 $X$의 접두사인 경우 $Y$가 $X$보다 앞선다.
위 경우에 해당하지 않을 경우: 첫번째 문자부터 시작하여 $X$, $Y$가 처음으로 달라지는 부분이 i$i$번째 문자라 하자. $X$의 $i$번째 문자를 $X_i$, $Y$의 $i$번째 문자를 $Y_i$라 했을 때:
둘 중 하나만 붙임표 ('-')인 경우, 붙임표가 들어간 문자열이 사전순에서 뒤진다. 예를 들어, Xi$X_i$가 붙임표이고 $Y_i$가 붙임표가 아닌 경우, $Y$가 앞선다.
둘 다 알파벳인 경우, 대소문자를 무시했을 때 서로 다른 알파벳이라면, 알파벳 순서를 따른다. 만약 같은 알파벳이지만 하나만 대문자인 경우 대문자가 들어간 문자열이 사전순에서 앞선다.
예를 들어, 아래와 같은 문자열 쌍을 비교해보자:
$X$ =Santa-Mar과 $Y$ = Santa-Maria이 경우 규칙 1에 따라 $X$가 앞선다. $X$가 $Y$의 접두사이기 때문이다.
$X$ = San-Francisco 와 $Y$ = Santa-Clara: 이 경우 처음 3$3$개의 문자는 같지만 4$4$번째 문자가 '-'와 't'로 다르다. 규칙 2-1에 따라 $X$가 $Y$에 뒤진다.
$X$ = Seoul과 $Y$ = seoul: 이 경우 규칙 2-2에 따라 Seoul이 앞선다.
입력으로 $n$개의 문자열이 주어졌을 때, 위 규칙에 따라 사전식 정렬 후 출력하는 문자열 정렬기를 만들어보자.
입력
첫 줄에 테스트 케이스의 수 $T$가 주어진다.
각 테스트 케이스의 첫 줄에는 $n$이 주어진다. 다음 $n$줄에 걸쳐 각 줄에 문자열이 하나씩 주어진다.
출력
각 테스트 케이스의 정답을 $n$줄에 걸쳐 출력한다. 각 줄에는 사전순으로 정렬된 문자열 하나씩을 순서대로 출력한다.
풀이
1. functools 모듈을 활용한 풀이
functools 모듈과 cmp_to_key 함수
functools는 파이썬의 내장 모듈로, 함수를 다루는 데 유용한 도구들을 제공합니다. 그 중 cmp_to_key 함수는 Python 2에서 사용되던 비교 함수를 Python 3의 키 함수로 변환해주는 역할을 합니다.
Python 2에서는 sort() 함수에 cmp 매개변수를 제공하여 두 요소를 직접 비교하는 함수를 사용할 수 있었습니다.
Python 3에서는 이러한 방식이 제거되고 key 매개변수만 남았습니다.
cmp_to_key는 두 요소를 비교하는 함수를 받아서, 각 요소에 대해 정렬 키를 생성하는 함수로 변환해줍니다.
# 25204 문자열 정렬
import sys
import functools
def compare(s1, s2):
# 두 문자열을 한 글자씩 비교
i = 0
min_len = min(len(s1), len(s2)) # 두 문자열 중 더 짧은 문자열의 길이
while i < min_len:
# 두 문자열의 현재 위치 문자가 같으면 다음 문자로 넘어감
if s1[i] == s2[i]:
i += 1
continue
# 다른 문자를 발견했을 때
# 붙임표(-)) 우선순위 처리 => 두 문자가 다르고 그 중 하나가 붙임표(-)라면, 붙임표가 아닌 문자열이 앞에 온다
if s1[i] == '-':
return 1 # s2가 앞선다
if s2[i] == '-':
return -1 # s1이 앞선다
# 알파벳 비교
if s1[i].lower() != s2[i].lower():
# 대소문자 무시했을 때 다른 알파벳이면 알파벳 순서
return -1 if s1[i].lower() < s2[i].lower() else 1
else:
# 같은 알파벳이지만 대소문자가 다른 경우 대문자가 앞선다
return -1 if s1[i].isupper() and s2[i].islower() else 1 if s1[i].islower() and s2[i].isupper() else 0
# 여기까지 왔다면 접두사 관계 확인
if len(s1) == len(s2):
return 0
# 짧은 문자열이 긴 문자열의 접두사면 짧은 것이 앞선다
return -1 if len(s1) < len(s2) else 1
# 입력 처리
input = sys.stdin.readline
T = int(input())
for _ in range(T):
N = int(input())
strings = [input().strip() for _ in range(N)]
# functools.cmp_to_key를 사용하여 정렬
sorted_strings = sorted(strings, key=functools.cmp_to_key(compare))
# 순차적으로 출력
for s in sorted_strings:
print(s)
각 테스트 케이스마다
문자열 개수 N을 입력받습니다.
N개의 문자열을 입력받아 리스트에 저장합니다.
sorted() 함수와 functools.cmp_to_key(compare)를 사용하여 문자열을 정렬합니다.
정렬된 문자열을 한 줄에 하나씩 출력합니다.
2. __lt__ (less than) 연산자를 오버라이드한 래퍼 클래스를 이용한 풀이
모듈 없이도 구현이 가능한 방식입니다.
파이썬 클래스와 비교 연산자 오버라이딩
파이썬에서 객체를 비교할 때 (<, >, == 등), 파이썬은 특정 메서드를 찾아 호출합니다. 이것을 magic method 또는 double underscore method 라고 부릅니다.
__lt__ (less than): < 연산자에 대응
__gt__ (greater than): > 연산자에 대응
__eq__ (equal): == 연산자에 대응
파이썬의 sort() 함수는 객체들을 정렬할 때 기본적으로 < 연산자를 사용합니다. __lt__ 메서드를 구현하면, 파이썬은 정렬 과정에서 이 메서드를 호출하여 객체들의 순서를 결정합니다.
# 25204 문자열 정렬
import sys
# 입력 처리
input = sys.stdin.readline
T = int(input())
for _ in range(T):
N = int(input())
strings = [input().strip() for _ in range(N)]
# 직접 비교 정렬 구현 (파이썬 내장 정렬 알고리즘 활용)
# 두 문자열 비교를 위한 클래스 정의
# 문자열을 받아서 객체 내부에 저장
class StringComparer:
def __init__(self, string):
self.string = string
def __lt__(self, other):
# '<' 연산자 구현
# self는 왼쪽 객체(a), other은 오른쪽 객체(b)를 가리킴
s1, s2 = self.string, other.string
# 문자별 비교
# i는 현재 비교하는 문자의 위치(인덱스)
# min_len은 두 문자열 중 더 짧은 것의 길이
i = 0
min_len = min(len(s1), len(s2))
while i < min_len:
# 같은 위치의 문자가 같으면 다음 문자로
if s1[i] == s2[i]:
i += 1
continue
# 다른 문자 발견 시
# 붙임표 처리
# s1[i]가 붙임표면, s1은 s2보다 뒤에 와야 함 => s1 < s2는 거짓이므로 False 반환
# s2[i]가 붙임표면, s1은 s2보다 앞에 와야 함 => s1 < s2는 참이므로 True 반환
if s1[i] == '-':
return False # s2가 앞선다
if s2[i] == '-':
return True # s1이 앞선다
# 알파벳 비교
if s1[i].lower() != s2[i].lower():
# 대소문자 무시했을 때 다른 알파벳이면 알파벳 순서
return s1[i].lower() < s2[i].lower()
else:
# 같은 알파벳이지만 대소문자가 다른 경우 대문자가 앞선다
if s1[i].isupper() and s2[i].islower():
return True
if s1[i].islower() and s2[i].isupper():
return False
# 둘 다 같은 대소문자면 계속 비교
i += 1
continue
# 접두사 관계 확인
return len(s1) < len(s2)
# 래퍼 클래스를 사용하여 정렬
sorted_strings = [s.string for s in sorted([StringComparer(s) for s in strings])]
# 순차적으로 출력
for s in sorted_strings:
print(s)
엣지 컴퓨팅 등 다양한 환경에서 딥러닝 모델을 사용할 수 있도록, 파라미터와 가중치를 줄인 경량 모델의 수요가 증가했다.
대부분의 경량화, 모델 압축 기술이 성능 저하를 겪고 겪기 때문에, 이 Survey에서는 프루닝, 양자화, 지식 증류를 결합한 하이브리드 무손실 압축 모델을 제안했다. 제안된 모델은 일반적인 CNN 모델보다 세 배 작으며 압축 후 97%의 최첨단 정확도를 달성하는 성과를 보여줬다.
모델 경량화 기술
Prunning 프루닝
Prunning = 가지치기
딥러닝 모델에서 중요하지 않은 연결 또는 불필요한 파라미터를 제거하여 모델 크기와 계산 비용을 줄이는 기술
네트워크 프루닝(Network Prunning)은 중복된 매개변수를 줄이기 위해 사용하는 주요 기법으로, 불필요한 연결을 제거하여 매개변수의 수를 줄이고 계산 비용을 줄이는 방식으로 작동한다.
목표 : 모델의 정확도에 영향을 최소화 하면서 메모리 사용량과 연산 복잡도를 줄이는 것
원리 : 모델 성능에 기여도가 낮은 가중치와 뉴런, 중복 매겨변수 등은 제거해도 성능 저하가 거의 없다는 점을 활용함
채널, 필터, 뉴런과 같은 전체 구조적 구성 요소를 식별하고 제거해서 딥러닝 모델의 크기를 줄이는 것을 목표로 함
모델의 구조를 유지하여 하드웨어 가속기에서 효율적인 배포가 가능함
개별 매개변수를 제거하는 Unstructured Prunning과 달리 모델의 원래 구조를 보존하여 효율적으로 구현할 수 있다.
하드웨어 가속기가 프루닝으로 유도된 희소성 패턴을 활용해 메모리 접근 및 계산 효율성을 최적화하기 때문에, 리소스가 제한된 상황에서의 호환성이 좋다.
적용 사례
AlexNet 모델 : 9배 압축 후에도 정확도를 유지함
양자화(Quantization)나 지식 증류(Knowledge Distillation)와 함께 사용 가능
Unstructured Prunning 비구조적 프루닝
중요도가 낮은 개별 가중치나 뉴런을 제거
장점
구현이 상대적으로 간단하고 유연함
단점
모델의 밀도가 낮아져서 하드웨어 최적화가 어려움
정리된 구조가 없어 메모리 접근 및 계산 비효율 가능성
프루닝의 작동 원리
프루닝은 불필요한 가중치를 "0"으로 설정하거나 제거하여 전체 모델의 복잡성을 줄인다
프루닝 성과
방법
프루닝 유형
성과
기하학적 평균 기반 프루닝
구조적
성능 저하 없음
프루닝 계층 재구성
구조적
5.13배 속도 증가, 정확도 0.65% 감소
경량 Bi-LSTM
구조적
36% 파라미터 감소, 정확도 3% 증가
블록 제거 전략
비구조적
5.95배 압축, 90.5% 정확도
가중치 프루닝 전략
구조적
MnasNet 12MB 모델, 83.5% Top-1 정확도
저분산 특징 프루닝
비구조적
악성코드 탐지 모델 성능 향상
선택적 구조 제거
구조적
압축 후에도 만족스러운 성능 유지
Knowledge Distillation(KD) 지식 증류
지식 증류(Knowledge Distillation)는 복잡한 모델(교사 모델, Teacher Model)의 지식을 경량화된 모델(학생 모델, Student Model)로 전이시키는 기술
경량화된 모델이 교사 모델의 동작과 출력을 모방하도록 학습시킴으로써, 성능 저하 없이 모델 크기를 줄이고 효율을 높이는 기술!!
대부분의 딥러닝 모델, 특히 최신 대규모 모델은 높은 정확도를 자랑하지만, 계산량이 많고 메모리를 많이 차지하는데, 이를 엣지 디바이스에서 사용하려면 모델 크기와 연산량을 줄여야 하지만, 단순히 크기만 줄이면 성능 저하가 불가피함…
지식 증류는 이러한 문제를 해결하기 위해 설계된 방법으로, 교사 모델의 "지식"을 최대한 활용해 경량 모델에서도 유사한 수준의 성능을 달성할 수 있도록 도움
참고할 만한 자료
Hinton et al., "Distilling the Knowledge in a Neural Network" 논문: 링크
지식 증류의 작동 원리
KD는 교사 모델의 출력값과 행동을 학생 모델이 모방하도록 설계하며, 일반적으로 교사 모델은 복잡한 학습 과정을 통해 데이터를 잘 이해하고 높은 정확도로 예측한다. 이때 교사 모델이 생성하는 정보는 크게 세 가지 형태로 학생 모델에 전달된다.
교사 모델의 소프트 라벨 (Soft Labels)
교사 모델이 예측한 각 클래스의 확률 분포
(예시) 고양이 사진을 분류한다고 할 때 교사 모델의 출력은 [고양이: 0.7, 개: 0.2, 새: 0.1]와 같은 형태일 수 있다. 학생 모델은 이 확률 분포를 학습하며, 단순히 정답 여부만 학습하는 것보다 데이터의 미묘한 패턴을 더 잘 이해할 수 있다.
교사 모델의 중간 특징 표현 (Feature Representations)
교사 모델이 데이터의 중간 계층에서 추출한 특징 맵(feature maps)을 학생 모델이 학습한다. 이는 데이터가 교사 모델 내부에서 어떻게 처리되고 표현되는지를 학생 모델이 모방하도록 유도한ㄷㅏ
(예시) 이미지 분류 모델에서 교사 모델의 중간 계층이 이미지의 엣지(모서리)나 질감 같은 특징을 추출하면, 학생 모델도 이러한 정보를 학습하게 된다
클래스 간 관계 정보 (Relationships Between Classes)
교사 모델이 데이터 클래스 간의 관계나 상호작용을 이해하는 방식을 학생 모델이 학습
데이터 간의 복잡한 상관관계를 포착하여, 학생 모델이 더 깊이 있는 이해를 할 수 있게 함
(예시) 고양이와 개가 서로 비슷한 특성을 공유한다는 관계 정보를 학생 모델이 학습한다면, 새로운 데이터에서도 더 정확한 분류가 가능해짐
Response-Based Knowledge Distillation
개념: 교사 모델의 최종 출력값(Soft Probability Distribution), 즉 소프트 라벨을 학생 모델이 학습
소프트 라벨은 각 클래스에 대한 확률 분포를 나타냄
특징
각 클래스의 확률 분포를 학습하여 교사 모델의 분류 패턴을 모방
구현이 간단하고 다양한 작업에 효과적
예시: 이미지 분류에서, 교사 모델이 제공하는 출력 확률(예: 고양이: 0.7, 개: 0.2)을 학습 → 일반화 능력 향상
Feature-Based Knowledge Distillation
개념: 교사 모델의 중간 계층 출력(Feature Maps)을 학생 모델이 학습
특징
고차원 특징 표현을 학습하며 데이터의 세부적인 패턴을 이해하는 데에 유리함!
학생 모델이 교사 모델의 학습 과정과 유사한 표현을 생성하도록 함
장점: 학생 모델이 얕고 폭이 좁은 구조에서도 성능 유지가 가능
예시: 얼굴 인식에서, 교사 모델이 얼굴의 주요 포인트를 추출하면 학생 모델이 이를 학습
Relation-Based Knowledge Distillation
개념: 교사 모델이 데이터 클래스 간의 복잡한 관계 및 상관성(Relationships and Correlations)을 학생 모델에 전이한다
특징
데이터 클래스 간 복잡한 관계와 상호작용를 포착하여 모델 성능 향상
소프트 라벨이나 특징 표현에서 얻을 수 없는, 정답을 넘어선 추가 정보, 데이터의 깊은 구조를 학습할 수 있음
예시: 두 클래스 간의 거리나 유사성을 학습
고양이와 개의 관계를 학습해, 이전에 본 적 없는 새로운 동물 사진에서도 유사성을 파악
KD의 주요 장점
유연성(하드웨어 독립성) : 경량 모델은 다양한 하드웨어 가속기에서 실행 가능
효율성: 효율적인 추론 → 모델 크기와 계산향를 줄이면서도 성능 유지
확장성: 자연어 처리(NLP), 컴퓨터 비전 등 여러 도메인에서 사용 가능
KD 기반 경량 모델의 성과
저자 Response Feature Relation 성과
저자
Response
Feature
Relation
성과
Musa et al.
✓
-
-
정확도 개선
Chen et al.
✓
✓
✓
Inception 및 MobileNet에서 정확도 각각 72.25%, 64.14% 달성
Kang et al.
✓
✓
✓
다른 KD 모델보다 우수한 성능 달성
Mishra et al.
✓
-
-
엣지 디바이스에서 추론 시간 개선
Park et al.
-
✓
✓
학생 모델의 성능을 유의미하게 개선
Yang et al.
✓
-
-
IoT 및 임베디드 디바이스에 적합
KD의 도전 과제
하이퍼파라미터 설정
온도(Temperature), 손실 가중치 등 KD 과정에서 중요한 변수 최적화 필요
정확도-압축 균형
모델 크기를 줄이는 과정에서 정확도 손실 방지 필요
논문의 핵심 KD 실험 결과
교사 모델 성능 vs 학생 모델 성능 비교
학생 모델은 교사 모델에 비해 약간의 정확도 손실이 있지만, 모델 크기 및 속도에서 뛰어난 결과를 보임
MobileNet에서 KD를 적용한 결과, 64.14%의 높은 정확도를 유지
KD 적용으로 추론 시간 단축
학생 모델은 15MB 미만의 크기로 압축되었으며, 경량 하드웨어에서 실시간 처리 가능
Quantization 양자화
딥러닝 모델의 가중치(weights)와 활성값(activations)을 낮은 정밀도 데이터 형식으로 변환함으로써, 모델의 크기를 줄이고 계산 효율성을 높이는 기술
딥러닝 모델은 일반적으로 32비트 부동소수점(32-bit floating point) 형식으로 데이터를 처리하지만, 양자화를 통해 16비트 또는 8비트와 같은 낮은 정밀도의 형식으로 데이터를 표현하면, 메모리 사용량과 연산량을 획기적으로 줄일 수 있다!
양자화는 특히 엣지 디바이스, 스마트폰, IoT 장치처럼 자원이 제한된 환경에서의 딥러닝 모델 실행을 가능하게 하기 위해 설계되었다. 이런 장치들은 처리 능력, 메모리, 배터리 용량이 제한적이기 때문에, 효율성을 극대화한 모델 설계가 필요하다.
양자화는 이런 문제를 해결하며, 모델 크기 감소와 함께 추론 속도 향상을 꾀할 수 있다!
양자화의 원리
양자화는 모델이 사용하는 데이터 표현 방식을 변경하여 정밀도를 낮추는 방식으로 동작한다
데이터 정밀도 축소
딥러닝 모델의 가중치와 활성값을 높은 정밀도의 부동소수점에서 낮은 정밀도의 정수 데이터로 변환한다.
(예시) 32비트 부동소수점 데이터를 8비트 정수로 표현하면, 메모리 사용량이 약 4배 줄어든다
값 범위 조정
데이터의 값을 특정 범위로 압축한 뒤, 이 범위를 표현할 수 있는 낮은 비트의 정수로 변환한다
변환 과정에서 발생할 수 있는 손실을 최소화하기 위해 값을 정규화하거나, 비선형적인 변환을 적용하기도 한다.
계산량 감소
낮은 정밀도로 표현된 데이터는 더 적은 계산 리소스를 요구하므로, 연산 속도가 개선된다
하드웨어 가속기(CPU, GPU, TPU 등)에서는 양자화된 모델이 병렬 연산을 통해 더욱 빠르게 작동할 수 있다
양자화의 주요 방식
양자화는 모델 학습 시점과 적용 방식에 따라 양자화 인지 훈련(QAT, Quantization-Aware Training)과 훈련 후 양자화(PTQ, Post-Training Quantization)로 나눈다
양자화 인지 훈련 (Quantization-Aware Training, QAT)
QAT는 모델 학습 단계에서 양자화를 시뮬레이션하며, 모델이 저정밀 데이터의 특성에 적응하도록 학습
작동 방식
학습 중, 모델의 가중치와 활성값이 양자화된 상태를 시뮬레이션한다
손실 함수 계산 시, 양자화로 인한 정확도 손실을 고려한다
모델은 양자화 환경에서 발생할 수 있는 손실을 학습 과정에서 스스로 보정한다
장점
양자화 후에도 정확도 손실을 최소화할 수 있다
모델이 낮은 정밀도에서도 높은 성능을 유지하도록 최적화
단점
학습 시간이 더 길어지며, 추가적인 계산 리소스를 요구한다
기존 학습 모델을 사용할 수 없고, 양자화 환경에서 새로 학습해야 함
훈련 후 양자화 (Post-Training Quantization, PTQ)
PTQ는 이미 학습된 모델에 양자화를 적용하는 방식으로, 추가적인 학습 과정 없이 양자화를 수행할 수 있우ㅁ
작동 방식
학습이 완료된 32비트 부동소수점 모델을 가져온다
모델의 가중치와 활성값을 8비트 정수로 변환함
필요한 경우, 양자화로 인해 발생한 정확도 손실을 복구하기 위해 약간의 미세 조정(fine-tuning)을 진행한다
장점
구현이 간단하며, 기존 학습 모델에 쉽게 적용 가능
추가 학습 없이도 양자화를 수행할 수 있어 효율적
단점
양자화 후 정확도 손실이 QAT에 비해 클 수 있음
복잡한 모델에서는 정확도 손실이 두드러질 수 있음
양자화의 장점
메모리 사용량 감소
32비트 부동소수점 대신 8비트 정수를 사용하면 메모리 요구량이 최대 4배 줄어든다
이는 엣지 디바이스와 같은 메모리 제한 환경에서 큰 장점이 됨
추론 속도 개선
낮은 정밀도 데이터는 연산량이 줄어들기 때문에 모델의 추론 속도가 크게 빨라짐
특히, 하드웨어 가속기에서 양자화된 모델은 병렬 처리 효율이 극대화
에너지 효율성 증가
계산량 감소는 에너지 소비를 줄이며, 배터리로 작동하는 장치에서 배터리 수명을 연장
양자화의 도전 과제
정확도 손실
양자화는 데이터 표현 정밀도를 낮추기 때문에 정보 손실이 발생할 가능성이 있음
특히 복잡한 모델에서는 이 손실이 눈에 띄게 나타날 수 있다
모델 최적화 필요
양자화는 모든 모델에서 동일한 효과를 보장하지는 않기 때문에, 모델 구조와 데이터 특성에 따라 성능이 달라지므로, 모델을 양자화에 맞게 최적화해야 함
복잡성 증가 (QAT)
QAT를 사용하는 경우, 추가적인 학습 과정이 필요함 → 학습 시간이 증가하고 리소스 요구량이 늘어날 수 있음
논문에서의 양자화 실험 결과
논문에서는 양자화를 적용한 다양한 실험이 수행되었으며, 양자화된 모델이 효율성을 유지하면서도 성능을 크게 저하시키지 않음을 보여줌
QAT를 사용한 경우, 정확도 손실은 평균 0.1% 이하로 유지되었음
PTQ는 모델 크기를 5배 이상 줄이면서도 원래 모델과 거의 동일한 성능을 보여줌
QAT와 PTQ를 결합한 혼합 방법은 모델 크기를 최대 16배까지 줄이면서도 성능 손실을 최소화
Research Trends
데이터베이스 기반 연구 현황
Science Direct
가장 많은 논문(200편 이상)이 출판된 데이터베이스로, 경량 모델 관련 연구의 주요 플랫폼
연구 주제는 모델 구조 설계, 최적화 기술, 엣지 디바이스 적용 방법론 등 다양함
최근 몇 년간 논문 수가 급격히 증가하면서 연구의 주요 축을 형성.
Springer Link
Science Direct와 함께 많은 양의 연구 논문을 제공하며, 100~200편의 논문이 수록
모델 압축 기술(예: 프루닝, 양자화)과 실용적 응용 사례에 대한 논문이 다수 포함
IEEE Xplore
하드웨어 중심의 경량 모델 연구와 관련된 논문이 다수 포함되어 있음
엣지 디바이스의 계산 효율성 증대를 위한 하드웨어-소프트웨어 공동 설계와 관련된 논문들이 많음
ACM Digital Library
다른 데이터베이스에 비해 상대적으로 적은 수의 논문(100편 미만)을 제공하지만, 연구 주제의 다양성에서 중요한 기여를 함
모델 경량화의 알고리즘적 접근과 새로운 최적화 기법을 다루는 논문이 다수 존재
arXiv Preprints
가장 빠르게 성장하는 플랫폼 중 하나로, 최근 몇 년간 논문 수가 급격히 증가
최신 기술 동향과 실험적 접근이 공유되는 공간으로, 초기 아이디어와 이론적 연구가 활발히 진행
출판 추세 분석
2010년부터 2024년까지 모든 데이터베이스에서 경량 모델에 대한 연구가 꾸준히 증가
Science Direct와 Springer는 전체적으로 가장 많은 논문을 보유하며, 특히 2020년 이후 급격한 증가세를 보임
arXiv는 최근 몇 년간 가장 빠르게 성장하는 플랫폼으로, 연구자들이 최신 연구 결과를 공유하는 데 널리 사용됨
Proposed Hybrid Model Methodology
Dataset
실험 데이터셋
포트홀 탐지 데이터셋
도로의 포트홀(구멍)과 양호한 도로 상태를 분류
클래스: "포트홀" (1,245개 이미지), "양호한 도로" (2,943개 이미지)
데이터를 두 개의 디렉토리로 나누어 관리
벼 성숙도 탐지 데이터셋
벼의 성숙도를 평가
클래스: "성숙" (1,450개 이미지), "미성숙" (1,285개 이미지)
콩밭 잡초 탐지 데이터셋
농작물에서 잡초를 탐지
클래스: "콩", "옥수수", "잡초"로 구성 (3,200개 이미지)
데이터셋 특징
실제 환경에서 수집된 데이터를 기반으로 하며, 다양한 클래스와 불균형 데이터 분포를 포함
데이터셋의 불균형 문제를 해결하기 위해 데이터 증강(Data Augmentation) 기법을 활용
Data Pre-Processing (데이터 전처리)
전처리 절차
크기 조정 및 형식 변환
데이터셋은 모델 입력 형식에 맞게 크기를 조정하고, 다양한 형식의 이미지를 통합
데이터 불균형 해결
한 클래스에 데이터가 집중된 불균형 상태를 완화하기 위해 회전, 크기 조정, 반전 등의 증강 기법을 사용
데이터 증강은 소수 클래스의 데이터 양을 늘리고, 학습 데이터의 다양성을 증가시킴
데이터 정규화
각 픽셀 값을 정규화하여 학습 속도를 높이고 수렴성을 개선
Model Definition and Training (모델 정의 및 학습)
초기 모델 구성
처음에는 다수의 **합성곱 계층(Convolutional Layers)**과 수백만 개의 파라미터를 포함하는 대규모 CNN 모델을 정의했다
이 모델은 높은 성능을 달성했지만, 크기(603MB)와 연산량이 많아 엣지 디바이스에 적합하지 않았음
모델 압축 전략
초기 대규모 모델을 경량화하기 위해 세 가지 주요 기술을 결합
지식 증류(Knowledge Distillation)
초기 대규모 CNN 모델을 **교사 모델(Teacher Model)**로 설정하고, 경량화된 **학생 모델(Student Model)**에 지식을 전이
교사 모델은 데이터의 클래스 간 복잡한 관계를 표현하는 소프트 라벨과 특징 맵을 제공
학생 모델은 소프트 라벨과 특징 맵을 학습하여 경량화된 구조에서도 높은 성능을 유지
프루닝(Pruning)
모델의 비효율적인 가중치를 제거
설정된 프루닝 비율(0.5)에 따라, 중요도가 낮은 가중치를 "0"으로 설정하여 모델 크기를 절반으로 줄임
이 과정에서 모델의 크기가 줄어들며 성능 저하가 발생할 수 있기 때문에 재학습(Retraining) 단계에서 성능 저하를 보완
양자화(Quantization)
프루닝이 적용된 모델을 32비트 부동소수점에서 8비트 정수로 변환
정밀도를 낮추면서도 정확도를 유지하기 위해, 양자화 후 추가로 **2번의 미세 조정 학습(fine-tuning)**을 수행
하이브리드 모델 학습 절차
초기 모델 학습 : 대규모 CNN 모델을 학습하여 교사 모델로 사용
지식 증류 : 교사 모델의 출력값과 중간 계층 표현을 기반으로 학생 모델 학습
프루닝 적용 : 모델 가중치의 50%를 제거
양자화 및 미세 조정 : 모델을 양자화하고, 2번의 추가 학습으로 정확도를 복구
Performance Evaluation (성능 평가)
평가 지표
정확도 (Accuracy)
학습된 모델이 테스트 데이터에서 올바르게 예측한 비율
모델 크기 (Model Size)
압축 전후 모델의 메모리 사용량
파라미터 수 (Number of Parameters)
모델에서 사용된 가중치의 총 개수
훈련 시간 (Training Time)
각 모델이 학습을 완료하는 데 소요된 시간
실험 결과
제안된 하이브리드 모델은 기존 압축 기술(프루닝, 양자화, 지식 증류 단독)과 비교하여 가장 우수한 성능을 보여줌!
모델 정확도 파라미터 수 모델 크기 훈련 시간
모델
정확도
파라미터 수
모델 크기
훈련 시간
대규모 CNN
97.43%
52,768,432
603MB
17분
KD 모델
98.28%
126,569
15.3MB
3분
프루닝 모델
90.23%
52,711,489
195MB
7분
양자화 모델
92.41%
2,936,589
35MB
20분
하이브리드 모델
97.74%
142,345
3.3MB
3분
Algorithm 1: Proposed Hybrid Model
Data: Large model
Result: Lightweight model
initialized: pruning ratio ← β
obtained weights and parameters of large model γ, α;
compute threshold ϵ ← (β * sum (γ));
compute pruned weight (β, γ, ϵ);
while training do
For all γ:
if β ≤ ϵ then
γ ← 0
else if β > ϵ then
γ == γ
Update parameter α ← γ
return pruned model
while weights are pruned = true do
convert model precision from fp32 to int8
re-train pruned model with quantized parameters
return pruned and quantized model
Result and Discussion
Accuracy (정확도)
제안된 하이브리드 모델의 정확도는 기존의 모델 압축 기법(프루닝, 양자화, 지식 증류)을 개별적으로 적용한 모델과 비교하여 분석하였다.
실험 결과, 제안된 모델은 97.74%의 정확도를 기록하며 초기 대규모 CNN 모델(97.43%)과 거의 동일한 수준의 성능을 유지했다.
프루닝과 양자화를 단독으로 적용했을 때의 정확도 감소를 지식 증류를 통해 효과적으로 보완했기 때문인데…
모델
정확도(%)
비교 분석
대규모 CNN
97.43
초기 모델, 정확도는 높지만 모델 크기가 매우 큼
프루닝 모델
90.23
중요도가 낮은 가중치를 제거한 결과, 정확도가 감소
양자화 모델
92.41
정밀도 축소로 인한 정보 손실로 정확도가 약간 감소
지식 증류 모델
98.28
교사 모델의 지식을 효과적으로 전이하여 정확도가 가장 높음
하이브리드 모델
97.74
프루닝, 양자화, 지식 증류의 결합으로 정확도를 유지하며 효율성 개선
프루닝 : 프루닝 모델은 정확도가 90.23%로 감소했다. 중요도가 낮은 가중치를 제거하면서도 학습 데이터를 제대로 복구하지 못한 탓임.
양자화 : 양자화 모델은 정확도가 92.41%로, 정밀도 축소로 인한 데이터 손실이 원인으로 보임
지식 증류 : 교사 모델의 지식을 학생 모델로 전이한 지식 증류 모델은 정확도가 98.28%로 가장 높았다
하이브리드 모델 : 프루닝과 양자화로 인한 정확도 손실을 지식 증류를 통해 보완하며, 초기 대규모 모델과 거의 동일한 수준의 정확도를 유지했다
Model Size Reduction (모델 크기 감소)
하이브리드 모델은 모델 크기를 획기적으로 줄이며, 초기 CNN 모델의 603MB에서 3.3MB로 압축하는 데 성공했다.
이로써 약 182배의 크기 감소를 이루었으며, 이는 엣지 디바이스와 같은 제한된 환경에서 딥러닝 모델의 실용성을 크게 향상시킬 수 있음!
모델
모델 크기(MB)
비교 분석
대규모 CNN
603
초기 모델, 크기가 매우 커 엣지 디바이스에 비효율적
프루닝 모델
195
비효율적인 가중치를 제거하여 크기 감소, 하지만 최적화 수준은 낮음
양자화 모델
35
정밀도 축소로 크기를 대폭 감소, 다만 단독으로는 충분하지 않음
지식 증류 모델
15.3
교사 모델 대비 작은 크기지만 하드웨어 제약 환경에서는 여전히 비효율적
하이브리드 모델
3.3
프루닝, 양자화, 지식 증류를 결합하여 가장 작은 크기로 압축
프루닝 : 모델 크기가 195MB로 감소했으나, 대규모 모델에 비해 여전히 크며, 양자화와 결합하지 않으면 효과가 제한적
양자화 : 양자화는 모델 크기를 35MB까지 줄였지만, 지식 증류를 결합하지 않을 경우 정확도 손실이 심각할 수 있다
지식 증류 : 지식 증류로 모델 크기가 15.3MB로 줄었으나, 엣지 디바이스 환경에서의 최적화에는 부족
하이브리드 모델 : 프루닝과 양자화를 적용한 후 지식 증류로 성능을 보완한 결과, 3.3MB로 가장 작은 크기를 달성하며 실시간 추론 가능성을 확보했음
Discussion
제안된 하이브리드 모델의 성과
모델 크기를 603MB에서 3.3MB로 줄이면서도 정확도를 **97.74%**로 유지하여, 초기 대규모 CNN 모델과 거의 동일한 성능을 달성
개별 기술(프루닝, 양자화, 지식 증류)과 비교했을 때, 하이브리드 접근법은 각 기술의 약점을 보완하며 장점을 극대화했음
개별 기술의 한계와 개선
프루닝
비효율적인 가중치를 제거하는 데 효과적이지만, 모델의 구조가 복잡한 경우 성능 손실이 발생할 수 있다
이를 보완하기 위해 재학습(retraining) 단계를 포함했으나, 여전히 단독 사용으로는 부족함…
양자화
모델 크기를 대폭 줄이는 데 유용하지만, 데이터 표현의 정밀도가 낮아져 정확도 손실이 발생했다
QAT(Quantization-Aware Training)를 사용하지 않을 경우, 양자화 후 성능 저하가 두드러질 수도 있음
지식 증류
교사 모델에서 학생 모델로 지식을 전이하여 성능 손실을 줄이는 데 효과적이지만, 데이터의 클래스 간 복잡한 관계를 완전히 포착하는 데 한계가 있음
하이브리드 접근법의 강점
하이브리드 모델은 위의 한계를 각각 보완함!
프루닝으로 모델 크기를 줄이면서도, 지식 증류를 통해 정확도를 유지
양자화를 결합하여 메모리 사용량을 극단적으로 줄이면서도, 미세 조정 학습(fine-tuning)을 통해 손실을 보완
한계와 향후 연구 방향
한계점
프루닝과 양자화를 적용한 모델은 특정 데이터셋에서 성능이 저하될 가능성이 있음
모델 압축 과정에서 복잡한 데이터 클래스 간 관계를 완벽히 포착하지 못할 수 있음
향후 연구 방향
더 복잡한 데이터셋과 다양한 응용 사례에서 하이브리드 모델을 평가
자연어 처리(NLP) 및 음성 인식과 같은 다른 도메인으로 확장
모델의 공정성과 안전성을 강화하여 실질적 사용을 위한 신뢰성 확보
마무리
이 논문은 경량화된 딥러닝 모델 연구 분야에서 중요한 기여를 했으며, 특히 자원 제약이 있는 엣지 디바이스 환경에서 딥러닝 모델을 실행할 수 있는 실질적인 가능성을 제시했다. 제안된 하이브리드 접근법은 단순히 기술을 결합한 것에 그치지 않고, 각각의 기술이 가진 한계를 상호 보완하여 성능과 효율성을 동시에 극대화했다.
그러나 연구 범위가 특정 데이터셋과 응용 사례에 한정된 점, 모델 안정성과 공정성에 대한 추가적인 검토가 필요하다는 점에서, 향후 연구의 확장이 필요할 것이다. 특히, 자연어 처리(NLP), 음성 인식, 대규모 다중 태스크 환경에서 이 방법론을 적용하고 검증하는 것은 경량화 기술이 널리 확산되는 데 중요한 과제가 될 것으로 보인다.
자원 대비 효율이 우수하고 성능이 높은 모델은, 딥러닝 기술이 많은 산업과 응용 분야로 확산될 수 있는 기반이 될 수 있을 것!
DetEval(Detection Evaluation)은 OCR(Optical Character Recognition)에서 문자 영역 검출 성능을 평가하기 위한 대표적인 메트릭으로, 이는 객체 검출(Object Detection)에서 IoU(Intersection over Union)를 기반으로 성능을 측정하는 것과 유사하지만, OCR 특화 기준을 적용한다는 점이 특징.
DetEval에서는 검출된 영역과 GT를 IoU 기준이 아니라, 영역 기반 Recall과 Precision을 활용한 매칭 방식을 사용
Recall 기반 매칭: GT 박스 내에서 검출된 박스의 영역이 일정 비율 이상 포함되면 TP(참양성) 으로 간주
Precision 기반 매칭: 검출된 박스가 GT와 겹치는 비율이 일정 기준을 넘으면 TP(참양성) 으로 인정
1번 과정
모든 정답/예측박스들에 대해서 Area Recall, Area Precision을 미리 계산해낸다. 여기서 Area Recall, Area Precision은 다음과 같음.
Area Recall = 정답과 예측박스가 겹치는 영역 / 정답 박스의 영역
Area Precision = 정답과 예측박스가 겹치는 영역 / 예측 박스의 영역
2번 과정
모든 정답 박스와 예측 박스를 순회하면서, 매칭이 되었는지 판단하여 박스 레벨로 정답 여부를 측정한다.. 박스들이 매칭이 되는 조건은 박스들을 순회하면서, 위에서 계산한 Area Recall, Area Precision이 0 이상일 경우 매칭 여부를 판단하게 되며, 박스의 정답 여부는 Area Recall 0.8 이상, Area Precision 0.4 이상을 기준으로 하고 있음