카테고리 없음

[Python] 딥러닝

orin602 2025. 3. 13. 18:05

딥러닝 - 인공신경망(ANN, Artificial Neural Nework)

- 딥러닝은 인공신경망을 기반으로 한 머신러닝 기술.

인공신경망은 인간의 뇌 신경망을 모방하여 만든 모델로, 복잡한 데이터 패턴을 학습하고 예측할 수 있다.

  • 인공신경망(ANN) : 입력층(Input Layer), 은닉층(Hidden Layer), 출력층(Output layer)으로 구성된다.
    각 층의 뉴런이 가중치와 활성화 함수를 이용해 연결됨.
  • 기본 구조 : [입력층] > [은닉층1] > [은닉층2] > ... > [출력층]
    • 입력층 : 입력 데이터가 들어오는 층
    • 은닉층 : 여러 개의 뉴런이 가중치를 통해 연결됨
    • 출력층 : 최종 예측 결과가 출력되는 층
  • 뉴런(Neuron) : 여러 개의 입력 값을 받아 가중치를 곱하고 이를 활성화 함수를 통해 비선형 변환해서 다음 층으로 전달.

# 텐서플로우, 케라스 설치
# 아나콘다 프롬프트(파워쉔 프롬프트)에서
# pip 업그레이드 : python -m pip install --upgrade pip
# conda 가상환경 만들기 : conda create -n tensorflow python=3.11
# conda 가상환경 활성화 : activate tensorflow
# tensorflow 설치 : pip install tensorflow
# 케라스 설치 : pip install keras
# 텐서플로우 버전 확인
import tensorflow as tf
print(tf.__version__)

 

샘플 데이터 로드

from tensorflow import keras

# 훈련 데이터, 테스트 데이터 로드
(train_input, train_target), (test_input, test_target) = \
    keras.datasets.fashion_mnist.load_data()
print('훈련 이미지 크기 :', train_input.shape)
print('훈련 레이블 크기 :', train_target.shape)

# 테스트 데이터 크기 확인
print(test_input.shape, test_target.shape)

# 샘플 출력
import matplotlib.pyplot as plt
fig, axs = plt.subplots(1, 10, figsize = (10, 10))

for i in range(10):
    axs[i].imshow(train_input[i], cmap = 'gray_r')
    axs[i].axis('off')

plt.show()

0 ~ 9 까지 각 레이블마다 6000개의 샘플이 있음

 

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

# SGDClassifier : 확률적 경사하강법 사용
train_scaled = train_input / 255.0 # 값의 범위 표준화
train_scaled = train_scaled.reshape(-1, 28 * 28)
  • train_scaled = train_input / 255.0 : 0-1로 표준화
  • train_scaled = train_scaled.reshape(-1, 28 * 28) : 이미지를 1차원 벡터로 변

trian_input의 크기 (60000, 28, 28)에서 6000개의 28x28크기의 이미지 배열을

28 x 28 = 784 길이의 1차원 벡터로 변환

 

# SGDClassifier 클래스와 cross_validate 함수를 사용해서 교차검증으로 성능 확인
from sklearn.model_selection import cross_validate
from sklearn.linear_model import SGDClassifier
sgd = SGDClassifier(loss = 'log_loss', max_iter = 20, random_state = 42)
scores = cross_validate(sgd, train_scaled, train_target, n_jobs = -1)
print('교차 검증 점수 :', np.mean(scores['test_score']))

 

인공신경망 모델 만들기

# 훈련 데이터와 테스트 데이터로 나누기
from sklearn.model_selection import train_test_split
train_scaled, val_scaled, train_target, test_target = train_test_split(
    train_scaled, train_target, test_size = 0.2, random_state = 42)
print('1차원 벡터로 변환된 훈련 이미지 데이터 :', train_scaled.shape)
print('훈련 이미지 레이블 :', train_target.shape)

 

