AttributeError: ‘NoneType’ object has no attribute ‘data’

17771 단어 Pytorch

참고 자료

  • issue
  • pytorch: grad is None while training
  • pytorch 동결부분 파라미터 훈련 다른 부분
  • 문제 설명


    다른 사람의 모형을 자신의 모형으로 바꾸어 훈련 과정에서 오류가 발생했다param.grad.data.clamp_(-grad_clip, grad_clip) AttributeError: 'NoneType' object has no attribute 'data'

    해결 방법


    인터넷에 접속하여 이 문제를 조회하면 대부분 모델에서 정의된 어느 층이 전방향 전파에 참여하지 않았기 때문에 역방향 전파를 계산할 때grad is None.주로 계산에 참여하지 않은 층을 찾아서 주석을 달아야 한다.
    이 문제는 시종 쓸데없는 층이 없다고 느꼈기 때문에 나를 매우 오랫동안 괴롭혔다.
    다음 코드는 AttentionResNet 모델을 정의합니다.나중에야 원흉이 self.encoder인 것을 발견했기 때문에 앞에서 이를 눈치채지 못한 것은 뒤에 있는 층의 정의가 self.encoder 중의 어느 층이나 몇 개의 층을 조합하기 때문이다.
    class AttentionResNet(nn.Module):
        
        def __init__(self, in_channels=3, out_channels=1, num_filters=32, encoder_depth=34, pretrained=True):
            super(AttentionResNet, self).__init__()
            self.in_channels  = in_channels
            self.out_channels = out_channels 
            self.num_filters = num_filters
             
            if encoder_depth == 34:
                self.encoder = torchvision.models.resnet34(pretrained=pretrained)
                bottom_channel_nr = 512
            elif encoder_depth == 101:
                self.encoder = torchvision.models.resnet101(pretrained=pretrained)
                bottom_channel_nr = 2048
            elif encoder_depth == 152:
                self.encoder = torchvision.models.resnet152(pretrained=pretrained)
                bottom_channel_nr = 2048
            else:
                raise NotImplementedError('only 34, 101, 152 version of Resnet are implemented')
    
            #attention module
            self.pool  = nn.MaxPool2d(2, 2)
            self.relu  = nn.ReLU(inplace=True)
            self.conv1 = nn.Sequential(self.encoder.conv1, self.encoder.bn1, self.encoder.relu, self.pool)
            self.conv2 = self.encoder.layer1
            self.conv3 = self.encoder.layer2
            self.conv4 = self.encoder.layer3
            self.conv5 = self.encoder.layer4  
    
            self.center = DecoderBlockV2(bottom_channel_nr,                        num_filters * 8 * 2, num_filters * 8)
            self.dec5   = DecoderBlockV2(bottom_channel_nr + num_filters * 8,      num_filters * 8 * 2, num_filters * 8)
            self.dec4   = DecoderBlockV2(bottom_channel_nr // 2 + num_filters * 8, num_filters * 8 * 2, num_filters * 8)
            self.dec3   = DecoderBlockV2(bottom_channel_nr // 4 + num_filters * 8, num_filters * 4 * 2, num_filters * 2)
            self.dec2   = DecoderBlockV2(bottom_channel_nr // 8 + num_filters * 2, num_filters * 2 * 2, num_filters * 2 * 2)
            self.dec1   = DecoderBlockV2(num_filters * 2 * 2,                      num_filters * 2 * 2, num_filters)
            
            self.attention_map = nn.Sequential(
                ConvRelu(num_filters, num_filters),
                nn.Conv2d(num_filters, 1, kernel_size=1)  
            )  
    
    
    
        def forward(self, x):        
    
            #attention module
            conv1 = self.conv1(x)
            conv2 = self.conv2(conv1)
            conv3 = self.conv3(conv2)
            conv4 = self.conv4(conv3)
            conv5 = self.conv5(conv4)
            
            pool = self.pool(conv5)
            center = self.center( pool )  
            dec5 = self.dec5(torch.cat([center, conv5], 1))        
            dec4 = self.dec4(torch.cat([dec5, conv4], 1))
            dec3 = self.dec3(torch.cat([dec4, conv3], 1))
            dec2 = self.dec2(torch.cat([dec3, conv2], 1))
            dec1 = self.dec1(dec2)           
            
            #attention map
            x = self.attention_map( dec1 ) 
            return x
    
    

    잘못된 위치를 찾았는데 어떻게 수정합니까?자료 3 참조, 우선self.코드의 매개 변수 requires_grad 는false로 설정하고 최적화기에 필터를 넣고 requires_grad = True 의 매개 변수만 업데이트합니다.
    for param in net.encoder.parameters():
        param.requires_grad = False
    
    optimizer = optim.SGD(filter(lambda p: p.requires_grad, net.parameters()), lr=opt.lr, momentum=0.9, weight_decay=5e-4)
    

    이틀 동안 찾다가 마침내 잘못된 위치를 찾았으니 너무 어렵다.

    좋은 웹페이지 즐겨찾기