과제를 하며 모르는 점 위주로 정리하자.
torch.tensor() vs torch.Tensor()
- torch.tensor() : function. data를 input으로 받아 Tensor의 객체로 생성
a = torch.tensor([1])
b = torch.tensor(a)
print(a)
>>> tensor([1])
print(b)
>>> tensor([1])
a[0] = 2
print(a)
>>> tensor([2])
print(b)
>>> tensor([1])
→ 알 수 있는 것 : int가 들어가도 그대로 int 유지된다. a를 바꿔도 b는 안 바뀜. deep copy가 이루어짐.
- torch.Tensor() : class. 빈 Tensor 객체를 만들기 위해 사용 가능.
a = torch.Tensor([1])
b = torch.Tensor(a)
print(a)
>>> tensor([1.])
print(b)
>>> tensor([1.])
a[0] = 2
print(a)
>>> tensor([2.])
print(b)
>>> tensor([2.])
→ 알 수 있는 것 : int가 float형으로 바뀐다. a를 바꾸니 b도 바뀐다. 즉, torch.Tensor()의 input으로 Tensor가 들어오니 shallow copy가 이루어졌다.
a = [1]
b = torch.Tensor(a)
print(a)
>>> [1]
print(b)
>>> tensor([1.])
a[0] = 2
print(a)
>>> [2]
print(b)
>>> tensor([1.])
→ 알 수 있는 것 : 역시 int가 float형으로 바뀐다. a를 바꿔도 b는 안 바뀐다. 즉, torch.Tensor()의 input으로 list가 들어오니 deep copy가 이루어졌다.
그래서 정리하면?
torch.tensor
- int 입력 시 int 그대로 입력
- 입력받은 데이터를 새로운 메모리 공간에 복사해 Tensor 객체 생성 (call by value)
torch.Tensor
- int 입력 시 float 변환
- 데이터 입력 시 (Tensor 객체) 입력 받은 메모리 공간을 그대로 사용 (call by reference)
- 데이터 입력 시 (list, numpy) 입력 받은 값을 복사하여 Tensor 객체 생성 (call by value)
torch.gather()
아직 이해 못함.. 이해하고 채워 넣겠다.
torch.nn.Linear() vs torch.nn.LazyLinear()
- torch.nn.Linear : 그냥 일반적인 선형 연산
- torch.nn.LazyLinear : forward call이 있기 전에 weight, bias initialization이 이루어져 있지 않다가, forward call이 있으면 그제서야 initialize하고, nn.Linear()처럼 행동한다.
그 이유에 대해서는 필요할 때만 가중치를 초기화해서 메모리 부담을 적게 하려 함이라고 생각(뇌피셜)했는데, 더 정확한 이유를 알게 되면 그때 더 추가해서 쓰겠다.
Tensor vs Parameter vs Buffer
Tensor
- gradient 계산 ❌
- 값 업데이트 ❌
- 모델 저장시 값 저장 ❌
Parameter
- gradient 계산 🆗
- 값 업데이트 🆗
- 모델 저장시 값 저장 🆗
torch.nn.Parameter()
.register_parameter()
Buffer
- gradient 계산 ❌
- 값 업데이트 ❌
- 모델 저장시 값 저장 🆗
.register_buffer()