[혼공머신] 6주차_인공신경망

07-1 인공신경망

패션 MNIST

머신러닝에서는 붓꽃 데이터셋이 유명하고, 딥러닝에서는 MNIST 데이터셋이 유명합니다.

이 데이터는 손으로 쓴 0~9까지의 숫자로 이루어져 있습니다.

MNIST와 크기, 개수가 동일하지만 숫자 대신 패션 아이템으로 이루어진 데이터가 바로 패션 MNIST입니다.

 

axs[i].axis('off') : i번째 이미지에 좌표축과 테두리를 없애서 순수한 이미지만 보이게 합니다.

 

 

로지스틱 회귀로 패션 아이템 분류하기

전체 데이터를 한꺼번에 사용하여 모델을 훈련하는 것보다 샘플을 하나씩 꺼내서 모델을 훈련하는 방법이 더 효율적으로 보입니다.

이런 상황에 잘 맞는 방법이 확률적 경사 하강법입니다.

SGDClassifier는 이름만 보면 좀 어려워 보이지만, 사실입은 확률적 경사 하강법(Stochastic Gradient Descent, SGD) 을 이용해서 분류 문제를 푸는 머신러닝 모델입니다.

1. 기본 개념

  • SGD → 데이터를 한꺼번에 쓰지 않고 한 샘플씩(또는 작은 배치씩) 보면서 가중치를 조금씩 업데이트하는 학습 방법.
  • Classifier → 분류기, 즉 입력 데이터를 보고 미리 정해진 카테고리 중 하나를 예측하는 모델.

2. 어디에 쓰이는가?

  • 로지스틱 회귀(Logistic Regression)나 SVM(Support Vector Machine) 같은 선형 분류 모델을 SGD 방식으로 빠르게 학습.
  • 특히 데이터가 매우 크거나 온라인 학습(실시간으로 데이터 들어올 때 학습)에 적합.

3. 주요 특징

 

  1. 빠름 – 한 번에 전체 데이터 보지 않음 → 메모리 절약, 대규모 데이터 처리 가능.
  2. 유연함loss 파라미터를 바꾸면 다른 모델처럼 동작:
    • loss="log_loss" → 로지스틱 회귀
    • loss="hinge" → 선형 SVM
  3. 규제(Regularization) 가능 → penalty="l2" 같은 옵션으로 과적합 방지.
  4. 온라인 학습 가능partial_fit()로 새 데이터 들어올 때마다 조금씩 업데이트.

 

확률적 경사 하강법(SGD)이 기울기가 가장 가파른 방향을 따라 이동한다

  • 기울기(gradient)는 현재 위치에서 손실이 가장 빠르게 증가하는 방향을 나타내는 화살표
  • 경사 하강법은 그 반대 방향(손실이 가장 빨리 줄어드는 방향)으로 이동
  • “가장 가파른 방향”이란, 손실을 줄이기 위해 가장 효율적으로 내려가는 경로를 의미

만약 특성마다 값의 범위가 많이 다르면 올바르게 손실 함수의 경사를 내려올 수 없겠죠.
특성마다 값의 범위가 많이 다르면, 경사 하강법이 한쪽 방향으로는 크게 움직이고 다른 쪽 방향으로는 조금밖에 못 움직여서, 최적점까지 제대로 내려가기 힘듭니다.
그래서 패션 MNIST 같은 이미지 데이터도 반드시 전처리를 해줘야 합니다.

 

패션 MNIST 전처리 방법

  • 패션 MNIST는 각 픽셀 값이 0 ~ 255 범위의 정수로 저장돼 있음.
  • 모든 픽셀 값을 0 ~ 1 사이로 스케일링해야 함 → 학습 안정화 + 수렴 속도 향상.
  • 방법: 각 픽셀 값을 255.0으로 나눔.

 

인공신경망

1. 인공신경망(Artificial Neural Network, ANN)이란?

  • 뇌의 뉴런 구조를 모방해 만든 수학적 모델이자 머신러닝 알고리즘.

  • 입력 데이터를 여러 연산과 변환을 거쳐 출력값을 만드는 구조.

  • 주로 패턴 인식, 분류, 예측 등에 사용.

2. 역사적 배경 — 매컬러 & 피츠

  • 워런 매컬러(Warren McCulloch) (신경생리학자)

  • 월터 피츠(Walter Pitts) (수학자)

  • 1943년, 둘이 함께 매컬러–피츠 뉴런(McCulloch–Pitts Neuron) 모델 제안.

  • 특징:

    1. 뇌 속 뉴런을 이진(binary) 논리 연산 장치로 단순화.

    2. 여러 입력 신호를 받아 가중치 합을 계산.

    3. 합이 임계값을 넘으면 출력 1(활성화), 아니면 0(비활성화).

  • 이 모델이 인공신경망 연구의 시초.

