본문 바로가기
정보/IT 지식 정보

ADALINE이란? 경사 하강법으로 학습하는 신경망 구현하기 [2편]

by 안다니. 2026. 3. 26.
반응형

 

ADALINE

 

학습률 하나 바꿨을 뿐인데 결과가 완전히 달라지는 이유를 코드로 확인합니다

시리즈: 신경망 밑바닥부터 구현하기
1편: 퍼셉트론 · 2편: ADALINE과 경사 하강법 · 3편: 확률적 경사 하강법(SGD)

퍼셉트론의 한계, ADALINE의 등장

1편에서 구현한 퍼셉트론은 잘 동작했지만, 근본적인 문제가 있었습니다. 예측이 맞았는지 틀렸는지만 보고 가중치를 업데이트하기 때문에, "얼마나 틀렸는지"를 알 수 없습니다. 그래서 선형 분리가 불가능한 데이터에서는 영원히 수렴하지 못합니다.

ADALINE(Adaptive Linear Neuron)은 이 문제를 해결합니다. 핵심 차이는, 계단 함수로 분류하기 전에 연속적인 출력값을 가지고 가중치를 업데이트한다는 것입니다.

퍼셉트론 vs ADALINE의 핵심 차이
퍼셉트론: 예측 결과(1 또는 -1)를 보고 가중치 업데이트 → "맞았다/틀렸다"만 앎
ADALINE: 가중합(연속값)과 실제값의 차이를 보고 가중치 업데이트 → "얼마나 틀렸는지" 앎

ADALINE은 퍼셉트론과 뭐가 다른가?

구조는 거의 같습니다. 입력을 받고, 가중합을 계산하고, 분류하는 흐름은 동일합니다. 차이는 어디서 가중치를 업데이트하느냐입니다.

퍼셉트론은 최종 분류 결과(1 or -1)를 기준으로 업데이트하지만, ADALINE은 가중합 결과(연속값)를 기준으로 업데이트합니다. 이 연속값과 실제값의 차이를 제곱해서 합한 것이 비용 함수(Cost Function)이고, 이 비용을 최소화하는 방향으로 가중치를 조정하는 것이 경사 하강법(Gradient Descent)입니다.

비용 함수가 뭔가요?
"모델이 얼마나 틀리고 있는지"를 하나의 숫자로 나타낸 것입니다. ADALINE은 (실제값 - 예측값)²의 합을 2로 나눈 값을 사용합니다. 이 숫자가 작을수록 모델이 잘 학습된 것입니다.

파이썬으로 ADALINE 구현하기

퍼셉트론 코드와 비교하면, fit 메서드의 가중치 업데이트 부분만 달라집니다.

핵심 변경점 — fit 메서드
def fit(self, X, y):
    self.w_ = rgen.normal(loc=0.0, scale=0.01, size=1 + X.shape[1])
    self.cost_ = []

    for _ in range(self.n_iter):
        # 전체 데이터에 대한 가중합 계산
        net_input = self.net_input(X)
        output = self.activation(net_input)
        # 전체 오차 = 실제값 - 출력값
        errors = (y - output)
        # 가중치 업데이트 (전체 데이터 기반)
        self.w_[1:] += self.eta * X.T.dot(errors)
        self.w_[0] += self.eta * errors.sum()
        # 비용 함수 계산
        cost = (errors ** 2).sum() / 2.0
        self.cost_.append(cost)
    return self

퍼셉트론과 결정적 차이가 두 가지 있습니다.

첫째, 샘플 하나씩이 아니라 전체 데이터를 한 번에 계산합니다. X.T.dot(errors)는 모든 샘플의 오차를 한꺼번에 반영하는 것입니다. 이것을 배치 경사 하강법(Batch Gradient Descent)이라고 합니다.

둘째, activation 함수가 항등 함수입니다. 즉 가중합을 그대로 통과시킵니다. 분류는 predict에서 하지만, 학습할 때는 연속값을 사용하는 것이 핵심입니다.

 

반응형

학습률이 결과를 바꾼다 — 0.01 vs 0.0001

