Autoencoder
오토인코더는 레이블 없이 데이터를 압축해 간결한 코드로 만들고 다시 복원하도록 학습합니다. 구조, 변형, 이상 탐지, 코드를 다룹니다.
오토인코더는 자체 입력을 재현하도록 학습하는 신경망입니다. 인코더는 입력을 잠재 표현이라고도 하는 압축 코드로 매핑하고, 디코더는 코드를 다시 복원해 복원 결과를 생성합니다. 학습은 입력과 복원 결과의 차이를 최소화합니다. 목표값이 입력 자체이므로 오토인코더는 라벨이 없는 데이터로 학습할 수 있습니다. 이는 일반적으로 오늘날 자기 지도 학습으로 분류되는 비지도 학습의 한 형태입니다. 네트워크를 유용하게 만드는 요소는 입력을 그대로 복사하지 못하게 하는 제약입니다. 좁은 병목 계층, 추가 노이즈, 마스킹된 입력, 희소성 페널티 등을 사용하면 데이터가 압축될 수 있게 하는 구조를 학습하도록 유도할 수 있습니다. 오토인코더는 차원 축소, 이상 탐지, 노이즈 제거, 사전 학습, 최신 이미지 생성기의 압축 단계에 사용됩니다.
오토인코더 작동 방식#
인코더 f는 입력 x를 코드 z = f(x)로 매핑하고, 디코더 g는 z에서 복원 결과 x̂ = g(z)를 생성합니다. 학습에서는 x와 x̂ 간 평균 제곱 오차와 같은 복원 손실을 역전파로 최소화합니다. 불완전 자동인코더에서는 z의 차원이 x보다 훨씬 작으므로, 코드는 디코더에 필요한 정보만 보존하는 잠재 공간 요약입니다. 제곱 오차로 학습한 선형 오토인코더는 주성분 분석(PCA)과 동일한 부분 공간을 학습합니다. 이 결과는 Pierre Baldi와 Kurt Hornik이 1989년에 증명했습니다. 비선형 활성화 함수를 사용하면 심층 오토인코더가 PCA로 포착할 수 없는 곡선형 구조를 학습할 수 있습니다. Geoffrey Hinton과 Ruslan Salakhutdinov는 2006년 Science 논문에서 심층 오토인코더가 이미지와 문서에서 PCA보다 훨씬 나은 저차원 코드를 생성한다는 사실을 보였습니다.
좁은 병목 계층에 의존하지 않는 변형 모델은 대신 입력을 손상시키며, 깨끗한 원본을 기준으로 복원 결과의 점수를 계산합니다.
오토인코더 유형#
- 노이즈 제거: 입력에 노이즈를 추가하고 네트워크가 깨끗한 원본을 복원하도록 학습합니다. Pascal Vincent와 동료들은 2008년에 이 방법을 설명했습니다. 학습된 특징은 손상에 강하며, 학습된 모델은 노이즈가 있는 이미지나 신호를 정제할 수 있습니다.
- 희소: 입력보다 많은 코드 단위를 사용하지만, 한 번에 활성화되는 단위의 수에 페널티를 부과합니다. 희소 오토인코더는 대규모 언어 모델(LLMs)의 내부 활성화에 대해 학습되어, 이를 각각 해석 가능한 개념 하나에 대응하는 경향이 있는 여러 특징으로 분해합니다.
- 변분(VAE): 인코더는 코드에 대한 확률 분포를 출력하고, KL 발산 페널티는 이 분포가 표준 정규 분포에 가깝도록 유지합니다. 따라서 무작위로 샘플링한 코드를 디코딩하면 새로운 데이터가 생성됩니다. Diederik Kingma와 Max Welling은 2013년에 VAE를 소개했습니다.
- 벡터 양자화(VQ-VAE): 벡터 양자화를 통해 각 코드 벡터를 학습된 코드북에서 가장 가까운 항목으로 맞춥니다. 이를 통해 이미지나 오디오를 자기회귀 모델이 생성할 수 있는 이산 토큰으로 변환합니다.
- 마스킹: 입력의 대부분을 가리고 누락된 부분을 재구성합니다. 마스크드 오토인코더(MAE)는 이미지 패치의 75%를 가리며, 이런 방식으로 학습된 인코더는 다른 비전 작업을 위한 강력한 백본이 됩니다. Ultralytics 패키지에서 실행되는 Meta의 Segment Anything Model (SAM)은 MAE로 사전 학습된 Vision Transformer를 이미지 인코더의 기반으로 사용하고, SAM 2는 MAE로 사전 학습된 Hiera 인코더를 사용합니다. 따라서 프롬프트로 생성할 수 있는 모든 마스크의 기반이 되는 특징은 숨겨진 패치를 채우는 과정에서 처음 학습되었습니다.
재구성 오류를 이용한 이상 탐지#
정상 데이터만으로 학습된 오토인코더는 정상 입력을 잘 재구성하고 낯선 입력은 잘 재구성하지 못합니다. 따라서 재구성 오류를 제조 결함, 사기 거래 또는 고장 기계에 대한 이상 점수로 사용할 수 있으며, 이상 데이터에 라벨을 지정할 필요가 없습니다. 아래 PyTorch 코드 조각은 scikit-learn에 포함된 손글씨 숫자로 작은 오토인코더를 학습하되 7은 모두 제외하고, 홀드아웃 숫자와 7에서 발생한 오류를 비교합니다:
import torch
from sklearn.datasets import load_digits
from torch import nn
# 8x8 handwritten digits scaled to [0, 1]; every 7 is held out as the unseen anomaly
digits = load_digits()
x = torch.tensor(digits.data / 16, dtype=torch.float32)
normal, sevens = x[digits.target != 7], x[digits.target == 7]
train, test = normal[:1200], normal[1200:]
# Encoder: 64 pixels to an 8-number code; decoder: code back to 64 pixels
torch.manual_seed(0)
encoder = nn.Sequential(nn.Linear(64, 32), nn.ReLU(), nn.Linear(32, 8))
decoder = nn.Sequential(nn.Linear(8, 32), nn.ReLU(), nn.Linear(32, 64), nn.Sigmoid())
model = nn.Sequential(encoder, decoder)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
for step in range(1000):
optimizer.zero_grad()
nn.functional.mse_loss(model(train), train).backward() # reconstruction error
optimizer.step()
with torch.no_grad():
for name, data in [("Held-out digits", test), ("Unseen 7s", sevens)]:
print(f"{name}: reconstruction error {nn.functional.mse_loss(model(data), data):.4f}")홀드아웃 숫자의 재구성 오류로 0.0163을, 7의 재구성 오류로 0.0547을 출력합니다. 7의 오류는 평균적으로 3.4배 더 높으며, 각 이미지 오류에 임계값을 적용하면 이 차이를 이상 플래그로 바꿀 수 있습니다. 오토인코더가 지나치게 잘 일반화되어 일부 이상을 정확하게 재구성할 수도 있으므로, 실제 시스템에서는 알려진 이상이 포함된 검증 데이터를 사용해 병목 크기와 임계값을 조정합니다.
오토인코더와 관련 개념 비교#
- 생성적 적대 신경망(GANs): GAN 생성기는 무작위 노이즈를 데이터로 변환하고 판별자로부터 학습하며, 인코더나 재구성 대상은 없습니다. VAE도 데이터를 생성하며, 우도 기반 목적 함수 덕분에 더 안정적으로 학습되지만 이미지가 더 흐릿해지는 경향이 있습니다.
- U-Net: 인코더-디코더 구조를 공유하지만 입력을 세그멘테이션 마스크와 같은 다른 대상으로 매핑하며, 오토인코더에서 네트워크가 입력을 복사하게 할 수 있는 스킵 연결을 병목 구간을 건너뛰어 전달합니다.
- 대조 학습: 샘플을 서로 비교해 표현을 학습하므로, 특징은 이미지를 구별하는 요소를 포착하고 재구성 손실이 보존해야 하는 픽셀 수준의 세부 정보는 무시합니다.
- 임베딩: 인코더가 생성하는 코드는 임베딩의 한 종류이며, 오토인코더는 임베딩을 학습하는 여러 방법 중 하나입니다.
이미지 생성에서의 오토인코더#
잠재 확산 모델은 Stable Diffusion과 같이 오토인코더의 잠재 공간에서 확산 과정을 실행하고, 마지막에 결과를 픽셀로 디코딩합니다. Stable Diffusion 1.x는 512×512 RGB 이미지를 64×64×4 잠재 표현으로 압축하는 KL 정규화 오토인코더를 사용합니다. 이는 확산 모델이 각 노이즈 제거 단계에서 처리해야 하는 값의 수를 48분의 1로 줄입니다.