3. 신경망 기본 구성 요소

(1) 입력층(Input Layer)

  • 입력 데이터가 처음 들어오는 층.

  • 각 입력은 하나의 유닛(Unit) 또는 뉴런(Neuron) 으로 연결됨.

  • 예: 이미지라면 각 픽셀 값이 입력 뉴런 하나씩 차지.

(2) 은닉층(Hidden Layer)

  • 입력층과 출력층 사이에 있는 층.

  • 입력 신호에 가중치(weight)를 곱하고, 합을 구한 뒤 활성화 함수를 적용.

  • 은닉층이 많아질수록 딥러닝(Deep Learning).

(3) 출력층(Output Layer)

  • 최종 예측값을 만드는 층.

  • 분류 문제 → Softmax, 시그모이드 등 사용.

  • 회귀 문제 → 활성화 함수 없이 그대로 출력.

(4) 뉴런(Neuron)과 유닛(Unit)

  • 뉴런: 입력을 받아 가중합 + 활성화 함수를 거쳐 출력 신호를 보내는 연산 단위.

  • 유닛(Unit): 뉴런과 거의 같은 의미로 쓰이며, 층(layer) 안의 개별 노드(node)를 가리킴.

4. 동작 방식

  1. 입력층에서 데이터(예: 숫자, 픽셀 값) 받기.

  2. 각 입력에 가중치 곱하고, 모두 합산 + 편향(bias) 더함.

  3. 활성화 함수(Activation Function) 적용 → 비선형성 부여.

  4. 다음 층으로 출력 신호 전달.

  5. 마지막 출력층에서 최종 예측값 생성.

5. 매컬러–피츠 뉴런의 한계

  • 단순한 임계값 함수만 써서 선형 분리 문제만 해결 가능.

  • XOR 문제 해결 불가 → 이후 퍼셉트론, 다층 퍼셉트론(MLP), 역전파(backpropagation)로 발전.

 

텐서플로와 케라스

텐서플로(TensorFlow)는 구글이 개발한 오픈소스 머신러닝 프레임워크로, 딥러닝 모델을 구축하고 학습, 배포하는 데 사용되는 핵심 플랫폼입니다. 텐서플로의 핵심 개념은 텐서(Tensor)라는 다차원 배열을 노드(연산) 간에 주고받는 데이터 흐름 그래프를 기반으로 연산을 수행하는 것입니다.

케라스(Keras)는 텐서플로와 같은 하위 엔진 위에서 동작하는 고수준 신경망 API입니다. 텐서플로의 복잡한 기능을 사용자 친화적인 방식으로 단순화하여, 딥러닝 모델을 빠르고 쉽게 구축할 수 있도록 돕습니다. 텐서플로 2.0부터는 케라스가 공식적으로 텐서플로의 표준 API로 통합되었습니다.

딥러닝 라이브러리가 다른 머신러닝 라이브러리와 다른 점 중 하나는 그래픽 처리 장치인 GPU를 사용하여 인공 신경망을 훈련한다는 것입니다. GPU는 벡터와 행렬 연산에 매우 최적화되어 있기 때문에 곱셈과 덧셈이 많이 수행되는 인공 신경망에 큰 도움이 됩니다.

케라스 라이브러리는 직접 GPU 연산을 수행하지 않습니다. 대신 GPU 연산을 수행하는 다른 라이브러리는 백엔드로 사용합니다. 예를 들면 텐서플로가 케라스의 백엔드 중 하나입니다.

 

import os: Python의 os 모듈을 가져옵니다. 이 모듈은 운영체제와 상호작용할 수 있는 다양한 함수를 제공하며, 환경 변수를 설정하는 데 사용됩니다.

os.environ["KERAS_BACKEND"] = "torch": os.environ은 현재 시스템의 환경 변수를 담고 있는 딕셔너리 객체입니다. 이 코드 라인은 KERAS_BACKEND라는 환경 변수에 "torch"라는 값을 할당합니다.

다만 벡엔드를 바꾸려면 케라스 패키지를 임포트하기 전에 “KERAS_BACKEND” 환경 변수를 설정해야 합니다. 코렙의 경우에는 런타임을 종료하고 다시 시작해 주세요.

 

인공 신경망으로 모델 만들기

로지스틱 회귀에서는 교차 검증을 사용해 모델을 평가했지만, 인공 신경망에서는 교차 검증을 잘 사용하지 않고 검증 세트를 별도로 덜어내여 사용합니다.

