3장 파이토치의 기본 기능
- “부록3 매트플롯립 입문”에서 한글 폰트를 올바르게 출력하기 위한 설치 방법을 설명했다. 설치 방법은 다음과 같다.
!sudo apt-get install -y fonts-nanum* | tail -n 1
!sudo fc-cache -fv
!rm -rf ~/.cache/matplotlibdebconf: unable to initialize frontend: Dialog
debconf: (No usable dialog-like program is installed, so the dialog based frontend cannot be used. at /usr/share/perl5/Debconf/FrontEnd/Dialog.pm line 78, <> line 4.)
debconf: falling back to frontend: Readline
debconf: unable to initialize frontend: Readline
debconf: (This frontend requires a controlling tty.)
debconf: falling back to frontend: Teletype
dpkg-preconfigure: unable to re-open stdin:
Processing triggers for fontconfig (2.13.1-4.2ubuntu5) ...
/usr/share/fonts: caching, new cache contents: 0 fonts, 1 dirs
/usr/share/fonts/truetype: caching, new cache contents: 0 fonts, 3 dirs
/usr/share/fonts/truetype/humor-sans: caching, new cache contents: 1 fonts, 0 dirs
/usr/share/fonts/truetype/liberation: caching, new cache contents: 16 fonts, 0 dirs
/usr/share/fonts/truetype/nanum: caching, new cache contents: 39 fonts, 0 dirs
/usr/local/share/fonts: caching, new cache contents: 0 fonts, 0 dirs
/root/.local/share/fonts: skipping, no such directory
/root/.fonts: skipping, no such directory
/usr/share/fonts/truetype: skipping, looped directory detected
/usr/share/fonts/truetype/humor-sans: skipping, looped directory detected
/usr/share/fonts/truetype/liberation: skipping, looped directory detected
/usr/share/fonts/truetype/nanum: skipping, looped directory detected
/var/cache/fontconfig: cleaning cache directory
/root/.cache/fontconfig: not cleaning non-existent cache directory
/root/.fontconfig: not cleaning non-existent cache directory
fc-cache: succeeded
# 필요 라이브러리 설치
!pip install torchviz | tail -n 1Successfully installed nvidia-cublas-cu12-12.4.5.8 nvidia-cuda-cupti-cu12-12.4.127 nvidia-cuda-nvrtc-cu12-12.4.127 nvidia-cuda-runtime-cu12-12.4.127 nvidia-cudnn-cu12-9.1.0.70 nvidia-cufft-cu12-11.2.1.3 nvidia-curand-cu12-10.3.5.147 nvidia-cusolver-cu12-11.6.1.9 nvidia-cusparse-cu12-12.3.1.170 nvidia-nvjitlink-cu12-12.4.127 torchviz-0.0.3
- 모든 설치가 끝나면 한글 폰트를 바르게 출력하기 위해 [런타임] -> **[런타임 다시시작]**을 클릭한 다음, 아래 셀부터 코드를 실행해 주십시오.
# 라이브러리 임포트
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
from IPython.display import display
# 폰트 관련 용도
import matplotlib.font_manager as fm
# Colab, Linux
# 나눔 고딕 폰트의 경로 명시
path = '/usr/share/fonts/truetype/nanum/NanumGothic.ttf'
font_name = fm.FontProperties(fname=path, size=10).get_name()
# Window
# font_name = "NanumBarunGothic"
# Mac
# font_name = "AppleGothic"# 기본 폰트 설정
plt.rcParams['font.family'] = font_name
# 기본 폰트 사이즈 변경
plt.rcParams['font.size'] = 14
# 기본 그래프 사이즈 변경
plt.rcParams['figure.figsize'] = (6,6)
# 기본 그리드 표시
# 필요에 따라 설정할 때는, plt.grid()
plt.rcParams['axes.grid'] = True
plt.rcParams["grid.linestyle"] = ":"
# 마이너스 기호 정상 출력
plt.rcParams['axes.unicode_minus'] = False
# 넘파이 부동소수점 자릿수 표시
np.set_printoptions(suppress=True, precision=4)텐서
라이브러리 임포트
# 파이토치 라이브러리
import torch다양한 계수의 텐서 만들기
## Tensor 만들기
r0 = torch.tensor(10) # rank 0
print("r0 = \n", r0)
# print("r0.shape = \n", r0.shape)
print(r0.dtype)
r1 = torch.tensor([1, 2 ,3]) # rank 1
print("r1 = \n",r1)
# print("r1.shape = \n", r1.shape)
r2 = torch.tensor([[1, 2, 3], [3, 4, 5]]) # rank 2
print("r2 = \n",r2)
# print("r2.shape = \n", r2.shape)
r3 = torch.tensor([[[1, 2], [3, 4]], # rank 3
[[5, 6], [7, 8]]])
print("r3 = \n",r3)
# print("r3.shape = \n", r3.shape)
r0 =
tensor(10)
torch.int64
r1 =
tensor([1, 2, 3])
r2 =
tensor([[1, 2, 3],
[3, 4, 5]])
r3 =
tensor([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]])
# 0계 텐서(스칼라)
r0 = torch.tensor(1.0).float()
# r0 = torch.tensor(1.0).float()
# type 확인
print(type(r0))
# dtype 확인
print(r0.dtype)<class 'torch.Tensor'>
torch.float32
# shape 확인
print(r0.shape)
# 데이터 확인
print(r0.data)torch.Size([])
tensor(1.)
## tensor attribute
print("int attribute:")
int_atr = torch.tensor([1, 2, 3])
print(int_atr)
print(int_atr.shape)
print(int_atr.dtype)
print(int_atr.device)
print()
print("float attribute:")
float_atr = torch.tensor([[1, 2, 3, 4],
[5, 6, 7, 8]], dtype=torch.float32)
print(float_atr)
print(float_atr.shape)
print(float_atr.dtype)
print(float_atr.device)int attribute:
tensor([1, 2, 3])
torch.Size([3])
torch.int64
cpu
float attribute:
tensor([[1., 2., 3., 4.],
[5., 6., 7., 8.]])
torch.Size([2, 4])
torch.float32
cpu
## gpu 사용확인
# 현재 시스템에서 cuda가 사용가능한지 여부
print("torch.cuda.is_available():")
print(torch.cuda.is_available())
print()
# 현재 pythorch가 사용 중인 gpu 인덱스 번호 반환 여러개시 0반환
# 없거나 사용 불가시 오류
print("torch.cuda.current_device():")
print(torch.cuda.current_device())
print()
# 지정한 gpu의 모델명 반환
print("torch.cuda.get_device_name():")
print(torch.cuda.get_device_name(0))
print()
# 사용가능한 gpu의 개수 반환 없으면 0반환
print("torch.cuda.device_count():")
print(torch.cuda.device_count())torch.cuda.is_available():
True
torch.cuda.current_device():
0
torch.cuda.get_device_name():
Tesla T4
torch.cuda.device_count():
1
# 1계 텐서(벡터)
# 1계 넘파이 변수 작성
r1_np = np.array([1, 2, 3, 4, 5])
print(r1_np.shape)
# 넘파이에서 텐서로 변환
r1 = torch.tensor(r1_np).float()
# dtype 확인
print(r1.dtype)
# shape 확인
print(r1.shape)
# 데이터 확인
print(r1.data)(5,)
torch.float32
torch.Size([5])
tensor([1., 2., 3., 4., 5.])
# 2계 텐서(행렬)
# 2계 넘파이 변수 작성
r2_np = np.array([[1, 5, 6], [4, 3, 2]])
print(r2_np.shape)
# 넘파이에서 텐서로 변환
r2 = torch.tensor(r2_np).float()
# shape 확인
print(r2.shape)
# 데이터 확인
print(r2.data)(2, 3)
torch.Size([2, 3])
tensor([[1., 5., 6.],
[4., 3., 2.]])
# 3계 텐서
# 난수 seed 초기화
torch.manual_seed(123)
# shape=[3,2,2]의 정규분포 텐서 작성
r3 = torch.randn((3, 2, 2))
# shape 확인
print(r3.shape)
# 데이터 확인
print(r3.data)torch.Size([3, 2, 2])
tensor([[[-0.1115, 0.1204],
[-0.3696, -0.2404]],
[[-1.1969, 0.2093],
[-0.9724, -0.7550]],
[[ 0.3239, -0.1085],
[ 0.2103, -0.3908]]])
# 4계 텐서
# 요소가 모두 1인 shape=[2,3,2,2] 텐서 작성
r4 = torch.ones((2, 3, 2, 2))
# shape 확인
print(r4.shape)
# 데이터 확인
print(r4.data)torch.Size([2, 3, 2, 2])
tensor([[[[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.]]],
[[[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.]]]])
## list, numpy to Tensor
x = [1, 2, 3]
y = torch.tensor(x)
print(y)
x1 = np.array([1, 2, 3])
# y1 = torch.tensor(x1) # 복사
y1 = torch.from_numpy(x1) # memory 공유
print(y1)
tensor([1, 2, 3])
tensor([1, 2, 3])
## ones, zeros tensor
print("torch.ones:")
print(torch.ones(2))
print()
print(torch.ones(2, 3))
print()
print(torch.ones(2, 3, 2))
print("torch.zeros:")
print(torch.zeros(2))
print()
print(torch.zeros(2, 3))
print()
print(torch.zeros(2, 3, 2))torch.ones:
tensor([1., 1.])
tensor([[1., 1., 1.],
[1., 1., 1.]])
tensor([[[1., 1.],
[1., 1.],
[1., 1.]],
[[1., 1.],
[1., 1.],
[1., 1.]]])
torch.zeros:
tensor([0., 0.])
tensor([[0., 0., 0.],
[0., 0., 0.]])
tensor([[[0., 0.],
[0., 0.],
[0., 0.]],
[[0., 0.],
[0., 0.],
[0., 0.]]])
Random 텐서 만들기
## tensor random
print("torch.rand: uniform distribution")
print(torch.rand(2, 3))
print()
print("torch.randn: standard normal distribution")
print(torch.randn(2, 3)) #standard normal distribution
print()
print("torch.randint: random integer")
print(torch.randint(1, 10, (2, 3)))
print("torch.normal: normal distribution")
print(torch.normal(10, 1, (2, 3)))
print("torch.randperm: random permutation")
print(torch.randperm(10))
print(torch.randperm(10).dtype)torch.rand: uniform distribution
tensor([[0.2745, 0.6584, 0.2775],
[0.8573, 0.8993, 0.0390]])
torch.randn: standard normal distribution
tensor([[-1.4168, 0.8429, -0.6307],
[ 1.2340, 0.3127, 0.6972]])
torch.randint: random integer
tensor([[8, 8, 9],
[8, 2, 3]])
torch.normal: normal distribution
tensor([[ 9.0399, 9.5913, 11.0764],
[ 9.5985, 9.2709, 9.8782]])
torch.randperm: random permutation
tensor([0, 6, 2, 3, 4, 5, 8, 9, 7, 1])
torch.int64
정숫값을 갖는 텐서 만들기
# # 1계 넘파이 변수 작성
# r1_np = np.array([1, 2, 3, 4, 5])
# print(r1_np.shape)
# # 넘파이에서 텐서로 변환
# r1 = torch.tensor(r1_np).float()
r5 = r1.long()
# dtype 확인
print(r5.dtype)
# 값 확인
print(r5)torch.int64
tensor([1, 2, 3, 4, 5])
view 함수
r3
# r3.shapetensor([[[-0.1115, 0.1204],
[-0.3696, -0.2404]],
[[-1.1969, 0.2093],
[-0.9724, -0.7550]],
[[ 0.3239, -0.1085],
[ 0.2103, -0.3908]]])
# 2계화
# 남은 자리에 -1을 지정하면 이 수를 자동으로 조정함
r6 = r3.view(3, -1) # r3.shape = (3, 2, 2)
# shape 확인
print(r6.shape)
# 값 확인
print(r6.data)torch.Size([3, 4])
tensor([[-0.1115, 0.1204, -0.3696, -0.2404],
[-1.1969, 0.2093, -0.9724, -0.7550],
[ 0.3239, -0.1085, 0.2103, -0.3908]])
# 1계화
# 남은 자리에 -1을 지정하면 이 수를 자동으로 조정함
r7 = r3.view(-1)
# shape 확인
print(r7.shape)
# 값 확인
print(r7.data)torch.Size([12])
tensor([-0.1115, 0.1204, -0.3696, -0.2404, -1.1969, 0.2093, -0.9724, -0.7550,
0.3239, -0.1085, 0.2103, -0.3908])
Tensor reshape
## tensor reshape
tensor_reshape_list= [[1, 2, 3, 4], [5, 6, 7, 8]]
tensor_reshape = torch.tensor(tensor_reshape_list)
print("tensor_reshape:")
print(tensor_reshape)
print(tensor_reshape.shape)
print()
print("tensor_reshape.reshape(4, 2):")
print(tensor_reshape.reshape(4, 2))
print(tensor_reshape.reshape(4, 2).shape)
print()
print("tensor_reshape.reshape(4, -1):")
print(tensor_reshape.reshape(4, -1))
print(tensor_reshape.reshape(4, -1).shape)
print()
print("tensor_reshape.reshape(-1):")
print(tensor_reshape.reshape(-1))
print(tensor_reshape.reshape(-1).shape)
print()
print("tensor_reshape.reshape(-1, 2):")
print(tensor_reshape.reshape(-1, 2))
print(tensor_reshape.reshape(-1, 2).shape)
print()
print("tensor_reshape.reshape(1, 2, -1)")
print(tensor_reshape.reshape(1, 2, -1))
print()
print("tensor_reshape.reshape(-1, 2, 2)")
print(tensor_reshape.reshape(-1, 2, 2))
print(tensor_reshape.reshape(-1, 2, 2).shape)
tensor_reshape:
tensor([[1, 2, 3, 4],
[5, 6, 7, 8]])
torch.Size([2, 4])
tensor_reshape.reshape(4, 2):
tensor([[1, 2],
[3, 4],
[5, 6],
[7, 8]])
torch.Size([4, 2])
tensor_reshape.reshape(4, -1):
tensor([[1, 2],
[3, 4],
[5, 6],
[7, 8]])
torch.Size([4, 2])
tensor_reshape.reshape(-1):
tensor([1, 2, 3, 4, 5, 6, 7, 8])
torch.Size([8])
tensor_reshape.reshape(-1, 2):
tensor([[1, 2],
[3, 4],
[5, 6],
[7, 8]])
torch.Size([4, 2])
tensor_reshape.reshape(1, 2, -1)
tensor([[[1, 2, 3, 4],
[5, 6, 7, 8]]])
tensor_reshape.reshape(-1, 2, 2)
tensor([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]])
torch.Size([2, 2, 2])
Tensor squeeze
tensor_squeeze = torch.tensor([[1], [2], [3]])
print("tensor_squeeze:")
print(tensor_squeeze)
print(tensor_squeeze.shape)
print()
print("tensor_squeeze.squeeze():")
print(tensor_squeeze.squeeze())
print(tensor_squeeze.squeeze().shape)
tensor_squeeze2 = torch.ones(1,2,1,4)
print()
print("tensor_squeeze2:")
print(tensor_squeeze2)
print(tensor_squeeze2.shape )tensor_squeeze:
tensor([[1],
[2],
[3]])
torch.Size([3, 1])
tensor_squeeze.squeeze():
tensor([1, 2, 3])
torch.Size([3])
tensor_squeeze2:
tensor([[[[1., 1., 1., 1.]],
[[1., 1., 1., 1.]]]])
torch.Size([1, 2, 1, 4])
## tensor arange
print(torch.arange(1, 10))
print(torch.arange(1, 10, 2))
print(torch.arange(1, 3, 0.5))
print(torch.arange(10))
print(torch.linspace(1, 10, 5))tensor([1, 2, 3, 4, 5, 6, 7, 8, 9])
tensor([1, 3, 5, 7, 9])
tensor([1.0000, 1.5000, 2.0000, 2.5000])
tensor([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
tensor([ 1.0000, 3.2500, 5.5000, 7.7500, 10.0000])
그 밖의 속성
# requires_grad 속성
print('requires_grad: ', r1.requires_grad)
# device 속성
print('device: ', r1.device)requires_grad: False
device: cpu
item 함수
# 스칼라 텐서(0계 텐서)는 item 함수로 값을 꺼낼 수 있음
item = r0.item()
print(type(item))
print(item)<class 'float'>
1.0
# 스칼라 이외의 텐서에 item 함수는 무효함
print(r1.item()) # RuntimeError: a Tensor with 5 elements cannot be converted to Scalar---------------------------------------------------------------------------
RuntimeError Traceback (most recent call last)
<ipython-input-25-19b2fc013c51> in <cell line: 0>()
1 # 스칼라 이외의 텐서에 item 함수는 무효함
2
----> 3 print(r1.item())
RuntimeError: a Tensor with 5 elements cannot be converted to Scalar
# 요소 수가 하나뿐인 1계 텐서는 OK
# (2계 이상에서도 마찬가지)
t1 = torch.ones(1)
# shape 확인
print(t1.shape)
# item 함수 호출
print(t1.item())torch.Size([1])
1.0
max 함수
# 텐서 r2 확인
print(r2)
# max 함수를 인수 없이 호출하면, 최댓값을 얻음
print(r2.max())tensor([[1., 5., 6.],
[4., 3., 2.]])
tensor(6.)
# torch.max 함수
# 두번째 인수는 기준이 되는 축을 의미함
print(torch.max(r2, 1))torch.return_types.max(
values=tensor([6., 4.]),
indices=tensor([2, 0]))
# 몇 번째 요소가 최댓값인지 indices 확인을 통해 알 수 있음
# 아래 계산은 다중 분류에서 예측 라벨을 구할 때 자주 사용되는 패턴임
print(torch.max(r2, 1)[1])tensor([2, 0])
tensor statistic
## tensor statistic
tensor_stat_list = [[1, 3, 5], [2, 4, 8]]
tensor_stat = torch.tensor(tensor_stat_list, dtype=torch.float)
print("tensor_stat:")
print(tensor_stat)
print()
print( "tensor_stat.sum():")
print(tensor_stat.sum())
print(tensor_stat.median())
print()
print("tensor_stat.sum(dim = 0):")
print(tensor_stat.sum(dim = 0))
print(tensor_stat.median(dim = 0))
print()
print("tensor_stat.sum(dim = 1):")
print(tensor_stat.sum(dim = 1))
print()
print("tensor_stat.sum(dim = -1):")
print(tensor_stat.sum(dim = -1))
print()
print("tensor_stat.mean():")
print(tensor_stat.mean())
print()
print("tensor_stat.mean(dim = 1):")
print(tensor_stat.mean(dim = 1))
print()
print("tensor_stat.std():")
print(tensor_stat.std())
print()
print("tensor_stat.max():")
print(tensor_stat.max())
print()
print("tensor_stat.min():")
print(tensor_stat.min())
print("tensor_stat.argmax()")
print(tensor_stat.argmax(dim = 1))tensor_stat:
tensor([[1., 3., 5.],
[2., 4., 8.]])
tensor_stat.sum():
tensor(23.)
tensor(3.)
tensor_stat.sum(dim = 0):
tensor([ 3., 7., 13.])
torch.return_types.median(
values=tensor([1., 3., 5.]),
indices=tensor([0, 0, 0]))
tensor_stat.sum(dim = 1):
tensor([ 9., 14.])
tensor_stat.sum(dim = -1):
tensor([ 9., 14.])
tensor_stat.mean():
tensor(3.8333)
tensor_stat.mean(dim = 1):
tensor([3.0000, 4.6667])
tensor_stat.std():
tensor(2.4833)
tensor_stat.max():
tensor(8.)
tensor_stat.min():
tensor(1.)
tensor_stat.argmax()
tensor([2, 2])
넘파이 변수로 변환
# 넘파이로 변환
r2_np = r2.data.numpy()
# type 확인
print(type(r2_np))
# 값 확인
print(r2_np)<class 'numpy.ndarray'>
[[1. 5. 6.]
[4. 3. 2.]]
2차 함수의 경사 계산
데이터 준비
# x를 넘파이 배열로 정의
x_np = np.arange(-2, 2.1, 0.25)
# x값 표시
print(x_np)[-2. -1.75 -1.5 -1.25 -1. -0.75 -0.5 -0.25 0. 0.25 0.5 0.75
1. 1.25 1.5 1.75 2. ]
# (1) 경사 계산용 변수 정의
x = torch.tensor(x_np, requires_grad=True,
dtype=torch.float32)
# 결과 확인
print(x)tensor([-2.0000, -1.7500, -1.5000, -1.2500, -1.0000, -0.7500, -0.5000, -0.2500,
0.0000, 0.2500, 0.5000, 0.7500, 1.0000, 1.2500, 1.5000, 1.7500,
2.0000], requires_grad=True)
2차 함수 계산
# 2차 함수의 계산
# 계산 그래프는 내부에서 자동 생성됨
y = 2 * x**2 + 2를 의미한다.
# y의 계산 결과 확인
print(y)tensor([10.0000, 8.1250, 6.5000, 5.1250, 4.0000, 3.1250, 2.5000, 2.1250,
2.0000, 2.1250, 2.5000, 3.1250, 4.0000, 5.1250, 6.5000, 8.1250,
10.0000], grad_fn=<AddBackward0>)
# 그래프(산포도) 출력
plt.plot(x.data, y.data)
plt.title("Y=2X^2+2")
plt.show()
# 경사 계산을 위해 최종 값은 스칼라일 필요가 있으므로, 더미로 sum 함수를 붙임
z = y.sum()# (3) 계산 그래프 시각화
# 필요한 라이브러리 임포트
from torchviz import make_dot
# 시각화 함수 호출
g = make_dot(z, params={'x': x})
display(g)# (4) 경사 계산
z.backward()# (5) 경삿값 가져오기
print(x.grad)tensor([-8., -7., -6., -5., -4., -3., -2., -1., 0., 1., 2., 3., 4., 5.,
6., 7., 8.])
# 원래 함수와 경사 그래프
plt.plot(x.data, y.data, c='b', label='y')
plt.plot(x.data, x.grad.data, c='k', label='y.grad')
plt.legend()
plt.show()
원래 함수가 2차 함수이기 때문에 경사 계산의 결과가 직선인 것은 타당한 결과
경사 계산을 한번 더 해보자.
# 경사를 초기화하지 않고 두번째 경사를 계산
y = 2 * x**2 + 2
z = y.sum()
z.backward()
# x의 경사 확인
print(x.grad)tensor([-16., -14., -12., -10., -8., -6., -4., -2., 0., 2., 4., 6.,
8., 10., 12., 14., 16.])
경삿값은 경사 계산의 값이 점차 합해진 결과다. 새로운 값을 계산하기 위해서 경삿값을 조기화 해야한다.
# (6) 경삿값의 초기화는 zero_() 함수를 사용함
x.grad.zero_()
print(x.grad)tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
시그모이드 함수의 경사 계산
시그모이드 함수는 수식으로 나타내면 다음과 같지만, 여기서는 파이토치에서 제공하는 함수를 사용한다.
# 시그모이드 함수의 정의
sigmoid = torch.nn.Sigmoid()# (2) y값의 계산
y = sigmoid(x)# 그래프(산포도) 출력
plt.plot(x.data, y.data)
plt.show()
# 경사 계산을 위해 최종 값은 스칼라일 필요가 있으므로, 더미로 sum 함수를 붙임
z = y.sum()# (3) 계산 그래프 시각화
g = make_dot(z, params={'x': x})
display(g)# (4) 경사 계산
z.backward()
# (5) 경삿값 확인
print(x.grad)tensor([0.1050, 0.1261, 0.1491, 0.1731, 0.1966, 0.2179, 0.2350, 0.2461, 0.2500,
0.2461, 0.2350, 0.2179, 0.1966, 0.1731, 0.1491, 0.1261, 0.1050])
# 원래 함수와 경사 그래프
plt.plot(x.data, y.data, c='b', label='y')
plt.plot(x.data, x.grad.data, c='k', label='y.grad')
plt.legend()
plt.show()
시그모이드 함수의 경사는 이다.
2차 함수이므로, (x=0일때) 최댓값 을 얻는다. 위의 그래프는 이 계산 결과와 일치한다.
# (6) 경사 초기화는 zero_() 함수를 사용
x.grad.zero_()
print(x.grad)tensor([0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.])
(참고) 시그모이드 함수를 직접 구현한 경우
# 시그모이드 함수의 정의
def sigmoid(x):
return(1/(1 + torch.exp(-x)))# (2) y값의 계산
y = sigmoid(x)# 그래프(산포도) 출력
plt.plot(x.data, y.data)
plt.xlabel('x')
plt.ylabel('y')
plt.title('시그모이드 함수 그래프')
plt.show()
# 경사 계산을 위해 최종 값은 스칼라일 필요가 있으므로, 더미로 sum 함수를 붙임
z = y.sum()# (3) 계산 그래프 시각화
params = {'x': x}
g = make_dot(z, params=params)
display(g)# (4) 경사 계산
z.backward()
# (5) 경삿값 확인
print(x.grad)tensor([0.1050, 0.1261, 0.1491, 0.1731, 0.1966, 0.2179, 0.2350, 0.2461, 0.2500,
0.2461, 0.2350, 0.2179, 0.1966, 0.1731, 0.1491, 0.1261, 0.1050])
# 원래 함수와 경사 그래프
plt.plot(x.data, y.data, c='b', label='y')
plt.plot(x.data, x.grad.data, c='k', label='y.grad')
plt.legend()
plt.show()