Pytorch 의 backward()여러 loss 함수 사용법

6637 단어 Pytorchbackwardloss
Pytorch 의 backward()함수
만약 여러 개의 loss 함수 가 있다 면 어떻게 역방향 전파 와 업 데 이 트 를 진행 합 니까?

 x = torch.tensor(2.0, requires_grad=True)                                                    
 y = x**2                                                                                     
 z = x                                                                                        
#     
 y.backward()                                                                                 
 x.grad                                                                                       
 tensor(4.)
 z.backward()                                                                                 
 x.grad                                                                                       
 tensor(5.) ##   
보충:Pytorch 에서 torch.autograd-backward 함수 의 사용 방법 에 대한 상세 한 분석,구체 적 인 사례 분석
백 워드 함수
공식 정의:
torch.autograd.backward(tensors, grad_tensors=None, retain_graph=None, create_graph=False, grad_variables=None)
Computes the sum of gradients of given tensors w.r.t. graph leaves.The graph is differentiated using the chain rule. If any of tensors are non-scalar (i.e. their data has more than one element) and require gradient, the function additionally requires specifying grad_tensors. It should be a sequence of matching length, that contains gradient of the differentiated function w.r.t. corresponding tensors (None is an acceptable value for all tensors that don't need gradient tensors). This function accumulates gradients in the leaves - you might need to zero them before calling it.
번역 과 해석:
매개 변수 tensors 가 스칼라 라면 함수 backward 계산 매개 변수 tensors 가 주어진 그림 잎 노드 에 대한 경사도(graph leaves,즉 requires 를 설정 합 니 다.grad=True 의 변수).
매개 변수 tensors 가 스칼라 가 아니라면 따로 매개 변수 grad 를 지정 해 야 합 니 다.tensors,파라미터 gradtensors 는 인자 tensors 와 길이 가 같 아야 합 니 다.이러한 상황 에서 backward 는 실제 적 으로 대가 함수(loss=torch.sum(tensors*grad)를 실현 한다.tensors); 주:torch 에서 벡터*벡터 는 실제 적 으로 점 적 이기 때문에 tensors 와 gradtensors 의 차원 은 일치 해 야 합 니 다)잎 노드 에 대한 경사도 계산 은 매개 변수 tensors 가 주어진 그림 잎 노드 에 대한 경사도 가 아 닙 니 다.매개 변수 grad 를 지정 하면tensors=torch.ones(size(tensors))는 대가 함수 가 잎 노드 에 대한 경사도,즉 매개 변수 tensors 가 주어진 그림 잎 노드 에 대한 경사도 와 같 음 을 알 수 있다.
매번 backward 전에 잎의 경사도 노드 가 0 인지 주의해 야 합 니 다.0 이 없 으 면 두 번 째 backward 는 지난번 의 경사도 가 누 적 됩 니 다.
다음은 구체 적 인 예 를 들 어 보 겠 습 니 다.

import torch
x=torch.randn((3),dtype=torch.float32,requires_grad=True)
y = torch.randn((3),dtype=torch.float32,requires_grad=True)
z = torch.randn((3),dtype=torch.float32,requires_grad=True)
t = x + y
loss = t.dot(z)  #      
backward 를 호출 하기 전에 먼저 수 동 으로 도 수 를 구 할 수 있 습 니 다.아마도:

코드 로 가이드 구현:

loss.backward(retain_graph=True)
print(z,x.grad,y.grad)  #           
print(t,z.grad)    #           
print(t.grad)    #      ,x,y,z      , t  ,t    backward                ,       None
결 과 는 예상 과 일치 합 니 다.
tensor([-2.6752, 0.2306, -0.8356], requires_grad=True) tensor([-2.6752, 0.2306, -0.8356]) tensor([-2.6752, 0.2306, -0.8356])
tensor([-1.1916, -0.0156, 0.8952], grad_fn=) tensor([-1.1916, -0.0156, 0.8952]) None
요점 두 드 리 기:
앞의 함수 해석 에서 인자 tensors 가 스칼라 가 아 닌 상황 에서 tensor.backward(gradtensors)는 대가 함수(torch.sum(tensors*gradtensors))잎 노드 에 대한 도체
위의 예 에서 loss=t.dot(z)이기 때문에 t.backward(z)를 사용 하면 loss 가 모든 잎 결점 에 대한 구 도 를 실현 하고 실제 연산 결 과 는 기대 와 부합된다.