이렇게 하는 이유는 딥러닝 분야의 데이터셋은 충분히 크기 때문에 검증 점수가 안정적이고, 교차 검증을 수행하기에는 훈련 시간이 너무 오래 걸리기 때문입니다.

 

train_scaled: train_input에서 80%를 가져와 만든 새로운 훈련 입력 데이터

val_scaled: train_input에서 20%를 가져와 만든 새로운 검증 입력 데이터

train_target: train_target에서 80%를 가져와 만든 새로운 훈련 타겟 데이터

val_target: train_target에서 20%를 가져와 만든 새로운 검증 타겟 데이터

 

출력 결과인 (48000, 784)(48000,)은 데이터셋의 차원(dimension)을 의미합니다.

train_scaled.shape: (48000, 784)

  • 48000: 훈련에 사용될 데이터 샘플의 개수를 나타냅니다. 이전에 60,000개의 전체 데이터셋을 80% 훈련 세트와 20% 검증 세트로 나누었기 때문에, 60,000의 80%인 48,000이 남은 것입니다.
  • 784: 각 데이터 샘플의 특성(feature) 개수를 나타냅니다. 28×28 크기의 이미지 픽셀이 1차원으로 펼쳐져 784개의 픽셀 값으로 구성되어 있음을 의미합니다.

train_target.shape: (48000,)

  • 48000: 정답(label)의 개수를 나타냅니다. 이는 train_scaled의 데이터 샘플 개수와 동일하며, 각 데이터 샘플에 대한 정답(레이블)이 하나씩 존재함을 의미합니다.
  • 쉼표 뒤에 아무것도 없는 (48000,)1차원 배열을 나타냅니다. 즉, 48,000개의 정답이 순서대로 나열된 형태입니다.

 

입력층은 입력 그 자체이고 별다른 연산은 수행하지 않습니다.

하지만 신경망 알고리즘은 입력의 크기에 따라 모델의 가중치가 결정되는 경우가 많기 때문에 종종 입력층이라는 개념을 도입합니다.

케라스에서 입력층을 정의할 때는 Input() 함수를 사용합니다.

 

inputs = keras.layers.Input(shape=(784,)) 코드는 Keras 모델의 입력 레이어(Input Layer)를 정의하는 코드입니다. 이 코드는 모델에 들어갈 데이터의 모양(shape)을 지정하는 역할을 합니다.

keras.layers.Input: Keras에서 모델의 입력을 정의하는 함수입니다.

shape=(784,): 입력 데이터의 모양을 지정합니다. 여기서 784는 각 데이터 샘플의 특성(feature) 개수를 의미합니다.

  • 예를 들어, 28×28 픽셀의 이미지를 1차원 배열로 펼치면 총 784개의 픽셀 값을 가지게 됩니다.
  • 튜플의 (784,)에서 쉼표(,)는 이 입력이 1차원 벡터임을 나타냅니다.

튜플의 (784,)에서 쉼표(,)는 이 입력이 1차원 벡터임을 나타냅니다.

input(shape=784)와 같이 쓰면 오류가 발생합니다. shape 매개변수에는 꼭 튜플을 전달해야 합니다.

파이썬은 괄호 안의 값이 하나일 때, 쉼표가 없으면 이를 튜플이 아닌 일반적인 정수(integer)로 인식합니다.

 

밀집층(Dense layer)은 케라스(Keras)에서 사용하는 가장 기본적인 인공신경망 레이어입니다. 이 레이어는 이름처럼 레이어의 모든 뉴런이 이전 레이어의 모든 뉴런과 완전히 연결된 구조를 가지고 있습니다. 밀집층은 입력 데이터의 각 특성에 가중치를 곱하고 편향(bias)을 더하여 활성화 함수를 통해 다음 레이어로 전달하는 역할을 합니다.

이런 층을 양쪽 뉴런이 모두 연결하고 있기 때문에 완전 연결층(fully connected layer)이라고도 부릅니다.

 

dense = keras.layers.Dense(10, activation='softmax')

  • 밀집층(Dense Layer)을 정의합니다.
  • 10: 이 레이어에 10개의 뉴런이 있음을 의미합니다. 이는 Fashion MNIST와 같이 10개의 클래스를 분류하는 문제에 적합합니다.
  • activation='softmax': 소프트맥스(Softmax) 활성화 함수를 사용합니다. 소프트맥스는 각 뉴런의 출력을 모든 뉴런 출력의 합이 1이 되도록 정규화하여, 각 클래스에 대한 확률을 나타냅니다. 가장 높은 확률을 가진 클래스가 모델의 최종 예측이 됩니다.
  • 이진 분류라면 시그모이드 함수를 사용하기 위해 activation=’sigmoid’와 같이 설정합니다.