# 패션 아이템 10개를 분류하기 위한 10개의 뉴런
# 10 - 뉴련 갯수, activation - 뉴런의 출력층에 적용할 함수, input_shape - 입력 크기
dense = keras.layers.Dense(10, activation = 'softmax', input_shape = (784,))
# Sequential - 케라스에서 신경망 모델을 생성하는 클래스
model = keras.Sequential([dense])
model.compile(loss = 'sparse_categorical_crossentropy', metrics = ['accuracy'])
# 케라스 모델 훈련 전 설정 단계 : compile() 메서드
# 이진분류 : loss = 'binary_crossentropy'
# 다중분류 : loss = 'categorial_crossentropy'
  • keras.layers.Dense : 출력층 정의
    • 10 : 출력층의 뉴런 수
    • activation = 'sorftmas : sorftmax 활성화 함수(다중 클래스 분류에서 사용)
      각 클래스에 대한 확률을 출력
    • input_shpae(784,) : 입력 데이터 크기
  • model = keras.Sequential([dense])
    • keras.Sequential : 순차 모델 정의
    • [dense] : 출력층만 있는 모델
  • model.compile(loss='sparse_categorical_crossentropy', metrics=['accuracy'])
    • loss='sparse_categorical_crossentropy' : 손실 함수를 설정
    • metrics=['accuracy']: 모델의 성능을 평가할 지표로 정확도(accuracy)를 설정

model.fit(train_scaled, train_target, epochs = 5)

5번의 에포크(epoch) 동안 학습 : accuracy(정확도) - loss(손실)

>> 정확도 85%

 

검증 세트에서 모델 성능 확인하기

val_loss, val_acc = model.evaluate(val_scaled, test_target)
print(f"검증 데이터 손실 : {val_loss}, 검증 데이터 정확도 : {val_acc}")

검증 세트 점수는 훈련 세트 보다 조금 낮은 수


딥러닝 - 심층 신경망(DNN, Deep Neural Networks)

- 여러개의 은닉층을 가진 신경망 모델

  • 특징
    • 다양한 층 : 은닉층이 여러 개인 신경망, 모델이 더 복잡한 패턴을 학습할 수 있다.
    • 활성화 함수 : 단순한 선형 모델이 아니라 복잡한 패턴을 학습할 수 있다.
    • 역전파 : 신경망의 가중치 학습을 위한 알고리즘, 예측 결과와 실제 값의 차이를 계산하고 오차를 기반으로 가중치를 조정.
  • 장점 
    • 특징 학습을 통해 데이터를 직접적으로 특성으로 변환해 자동으로 중요한 정보를 추출
    • 단순한 선형 관계를 넘어 복잡한 비선형 관계를 모델링할 수 있음
    • 데이터가 많을수록 성능이 향상됨
  • 단점
    • 모델이 매우 복잡하기 때문에 훈련 데이터에 과적합
    • 훈련에 많은 계산 자원(CPU/GPU)과 시간이 필요
    • 하이퍼파라미터 조정이 중요
# 2개의 층 생성
# 데이터셋 준비
from tensorflow import keras

# 훈련 데이터와 데스트 데이터 로드
(train_input, train_target), (test_input, test_target) = \
    keras.datasets.fashion_mnist.load_data()

print('훈련 이미지 크기 :', train_input.shape)
print('훈련 레이블 크기 :', train_target.shape)

from sklearn.model_selection import train_test_split
train_scaled = train_input / 255.0
train_scaled = train_scaled.reshape(-1, 28 * 28)
train_scaled, val_scaled, train_target, val_target = train_test_split(
    train_scaled, train_target, test_size = 0.2, random_state = 42)

 

시그모이드 활성화 함수를 사용한 은닉층과 소프트맥스 함수를 사용한 출력층을 케라스의 Dense 클래스에 등록

dense1 = keras.layers.Dense(100, activation = 'sigmoid', input_shape = (784,))
dense2 = keras.layers.Dense(10, activation = 'softmax')
  • dense1
    • 100개의 뉴런을 가진 은닉층
    • 입력 크기 : (784,) = 28 x 28 이미지를 1차원 벡터로 변환
    • 활성화 함수 : 시그모이드(sigmoid)는 출력값을 0과 1사이로 제한해서 각 뉴런의 출력을 표현
  • dense2
    • 10개의 뉴런을 가진 출력층
    • 활성화 함수 : 소프트맥스(softmax)로 각 뉴런의 출력값을 클래스 확률로 변환해서 각 클래스의 확률을 출

심층 신경망 만들기

model = keras.Sequential([dense1, dense2])
model.summary()

 

층을 추가하는 다른 방법

1. Sequential 클래스 안에 바로 작성해서 추가하기

# dense1과 dense2 객체를 따로 사용할 일이 없으므로 Sequential클래스 안에 바로 작성
model = keras.Sequential(
    [keras.layers.Dense(100, activation = 'sigmoid', input_shape = (784,), name = 'hidden'),
     keras.layers.Dense(10, activation = 'softmax', name = 'output')],
    name = '패션 MNIST 모델')
model.summary()

 

2. add() 메서드 사용해서 추가하기

model = keras.Sequential()
model.add(keras.layers.Dense(100, activation='sigmoid', input_shape=(784,)))
model.add(keras.layers.Dense(10, activation='softmax'))
model.summary()

 

