Tensor의 최소값 연산

코드 1)

x = torch.tensor([[0, 1, 2], [5, 4, 3], [7, 8, 6]])
print('the minimum:', x.min())

the minimum : tensor(0)

1) torch.min(tensor)의 결과는 tensor가 반환된다. 여기서는 0, 즉, tensor(0)이 출력된다.

코드 2)

values, indices = x.min(dim = 0)
print('values=:', values)
print('indices=:', indices)

values =: tensor([0, 1, 2])
indices =: tensor([0, 0, 0])

2) torch.min(tensor, dim)의 결과는 values와 indices가 반환된다. 여기서는 텐서에서 0, 1, 2 이것들이 각 열 (dim=0)에서 최솟값으로 판별되었고, 그 행 번호는 0이다. dim = 1으로 하면 행 기준으로 최솟값이 출력된다.

코드 3)

values, indices = x.min(dim = 0, keepdim = True)
print('values:', values, 'size=:', values.shape)
print('indices=:', indices, 'size=:', indices.shape)

3) torch.min(tensor, dim, keepdim = True)의 결과는 values와 indices 값의 형태가 유지되는 tensor가 반환된다.

코드 4)

values, indices = x.min(dim = 1, keepdim = True)
print('values=:', values, 'size=:', values.shape)
print('indices=:', indices, 'size=:', indices.shape)

values=: tensor([[0],
[3],
[6]]) size=: torch.Size([3, 1])
indices=: tensor([[0],
[2],
[2]]) size=: torch.Size([3, 1])

4) torch.min(tensor, dim, keepdim = True)를 dim = 1로 바꾸어 실행한 결과이다. 행 기준이다.

코드 5)

x = torch.tensor([1, 4, 5])
y = torch.tensor([2, 3, 5])

print('the minimum =:', torch.min(x, y))

the minimum =: tensor([1, 3, 5])

5) torch.min(tensor, tensor)의 형태인 경우에도 tensor의 형태를 유지하지만, dim = 0을 기준으로 각 원소의 최솟값을 찾아 tensor로 반환환다.

Tensor의 최댓값 연산

코드 1번

x = torch.tensor([[0, 1, 2], [5, 4, 3], [7, 8, 6]])
print('the maximum:', x.max())

the maximm : tensor(8)

1) 최댓값 연산은 최솟값 연산과 동일한 연산 형태를 취한다. torch.max(tensor)의 결과는 tensor가 반환된다.

코드 2번

values, indices = x.max(dim = 0)
print('values=:', values)
print('indcies=:', indices)

values, indices = x.max(dim = 0)
print('values=:', values)
print('indcies=:', indices)

2) torch.max(tensor, dim)의 values는 하나의 열에 각 행의 원소를 비교해 최댓값을 반환한다.

코드 3번

values, indices = x.max(dim = 0, keepdim = True)
print('values:', values, 'size=:', values.shape)
print('indices=:', indices, 'size=:', indices.shape)

values: tensor([[7, 8, 6]]) size=: torch.Size([1, 3])
indices=: tensor([[2, 2, 2]]) size=: torch.Size([1, 3])

코드 4번

values, indices = x.max(dim = 1, keepdim = True)
print('values=:', values, 'size=:', values.shape)
print('indices=:', indices, 'size=:', indices.shape)

values=: tensor([[2],
[5],
[8]]) size=: torch.Size([3, 1])
indices=: tensor([[2],
[0],
[1]]) size=: torch.Size([3, 1])

코드 5번

x = torch.tensor([1, 4, 5])
y = torch.tensor([2, 3, 5])

print('the maximum =:', torch.max(x, y))

the maximum =: tensor([2, 4, 5])

Tensor의 인덱스 연산

코드 1)

x = torch.tensor([[0, 1, 2], [5, 4, 3], [7, 8, 6]])
print('x=:', x)
print('x.argmin()=:', x.argmin())
print('x.argmax()=:', x.argmax())

x=: tensor([[0, 1, 2],
[5, 4, 3],
[7, 8, 6]])
x.argmin()=: tensor(0)
x.argmax()=: tensor(7)

1) torch.argmin(tensor)는 최소값의 위치를 찾아 텐서로 반환한다. 즉, [0, 1, 2, 5, 4, 3, 7, 8, 6]에서 0은 tensor(0), 8은 tensor(7)이라 저렇게 출력이 된다.

코드 2)

print('x.argmin()=:', x.argmin(dim=0))
print('x.argmax()=:', x.argmax(dim=0))

x.argmin()=: tensor([0, 0, 0])
x.argmax()=: tensor([2, 2, 2])

