Pytorch 역방향 전파 의 디 테 일-경사도 계산 시 기본 누적 작업

Pytorch 역방향 전파 계산 경사도 기본 누적
오늘 은 pytorch 가 간단 한 선형 회 귀 를 실현 하 는 것 을 배 웠 습 니 다.pytorch 의 역방향 전파 시 계산 경도 가 사용 하 는 누적 체 제 를 발 견 했 습 니 다.그래서 바 이 두 가 왔 습 니 다.많은 블 로그 들 이 누적 체 제 를 말 했 지만 많은 사람들 이 이 누적 체제 가 도대체 어떤 영향 을 미 칠 지 설명 하지 않 았 습 니 다.그래서 저 는 제 가 연습 한 예 를 들 어 직관 적 으로 보고 어떻게 해결 하 는 지 보 겠 습 니 다.
pytorch 선형 회귀 실현
먼저 시험 코드 를 첨부 하여 느껴 보 세 요.

torch.manual_seed(6)
lr = 0.01   #    
result = []

#       
x = torch.rand(20, 1) * 10
y = 2 * x + (5 + torch.randn(20, 1)) 

#         
w = torch.randn((1), requires_grad=True)
b = torch.zeros((1), requires_grad=True)
#        ,   pytorch            ,      
for iteration in range(2):

    #     
    wx = torch.mul(w, x)
    y_pred = torch.add(wx, b)

    #    MSE loss
    loss = (0.5 * (y - y_pred) ** 2).mean()
    
    #     
    loss.backward()
    
    #               
    print("w.grad:", w.grad)
    print("b.grad:", b.grad)
    
    #     
    b.data.sub_(lr * b.grad)
    w.data.sub_(lr * w.grad)
위의 코드 는 비교적 간단 합 니 다.두 번 교체 되 었 습 니 다.계 산 된 경사도 결 과 를 보 세 요.
w.grad: tensor([-74.6261])
b.grad: tensor([-12.5532])
w.grad: tensor([-122.9075])
b.grad: tensor([-20.9364])
그리고 저 는 두 줄 의 코드 를 조금 더 넣 었 습 니 다.바로 역방향 전파 위 에 제 가 수 동 으로 경사도 제거 작업 코드 를 추가 하고 결 과 를 느 꼈 습 니 다.

torch.manual_seed(6)
lr = 0.01
result = []
#       
x = torch.rand(20, 1) * 10
#print(x)
y = 2 * x + (5 + torch.randn(20, 1)) 
#print(y)
#         
w = torch.randn((1), requires_grad=True)
#print(w)
b = torch.zeros((1), requires_grad=True)
#print(b)
for iteration in range(2):
    #     
    wx = torch.mul(w, x)
    y_pred = torch.add(wx, b)

    #    MSE loss
    loss = (0.5 * (y - y_pred) ** 2).mean()
    
    #   pytorch     ,      ,                    ,     0
     if iteration > 0: 
        w.grad.data.zero_()
        b.grad.data.zero_()
    
    #     
    loss.backward()
    
    #      
    print("w.grad:", w.grad)
    print("b.grad:", b.grad)
    
    #     
    b.data.sub_(lr * b.grad)
    w.data.sub_(lr * w.grad)
w.grad: tensor([-74.6261])
b.grad: tensor([-12.5532])
w.grad: tensor([-48.2813])
b.grad: tensor([-8.3831])
위 에서 알 수 있 듯 이 pytorch 는 역방향 으로 전 파 될 때 지난번 에 구 한 경사도 가 기본 적 으로 누적 되 었 습 니 다.지난번 의 경사도 가 자신의 이번 경사도 계산 에 영향 을 주지 않 으 려 면 수 동 으로 0 을 제거 해 야 합 니 다.
하지만 수 동 청 소 를 하지 않 으 면 어떻게 될 까?내 가 이번 선형 회귀 시험 에서 만난 결 과 는 바로 loss 수치 가 반복 되 는 진동 이 수렴 되 지 않 는 것 이다.다음 느낌:

torch.manual_seed(6)
lr = 0.01
result = []
#       
x = torch.rand(20, 1) * 10
#print(x)
y = 2 * x + (5 + torch.randn(20, 1)) 
#print(y)
#         
w = torch.randn((1), requires_grad=True)
#print(w)
b = torch.zeros((1), requires_grad=True)
#print(b)

for iteration in range(1000):
    #     
    wx = torch.mul(w, x)
    y_pred = torch.add(wx, b)

    #    MSE loss
    loss = (0.5 * (y - y_pred) ** 2).mean()
#     print("iteration {}: loss {}".format(iteration, loss))
    result.append(loss)
    
    #   pytorch     ,      ,                    ,     0
    #if iteration > 0: 
    #    w.grad.data.zero_()
    #    b.grad.data.zero_()
  
    #     
    loss.backward()
 
    #     
    b.data.sub_(lr * b.grad)
    w.data.sub_(lr * w.grad)
    
    if loss.data.numpy() < 1:
        break
   plt.plot(result)
위의 코드 에서 저 는 수 동 으로 0 을 제거 하고 1000 번 을 교체 하지 않 았 습 니 다.매번 의 loss 를 result 에 넣 은 다음 에 그림 을 그 려 서 결 과 를 느 꼈 습 니 다.
没有进行手动清零
그 다음 에 저 는 수 동 으로 0 을 지 우 는 주석 을 열 고 매번 교체 한 후에 수 동 으로 0 을 지 우 는 작업 을 해서 얻 은 결 과 를 얻 었 습 니 다.
手动清零之后的操作
이것 이 야 말로 이상 적 인 역방향 전파 가이드 이 고 파 라 메 터 를 업데이트 한 후에 얻 은 loss 값 의 변 화 를 볼 수 있다.
총결산
이번 에는 주로 pytorch 가 역방향 전파 계산 경사도 를 진행 할 때의 누적 체 제 는 도대체 어떤 모습 인지 기록 하 는 것 입 니 다.왜 이런 메커니즘 을 채 택 했 는 지 나 도 찾 아 보 았 는데 대부분 제 시 된 결 과 는 이렇다.

그러나 누적 되 지 않 으 려 면 수 동 으로 0 을 제거 하 는 방식 으로 매번 교체 할 때마다 추가 하면 된다.

w.grad.data.zero_()
b.grad.data.zero_()
또한 자 료 를 검색 할 때 한 블 로그 에서 좋 은 선형 회귀 두 개 를 보 았 을 때 pytorch 의 계산 도 는 여기 서 빌려 씁 니 다.
前向传播
反向传播
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기