참고Clickhereto download the full example codePyTorch: 새 autograd Function 정의하기¶\(y=\sin(x)\)을 예측할 수 있도록,\(-\pi\)부터\(\pi\)까지
유클리드 거리(Euclidean distance)를 최소화하도록 3차 다항식을 학습합니다.
다항식을\(y=a+bx+cx^2+dx^3\)라고 쓰는 대신\(y=a+b P_3(c+dx)\)로 다항식을 적겠습니다.
여기서\(P_3(x)=\frac{1}{2}\left(5x^3-3x\right)\)은 3차르장드르 다항식(Legendre polynomial)입니다.이 구현은 PyTorch 텐서 연산을 사용하여 순전파 단계를 계산하고, PyTorch autograd를 사용하여
변화도(gradient)를 계산합니다.아래 구현에서는\(P_3'(x)\)을 수행하기 위해 사용자 정의 autograd Function를 구현합니다.
수학적으로는\(P_3'(x)=\frac{3}{2}\left(5x^2-1\right)\)입니다.importtorchimportmathclassLegendrePolynomial3(torch.autograd.Function):"""torch.autograd.Function을 상속받아 사용자 정의 autograd Function을 구현하고,텐서 연산을 하는 순전파 단계와 역전파 단계를 구현해보겠습니다."""@staticmethoddefforward(ctx,input):"""순전파 단계에서는 입력을 갖는 텐서를 받아 출력을 갖는 텐서를 반환합니다.ctx는 컨텍스트 객체(context object)로 역전파 연산을 위한 정보 저장에 사용합니다.ctx.save_for_backward 메소드를 사용하여 역전파 단계에서 사용할 어떤 객체도저장(cache)해 둘 수 있습니다."""ctx.save_for_backward(input)return0.5*(5*input**3-3*input)@staticmethoddefbackward(ctx,grad_output):"""역전파 단계에서는 출력에 대한 손실(loss)의 변화도(gradient)를 갖는 텐서를 받고,입력에 대한 손실의 변화도를 계산해야 합니다."""input,=ctx.saved_tensorsreturngrad_output*1.5*(5*input**2-1)dtype=torch.floatdevice=torch.device("cpu")# device = torch.device("cuda:0") # GPU에서 실행하려면 이 주석을 제거하세요# 입력값과 출력값을 갖는 텐서들을 생성합니다.# requires_grad=False가 기본값으로 설정되어 역전파 단계 중에 이 텐서들에 대한 변화도를 계산할# 필요가 없음을 나타냅니다.x=torch.linspace(-math.pi,math.pi,2000,device=device,dtype=dtype)y=torch.sin(x)# 가중치를 갖는 임의의 텐서를 생성합니다. 3차 다항식이므로 4개의 가중치가 필요합니다:# y = a + b * P3(c + d * x)# 이 가중치들이 수렴(convergence)하기 위해서는 정답으로부터 너무 멀리 떨어지지 않은 값으로# 초기화가 되어야 합니다.# requires_grad=True로 설정하여 역전파 단계 중에 이 텐서들에 대한 변화도를 계산할 필요가# 있음을 나타냅니다.a=torch.full((),0.0,device=device,dtype=dtype,requires_grad=True)b=torch.full((),-1.0,device=device,dtype=dtype,requires_grad=True)c=torch.full((),0.0,device=device,dtype=dtype,requires_grad=True)d=torch.full((),0.3,device=device,dtype=dtype,requires_grad=True)learning_rate=5e-6fortinrange(2000):# 사용자 정의 Function을 적용하기 위해 Function.apply 메소드를 사용합니다.# 여기에 'P3'라고 이름을 붙였습니다.P3=LegendrePolynomial3.apply# 순전파 단계: 연산을 하여 예측값 y를 계산합니다;# 사용자 정의 autograd 연산을 사용하여 P3를 계산합니다.y_pred=a+b*P3(c+d*x)# 손실을 계산하고 출력합니다.loss=(y_pred-y).pow(2).sum()ift%100==99:print(t,loss.item())# autograd를 사용하여 역전파 단계를 계산합니다.loss.backward()# 경사하강법(gradient descent)을 사용하여 가중치를 갱신합니다.withtorch.no_grad():a-=learning_rate*a.gradb-=learning_rate*b.gradc-=learning_rate*c.gradd-=learning_rate*d.grad# 가중치 갱신 후에는 변화도를 직접 0으로 만듭니다.a.grad=Noneb.grad=Nonec.grad=Noned.grad=Noneprint(f'Result: y ={a.item()}+{b.item()}* P3({c.item()}+{d.item()}x)')Total running time of the script:( 0 minutes  0.000 seconds)DownloadPythonsourcecode:polynomial_custom_function.pyDownloadJupyternotebook:polynomial_custom_function.ipynbGallery generated by Sphinx-Gallery