2021-09-15 목차 작성
2021-09-18 글씨크기 수정
개요
개요
부스트캠프 ai Tech2기를 한지 벌써 3주차가 되고 있습니다. 예전에는, 저와 팀원(캠퍼)분들 모두 따끈따끈
한 ai뉴비들이었습니다.
한주, 한주 지나가면서 팀원분들의 질문 수준도 점점 올라가면서 서로서로 답변해주기 점점 어려워지고 있습니다..;;
오늘 , 그 질문들 중 최고봉의 질문이 나왔다고 생각합니다.
PyTorch.gather 함수는 무엇인가??????
gather함수를 쓰다보면 텐서의 차원개념이 햇갈립니다.
차원이 1 인 텐서(dim=0)는 쉽습니다 .
차원이 2인 텐서(dim=1)까지도 할만합니다.
차원이 3인 텐서(dim=2)부터 인간의 이해범위를 넘어가는거 같습니다.
차원이 4라면 ???
차원이 4인 텐서를 시각화하기 정말 힘듭니다.그 이상은 더 힘들겟죠.. ㅠㅠ
우주공간의 11차원 ,26차원 도 그릴건가요?
못그려요.. ㅡㅡ
그러면?
수식으로 표현해야죠!!!!!
Torch.gather
저는 gather함수를 수학적으로 이해해야한다고 생각합니다.
input output
수학적으로 이해하기 위해선 우선 torch.gather 함수의 paramter들이 무엇이 있는지 알아야합니다.
input:
input으로 받는 텐서에요.
dim:
어떤 axis를 변동을 줄지 정해주는거에요(아래에서 더 자세히 설명할게요)
index:
output의 shape를 지정하고 , 어떻게 치환해줄지 정해주는거에요(아래에서 더 자세히 설명할게요)
return값:
out
how to calculate gather
어떻게 수학적으로 보는지 실습을 통해 알아보도록 하겠습니다.
ex)
import torch
A = torch.Tensor([[1, 2],
[3, 4]])
Q1: A의 대각성분을 shape이 (,2)인 tensor로 만들어보세요.
A의대각성분을 수식적으로 표현해볼까요?
A[0][0],A[1][1] 를 떠올리셧다면 반은 성공한겁니다.
이를 일반식으로 적으면 A[i][i] 일 겁니다. (0<=i<=1)
gather가 해줘야할일은 shape(1,2) 인 텐서에 A[i][i]를 대입해주는 겁니다.
(왜 shape(1,2)에 대입을 해줘야하는지는 추후 나옵니다.)
indexing방식으로 표현하자면,
A[0][0] -> out[0][0] ,A[1][1] -> out[0][1]
대입해주는 거겟죠?
여기서 변하는 부분은 눈치채셧겠지만, 색깔로 칠한 부분이겟죠?ㅎㅎ
따라서, dim parameter 값으로 0를 사용합니다.
색깔을 칠한 부분을 보면 A의 indexing 값과 out의 indexing값은 다릅니다.
따라서, 어떻게 다른지 지정을 해줘야합니다.
그 역할을 하는것이 index입니다.
ex) index[0][1] = 1이고 , dim=0 이면 out의[0][1] 자리에 A[1][1] 값을 넣는것입니다.
식으로 표현하면 , out[0][1]=A[index[0][1]][1] 이 되는 거겟죠.
index에는 torch.tensor.arange(2).reshape(1,2) 가 들어가야합니다.
주의할점은 index와 A의 차원이 같아야합니다.
따라서, output의 원소의 수는 같지만, 차원은 A와 같은 차원이 되도록 처리해준것입니다.
결과적으로
Ans.
import torch
A = torch.Tensor([[1, 2],
[3, 4]])
# torch.gather 함수를 써서 해보세요!
output=torch.gather(A,0,torch.arange(2).reshape(1,2))
# output=A
output=output.reshape(2)
print(output.shape)
# 아래 코드는 수정하실 필요가 없습니다!
if torch.all(output == torch.Tensor([1, 4])):
print("🎉🎉🎉 성공!!! 🎉🎉🎉")
else:
print("🦆 다시 도전해봐요!")
이러한 코드를 적으시면 됩니다.
2차원 텐서에 대하여 적용하는것은 쉬었나요?
2차원 텐서에 대하여 적용할 때는, 위 코드가 아니더라도 시행착오를 통해 같은 결과를 도출해 낼 수 있습니다.
그럼, 좀 더 매운 문제를 내보도록 하겠습니다.
Q2.
[[[1 2]
[3 4]]
[[5 6] [[1 4]
[7 8]]] 3차원 텐서에서 대각선 요소만 가져와서 [5 8]] 이라는 2차원 텐서를 만들고 싶어요!
Ans???
시각화 NO NO NO!!!
아까 했던 로직을 그대로 적용해봅시다.
input 의대각성분을 수식적으로 표현해볼까요?
A[0][0][0],A[0][1][1],A[1][0][0],A[1][1][1] 로 다들 나오셧을거에요.
이를 일반식으로 작성하면 , A[k][i][i] 에요 (0<=k<=1 , 0<=i<=1)
output의 shape은 (2,2)를 원하고 있네요 .
하지만, dimension(차원) 을 맞춰줘야 하니까 , (1,2,2) ,(2,1,2),(2,2,1)이 index의 shape으로 가능하겟죠.
저는 이번엔 한번 (1,2,2)shape으로 해보겠습니다.
A[k][i][i] -> out[0][k][i] 가 되어야 겟죠
하지만, 이렇게하면 ,axis를 0,1 둘다 바꿔야해서 안되죠
따라서, (2,1,2) shape으로 해보겠습니다.
(k,i,i)->(k,0,i) 가 됩니다.
axis= 1를 바꿔주면서 하면 되겟죠
index=torch.arange(2).expand(2,2).reshape(2,1,2)로 하면 되겟죠
ANS
import torch
A = torch.Tensor([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]])
# torch.gather 함수를 써서 해보세요!
index=torch.arange(2).expand(2,2).reshape(2,1,2)
output = torch.gather(A,1,index).view(2,2)
# print(A[1][0][0])
# output=A
print(output)
# 아래 코드는 수정하실 필요가 없습니다!
if torch.all(output == torch.Tensor([[1, 4], [5, 8]])):
print("🎉🎉🎉 성공!!! 🎉🎉🎉")
else:
print("🦆 다시 도전해봐요!")
가 됩니다.
BONUS
저희는 지금까지 정해진 크기의 입력에서 대각선 요소를 가져왔는데
임의의 크기의 3D 텐서에서도 마찬가지로 대각선 요소를 가져와서 2D 텐서를 만들 수 있을까요?
ANS
#TODO BY YOURSELF
#정답은 8월20일날 올리겠습니다.
#보는것보다 직접해보는것이 도움이됩니다. 힌트는 다 드렸습니다.
※아직 작성중..ㅡㅡ
'딥러닝 > Pytorch' 카테고리의 다른 글
HuggingFace:나만의 Transformer 모델 만들기 (0) | 2021.10.02 |
---|---|
Pytorch:hooking,nn.Module,autograd에 대한 고찰 (0) | 2021.09.03 |
Pytorch: Torchviz (0) | 2021.08.31 |
파이토치의 데이터셋:Dataset,DataLoader,Transforms (0) | 2021.08.20 |