Deep learning 定制pytorch DenseNet模型上的渐变凸轮
我使用以下代码在PyTorch中实现了自己的DenseNet:Deep learning 定制pytorch DenseNet模型上的渐变凸轮,deep-learning,computer-vision,pytorch,conv-neural-network,Deep Learning,Computer Vision,Pytorch,Conv Neural Network,我使用以下代码在PyTorch中实现了自己的DenseNet: class Dense_Block(nn.Module): def __init__(self, in_channels): super(Dense_Block, self).__init__() self.bn = nn.BatchNorm2d(num_features = in_channels) self.relu = nn.ReLU(inplace = True)
class Dense_Block(nn.Module):
def __init__(self, in_channels):
super(Dense_Block, self).__init__()
self.bn = nn.BatchNorm2d(num_features = in_channels)
self.relu = nn.ReLU(inplace = True)
self.conv1 = nn.Conv2d(in_channels = in_channels, out_channels = 32, kernel_size = 3, stride = 1, padding = 1)
self.conv2 = nn.Conv2d(in_channels = 32, out_channels = 32, kernel_size = 3, stride = 1, padding = 1)
self.conv3 = nn.Conv2d(in_channels = 64, out_channels = 32, kernel_size = 3, stride = 1, padding = 1)
self.conv4 = nn.Conv2d(in_channels = 96, out_channels = 32, kernel_size = 3, stride = 1, padding = 1)
self.conv5 = nn.Conv2d(in_channels = 128, out_channels = 32, kernel_size = 3, stride = 1, padding = 1)
def forward(self, x):
bn = self.bn(x)
conv1 = self.relu(self.conv1(bn))
conv2 = self.relu(self.conv2(conv1))
c2_dense = self.relu(torch.cat([conv1, conv2], 1))
conv3 = self.relu(self.conv3(c2_dense))
c3_dense = self.relu(torch.cat([conv1, conv2, conv3], 1))
conv4 = self.relu(self.conv4(c3_dense))
c4_dense = self.relu(torch.cat([conv1, conv2, conv3, conv4], 1))
conv5 = self.relu(self.conv5(c4_dense))
c5_dense = self.relu(torch.cat([conv1, conv2, conv3, conv4, conv5], 1))
return c5_dense
class Transition_Layer(nn.Module):
def __init__(self, in_channels, out_channels):
super(Transition_Layer, self).__init__()
self.relu = nn.ReLU(inplace = True)
self.bn = nn.BatchNorm2d(num_features = out_channels)
self.conv = nn.Conv2d(in_channels = in_channels, out_channels = out_channels, kernel_size = 1, bias = False)
self.avg_pool = nn.AvgPool2d(kernel_size = 2, stride = 2, padding = 0)
def forward(self, x):
bn = self.bn(self.relu(self.conv(x)))
out = self.avg_pool(bn)
return out
class DenseNet(nn.Module):
def __init__(self, nr_classes):
super(DenseNet, self).__init__()
self.lowconv = nn.Conv2d(in_channels = 3, out_channels = 64, kernel_size = 7, padding = 3, bias = False)
self.relu = nn.ReLU()
# Make Dense Blocks
self.denseblock1 = self._make_dense_block(Dense_Block, 64)
self.denseblock2 = self._make_dense_block(Dense_Block, 128)
self.denseblock3 = self._make_dense_block(Dense_Block, 128)
# Make transition Layers
self.transitionLayer1 = self._make_transition_layer(Transition_Layer, in_channels = 160, out_channels = 128)
self.transitionLayer2 = self._make_transition_layer(Transition_Layer, in_channels = 160, out_channels = 128)
self.transitionLayer3 = self._make_transition_layer(Transition_Layer, in_channels = 160, out_channels = 64)
# Classifier
self.bn = nn.BatchNorm2d(num_features = 64)
self.classifier = nn.Linear(64, nr_classes)
def _make_dense_block(self, block, in_channels):
layers = []
layers.append(block(in_channels))
return nn.Sequential(*layers)
def _make_transition_layer(self, layer, in_channels, out_channels):
modules = []
modules.append(layer(in_channels, out_channels))
return nn.Sequential(*modules)
def forward(self, x):
out = self.relu(self.lowconv(x))
out = self.denseblock1(out)
out = self.transitionLayer1(out)
out = self.denseblock2(out)
out = self.transitionLayer2(out)
out = self.denseblock3(out)
out = self.transitionLayer3(out)
out = self.bn(out)
out = self.relu(out)
out = nn.functional.adaptive_avg_pool2d(out, (1, 1))
out = torch.flatten(out, 1)
out = self.classifier(out)
return out
我想实施Grad CAM,这是我的方法:
class Dense(nn.Module):
def __init__(self, load_path):
super(Dense, self).__init__()
self.ckpt = t.load(load_path)
self.dense = DenseNet(5)
self.dense.load_state_dict(self.ckpt['state_dict'])
# disect the network to access its last convolutional layer
self.features_conv = self.dense.transitionLayer3[0].conv
# get the max pool of the features stem
self.avg_pool = nn.AvgPool2d(kernel_size=2, stride=2, padding=0)
# Classifier
self.bn = nn.BatchNorm2d(num_features = 64)
self.classifier = nn.Linear(64, 5)
# placeholder for the gradients
self.gradients = None
# hook for the gradients of the activations
def activations_hook(self, grad):
self.gradients = grad
def forward(self, x):
x = self.features_conv(x)
# register the hook
h = x.register_hook(self.activations_hook)
# apply the remaining pooling
x = self.avg_pool(x)
x = self.bn(x)
x = self.relu(x)
x = nn.functional.adaptive_avg_pool2d(x, (1, 1))
x = torch.flatten(x, 1)
x = self.classifier(x)
return x
# method for the gradient extraction
def get_activations_gradient(self):
return self.gradients
# method for the activation exctraction
def get_activations(self, x):
return self.features_conv(x)
然而,我收到了这个错误
给定组=1,大小权重[64,160,1,1],预期输入[8,3,64,64]有160个通道,但得到了3个通道
我以为我理解了逻辑,但似乎有些东西不符合逻辑。我已经检查过了,但这无助于解决我的问题
我知道这可以通过预先培训的网络来实现,但我必须使用自己的网络。如果您有任何其他注意事项(如网络架构),请让我知道,以便我可以改进
多谢各位