dev_AI_framework

leaf_node 방문, 그 구조 생각

명징직조지훈 2024. 9. 11. 14:27
    def backpropagate(self, node, upstream_gradient=1.0, leaf_nodes=None):
        if leaf_nodes is None:
            leaf_nodes = []
            
        # 1. 현재 노드에서 그래디언트 계산
        grad_a, grad_b = node.calculate_gradient(upstream_gradient)

        # 2. 부모 노드로 전파된 그래디언트 합산
        node.grad_a += grad_a
        node.grad_b += grad_b

        # 3. 자식 노드로 그래디언트 전파
        children = node.get_children()
        if not children:  # 자식 노드가 없으면 리프 노드
            leaf_nodes.append(node)
        else:
            for child in children:
                self.backpropagate(child, grad_a, leaf_nodes)  # 자식 노드로 그래디언트를 전파

        return leaf_nodes

하나의 노드에서의 가장 하위 노드들의 리스트를 생성하고 넘기게 됨, 

이는 leaf_node [][] 의 구조로 첫 번째 차원은 각 데이터 별 leaf_node 리스트들, 두 번째 차원은 그 자식 노드들의 개수들이다.

이렇게 얻은 leaf_node 와 그 전 layer 의 노드간 연결 시 실제 데이터 구조와는 상관없이 일차원으로 늘린 node 들을 연결하자. 어차피 그 개수는 동일, 구조는 알 수 있음

square
subtract
square
subtract
square
subtract
square
subtract
square
subtract
square
subtract
square
subtract
square
subtract
square
subtract
square
subtract
square
subtract
square
subtract
square
subtract
square
subtract
square
subtract
square
subtract
square
subtract
square
subtract
square
subtract
square
subtract
20
1
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
레이어 하위 노드 방문을 해볼게~
reciprocal
add
exp
negate
add
multiply
multiply
multiply
multiply
완료

20 개 데이터에 대한 가중치 갱신 과정을 확인

각 노드의 operations 을 출력해보았다.

model.add(Flatten(input_shape=(4,)))
model.add(Dense(2, 'sigmoid'))

x = np.random.rand(10,4)
y = np.random.rand(10,2)

 위의 모델 구조와 데이터 구조

4 개의 multiply 가 있는게 맞지 맞지

(1,4) 의 입력, (1,2) 의 출력을 내기 위해 (4,2) 의 가중치 

하지만 각 출력 노드에 사용되는 가중치는 (4,2) 의 가중치 행렬에서 각 열의 값만 사용되므로,  

입력 행 벡터의 각 열값과 가중치 열 벡터의 각 행값과의 곱 연산 multiply 와 그 합을 통해 출력 노드의 값을 얻기에 add,

이후 시그모이드 연산의 negate, exp, add, reciprocal

-x ->

exp^(-x) ->

1 - exp^(-x) ->

1 / (1 - exp^(-x)) 

activation 연산의 경우 grad_input 값만 갱신, 

노드에서 수행하는 연산이 activation 인지, dense 층인지, loss function 의 계산 노드인지 정보가 필요한지 생각