TypeError: new() received an invalid combination of arguments - got (float, int, int, int), but expected one of:
* (*, torch.device device)
* (torch.Storage storage)
* (Tensor other)
* (tuple of ints size, *, torch.device device)
* (object data, *, torch.device device)
현재 이미지 인페인팅과 관련된 논문의 코드를 뜯어보며 공부중인데, DeconvResnetBlock을 생성하는 부분에서 위와 같은 오류가 발생했다.
(git link: https://github.com/xcyan/neurips18_hierchical_image_manipulation)
DeconvResnetBlock을 생성하는 전체 클래스 코드는 다음과 같다.
class DeconvResnetBlock(nn.Module):
def __init__(self, in_planes, out_planes, num_layers=1, stride=1, kernel_size=3, norm_fn=None, activation_fn=None):
super(DeconvResnetBlock, self).__init__()
#두 함수가 정의되지 않으면 오류 발생
assert norm_fn
assert activation_fn
###############################
## Build shortcut connection ##
###############################
if out_planes == in_planes and stride == 1:
self.shortcut = None
else:
self.shortcut = []
if in_planes != out_planes:
self.shortcut += [nn.Conv2d(in_planes, out_planes, kernel_size=1),
norm_fn(out_planes)]
if stride > 1:
self.shortcut += [nn.Upsample(scale_factor=stride, mode='bilinear')]
self.shortcut = nn.Sequential(*self.shortcut)
###########################
## Build Deep connection ##
###########################
self.deep = []
if kernel_size % 2 == 1:
self.build_conv2d_block(in_planes, out_planes, num_layers, stride,
kernel_size, norm_fn, activation_fn)
else:
self.build_tconv2d_block(in_planes, out_planes, num_layers, stride,
kernel_size, norm_fn, activation_fn)
self.deep = nn.Sequential(*self.deep)
def build_conv2d_block(self, in_planes, out_planes, num_layers, stride, kernel_size, norm_fn, activation_fn):
if stride > 1:
self.deep.append(nn.Upsample(scale_factor=stride, mode='bilinear'))
padding = int((kernel_size-1)/2)
self.deep += [
activation_fn,
nn.Conv2d(in_planes, out_planes, kernel_size=kernel_size, stride=1, padding=padding), norm_fn(out_planes)]
for i in range(num_layers-1):
self.deep += [
activation_fn,
nn.Conv2d(out_planes, out_planes, kernel_size=kernel_size, stride=1, padding=padding),
norm_fn(out_planes)]
# 전치 합성곱은 업샘플링을 진행한다.
def build_tconv2d_block(self, in_planes, out_planes, num_layers, stride, kernel_size, norm_fn, activation_fn):
if stride == 1:
padding = int(kernel_size/2)
output_padding = stride
self.deep += [
activation_fn,
nn.ConvTranspose2d(in_planes, out_planes, kernel_size=kernel_size, stride=stride,
padding=padding, output_padding=output_padding),
norm_fn(out_planes)]
else:
padding = int((kernel_size-1)/2)
output_padding = stride - 2
self.deep += [
activation_fn,
nn.ConvTranspose2d(in_planes, out_planes, kernel_size=kernel_size, stride=stride,
padding=padding, output_padding=output_padding),
norm_fn(out_planes)]
#
for i in range(num_layers-1):
padding = int(kernel_size/2)
self.deep += [
activation_fn,
nn.ConvTranspose2d(out_planes, out_planes, kernel_size=kernel_size, stride=1, padding=padding, output_padding=1),
norm_fn(out_planes)]
def forward(self, x):
residual = x
out = self.deep(x)
if self.shortcut is not None:
residual = self.shortcut(residual)
out = out + residual
return out
이 클래스를 바탕으로 get_conv_decoder라는 함수를 이용하여 convolution 기반 디코더를 생성한다. 여기서 오류가 발생했다.
def get_conv_decoder(output_nc, skip_layers=None):
input_dim = 256
output_dim = 128
num_layers = 3
dim_list = [64, 96, 128, 256, 512]
activation_fn = nn.ReLU(True)
norm_fn=functools.partial(nn.BatchNorm2d, affine=True)
layers=[]
for i in range(num_layers + 1):
input_dim=output_dim
if i < 3:
output_dim = dim_list[num_layers - 1 - i]
else:
output_dim = input_dim / 2
DRBlock = DeconvResnetBlock(in_planes=input_dim, out_planes=output_dim, num_layers=1, stride=2,
kernel_size=4, norm_fn=norm_fn, activation_fn=activation_fn)
layers.append(DRBlock)
layers.append(nn.Conv2d(output_dim, output_nc, kernel_size=3, padding=1, stride=1))
return nn.Sequential(*layers)
며칠동안 구글링하며 디버깅해본 결과, 모델 생성시 입출력 차원에 대한 인수 type이 맞지 않아 위와 같은 오류가 발생한 것이었다.
for i in range(num_layers + 1):
input_dim=output_dim
if i < 3:
output_dim = dim_list[num_layers - 1 - i]
else:
#output_dim = input_dim / 2 # type: float
output_dim = int(input_dim / 2) # type: int
input_dim / 2의 결과값을 int로 형변환 하여 해결했다.
나중에 ChatGPT한테 물어보니 한 방에 해결 되더라...
깨달은 바:
1. type error를 조심할 것.
2. ChatGPT를 잘 활용하자.
'전공 공부 > 파이썬 기초' 카테고리의 다른 글
make_dataset 함수 (1) | 2023.10.02 |
---|---|
하위 디렉토리를 모두 순회하는 os.walk() (0) | 2023.10.02 |
Pycharm에 arguments 넣는 법 (0) | 2023.09.19 |
변수의 구분 (0) | 2023.09.13 |
클래스 (0) | 2023.09.13 |