https://github.com/pytorch/vision/issues/720
Q1
Q1. nn.Sequential( ) 안에서 tensor의 shape(size)을 바꿀 수 있는가?
A. 따로 Class를 정의하여 사용해야 된다. ex) View(shape)를 사용한다.
해당 코드는 Input Tensor를 내가 원하는 형태의 ouput Tensor의 형태로 바꿔주는 역할을 한다.
다만, 이때 parameter 값으로 "(내가 변형하고자 하는 shape)"가 들어가야 한다.
class View(nn.Module):
def __init__(self, shape):
super(View, self).__init__()
self.shape = shape,
def forward(self, x):
return x.view(*self.shape)
self.shape = shape, 처럼 뒤에 ,가 꼭 들어가야 한다.
https://github.com/pytorch/vision/issues/720
그 이유는 self.shape = shape로 할 경우에, 1D Tensor로 바꿀 때에 문제가 생긴다.
shape가 (218 * 178 * 3)와 같이 integer로 나올 경우 x.view( )안의 인자로 integer가 들어가는 문제가 생길 수 있다.
따라서, tuple과 simple integer를 동시에 처리할 수 있도록 shape, 로 받아 simple integer도 하여금 tuple로 처리되도록 설정한다.
Q2
Q2. shape,를 사용하면 리스트나 다른 iterable한 객체에 대해 해당 객체를 tuple의 첫 원소로 하는 새로운 tuple이 생성되기에 문제가 되지 않나?
A. 맞다. shape, 를 사용하면 주의할 점이 몇 가지 있다.
shape가 이미 튜플이거나 리스트와 같은 다른 iterable한 객체일 때도, 해당 객체를 튜플의 첫 번째 요소로 갖는 새 튜플을 생성하게 된다.
shape가 이미 튜플이나 리스트와 같은 iterable 객체일 경우에 shape,는 shape를 단일 요소로 가지는 튜플을 만든다.
즉, 원래 shape가 (218, 178, 3)이었다면, (shape,)는 ((218, 178, 3),)가 된다.
따라서, 이 기법을 사용할 때는 shape의 타입이 정확히 정수(int)일 때만 적용해야 한다는 것을 명심해야 한다. 만약 shape가 이미 튜플이나 다른 iterable한 객체일 경우에는 shape를 그대로 사용하거나, 혹은 다른 로직을 통해 적절히 처리해주어야 한다.
따라서, 명확하게 shape가 정수 값일 때만 이 기법을 적용하고 싶다면, shape의 타입을 체크하는 추가적인 로직을 넣는 것이 좋다.
class View(nn.Module):
def __init__(self, shape):
super(View, self).__init__()
# shape가 정수일 경우에만 튜플로 변환
self.shape = (shape,) if isinstance(shape, int) else shape
def forward(self, x):
return x.view(*self.shape)