ADALINE에서 학습률 선택이 얼마나 중요한지, 같은 데이터에 학습률만 바꿔서 비교해봅니다.

학습률 0.01 — 발산 비용 함수값: 51 → 3,212 → 5,006,791 → ... → 1.12 × 10²⁹

에포크가 진행될수록 비용이 폭발적으로 증가합니다. 학습이 완전히 실패한 것입니다.
학습률 0.0001 — 수렴 비용 함수값: 51 → 48.7 → 47.3 → ... → 40.6

에포크가 진행될수록 비용이 서서히 감소합니다. 학습이 잘 진행되고 있습니다.

같은 코드, 같은 데이터인데 학습률 하나 차이로 이렇게 극단적인 결과가 나옵니다. 0.01은 한 번에 너무 크게 가중치를 조정하다 보니 최적점을 지나쳐서 점점 멀어지는 것이고, 0.0001은 조금씩 안정적으로 다가가는 것입니다.

그런데 0.0001도 완벽하지 않습니다. 비용이 줄어들긴 하지만 매우 느립니다. 에포크를 수백 번은 더 돌려야 수렴할 것입니다. 적절한 학습률을 찾는 것은 머신러닝의 영원한 숙제입니다.

표준화가 왜 중요한가?

학습률 문제를 근본적으로 완화하는 방법이 있습니다. 바로 특성 표준화(Feature Standardization)입니다.

표준화 코드
X_std = np.copy(X)
X_std[:, 0] = (X[:, 0] - X[:, 0].mean()) / X[:, 0].std()
X_std[:, 1] = (X[:, 1] - X[:, 1].mean()) / X[:, 1].std()

각 특성에서 평균을 빼고 표준편차로 나누면, 모든 특성이 평균 0, 표준편차 1인 분포로 변환됩니다. 이게 왜 중요할까요?

원본 데이터에서 꽃받침 길이는 4~7cm, 꽃잎 길이는 1~5cm로 스케일이 다릅니다. 경사 하강법은 모든 특성의 가중치를 같은 학습률로 업데이트하기 때문에, 스케일이 다르면 어떤 가중치는 너무 크게, 어떤 가중치는 너무 작게 조정됩니다. 표준화하면 이 문제가 해결되어 학습이 훨씬 안정적으로 진행됩니다.

표준화 후 학습 결과 (학습률 0.01, 15 에포크)
비용 함수가 빠르게 수렴하고, 결정 경계도 깔끔하게 그려집니다. 발산했던 학습률 0.01로도 정상 학습이 가능해졌습니다.
실무에서의 교훈
머신러닝 모델을 학습시키기 전에 데이터를 표준화하는 것은 선택이 아니라 필수입니다. scikit-learn의 StandardScaler를 쓰면 한 줄로 처리할 수 있습니다.

정리와 다음 단계

ADALINE은 퍼셉트론의 업그레이드 버전으로, 비용 함수와 경사 하강법을 도입하여 "얼마나 틀렸는지"를 정량적으로 측정하고 개선합니다. 하지만 배치 경사 하강법은 매 에포크마다 전체 데이터를 계산해야 하기 때문에, 데이터가 커지면 속도가 매우 느려집니다.

2편 핵심 정리

ADALINE은 연속값(가중합)을 기준으로 가중치를 업데이트하여 퍼셉트론보다 안정적으로 학습합니다.

학습률이 너무 크면 발산, 너무 작으면 수렴이 느려집니다.

표준화는 경사 하강법의 안정성을 크게 높여주며, 실무에서 필수적인 전처리입니다.

다음 편에서는 대규모 데이터에서도 빠르게 학습하는 확률적 경사 하강법(SGD)을 다룹니다.

다음 글 예고
👉 3편: 확률적 경사 하강법(SGD)이란? 대규모 데이터를 위한 학습 방법
데이터를 한 건씩 학습하는 SGD와, 실시간으로 모델을 업데이트하는 온라인 학습을 구현합니다.

신경망 밑바닥부터 구현하기 시리즈 [2편]

반응형

댓글