모델 훈련

model.compile(loss = 'sparse_categorical_crossentropy', metrics = ['accuracy'])
model.fit(train_scaled, train_target, epochs = 5)
  • sparse_categorical_crossentropy는 다중 클래스 분류 문제에서 사용되는 손실 함수(레이블이 정수형일 때 사용)
  • metrics = ['accuracy'] : 훈련 중 모델 성능을 평가할 지표로 정확도를 사용

훈련 세트에 대한 성능을 보면 층이 추가되서 성능이 향상됨

 

 

Relu 함수

- 딥러닝에서 가장 많이 사용되는 활성화 함수 중 하나

>> 계산이 간단하고, 기울시 소실 문제를 해결하는데 효과적

비선형 함수로 출력값이 0보다 크면 그대로 출력하고, 0이하일 때는 0으로 출력

# 함수의 오른쪽 끝과 왼쪽 끝으로 갈수로 그래프가 누워있음(값의 변화가 거의 없다)
# == 시그모이드 함수의 단점 >>> 옳바른 출력을 만드는데 신속하게 대응하지 못함
# Relu함수로 개선 >> 0보다 크면 그대로 사용 0보다 작으면 0으로 만듬
model = keras.Sequential()
# Flatten() : 입력데이터를 받아 1차원 배열로 변환
model.add(keras.layers.Flatten(input_shape = (28, 28)))
model.add(keras.layers.Dense(100, activation = 'relu'))
model.add(keras.layers.Dense(10, activation = 'softmax'))
model.summary()

 

(train_iniput, train_target), (test_input, test_target) = \
    keras.datasets.fashion_mnist.load_data()
train_scaled = train_input / 255.0
train_scaled, val_scaled, train_target, val_target = train_test_split(
    train_scaled, train_target, test_size = 0.2, random_state = 42)

model.compile(loss = 'sparse_categorical_crossentropy', metrics = ['accuracy'])
model.fit(train_scaled, train_target, epochs = 5)

시그모이드 함수를 사용했을때 보다 조금 향상됨

 

옵티마이저

- 신경망 모델 훈련 시 손실 함수를 최소화하는 방법을 결정하는 알고리즘

모델의 가중치를 업데이트해서 예측 오류를 줄여가는 역할

  • 가중치 업데이트 : 모델이 훈련 중 학습하는 가중치와 편향 조정
  • 학습률 조정 : 각 파라미터의 업데이트 크기를 결정하는 학습률을 조절
  • 최소화할 손실 함수 선택 : 옵티마이저는 손실 함수의 값을 최소화하는 방향으로 학습
# 케라스에서 기본적으로 미니 배치 경사하강법을 사용.(미니배치 개수 32)
# 케라스에서 다양한 종류의 경사하강법 알고리즘을 제공 >> 옵티마이저
# optimizer : compile() 함수의 속성
# 옵티마이저로 경사하강법 알고리즘을 사용하기 위해 sgd값으로 설정
model.compile(optimizer = 'sgd', loss = 'sparse_categorical_crossentropy',
              metrics = ['accuracy'])
# 위의 코드와 동일한 코드

# SGD 옵티마이저 설정
sgd = tf.keras.optimizers.SGD()

# 모델 컴파일
model.compile(optimizer=sgd, loss='sparse_categorical_crossentropy', metrics=['accuracy'])
# SGD 클래스의 학습률의 기본값 = 0.01 >> learning_rate 속성과 지정 가능
sgd = keras.optimizers.SGD(learning_rate = 0.1)

 

- 기타 경사하강법 옵티마이저

# momentum은 0.9 이상 지정.
sgd = keras.optimizers.SGD(momentum=0.9, nesterov=True)

 

- 적응적 학습률 : Adagrad()

adagrad = keras.optimizers.Adagrad()
model.compile(optimizer=adagrad, loss='sparse_categorical_crossentropy', metrics=['accuracy'])

 

 

# Optimizer의 속성 : adam
# >> 모멘텀 최적화, 적응률 학습
model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy'])
model.fit(train_scaled, train_target, epochs=5)

 

 

적응적 학습률을 적용해서 모델 학습

model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape = (28, 28)))
model.add(keras.layers.Dense(100, activation = 'relu'))
model.add(keras.layers.Dense(10, activation = 'softmax'))
model.compile(optimizer = 'adam', loss = 'sparse_categorical_crossentropy',
              metrics = ['accuracy'])
model.fit(train_scaled, train_target, epochs = 5)