HOWTO · Python

Python에서 ReLU 함수의 도함수

ReLU 함수는 딥러닝 측면에서 머신러닝에서 가장 많이 사용된다. 이 기사에서는 ReLU 함수 구현과 함께 Python에서 ReLU 파생을 구현하는 방법에 대해 설명합니다.

이 페이지의 내용

ReLU는 f(x) = max(0, x)로 정의됩니다. Python에서는 스칼라 입력에 max를, 배열 입력에 numpy.maximum을 사용해 구현할 수 있습니다. 수학적으로 도함수는 x < 0일 때 0이고 x > 0일 때 1입니다. x = 0에서는 도함수가 정의되지 않습니다. 코드에서는 이 지점의 부분기울기로 흔히 0을 선택하며, 아래 예제도 이 관례를 따릅니다.

Python에서 ReLU 함수 구현

스칼라 입력에는 내장 함수 max를 사용하면 정의를 그대로 표현할 수 있습니다. 다음 예제를 실행해 보세요.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

def relu(x):
    return max(0, x)


print(relu(3))
print(relu(0.5))
3
0.5

입력이 양수이면 함수는 그 값을 반환하고, 그렇지 않으면 0을 반환합니다. 이 스칼라 구현은 한 번에 숫자 하나를 입력받으며 NumPy 배열에는 바로 적용할 수 없습니다.

스칼라 ReLU 도함수 구현

0이 아닌 입력에서 도함수는 구간별 선형 함수의 기울기를 따릅니다. 0보다 작으면 0이고, 0보다 크면 1입니다. 왼쪽과 오른쪽의 기울기가 다르므로 수학적 도함수는 0에서 존재하지 않습니다. 그래도 기울기를 계산하는 프로그램에는 그 지점의 값이 필요하므로, 이 함수는 일반적으로 사용하는 부분기울기 값 0을 명시적으로 선택합니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

def relu_derivative(x):
    return 1 if x > 0 else 0


for value in (-2, 0, 3):
    print(value, relu_derivative(value))
-2 0
0 0
3 1

이 규칙은 입력이 엄격히 양수일 때만 1을 반환하고, 0이거나 음수이면 0을 반환합니다. 이는 미분할 수 없는 지점에서 사용하는 구현 관례이며, 그곳의 수학적 도함수가 0이라는 뜻은 아닙니다.

NumPy 배열에 ReLU와 도함수 적용

NumPy는 이러한 연산을 각 원소에 적용합니다. np.maximum은 ReLU를 계산하고, np.where는 배열의 각 원소에 대응하는 도함수 값을 선택합니다. 도함수 식에도 스칼라 함수와 같은 0 부분기울기 관례를 적용합니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

import numpy as np

values = np.array([-2.0, 0.0, 3.0])
outputs = np.maximum(values, 0)
gradients = np.where(values > 0, 1, 0)

print(outputs)
print(gradients)
[0. 0. 3.]
[0 0 1]

배열 입력의 경우 출력된 두 배열은 values의 각 원소와 순서대로 대응합니다. 선택한 관례에 따라 입력이 0인 위치의 도함수 값은 0입니다. 입력이 배열이면 np.maximum과 np.where를 사용하고, 호출할 때마다 숫자 하나를 처리한다면 위의 스칼라 함수를 사용하세요.

스칼라 입력에 람다식 사용

짧은 스칼라 함수를 인라인으로 사용할 때 람다식은 간결한 선택지입니다. 다음 식은 이름이 있는 함수와 같은 정의 및 0 처리 관례를 사용합니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

relu = lambda x: max(0, x)
relu_derivative = lambda x: 1 if x > 0 else 0

print(relu(3), relu_derivative(3))
3 1

이 람다식은 스칼라 입력을 받으며, 배열에 원소별 연산을 적용하는 NumPy 연산을 대신할 수는 없습니다. 로직을 재사용하거나 설명을 덧붙여야 한다면 이름이 있는 def 함수가 대체로 더 읽기 쉽고 확장하기도 편합니다.

ReLU와 도함수를 그래프로 확인

그래프를 보면 평평한 구간과 기울기가 바뀌는 지점을 확인할 수 있습니다. 제공된 그래프의 도함수 곡선은 구현 관례에 맞춰 0에서 0을 사용하지만, 수학적 도함수는 여전히 그 지점에서 정의되지 않습니다. 다음은 그래프 라이브러리 없이 대표값을 확인하는 독립적인 검사입니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

points = (-2, 0, 2)
for x in points:
    relu = max(0, x)
    derivative = 1 if x > 0 else 0
    print(x, relu, derivative)
-2 0 0
0 0 0
2 2 1

ReLU와 도함수 그래프: ReLU는 음수 x에서 평평하고 양수 x에서 증가합니다. 도함수는 음수 쪽에서 0이고 양수 쪽에서 1입니다. x = 0에서는 수학적 도함수가 정의되지 않으며, 이 문서의 구현 관례는 부분기울기 0을 선택합니다. 점선 수직 선분은 도약을 나타내며 중간 도함수 값을 표시하지 않습니다.

ReLU 곡선은 입력이 음수일 때 0에 머물고, 입력이 양수일 때 기울기 1로 증가합니다. 수학적 도함수는 x = 0에서 정의되지 않으며, 위 구현은 이 지점의 부분기울기로 0을 선택합니다. 점선 연결선은 0에서 1로 바뀌는 도약을 표시하며 중간 도함수 값을 나타내지 않습니다. 신경망에서 기울기가 계속 0이면 음수 입력을 받는 일부 유닛의 가중치가 갱신되지 않을 수 있습니다. Leaky ReLU는 음수 쪽에 작은 양의 기울기를 사용하는 대안 중 하나입니다.