import torch
import torch.nn.functional as F
target = torch.FloatTensor([[.1,.2,.3],[.4,.5,.6],[.7,.8,.9]])
x = torch.rand_like(target)
x
'''
tensor([[0.4374, 0.3090, 0.8592],
[0.2560, 0.9136, 0.2861],
[0.8658, 0.8617, 0.0715]])
'''
텐서의 requires_grad 속성이 True가 되도록 설정 하면 미분 및 경사하강법 수행이 가능해진다.
x.requires_grad = True
print(x)
'''
tensor([[0.4374, 0.3090, 0.8592],
[0.2560, 0.9136, 0.2861],
[0.8658, 0.8617, 0.0715]], requires_grad=True)
'''
loss = F.mse_loss(x, target)
loss
# tensor(0.2287, grad_fn=<MseLossBackward0>)
backward() 함수를 이용해 편미분을 진행하며, 이 gradient는 x.grad에 자동으로 저장된다. backward()사용하기위해 텐서의 크기는 scalar이여야 한다.
threshold = 1e-5
learning_rate = 1.
iter_cnt = 0
while loss > threshold:
iter_cnt += 1
loss.backward() # 기울기 계산
x = x - learning_rate * x.grad
x.detach_()
x.requires_grad_(True)
loss = F.mse_loss(x, target)
print(iter_cnt, loss)
print(x)
아래 출력은 손실값이 점차 줄어드는 모습을 볼 수 있다.
'''
count : 1, loss : 0.08802667260169983
tensor([[0.2943, 0.1191, 0.7827],
[0.3981, 0.4318, 0.5430],
[0.5266, 0.1810, 0.5937]], requires_grad=True)
count : 2, loss : 0.053250689059495926
tensor([[0.2511, 0.1371, 0.6754],
[0.3985, 0.4469, 0.5557],
[0.5651, 0.3186, 0.6617]], requires_grad=True)
count : 3, loss : 0.032213374972343445
tensor([[0.2176, 0.1511, 0.5920],
[0.3988, 0.4587, 0.5655],
[0.5951, 0.4256, 0.7147]], requires_grad=True)
count : 4, loss : 0.019487105309963226
tensor([[0.1914, 0.1619, 0.5271],
[0.3991, 0.4679, 0.5732],
[0.6184, 0.5088, 0.7559]], requires_grad=True)
count : 5, loss : 0.011788494884967804
tensor([[0.1711, 0.1704, 0.4766],
[0.3993, 0.4750, 0.5791],
[0.6365, 0.5735, 0.7879]], requires_grad=True)
... 생략
count : 16, loss : 4.6803688746877015e-05
tensor([[0.1045, 0.1981, 0.3111],
[0.4000, 0.4984, 0.5987],
[0.6960, 0.7857, 0.8929]], requires_grad=True)
count : 17, loss : 2.8313312213867903e-05
tensor([[0.1035, 0.1985, 0.3087],
[0.4000, 0.4988, 0.5990],
[0.6969, 0.7889, 0.8945]], requires_grad=True)
count : 18, loss : 1.7127826140495017e-05
tensor([[0.1027, 0.1989, 0.3067],
[0.4000, 0.4990, 0.5992],
[0.6976, 0.7914, 0.8957]], requires_grad=True)
count : 19, loss : 1.0361281965742819e-05
tensor([[0.1021, 0.1991, 0.3052],
[0.4000, 0.4993, 0.5994],
[0.6981, 0.7933, 0.8967]], requires_grad=True)
count : 20, loss : 6.2678964241058566e-06
tensor([[0.1016, 0.1993, 0.3041],
[0.4000, 0.4994, 0.5995],
[0.6985, 0.7948, 0.8974]], requires_grad=True)
'''
x = torch.FloatTensor([[1,2],[3,4]]).requires_grad_(True)
x1 = x + 2
print(x1)
#tensor([[3., 4.],
# [5., 6.]], grad_fn=<AddBackward0>)
x2 = x-2
x2
# tensor([[-1., 0.],
# [ 1., 2.]], grad_fn=<SubBackward0>)
x3 = x1 * x2
print(x3)
# tensor([[-3., 0.],
# [ 5., 12.]], grad_fn=<MulBackward0>)
y = x3.sum()
y
# tensor(14., grad_fn=<SumBackward0>)
y.backward()
x.grad
# tensor([[2., 4.],
# [6., 8.]])
x.grad 값은 각 원소의 편미분된 값이 모두 2x이기 때문에 기존 x값에서 2를 곱한 형태로 출력된다.