VAE 기반 신약 분자 생성 #3 AspuruGuzikAutoEncoder 모델 구성

VAE 기반 신약 분자 생성 #3 AspuruGuzikAutoEncoder 모델 구성 #

#2026-02-28


3단계: AspuruGuzikAutoEncoder 모델 구성 (vae.py 20~25행) #

from deepchem.models.optimizers import ExponentialDecay
from deepchem.models.seqtoseq import AspuruGuzikAutoEncoder

batch_size = 100
batches_per_epoch = len(train_smiles) / batch_size
learning_rate = ExponentialDecay(0.001, 0.95, batches_per_epoch)
model = AspuruGuzikAutoEncoder(
    tokens, max_length,
    model_dir='vae',
    batch_size=batch_size,
    learning_rate=learning_rate)

AspuruGuzikAutoEncoder 내부 구조 #

이 모델은 2018년 Aspuru-Guzik 연구실의 논문 “Automatic Chemical Design Using a Data-Driven Continuous Representation of Molecules” 에서 제안한 아키텍처다.

인코더 (Encoder):
SMILES 문자열 (예: 길이 120)
    ↓ 문자 임베딩 (one-hot 또는 embedding)
    ↓ GRU × 3층 (순방향)
    ↓ 마지막 은닉 상태 → Dense(196) = μ (평균)
                       → Dense(196) = log σ² (로그 분산)
    ↓ 재파라미터화: z = μ + ε·exp(log σ²/2)
z: 196차원 잠재 벡터

디코더 (Decoder):
z (196차원)
    ↓ Dense → 초기 은닉 상태
    ↓ GRU × 3층 (자기회귀적 생성)
    ↓ 매 스텝마다 Dense(|tokens|) → Softmax
다음 문자 확률 분포 → 문자 샘플링 반복

GRU (Gated Recurrent Unit) 직관:

SMILES는 순서가 있는 시퀀스다. CC(=O)O에서 (는 그 앞의 C에 가지가 생긴다는 의미다. GRU는 시퀀스를 순서대로 처리하며 이전 문맥을 기억한다.

GRU 처리 흐름:
  'C' → h₁ → 'C' → h₂ → '(' → h₃ → '=' → h₄ → ...
  ↑              ↑              ↑
이전 은닉 상태를 다음 스텝에 전달 → 긴 의존성 학습

잠재 벡터 차원 = 196:

np.random.normal(size=(1000, 196))  # 나중에 생성할 때 사용

196은 이 논문에서 선택한 값이다. 수만 개 분자의 구조 정보를 196개 실수로 압축한다.


ExponentialDecay 학습률 #

batches_per_epoch = len(train_smiles) / batch_size
learning_rate = ExponentialDecay(0.001, 0.95, batches_per_epoch)

매 에포크마다 학습률을 0.95배 감소:

epoch 0:  lr = 0.001
epoch 1:  lr = 0.001 × 0.95 = 0.00095
epoch 2:  lr = 0.001 × 0.95² ≈ 0.000903
...
epoch 50: lr = 0.001 × 0.95⁵⁰ ≈ 0.000077

batches_per_epoch를 decay_steps로 사용 → 정확히 에포크 단위로 감소.