Hello,
I am trying to convert the 2d R2AttentionUNET to 3D architeecture.The code is below.The error is given below .I think I need to change padding size also as I just changed the Con2d to conv3d and batch2d to batch3d.But I don’t have much idea. Can anybody see the code and reply?
RuntimeError: Calculated padded input size per channel: (2 x 2 x 2). Kernel size: (3 x 3 x 3). Kernel size can’t be greater than actual input size.
import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.nn import init
from torchsummary import summary
def init_weights(net, init_type=‘normal’, gain=0.02):
def init_func(m):
classname = m.class.name
if hasattr(m, ‘weight’) and (classname.find(‘Conv’) != -1 or classname.find(‘Linear’) != -1):
if init_type == ‘normal’:
init.normal_(m.weight.data, 0.0, gain)
elif init_type == ‘xavier’:
init.xavier_normal_(m.weight.data, gain=gain)
elif init_type == ‘kaiming’:
init.kaiming_normal_(m.weight.data, a=0, mode=‘fan_in’)
elif init_type == ‘orthogonal’:
init.orthogonal_(m.weight.data, gain=gain)
else:
raise NotImplementedError(‘initialization method [%s] is not implemented’ % init_type)
if hasattr(m, ‘bias’) and m.bias is not None:
init.constant_(m.bias.data, 0.0)
elif classname.find(‘BatchNorm3d’) != -1:
init.normal_(m.weight.data, 1.0, gain)
init.constant_(m.bias.data, 0.0)
print('initialize network with %s' % init_type)
net.apply(init_func)
class conv_block(nn.Module):
def init(self, ch_in, ch_out):
super(conv_block, self).init()
self.conv = nn.Sequential(
nn.Conv3d(ch_in, ch_out, kernel_size=3, stride=1, padding=1, bias=True),
nn.BatchNorm3d(ch_out),
nn.ReLU(inplace=True),
nn.Conv3d(ch_out, ch_out,kernel_size=3, stride=1, padding=1, bias=True),
nn.BatchNorm3d(ch_out),
nn.ReLU(inplace=True)
)
def forward(self, x):
x = self.conv(x)
return x
class up_conv(nn.Module):
def init(self, ch_in, ch_out):
super(up_conv, self).init()
self.up = nn.Sequential(
nn.Upsample(scale_factor=2),
nn.Conv3d(ch_in, ch_out, kernel_size=3, stride=1, padding=1, bias=True),
nn.BatchNorm3d(ch_out),
nn.ReLU(inplace=True)
)
def forward(self, x):
x = self.up(x)
return x
class Recurrent_block(nn.Module):
def init(self, ch_out, t=2):
super(Recurrent_block, self).init()
self.t = t
self.ch_out = ch_out
self.conv = nn.Sequential(
nn.Conv3d(ch_out, ch_out, kernel_size=3, stride=1, padding=1, bias=True),
nn.BatchNorm3d(ch_out),
nn.ReLU(inplace=True)
)
def forward(self, x):
for i in range(self.t):
if i == 0:
x1 = self.conv(x)
x1 = self.conv(x + x1)
return x1
class RRCNN_block(nn.Module):
def init(self, ch_in, ch_out, t=2):
super(RRCNN_block, self).init()
self.RCNN = nn.Sequential(
Recurrent_block(ch_out, t=t),
Recurrent_block(ch_out, t=t)
)
self.Conv_1x1 = nn.Conv3d(ch_in, ch_out, kernel_size=3, stride=1)
def forward(self, x):
x = self.Conv_1x1(x)
x1 = self.RCNN(x)
return x + x1
class single_conv(nn.Module):
def init(self, ch_in, ch_out):
super(single_conv, self).init()
self.conv = nn.Sequential(
nn.Conv3d(ch_in, ch_out, kernel_size=3, stride=1, padding=1, bias=True),
nn.BatchNorm3d(ch_out),
nn.ReLU(inplace=True)
)
def forward(self, x):
x = self.conv(x)
return x
class Attention_block(nn.Module):
def init(self, F_g, F_l, F_int):
super(Attention_block, self).init()
self.W_g = nn.Sequential(
nn.Conv3d(F_g, F_int, kernel_size=3, stride=1, padding=0, bias=True),
nn.BatchNorm3d(F_int)
)
self.W_x = nn.Sequential(
nn.Conv3d(F_l, F_int, kernel_size=3, stride=1, padding=0, bias=True),
nn.BatchNorm3d(F_int)
)
self.psi = nn.Sequential(
nn.Conv3d(F_int, 1, kernel_size=3, stride=1, padding=0, bias=True),
nn.BatchNorm3d(1),
nn.Sigmoid()
)
self.relu = nn.ReLU(inplace=True)
def forward(self, g, x):
g1 = self.W_g(g)
# print(g1.shape)
x1 = self.W_x(x)
# print(x1.shape)
psi = self.relu(g1 + x1)
# print(psi.shape)
psi = self.psi(psi)
print(psi.shape)
print(x.shape)
return x * psi
class R2AttU_Net(nn.Module):
def init(self, img_ch=1, output_ch=1, t=2):
super(R2AttU_Net, self).init()
self.Maxpool = nn.MaxPool3d(kernel_size=2, stride=2)
self.Upsample = nn.Upsample(scale_factor=2)
self.RRCNN1 = RRCNN_block(ch_in=img_ch, ch_out=64, t=t)
self.RRCNN2 = RRCNN_block(ch_in=64, ch_out=128, t=t)
self.RRCNN3 = RRCNN_block(ch_in=128, ch_out=256, t=t)
self.RRCNN4 = RRCNN_block(ch_in=256, ch_out=512, t=t)
self.RRCNN5 = RRCNN_block(ch_in=512, ch_out=1024, t=t)
self.Up5 = up_conv(ch_in=1024, ch_out=512)
self.Att5 = Attention_block(F_g=512, F_l=512, F_int=256)
self.Up_RRCNN5 = RRCNN_block(ch_in=1024, ch_out=512, t=t)
self.Up4 = up_conv(ch_in=512, ch_out=256)
self.Att4 = Attention_block(F_g=256, F_l=256, F_int=128)
self.Up_RRCNN4 = RRCNN_block(ch_in=512, ch_out=256, t=t)
self.Up3 = up_conv(ch_in=256, ch_out=128)
self.Att3 = Attention_block(F_g=128, F_l=128, F_int=64)
self.Up_RRCNN3 = RRCNN_block(ch_in=256, ch_out=128, t=t)
self.Up2 = up_conv(ch_in=128, ch_out=64)
self.Att2 = Attention_block(F_g=64, F_l=64, F_int=32)
self.Up_RRCNN2 = RRCNN_block(ch_in=128, ch_out=64, t=t)
self.Conv_1x1 = nn.Conv3d(64, output_ch, kernel_size=1, stride=1, padding=0)
def forward(self, x):
# encoding path
x1 = self.RRCNN1(x)
x2 = self.Maxpool(x1)
x2 = self.RRCNN2(x2)
x3 = self.Maxpool(x2)
x3 = self.RRCNN3(x3)
x4 = self.Maxpool(x3)
x4 = self.RRCNN4(x4)
x5 = self.Maxpool(x4)
x5 = self.RRCNN5(x5)
# decoding + concat path
d5 = self.Up5(x5)
x4 = self.Att5(g=d5, x=x4)
d5 = torch.cat((x4, d5), dim=1)
d5 = self.Up_RRCNN5(d5)
d4 = self.Up4(d5)
x3 = self.Att4(g=d4, x=x3)
d4 = torch.cat((x3, d4), dim=1)
d4 = self.Up_RRCNN4(d4)
d3 = self.Up3(d4)
x2 = self.Att3(g=d3, x=x2)
d3 = torch.cat((x2, d3), dim=1)
d3 = self.Up_RRCNN3(d3)
d2 = self.Up2(d3)
x1 = self.Att2(g=d2, x=x1)
d2 = torch.cat((x1, d2), dim=1)
d2 = self.Up_RRCNN2(d2)
d1 = self.Conv_1x1(d2)
return d1
if name == “main”:
inputs = torch.randn(1, 1, 64, 64, 64)
print("The shape of inputs: ", inputs.shape)
data_folder = “…/processed”
model = R2AttU_Net()
inputs = inputs.cuda()
model.cuda()
x = model(inputs)
print(model)
summary(model, x)