Что означает код (python,pytorch)
что означает код:
for in_channel, out_channel, stride, num_block in [
[ 64, 64, 1, 2],
[ 64, 128, 2, 2],
[ 128, 256, 2, 2],
[ 256, 512, 2, 2],
]:
self.encode.append(
nn.Sequential(
Basic( in_channel, out_channel, stride=stride, ),
*[ Basic(out_channel, out_channel, stride=1, ) for i in range(1, num_block) ]
)
)
Мне не очень понятно, почему"*" используется? Почему нет звездочки перед первым упоминанием класса Basic
Зачем используется "for i in range(1, num_block)" ?
Тут я вижу класс в классе (класс Basic внутри класса net) Означает ли это, что методы класса Basic не используются?
Я думала, что "out_channel" должно быть равно "in_channel" в следующем слое. Если знак звездочка означает "И", то какое значение у "out_channel" во "втором" классе Basic
Полный код:
class Basic(nn.Module):
def __init__(self, in_channel, out_channel, stride=1, is_shortcut=False):
super(Basic, self).__init__()
self.conv1 = nn.Conv2d( in_channel, out_channel, kernel_size=3, stride=stride, padding=1, bias=False)
self.bn1 = BatchNorm2d(out_channel)
self.conv2 = nn.Conv2d(out_channel, out_channel, kernel_size=3, stride=1, padding=1, bias=False)
self.bn2 = BatchNorm2d(out_channel)
self.is_shortcut = in_channel != out_channel or stride!=1
if self.is_shortcut:
self.shortcut = nn.Sequential(
nn.Conv2d(in_channel, out_channel, kernel_size=1, padding=0, stride=stride, bias=False),
BatchNorm2d(out_channel)
)
def forward(self, x):
if self.is_shortcut:
shortcut = self.shortcut(x)
else:
shortcut = x
x = self.bn1(self.conv1(x))
x = F.relu(x,inplace=True)
x = self.bn2(self.conv2(x)) + shortcut
x = F.relu(x,inplace=True)
return x
class Net(nn.Module):
def __init__(self, in_channel=3, num_class=4):
super(Net, self).__init__()
self.encode = nn.ModuleList([
nn.Sequential(
nn.Conv2d(in_channel, 64, kernel_size=7, stride=2, padding=3, bias=False),
BatchNorm2d(64),
nn.ReLU(inplace=True),
#nn.MaxPool2d(kernel_size=3,stride=2,padding=1)
)
])
for in_channel, out_channel, stride, num_block in [
[ 64, 64, 1, 2],
[ 64, 128, 2, 2],
[ 128, 256, 2, 2],
[ 256, 512, 2, 2],
]:
self.encode.append(
nn.Sequential(
Basic( in_channel, out_channel, stride=stride, ),
*[ Basic(out_channel, out_channel, stride=1, ) for i in range(1, num_block) ]
)
)
self.decode = nn.ModuleList([
Decode( 512+256, 256),
Decode( 256+128, 128),
Decode( 128+ 64, 64),
Decode( 64+ 64, 32),
Decode( 32+ 0, 16),
])
self.logit = nn.Conv2d(16, num_class, kernel_size=1)
def forward(self, x):
batch_size,C,H,W = x.shape
x = self.encode[0](x) ; e0=x #; print('encode[0] :', x.shape)
x = F.max_pool2d(x, kernel_size=3,stride=2,padding=1)
x = self.encode[1](x) ; e1=x #; print('encode[1] :', x.shape)
x = self.encode[2](x) ; e2=x #; print('encode[2] :', x.shape)
x = self.encode[3](x) ; e3=x #; print('encode[3] :', x.shape)
x = self.encode[4](x) ; e4=x #; print('encode[4] :', x.shape)
#exit(0)
x = self.decode[0](x,e3) #; print('decode[0] :', x.shape)
x = self.decode[1](x,e2) #; print('decode[1] :', x.shape)
x = self.decode[2](x,e1) #; print('decode[2] :', x.shape)
x = self.decode[3](x,e0) #; print('decode[3] :', x.shape)
x = self.decode[4](x) #; print('decode[3] :', x.shape)
#x = F.dropout(x, 0.5, training=self.training)
logit = self.logit(x)
return logit
net = Net().cuda()
net.load_state_dict(torch.load(CHECKPOINT_FILE, map_location=lambda storage, loc: storage))
net.eval()
with torch.no_grad():
logit = net(input)
probability= torch.sigmoid(logit)
print('input: ',input.shape)
print('logit: ',logit.shape)
print('')
Ответы (1 шт):
этот код создает список параметров в виде list
[ Basic(out_channel, out_channel, stride=1, ) for i in range(1, num_block) ]
это является единичным параметром
Basic( in_channel, out_channel, stride=stride, )
преобразует в последовательность единичных параметров
*[ Basic(out_channel, out_channel, stride=1, ) for i in range(1, num_block) ]
тоесть Вы получаете на выходе обычный список параметров
Basic( in_channel, out_channel, stride=stride, ), Basic(out_channel, out_channel, stride=1, ), Basic(out_channel, out_channel, stride=1, ), Basic(out_channel, out_channel, stride=1, ), Basic(out_channel, out_channel, stride=1, )... и так далее
может быть этот пример поможет Вам понять что делает звездочка. попробуйте запустить:
print([a for a in range(10)], sep='\n')
print(*[a for a in range(10)], sep='\n')
print([1, 2, 3, 4, 5, 6, 7, 8, 9], sep='\n')
print(*[1, 2, 3, 4, 5, 6, 7, 8, 9], sep='\n')
print(1, 2, 3, 4, 5, 6, 7, 8, 9, sep='\n')