model = keras.Sequential([inputs, dense])

  • 순차 모델을 생성하고, 위에서 정의한 inputsdense 레이어를 순서대로 연결합니다.
  • Sequential 모델은 레이어들을 순차적으로 쌓아 올리는 가장 간단한 모델 구조입니다. 이 코드에서는 입력층 다음에 바로 밀집층이 연결됩니다.

 

활성화 함수(activation function) : 소프트맥스와 같이 뉴련의 선형 방정식 계산 결과에 적용되는 함수

 

인공신경망으로 패션 아이템 분류하기

model.compile() 메서드는 모델을 학습시키기 위한 준비 과정입니다. 이 메서드는 모델이 어떻게 학습될지를 정의하는 중요한 역할을 합니다.

model.compile(loss='sparse_categorical_crossentropy', metrics=['accuracy'])

 

이 코드는 크게 두 가지를 설정합니다: 손실 함수(loss)와 평가 지표(metrics).

loss='sparse_categorical_crossentropy'

  • 손실 함수(Loss function)를 sparse_categorical_crossentropy로 설정합니다.
  • 이 손실 함수는 다중 분류(multi-class classification) 문제에서 주로 사용됩니다.
  • 모델의 예측값과 실제 정답값 사이의 오차를 계산하는 역할을 합니다.
  • sparse라는 단어는 정답이 [0, 1, 2]와 같이 정수 형태로 되어 있을 때 사용합니다. 만약 정답이 [[0, 0, 1], [1, 0, 0]]처럼 원-핫 인코딩(one-hot encoding) 형태로 되어 있다면, categorical_crossentropy를 사용해야 합니다.

metrics=['accuracy']

  • 평가 지표(metrics)를 accuracy로 설정합니다.
  • metrics 매개변수에는 여러 개의 지표를 지정할 수 있으며, 하나의 지표를 지정할 때도 꼭 리스트로 전달해야 합니다.
  • 이 지표는 모델의 학습을 직접적으로 돕지는 않지만, 학습 과정 중에 모델의 성능을 모니터링하는 데 사용됩니다.
  • accuracy는 모델이 정답을 얼마나 정확하게 맞혔는지 비율로 나타내는 지표입니다. model.fit()을 실행하면 매 에포크마다 이 정확도 값이 출력됩니다.

에포크(Epoch) : 인공 신경망이 전체 훈련 데이터셋을 한 번 학습하는 단위

 

정확도(Accuracy)

정확도는 모델이 정답을 맞힌 비율을 의미합니다. 예를 들어, 1000개의 검증 데이터 중에서 900개를 올바르게 예측했다면 정확도는 90%가 됩니다. 정확도는 모델의 성능을 한눈에 알 수 있는 가장 직관적인 지표입니다.

성능평가(Model Evaluation)

성능평가는 모델이 얼마나 잘 작동하는지 종합적으로 판단하는 과정입니다. 정확도 외에도 정밀도(Precision), 재현율(Recall), F1-점수 등 다양한 지표를 포함합니다.

model.evaluate()는 모델이 학습된 후 최종 성능을 평가하는 데 사용됩니다. 이 함수는 지정된 손실 함수와 평가 지표(여기서는 정확도)를 사용하여 테스트 데이터셋에 대한 손실값과 정확도를 계산합니다.

왜 검증 데이터(validation data)를 사용해야 하는가?

모델을 훈련시킬 때 훈련 데이터에 대한 정확도는 계속 올라가지만, 이는 모델이 훈련 데이터에 과대적합(Overfitting)될 수 있기 때문입니다. 과대적합된 모델은 훈련 데이터에서는 높은 성능을 보이지만, 실제로는 새로운 데이터에 대한 예측 능력이 떨어집니다.

따라서 model.evaluate(val_scaled, val_target)처럼 훈련에 사용되지 않은 검증 데이터를 사용하여 모델의 성능을 평가하면, 모델의 진정한 일반화 능력을 객관적으로 측정할 수 있습니다.

 

07-2 심층 신경망

2개의 층

은닉층(hidden layer) : 입력층과 출력층 사이에 있는 모든 층

활성화 함수 : 신경망 층의 선형 방정식의 계산 값에 적용하는 함수

출력층에 적용하는 활성화 함수는 이진 분류일 경우 시그모이드 함수를 사용하고, 다중 분류일 경우 소프트 맥스 함수를 사용합니다.

