딕셔너리 학습(Dictionary Learning)이란? AI에서 기본 패턴과 희소한 조합을 함께 배우는 방법
TL;DR
딕셔너리 학습은 데이터를 적은 기본 패턴의 조합으로 나타내도록 기본 패턴과 표본별 계수를 함께 학습하는 방법입니다. 기본 패턴의 집합을 사전, 한 패턴을 원자, 각 표본의 조합 계수를 코드라고 부릅니다. 이 글의 scikit-learn DictionaryLearning은 표본별 코드에 L1 벌점을 둡니다. 사전을 학습하는 단계와 고정한 사전으로 새 입력을 코딩하는 단계를 나누어 읽고 재구성 오차·희소성·실제 작업 품질을 따로 확인합니다.
핵심 3줄 요약
- 핵심 1
조합할 기본 패턴도 학습합니다. 주어진 사전에서 계수만 찾는 희소 코딩보다 한 단계 넓은 작업입니다. - 핵심 2
표본별 코드에 0을 늘립니다. 각 입력이 일부 원자만 사용하도록 재구성 오차와 L1 벌점을 함께 줄입니다. - 핵심 3
원자 수와 차원 축소는 다릅니다. 원본 특징보다 원자가 많아도 각 표본의 조합은 희소할 수 있습니다.
이 글에서 다룰 내용
- 딕셔너리 학습의 한 문장 정의
- 네 원자로 세 숫자를 표현하는 쉬운 예시
- 원자 사전·희소 코드·재구성의 작동 순서
- 학습 규제와 새 입력 코딩 설정의 차이
- 희소 PCA·OMP·NMF·사전 학습과의 구분
- 이미지 패치와 미니배치의 실전 사용처
- 평가 누수·코드 안정성·근사 복원의 주의점
딕셔너리 학습을 한 문장으로 정의하면 무엇인가요?
딕셔너리 학습은 여러 입력을 적은 원자의 선형 조합으로 근사하도록 원자 집합과 표본별 희소 계수를 함께 찾는 비지도 행렬 분해 방법입니다.
영문명은 Dictionary Learning입니다. 딕셔너리 러닝 또는 사전 학습이라고도 부르지만 이 글에서는 LLM의 Pre-training과 혼동하지 않도록 딕셔너리 학습으로 표기합니다. 여기의 사전은 낱말 뜻이나 학습의 선행 시점이 아니라 재사용할 기본 패턴들의 집합입니다.
입력 행렬 X에서 한 행은 한 표본, 한 열은 수치 특징입니다. 코드 행렬 U와 사전 행렬 V를 찾아
X ≈ U @ V
로 나타냅니다. U의 한 행은 해당 표본이 어떤 원자를 얼마나 쓰는지, V의 한 행은 원본 특징 공간의 기본 패턴을 뜻합니다. 이 API의 학습에는 클래스 정답이 필요하지 않습니다.
한 줄 정리: 표본의 배합 계수만 구하는 데서 끝나지 않고 여러 표본에 잘 맞는 기본 패턴도 데이터에서 배웁니다.
쉬운 예시로 이해해 볼까요?
감자나라ai님이 세 위치에서 측정한 신호를 기본 패턴으로 표현한다고 가정해 보겠습니다. 원자를
(1, 0, 0)
,
(0, 1, 0)
,
(0, 0, 1)
,
(0.6, 0.8, 0)
으로 직접 정했습니다. 네 원자는 각각 길이가 1이며 네 번째 원자는 앞의 두 원자와 겹칩니다.
입력이
(3, 0, -2)
이면 코드
(3, 0, -2, 0)
으로 표현합니다. 첫 원자를 3배, 셋째 원자를 -2배 더한 값입니다. 코드의 네 칸 중 두 칸은 0이므로 0 비율은 50%입니다. 원자 수는 원본 숫자의 수보다 많지만 한 표본에 쓰인 원자는 두 개뿐입니다.
- 사전 V의 모양은 4 × 3이고 코드 U는 1 × 4입니다. 행렬 곱의 결과는 원본과 같은 1 × 3입니다.
- 코드가 희소하다고 모든 원자의 내부 숫자까지 대부분 0이어야 하는 것은 아닙니다. 이번 원자는 계산 설명을 위해 단순하게 골랐습니다.
- 기본 설정은 음수 계수도 허용합니다. 셋째 원자를 반대 방향으로 사용해 -2를 표현합니다.
위 행렬 곱과 0 비율은 NumPy로 실제 계산했습니다. 고정 사전과 직접 정한 코드의 교육용 계산이며 DictionaryLearning을 학습해 얻은 사전이나 독립 평가 결과는 아닙니다. 딕셔너리 학습은 여러 표본을 보고 위의 원자들에 해당하는 패턴 자체를 조정하는 작업입니다.
쉬운 예시: 블록의 모양을 미리 정해 조립하는 것이 고정 사전 코딩이라면 자주 필요한 조립 형태에 맞춰 블록 모양도 배우는 것이 딕셔너리 학습입니다.
왜 AI에서 딕셔너리 학습이 중요한가요?
자료에 맞는 재사용 패턴을 만듭니다
직접 정한 기본 패턴이 모든 자료를 잘 나타내는 것은 아닙니다. 이미지 패치나 센서 신호에 반복되는 구조를 사전으로 학습하면 각 입력을 그 패턴의 조합으로 표현합니다. 어떤 원자가 실제 사용되는지 살펴볼 수 있지만 원자의 그림이 사람이 붙인 의미와 항상 일치하지는 않습니다.
표현의 간결함과 복원 품질을 비교합니다
표본마다 많은 계수를 쓰면 세부 값을 잘 맞추기 쉬워도 표현이 복잡해집니다. L1 벌점은 적은 계수 사용을 유도합니다. 0 비율만 높이는 대신 같은 자료에서 복원 오차와 후속 분류 품질을 함께 비교해야 필요한 정보까지 없애지 않았는지 알 수 있습니다.
원자 학습과 입력 코딩을 따로 바꿉니다
학습한 사전을 고정하고 새 입력의 코딩 방식만 비교하면 원자 품질과 계수 계산의 영향을 구별하기 쉽습니다. L1 규제 방식과 OMP의 개수 제한은 같은 설정이 아닙니다. 빠른 계산이 목적이라도 실제 복원이나 후속 작업의 오류를 따로 확인합니다.
핵심 인사이트: 원자 사전, 각 표본의 코드, 근사 복원값은 서로 다른 산출물입니다. 하나의 숫자로 세 단계의 품질을 대신하지 않습니다.
딕셔너리 학습은 어떤 순서로 작동하나요?
1. 자료와 전처리의 기준을 정합니다
먼저 훈련·검증·테스트를 나누고 열의 순서와 단위를 기록합니다. 이 DictionaryLearning은 PCA처럼 훈련 평균을 저장해 자동 중심화하는 변환이 아닙니다. 중심화나 스케일링이 필요한 경우 별도 전처리를 훈련에서 맞추고 운영에서도 같은 기준을 적용합니다.
2. 사전을 고정하고 희소 코드를 구합니다
현재 사전으로 각 표본을 근사하는 코드를 찾습니다. 원본과 재구성값의 제곱 오차에 코드 계수 절댓값 합의 벌점을 더한 목적을 줄입니다. 벌점의 세기는
alpha
입니다. 여기서 L1 벌점을 받는 대상은 원자 내부 계수가 아닌 표본별 U입니다.
3. 코드를 고정하고 원자를 갱신합니다
현재 코드를 잘 설명하도록 사전 V를 바꾼 뒤 코드 계산과 사전 갱신을 반복합니다. 원자 크기를 무한히 키우고 코드를 작게 만들어 벌점만 줄이는 문제를 막으려고 각 원자의 L2 노름을 1 이하로 제한합니다. 원자 사이의 직교성이나 통계적 독립을 요구하는 조건은 아닙니다.
한쪽을 고정했을 때의 계산과 두 행렬을 함께 찾는 전체 문제는 구별합니다. 반복 종료만으로 전역에서 가장 좋은 사전을 찾았다고 단정하지 않고 초기화·반복 기록·독립 자료의 품질을 함께 봅니다.
4. 새 입력은 저장한 사전으로 코딩합니다
학습 후
components_
는 원자 수 × 원본 특징 수 모양의 사전입니다.
transform
은 사전을 고정한 채 새 입력의 코드를 구합니다. 일반 설정의 코드 모양은 표본 수 × 원자 수이며 근사 복원은
code @ components_
입니다. 저장한 전처리를 썼다면 복원 뒤 그 역변환도 확인합니다.
주요 설정과 결과는 어떻게 읽나요?
원자 수와 코드의 희소성을 따로 정합니다
n_components
는 원자 개수입니다. 생략하면 원본 특징 수를 사용하며 원자가 특징 수보다 많으면 과완비 사전이라고 부릅니다. 큰 사전을 사용했다고 차원이 줄었다는 뜻은 아닙니다. 표본당 비영 계수 개수와 전체 코드 저장 크기를 함께 기록합니다.
alpha
는 학습 코드의 L1 벌점입니다. 특정 값이 모든 자료에서 같은 0 비율을 만드는 규칙은 아닙니다. 입력 단위나 스케일링을 바꾸면 오차와 벌점의 균형도 달라지므로 같은 전처리 조건에서 후보를 비교합니다.
학습 풀이와 새 입력 코딩을 구분합니다
fit_algorithm="lars"
와
fit_algorithm="cd"
는 학습 중 라쏘 문제를 푸는 방식입니다. 새 입력에는
transform_algorithm
이 적용되며 기본값은
transform_algorithm="omp"
입니다. 학습에서 L1 벌점을 썼다는 사실만으로 새 코드까지 같은 라쏘 해라고 부르지 않습니다.
OMP와 LARS에서는
transform_n_nonzero_coefs
로 사용할 계수 수를 조절합니다. 라쏘 변환에서는
transform_alpha
가 L1 벌점이며 생략하면 이 모델의 alpha를 따릅니다. 라쏘의 벌점 값을 OMP의 계수 개수와 같은 의미로 옮기지 않습니다.
학습 코드와 다시 계산한 코드를 비교합니다
확인한 1.9.1 구현의
fit_transform
은 학습 최적화에서 구한 코드를 반환합니다. 이후 같은 입력을
transform
하면 저장된 사전과 별도 변환 알고리즘으로 코드를 다시 계산합니다. 두 방식이 다르면 같은 입력의 코드도 같다고 보장하지 않습니다. 후속 모델의 훈련·평가에서 어느 코딩 경로를 썼는지 통일합니다.
error_
는 학습 반복의 오차·벌점 목적 기록이며 보류 자료의 순수 재구성 오차로 읽지 않습니다.
n_iter_
, 반복 한도와 계산 경고도 함께 남깁니다. 목적함수가 낮아졌다는 사실은 새 자료의 품질 평가와 별개입니다.
딕셔너리 학습과 헷갈리는 용어는 무엇이 다른가요?
희소 코딩·OMP와의 차이
직교 매칭 추구(OMP)는 주어진 후보에서 원자를 고르고 계수를 맞추는 방법입니다. 희소 코딩은 고정된 사전에 대한 적은 계수 표현을 구하는 작업이고 딕셔너리 학습은 사전 자체도 배웁니다. 현재 SparseCoder의 fit은 입력·설정 검증을 위한 메서드이며 원자 학습을 수행하지 않습니다.
희소 PCA·일반 PCA와의 차이
희소 주성분 분석은 각 성분에 참여하는 원본 변수 계수를 희소하게 만듭니다. 이 글의 딕셔너리 학습은 각 표본이 사용할 원자 계수를 희소하게 만듭니다. 어느 행렬에 L1 벌점을 거는지부터 다릅니다. 일반 PCA의 직교 축·설명 분산 순서를 사전 원자에 그대로 적용하지 않습니다.
NMF·사전 학습과의 차이
비음수 행렬 분해(NMF)는 입력과 요인의 비음수 제약을 다룹니다. 기본 딕셔너리 학습의 원자와 코드에는 음수가 나올 수 있습니다. Pre-training은 모델을 먼저 넓게 훈련하는 단계이고 Dictionary Learning은 원자 사전을 찾는 구체적인 방법입니다. 한글 표현이 같아도 같은 개념으로 연결하지 않습니다.
비교 정리: 희소 코딩은 고정 사전의 계수, OMP는 그 계수를 구하는 한 방법, 딕셔너리 학습은 원자까지 학습, 희소 PCA는 성분 내부 변수의 희소성을 다룹니다.
실전에서는 어디에 쓰이나요?
이미지 패치의 잡음과 복원값을 비교합니다
공식 이미지 잡음 제거 예제는 작은 패치로 사전을 배우고 다른 영역의 잡음 섞인 패치를 코딩해 복원합니다. 예제에는 MiniBatchDictionaryLearning과 여러 코딩 방식이 등장합니다. 예제의 방법별 순위나 실행 시간을 자기 사진의 성능으로 옮기지 말고 원본과의 차이·경계 보존을 직접 확인합니다.
센서 신호와 후속 분류의 표현을 살핍니다
반복되는 파형이나 측정 패턴을 원자로 나타내는 표현 후보입니다. 분류에 사용한다면 희소 코드 뒤에 별도 지도 모델을 학습합니다. 라벨 없는 재구성 목적이 업무 정답의 구분을 보장하지는 않습니다. 원본 특징을 쓰는 기준 모델과 같은 분할에서 비교합니다.
표본 묶음으로 사전을 갱신합니다
MiniBatchDictionaryLearning의
batch_size
는 한 번에 다루는 표본 수이고
partial_fit
으로 한 묶음의 입력을 이용해 사전을 갱신합니다. 현재 API에는
tol
과
max_no_improvement
를 이용한 fit의 종료 기준도 있습니다. 미니배치라고 무조건 끝까지 반복한다고 소개하지 않습니다.
딕셔너리 학습을 적용할 때 어떤 순서로 확인하나요?
1. 표현 목적과 자료 분할을 고정합니다
복원인지 잡음 제거인지 분류 입력 생성인지 먼저 적습니다. 같은 원본 이미지의 겹치는 패치나 같은 장비의 반복 기록이 훈련·평가 양쪽에 섞이면 독립 평가가 아닐 수 있습니다. 필요하면 이미지·장비·시점 단위로 나누고 사전을 훈련 범위에서만 배웁니다.
2. 같은 사전과 코딩 경로로 비교합니다
원자 수·학습 alpha와 새 입력의 코딩 설정을 따로 남깁니다. 훈련 자료도 저장한 사전의 transform으로 다시 코딩하면 평가 자료와 경로를 맞추기 쉽습니다. 교차 검증에서는 전처리·사전 학습·후속 모델까지 각 훈련 폴드에서 다시 맞춥니다.
3. 희소성·오차·운영 비용을 기록합니다
실제 비영 계수 수와 원자 사용 빈도, 보류 자료의 재구성 오차와 목적 지표를 각각 봅니다. 0이 많아도 반환 코드와 사전이 조밀한 배열이면 메모리가 자동으로 줄지 않습니다. 큰 원자 사전의 저장, 반복 학습과 코딩 시간을 포함해 비교합니다.
4. 사전과 전처리·후속 모델을 함께 저장합니다
열 순서, 중심과 척도, 원자 사전, 코딩 설정과 라이브러리 버전을 보관합니다. 사전을 갱신하면 코드의 의미가 달라질 수 있으므로 기존 코드 위의 분류기를 그대로 써도 된다고 가정하지 않습니다. 변경한 변환과 후속 모델을 묶어 재검증합니다.
실전 팁: 같은 사전에서 코딩 설정별 0 비율과 보류 자료의 오차를 나란히 확인하세요. 원자 학습의 차이와 코드 계산의 차이를 구분하기 쉽습니다.
사용할 때 무엇을 주의해야 하나요?
첫째, 원자 개별 번호를 고정 의미로 읽지 않습니다. 초기화나 자료 분할에 따라 원자의 순서·부호·모양이 달라질 수 있습니다. 비슷한 원자가 같은 신호를 대신 설명하면 코드도 바뀝니다. 원자 대응과 복원 결과를 함께 대조하고 인과 해석은 별도 근거로 판단합니다.
둘째, 부호 분리는 비음수 학습과 다릅니다.
split_sign=True
는 코드의 양수 부분과 음수 부분의 크기를 앞뒤로 나누어 출력 열을 두 배로 만듭니다. 원자를 비음수로 학습하는 설정이 아닙니다. 복원에는 두 부분을 원래 부호의 코드로 합치는 처리가 필요하며 이 구현의 inverse_transform이 그 과정을 수행합니다.
셋째, 잡음까지 잘 맞추는 사전을 좋은 사전으로 단정하지 않습니다. 많은 원자와 약한 규제로 훈련 오차만 줄이면 불필요한 변동을 담을 수 있습니다. 실제 목적에 맞는 보류 자료로 비교하고 희소성·잔차·분류 오류 중 무엇이 달라졌는지 확인합니다.
넷째, 근사 복원은 원본 보존이 아닙니다. inverse_transform은 코드를 사전과 결합한 값입니다. 희소화로 빠진 성분이나 잘못된 패턴 선택까지 되살리는 기능이 아닙니다. 앞단에서 바꾼 평균과 단위도 별도로 되돌려 원본과 대조합니다.
주의: 적은 코드, 낮은 훈련 목적값과 정확한 새 입력의 결과는 각각 검증할 항목입니다. 같은 이름의 설정도 학습과 변환에서 역할이 달라질 수 있습니다.
자주 묻는 질문
Q1. 딕셔너리 학습은 LLM의 사전 학습인가요?
다릅니다. Pre-training은 학습의 초기 단계이고 Dictionary Learning은 원자 집합을 배우는 행렬 분해 방법입니다. 여기의 사전은 재사용할 기본 패턴들을 뜻합니다.
Q2. 코드가 희소하면 원자도 희소한가요?
반드시 그렇지는 않습니다. 이 모델은 표본별 코드 U에 L1 벌점을 둡니다. 원자 V 내부의 많은 계수를 0으로 만드는 희소 PCA와 구별합니다.
Q3. 원자가 원본 특징보다 많아도 되나요?
가능하며 과완비 사전이라고 부릅니다. 출력 코드의 열 수는 늘지만 각 표본은 적은 원자만 사용할 수 있습니다. 차원 수와 비영 계수 개수는 다른 결과입니다.
Q4. SparseCoder도 fit으로 사전을 배우나요?
현재 API의 fit은 입력과 설정을 검증하는 용도입니다. 이미 전달한 사전을 사용해 코드를 구하며 새 원자를 학습하는 DictionaryLearning과 다릅니다.
Q5. fit_transform과 transform의 코드가 같은가요?
확인한 DictionaryLearning 1.9.1 구현에서는 전자가 학습 최적화 코드를 반환하고 후자는 변환 설정으로 코드를 다시 구합니다. 같은 코딩 경로인지 확인한 뒤 비교합니다.
Q6. inverse_transform이면 원본이 그대로 돌아오나요?
아닙니다. 코드와 사전의 조합에 따른 근사값입니다. 부호 분리를 사용했다면 해당 구현이 두 부분을 합치는지 확인하고 별도 전처리의 역변환도 적용합니다.
출처
마무리
딕셔너리 학습은 여러 입력을 적은 기본 패턴의 조합으로 표현하려고 패턴과 계수를 함께 배우는 방법입니다. 원자 사전과 표본별 코드를 나누어 읽으면 희소 코딩·OMP·희소 PCA와의 차이가 분명해집니다. 원자가 많다고 차원이 줄거나 원본이 완벽하게 복원되는 것은 아닙니다.
처음 적용한다면 작은 사전에서 코드와 복원값부터 직접 대조하세요. 이후 원자 수와 학습 규제, 새 입력 코딩, 자료 분리와 비용을 따로 기록합니다. 운영에서는 저장된 전처리·사전·코딩 설정을 함께 사용하고 변경 뒤에는 후속 작업까지 검증합니다.
