딥러닝에서 활성화 함수(Activation Function)
란, 모델이 복잡한 비선형 관계를 학습할 수 있도록 하기 위해 사용 하는 함수이다.
그림처럼 입력으로 들어온 데이터를 활성 함수를 거쳐서 출력을 하게 되는 흐름을 가진다.
그 종류로는 시그모이드
, 하이퍼볼릭 탄젠트
, ReLU(Rectified Linear Unit)
와 그 변형들이 널리 사용되고 있다.
활성화 함수의 종류와 활용에 대해서 더 자세히 알아보자
인공신경망(ANN)
에서 입력신호의 가중치 합을 변환해서 출력 신호로 생성하는 함수이다.비선형성(Non-Linearity)
을 추가하기 위해 활용된다.ReLU(Rectified Linear Unit)
함수는 입력이 0보다 크면 입력을 그대로 출력하고, 입력이 0보다 작으면 0을 출력합니다. ReLU 함수는 기울기가 항상 양수이기 때문에 학습이 빠르다는 장점이 있습니다.
*Rectified: 바로 잡은
# 파이썬 내장함수로 구현한 ReLU
def relu(x):
return max(x, 0)
# PyTorch로 구현한 ReLU
import torch
def relu(x):
return torch.max(x, torch.zeros_like(x))
한계 극복을 위해
Leaky ReLU
,Parametric ReLU
등 변환된 ReLU 함수 활용
import torch.nn as nn
import matplotlib.pyplot as plt
# 입력 데이터 정의
input_data = torch.tensor([-3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0])
# ReLU 활성화 함수 정의
relu = nn.ReLU()
# 입력 데이터에 ReLU 적용 -> output_data로
output_data = relu(input_data)
# 입력 데이터와 ReLU 출력 플롯
plt.scatter(input_data.numpy(), input_data.numpy(), color='blue', label='Input Data')
plt.scatter(input_data.numpy(), output_data.numpy(), color='red', label='ReLU Output')
plt.axhline(0, color='black', linewidth=0.5) # y=0에 수평선 추가 (참고용)
plt.xlabel('Input Data')
plt.ylabel('ReLU Output')
plt.legend()
plt.title('ReLU Activation Function')
plt.show()
# 넘파이(Numpy)로 구현한 Sigmoid
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
# PyTorch로 구현한 Sigmoid
import torch
def sigmoid(x):
return 1 / (1 + torch.exp(-x))
# 예제: 비만 여부 예측
# 입력 특성
height = np.array([160, 172, 155, 168, 180]) # 키 (단위: cm)
weight = np.array([58, 63, 52, 70, 85]) # 몸무게 (단위: kg)
# 이진 레이블
labels = np.array([0, 0, 0, 1, 1]) # 0: 정상, 1: 비만
# 가중치와 편향
weights = np.array([-0.7, 1.7]) # 키와 몸무게에 대한 가중치
bias = 0.65 # 편향 항
# 가중합 계산
weighted_sum = np.dot(np.column_stack((height, weight)), weights) + bias
# 시그모이드 함수를 적용하여 예측 확률 계산
predicted_probs = sigmoid(weighted_sum)
가중합 계산 코드
- np.column_stack((height, weight))
-> 키와 몸무게를 열로 쌓아 2차원 배열을 만듦- np.dot 함수
->이 배열
과가중치 배열 weights
를 곱하고, 편향 bias를 더하여 가중합을 계산
import torch.nn as nn
import matplotlib.pyplot as plt
# 입력 데이터 정의
input_data = torch.tensor([-3.0, -2.0, -1.0, 0.0, 1.0, 2.0, 3.0])
# ReLU 활성화 함수 정의
relu = nn.ReLU()
# 입력 데이터에 ReLU 적용 -> output_data로
output_data = relu(input_data)
➡️ 출력값이 0.5보다 크면 비만으로, 0.5보다 작으면 비만이 아닌 것으로 분류
수식에서, 지수함수(e^x, Exponential Function)를 무시하고 보면 여러 값들의 합 중에 하나의 값이 차지하는 비율을 의미함
➡️ 전체값 중에서 x_i
가 갖는 확률값을 의미
softmax 함수는
다중분류문제
에서 각 클래스가 정답일 확률을 추정하는데 주로 사용
# 넘파이(Numpy)로 구현한 Softmax
import numpy as np
def softmax(x):
exp = np.exp(x)
sum_exp = np.sum(exp)
return exp / sum_exp
# PyTorch로 구현한 Softmax
import torch
def softmax(x):
"""
입력 텐서에 소프트맥스 함수를 계산합니다.
입력:
x: (batch_size, num_classes) 형식의 텐서
출력:
(batch_size, num_classes) 형식의 소프트맥스 확률을 담은 텐서
"""
x = x - x.max()
exp_x = torch.exp(x)
return exp_x / exp_x.sum(dim = 1, keepdim = True)
.sum()
에 dim = 1
, keepdim = True
를 할당한 이유(1) 랜덤한 값을 갖는 4x4 크기의 2차원 텐서를 생성
a = torch.randn(4, 4)
>>> a
tensor([[ 0.0569, -0.2475, 0.0737, -0.3429],
[-0.2993, 0.9138, 0.9337, -1.6864],
[ 0.1132, 0.7892, -0.1003, 0.5688],
[ 0.3637, -0.9906, -0.4752, -1.5197]])
(2) torch.sum()
함수를 통해 텐서 값들을 더할 수 있음
dim = 1
의 2차원 값들끼리 더하라는 의미 (= 리스트 안에 있는 리스트를 기준으로 더함)dim = 0
으로 설정한다면, 1차원을 기준으로 더함 (= 같은 열끼리 더하기)>>> torch.sum(a, dim = 1)
tensor([-0.4598, -0.1381, 1.3708, -2.6217])
(3) keepdim = True
는 처음에 생성했던 차원을 유지하고 싶을 때 설정
>>> torch.sum(a, 1, keepdim=True)
tensor([[-0.4598],
[-0.1381],
[1.3708],
[-2.6217]])
nn.CrossEntropy()
에 포함되어 있음로짓 텐서 (Logit Tensor)
- 로짓텐서 -> 일반적으로
다중 클래스 분류 문제
에서 사용되는 용어- 각 클래스에 속할 확률을 변환하기 전의 값
- 로짓은 소프트맥스 함수를 통과하기 전의 출력값임
import torch.nn.functional as F
# 임의의 로짓 텐서
logits = torch.tensor([[2.0, 1.0, 0.1],
[0.5, 2.0, 1.0],
[0.2, 1.0, 3.0]])
# 소프트맥스 활성화 함수 적용
probabilities1 = softmax(logits)
probabilities2 = F.softmax(logits, dim=1)
# 확률 출력
print('직접 정의한 Softmax 확률값:\n', probabilities1)
print('PyTorch Softmax 확률값:\n', probabilities2)
>>>
직접 정의한 Softmax 확률값:
tensor([[0.6590, 0.2424, 0.0986],
[0.1402, 0.6285, 0.2312],
[0.0508, 0.1131, 0.8360]])
----------------------------------------
PyTorch Softmax 확률값:
tensor([[0.6590, 0.2424, 0.0986],
[0.1402, 0.6285, 0.2312],
[0.0508, 0.1131, 0.8360]])
➡️ 직접 정의한 Softmax 확률값 & PyTorch Softmax 확률값 동일
➡️ Softmax의 출력 결과 내 각 리스트의 합은 1이 되고, 각 확률의 크기 순서(0.6590 > 0.2424 > 0.0986)는 원래 값의 크기 순서(2.0 > 1.0 > 0.1)가 그대로 유지됨을 알 수 있음
➡️ 여러 활성화 함수를 넣어보고 비교하면서 가장 좋은 결괏값을 내는 함수를 선택
[출처 | 딥다이브 Code.zip 매거진]