활성화 함수 도함수의 명시적 정의가 아닌, 활성화 함수 자체 기본 연산들의 조합으로 구성된 계산 그래프 형태로 표현을 통해 자동 미분처럼 연산 노드의 조합들로부터 도함수를 유도, 일관된 방식으로 역전파를 수행할 수 있도록 한다.
이를 위해선 Node 들의 종류들의 사전 정의되어야 한다.
필요 연산 목록
그렇다면 build_sigmoid_node() 와 같은 함수 ( 활성화 함수의 계산 그래프 조립 ) 의 경우 어디에 위치시키는 것이 자연스러울지
책임 분리 (Cohesion & Responsibility) 측면에서의 생각
Cal_graph 클래스에 포함시키는 경우
계산 그래프를 담당하므로, 계산 그래프를 조립하는 함수를 여기에 두는 것이 자연스러움, 연산을 그래프로 구성하 듯, build_activation 도 이 책임에 포함?
역할을 좀 더 명확히 분리하기 위해
cal_graph 폴더 내에 core_graph 와 activations.py 의 분리 시행
from dev.cal_graph.node import Node
def build_sigmoid_node(input_node):
neg_node = Node("neg")
neg_node.add_parent(input_node)
exp_node = Node("exp")
exp_node.add_parent(neg_node)
add_one_node = Node("add", input_value=1.0)
add_one_node.add_parent(exp_node)
reciprocal_node = Node("reciprocal")
reciprocal_node.add_parent(add_one_node)
return reciprocal_node
def build_tanh_node(input_node):
exp_pos = Node("exp")
exp_pos.add_parent(input_node)
neg_node = Node("neg")
neg_node.add_parent(input_node)
exp_neg = Node("exp")
exp_neg.add_parent(neg_node)
numerator = Node("subtract")
numerator.add_parent(exp_pos)
numerator.add_parent(exp_neg)
denominator = Node("add")
denominator.add_parent(exp_pos)
denominator.add_parent(exp_neg)
tanh_node = Node("divide")
tanh_node.add_parent(numerator)
tanh_node.weight_value = 1.0 # 나누는 weight로 사용
return tanh_node
def build_relu_node(input_node):
"""
ReLU(x) = max(0, x)
간단한 방식으로 근사: ReLU(x) = x * sigmoid(large * x)
"""
scale = 10.0 # large 값 (ReLU 근사)
scale_node = Node("multiply", input_node.input_value, scale)
scale_node.add_parent(input_node)
sigmoid_node = build_sigmoid_node(scale_node)
relu_node = Node("multiply")
relu_node.add_parent(input_node)
relu_node.add_parent(sigmoid_node)
return relu_node
'dev_AI_framework' 카테고리의 다른 글
지금까지 구현 내용 정리 및 앞으로의 계획 (0) | 2025.03.31 |
---|---|
pyd 파일이 서로 다른 두 환경에서 import 되지 않는 문제 (0) | 2025.03.27 |
activation function 의 구현, backend 에선 활성화 함수 연산을 수행한다. (0) | 2025.03.27 |
operating_matrix_cuda_test (0) | 2025.03.27 |
cu 연산과 계산 그래프 연결 (0) | 2025.03.23 |