2) dim = 0으로 지정하는 경우, torch.argmin()과 torch.argmax()는 각각 최소값과 최대값을 각 열마다 찾아 텐서로 반환한다. 즉, 열기준으로 본다. 열 기준으로 x의 최소는 [0, 0, 0]에 있고, 최대는 [2, 2, 2]에 있다.

코드 3)

print('x.argmin()=:', x.argmin(dim=0, keepdim=True))
print('x.argmax()=:', x.argmax(dim=0, keepdim=True))

x.argmin()=: tensor([[0, 0, 0]])
x.argmax()=: tensor([[2, 2, 2]])

keepdim = True를 사용하는 경우, 실행 결과로 반환되는 tensor의 형태를 동일하게 유지하여 반환한다.

print('x.argmin()=:', x.argmin(dim=1, keepdim=True))
print('x.argmax()=:', x.argmax(dim=1, keepdim=True))

x.argmin()=: tensor([[0],
[2],
[2]])
x.argmax()=: tensor([[2],
[0],
[1]])

Tensor의 합과 곱

코드 1)

x = torch.arange(1, 7).reshape(2, 3)
print('x=:', x)

x=: tensor([[1, 2, 3],
[4, 5, 6]])

코드 2)

print('sum of x:', x.sum())
print('product of x:', x.prod())

sum of x: tensor(21)
product of x: tensor(720)

2) torch.sum()과 torch.prod()는 텐서의 합과 곱의 결과를 반환한다.

코드 3)

print('sum of x by dim = 0:', x.sum(dim=0))
print('product of x by dim = 0:', x.prod(dim = 0))

sum of x by dim = 0: tensor([5, 7, 9])
product of x by dim = 0: tensor([ 4, 10, 18])

3) dim = 0일때 각 열의 행의 값을 더하거나 곱하여 결과를 반환한다.

코드 4)

print('sum of x by dim=1:', x.sum(dim=1))
print('product of x by dim=1:', x.prod(dim=1))

sum of x by dim=1: tensor([ 6, 15])
product of x by dim=1: tensor([ 6, 120])

4) dim = 1일경우 행별로 더하거나 곱한 결과를 출력한다.

Tensor의 기초 통계량 연산

코드 1)

x = torch.arange(6).reshape(2, 3).float()
print('x=:', x)

x=: tensor([[0., 1., 2.],
[3., 4., 5.]])

코드 2)

print('mean of x:', x.mean())
print('mean of x by dim=0:', x.mean(dim=0))
print('mean of x by dim = 1:', x.mean(dim = 1))

mean of x: tensor(2.5000)
mean of x by dim=0: tensor([1.5000, 2.5000, 3.5000])
mean of x by dim = 1: tensor([1., 4.])

print('variance of x=:', x.var(unbiased=True))
print('variance of x by dim=0:', x.var(dim=0))
print('variance of x by dim=1:', x.var(dim=1))

variance of x=: tensor(3.5000)
variance of x by dim=0: tensor([4.5000, 4.5000, 4.5000])
variance of x by dim=1: tensor([1., 1.])

torch.mean()과 torch.var()은 산술평균과 분산의 값을 계산하여 텐서로 반환한다. torch.var()은 기본적으로 불편추정량을 사용하여 계산된 값을 반환한다.
불편 추정량은 (n-1)로 나눈다. 표본분산 구할때 그식 알죠? std로 하면 표준편차로 나오겠죠??

코드 3)

variance, mean = torch.var_mean(x)
print(f"mean is {mean}, variance is {variance}")

std, mean = torch.std_mean(x)
print(f"mean is {mean}, standard deviation is {std}")

mean is 2.5, variance is 3.5
mean is 2.5, standard deviation is 1.8708287477493286

torch.var_mean은 분산과 평균의 값을 쌍으로 반환하고, std_mean은 표준편차와 평균의 값을 쌍으로 반환한다.

Tensor의 인덱스 찾기

코드 1)

x = torch.tensor([-1, 2, -3, 4, 5], dtype = torch.float)
y = torch.ones(5, dtype=torch.float)
print('x=:', x)
print('y=:', y)

z = torch.where(x>0, x, y)
print('z=:', z)

x=: tensor([-1., 2., -3., 4., 5.])
y=: tensor([1., 1., 1., 1., 1.])
z=: tensor([1., 2., 1., 4., 5.])

1) torch.where(condition, x, y) 는 condition이 True이면, x의 항목을, condition이 False이면 y의 항목을 텐서로 반환한다. 즉, x>0 이면 x 텐서 값을 쓰고, 그렇지 않으면 y값을 쓴다.

Tensor 정렬하기

코드 1)

torch.manual_seed(0)
x = torch.randperm(6)
print('x=:', x)

x=: tensor([2, 5, 3, 0, 1, 4])