반면에 은닉층의 활성화 함수는 비교적 자유롭게 사용할 수 있는데 대표적으로 시그모이드 함수과 렐루(ReLU) 함수 등을 사용합니다.

 

분류 문제는 클래스에 대한 확률을 출력하기 위해 출력층에 활성화 함수를 사용합니다.

회귀의 출력은 임의의 어떤 숫자이므로 활성화 함수를 적용할 필요가 없습니다.

즉 출력층의 선형 방정식의 계산을 그대로 출력합니다.

이렇게 하려면 Dense 층의 activation 매개변수에 아무런 값을 지정하지 않습니다.

 

은닉층의 뉴런 개수를 정하는 데는 특별한 기준이 없습니다.

몇 개의 뉴런을 두어야 할지 판단하기 위해서는 상당한 경험이 필요합니다.

여기에서 한 가지 제약 사항이 있다면 적어도 출력층의 뉴런보다는 많게 만들어야 합니다.

클래스 10개에 대한 확률을 예측해야 하는데 이전 은닉층의 뉴런이 10개보다 적다면 부족한 정보가 전달될 것입니다.

 

심층 신경망 만들기

층마다 층 이름, 클래스, 출력 크기, 모델 파라미터 개수가 출력됩니다.

층을 만들 때 name 매개변수로 이름을 지정할 수 있습니다. (기본값 : dense)

(None, 100) : 출력 크기

  • 첫 번째 값 = 배치 크기 (샘플 수라고 해도 되지만 “전체”가 아니라 “한 번에 처리하는 수”라는 걸 명시해야 함)
  • 두 번째 값 = 뉴런 수 또는 출력 특성(feature) 수

 

 


기본 숙제

Ch.07(07-1) 확인 문제(p.386) 풀고, 설명하기

1. 어떤 인공신경망의 입력 특성이 100개이고 밀집층에 있는 뉴런 개수가 10개일 때 필요한 모델 파라미터의 개수는 몇 개인가요?

1) 1,000개
2) 1,001개
3) 1,010개
4) 1,100개

가중치(weight) 개수 = 입력 특성 수 × 뉴런 수 = 100 × 10 = 1,000개
편향(bias) 개수 = 뉴런 수 = 10개
Dense(완전 연결) 층은 각 입력 × 뉴런에 대해 가중치가 존재하고, 각 뉴런마다 편향이 하나씩 더해진다.
따라서 총 파라미터 수 = 1,000 + 10 = 1,010개

정답: 3) 1,010개

 

2. 케라스의 Dense 클래스를 사용해 신경망의 출력층을 만들려고 합니다. 이 신경망이 이진 분류 모델이라면 activation 매개변수에 어떤 활성화 함수를 지정해야 하나요?

1) ‘binary’
2) ‘sigmoid’
3) ‘softmax’
4) ‘relu’

이진 분류에서는 출력값을 0~1 사이 확률로 변환해야 하므로 sigmoid 함수를 사용한다.
softmax는 다중 분류, relu는 은닉층, ‘binary’는 활성화 함수가 아님.
정답: 2) ‘sigmoid’

 

ReLU 함수란?

 

f(x)=max(0,x)

 

  • 입력이 0보다 크면 그대로 통과, 0 이하이면 0으로 만든다.
  • 계산이 단순하고, 시그모이드보다 기울기 소실 문제(vanishing gradient)가 덜해서 은닉층에 많이 사용됨.
  • 입력: [-2, -0.5, 0, 2, 5]
  • 출력: [0, 0, 0, 2, 5]

 

f(x) = \max(0, x)

3. 케라스 모델에서 손실 함수와 측정 지표 등을 지정하는 메서드는 무엇인가요?

1) configure()
2) fit()
3) set()
4) compile()

compile()에서 optimizer, loss, metrics 등을 지정한 후 fit()으로 학습을 수행한다.
정답: 4) compile()

4. 정수 레이블을 타킷으로 가지는 다중 분류 문제일 때 케라스 모델의 compile() 메서드에 지정할 손실 함수로 적절한 것은 무엇인가요?

1) ‘sparse_categorial_crossentropy’
2) ‘categorical_crossentropy’
3) ‘binary_crossentropy’
4) ‘mean_square_error’

one-hot 인코딩 안 한 경우: sparse_categorical_crossentropy 사용
categorical_crossentropy는 one-hot 인코딩된 경우
binary_crossentropy는 이진 분류, mean_square_error는 회귀 문제에서 사용
정답: 1) ‘sparse_categorial_crossentropy’

 

추가 숙제

Ch.07(07-2) 확인 문제(p.409~410) 풀고, 설명하기

댓글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다