t.backward(z,retain_graph=True)
print(z,x.grad,y.grad)
print(t,z.grad)
실행 결 과 는 다음 과 같 습 니 다.
tensor([-0.7830, 1.4468, 1.2440], requires_grad=True) tensor([-0.7830, 1.4468, 1.2440]) tensor([-0.7830, 1.4468, 1.2440])
tensor([-0.7145, -0.7598, 2.0756], grad_fn=) None
위의 결과 에서 문제 가 발생 했다.비록 loss 가 x 와 y 에 관 한 도체 가 정확 하지만 z 는 더 이상 잎 노드 가 아니다.
질문 1:
t.backward(z,retain 사용 시graph=True)일 때 print(z.grad)결 과 는 None 입 니 다.이것 은 z 가 더 이상 잎 노드 가 아니 라 는 것 을 의미 합 니 다.이것 은 왜 일 까요?
또 다른 시도,loss=t.dot(z)=z.dot(t),하지만 z.backward(t)로 t.backward(z,retain 를 교체 하면graph=True),결 과 는 다르다.

z.backward(t)
print(z,x.grad,y.grad)
print(t,z.grad)
실행 결과:
tensor([-1.0716, -1.3643, -0.0016], requires_grad=True) None None
tensor([-0.7324, 0.9763, -0.4036], grad_fn=) tensor([-0.7324, 0.9763, -0.4036])
질문 2:
위의 결 과 를 보면 z.backward(t)를 사용 하면 x 와 y 는 더 이상 잎 노드 가 아니 라 z 는 잎 노드 이 고 얻 은 loss 는 z 의 도체 에 비해 정확 하 다.
상술 한 시 뮬 레이 션 에 나타 난 두 가지 문 제 를 저 는 아직 설명 할 수 없습니다.여러분 과 교류 하고 싶 습 니 다.
질문 1:
t.backward(z,retain 사용 시graph=True)일 때 print(z.grad)결 과 는 None 입 니 다.이것 은 z 가 더 이상 잎 노드 가 아니 라 는 것 을 의미 합 니 다.이것 은 왜 일 까요?
질문 2:
위의 결 과 를 보면 z.backward(t)를 사용 하면 x 와 y 는 더 이상 잎 노드 가 아니 라 z 는 잎 노드 이 고 얻 은 loss 는 z 의 도체 에 비해 정확 하 다.
또한,매번 백 워드 전에 잎의 경사도 노드 가 0 인지,0 이 없 으 면 두 번 째 백 워드 는 지난번 의 경사도 가 누적 되 는 지 주의해 야 한다 고 강조 했다.
간단 한 코드 는 다음 과 같다.

#  1,:         backward,        backward
t.backward(z,retain_graph=True)
print(z,x.grad,y.grad)
print(t,z.grad)
z.backward(t)
print(z,x.grad,y.grad)
print(t,z.grad)
#   x.grad,y.grad    None,        backward               
tensor([-0.5590, -1.4094, -1.5367], requires_grad=True) tensor([-0.5590, -1.4094, -1.5367]) tensor([-0.5590, -1.4094, -1.5367])tensor([-1.7914,  0.8761, -0.3462], grad_fn=<AddBackward0>) Nonetensor([-0.5590, -1.4094, -1.5367], requires_grad=True) tensor([-0.5590, -1.4094, -1.5367]) tensor([-0.5590, -1.4094, -1.5367])tensor([-1.7914,  0.8761, -0.3462], grad_fn=<AddBackward0>) tensor([-1.7914,  0.8761, -0.3462])

#  2,:      backward,    ,       backward    x y   
t.backward(z,retain_graph=True)
print(z,x.grad,y.grad)
print(t,z.grad)
x.grad.data.zero_()
y.grad.data.zero_()
z.backward(t)
print(z,x.grad,y.grad)
print(t,z.grad)
tensor([ 0.8671, 0.6503, -1.6643], requires_grad=True) tensor([ 0.8671, 0.6503, -1.6643]) tensor([ 0.8671, 0.6503, -1.6643])tensor([1.6231e+00, 1.3842e+00, 4.6492e-06], grad_fn=<AddBackward0>) Nonetensor([ 0.8671,  0.6503, -1.6643], requires_grad=True) tensor([0., 0., 0.]) tensor([0., 0., 0.])tensor([1.6231e+00, 1.3842e+00, 4.6492e-06], grad_fn=<AddBackward0>) tensor([1.6231e+00, 1.3842e+00, 4.6492e-06])
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기