randperm(n) 이거는 n개의 숫자를 n보다 작은 숫자들한에서 랜덤으로 뽑아서 텐서로 만드는거다.

코드 2)

sorted_values, indices = torch.sort(x)
print('sorted values:', sorted_values)
print('indices:', indices)

sorted values: tensor([0, 1, 2, 3, 4, 5])
indices: tensor([3, 4, 0, 2, 5, 1])

print(x.argsort())

tensor([3, 4, 0, 2, 5, 1])

코드 3)

x = torch.randperm(12).reshape(3, 4)
print('x=:', x)

sorted_values, indices = torch.sort(x)
print('sorted values:', sorted_values)
print('indices:', indices)
print(torch.argsort(x, dim=1))

x=: tensor([[ 3, 5, 1, 4],
[ 7, 0, 8, 6],
[11, 10, 9, 2]])
sorted values: tensor([[ 1, 3, 4, 5],
[ 0, 6, 7, 8],
[ 2, 9, 10, 11]])
indices: tensor([[2, 0, 3, 1],
[1, 3, 0, 2],
[3, 2, 1, 0]])
tensor([[2, 0, 3, 1],
[1, 3, 0, 2],
[3, 2, 1, 0]])

torch.sort(x, dim =0) 처럼 dim = 0을 추가할경우, 오름차순으로 정렬한 결과 값과 결과의 인덱스 값을 함께 반환한다.

Tensor의 행렬 연산

A = torch.tensor([1, 2], dtype=torch.float)
B = torch.tensor([3, 4], dtype=torch.float)
C = A.matmul(B)
print(C)

torch.matmul()은 일반적인 벡터 또는 행렬의 내적을 계산하여 돌려준다.

A = torch.tensor([1, 2], dtype=torch.float)
B = torch.tensor([[1, 2], [3, 4]], dtype=torch.float)

D1 = A@B
D2 = B@A
D3 = B@A.view(2, 1)

print(D1)
print(D2)
print(D3)
print(torch.allclose(D1, D2))
print(torch.allclose(D2, D3.flatten()))

tensor([ 7., 10.])
tensor([ 5., 11.])
tensor([[ 5.],
[11.]])
False
True

torch.allclose(A, B)는 두 개의 텐서간의 값이 tolerance를 기준으로 같은 지를 점검하여 돌려준다.

torch.matmul을 줄인 torch.mm이 있는데, torch.mm은 2차원간의 행렬곱에서만 쓰인다.

Tensor Operation

코드 1)

A = torch.stack((A, A, A))
B = torch.stack((B, B, B))

print('dimension of A=', A.shape)
print('dimension of B=', B.shape)

F1 = A.matmul(B)
F2 = A.bmm(B)

print('F1=', F1)
print('F2=', F2)

dimension of A= torch.Size([3, 2, 2])
dimension of B= torch.Size([3, 2, 2])
F1= tensor([[[ 1., 2.],
[-3., -4.]],

    [[ 1.,  2.],
     [-3., -4.]],

    [[ 1.,  2.],
     [-3., -4.]]])

F2= tensor([[[ 1., 2.],
[-3., -4.]],

    [[ 1.,  2.],
     [-3., -4.]],

    [[ 1.,  2.],
     [-3., -4.]]])
     

bmm은 3차원 배치에서만 가능

Tensor의 Norm, 전치, 행렬식, 역행렬의 연산

from torch import linalg as LA

A = torch.tensor([[2,3], [4,7]], dtype=torch.float)

print('A=', A)
print('norm of A=', LA.norm(A))
print('transpose of A=', A.T)
print('determinant of A=', LA.det(A))
print('inverse of A=', LA.inv(A))

A= tensor([[2., 3.],
[4., 7.]])
norm of A= tensor(8.8318)
transpose of A= tensor([[2., 4.],
[3., 7.]])
determinant of A= tensor(2.0000)
inverse of A= tensor([[ 3.5000, -1.5000],
[-2.0000, 1.0000]])

torch.linalg는 선형대수에 관련된 함수들을 제공해준다. LA.norm()은 텐서의 노름값을 반환한다. 벡터로 봤을때 유클리디안 거리이다. LA.det()은 행렬식을 구하여 반환한다. .T는 전치행렬이고, .inv는 역행렬이다.

선형 방정식의 해 구하기

import torch
from torch import linalg as LA

A = torch.tensor([[1,4,1], [1,6,-1], [2,-1,2]], dtype=torch.float)
b = torch.tensor([7,13,5], dtype=torch.float)

print('check the determinant:', LA.det(A))
print('rank of A:', LA.matrix_rank(A))

x1 = LA.inv(A) @ b
x2 = LA.solve(A, b)

print('x1=', x1)
print('x2=', x2)

rank는 해의 개수

0개의 댓글