# Fine tuning resnet: 'DataParallel' object has no attribute 'fc'

**URL:** <https://discuss.pytorch.org/t/fine-tuning-resnet-dataparallel-object-has-no-attribute-fc/14842>\
**Category:** vision\
**Created:** [March 13, 2018, 7:27am UTC](https://discuss.pytorch.org/t/fine-tuning-resnet-dataparallel-object-has-no-attribute-fc/14842 "2018-03-13T07:27:21Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![yang\_yang1](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/y/dbc845/32.png) [@yang\_yang1](https://discuss.pytorch.org/u/yang_yang1)\
**Post date:** [March 13, 2018, 7:27am UTC](https://discuss.pytorch.org/t/fine-tuning-resnet-dataparallel-object-has-no-attribute-fc/14842/1 "2018-03-13T07:27:21Z")

</div>

When I tried to fine tuning my resnet module, and run the following code:

ignored\_params = list(map(id, model.fc.parameters()))  
base\_params = filter(lambda p: id§ not in ignored\_params,  
model.parameters())

optimizer = optim.Adam([  
{‘params’: base\_params},  
{‘params’: model.fc.parameters(), ‘lr’: opt.lr}  
], lr=opt.lr\*0.1, momentum=0.9)

it raise a error:  
AttributeError Traceback (most recent call last)  
 in ()  
----\> 1 ignored\_params = list(map(id, model.module.fc.parameters()))  
2 base\_params = filter(lambda p: id§ not in ignored\_params,  
3 model.parameters())  
4  
5 optimizer = optim.Adam([

/usr/local/lib/python3.6/dist-packages/torch/nn/modules/module.py in **getattr** (self, name)  
364 return modules[name]  
365 raise AttributeError("’{}’ object has no attribute ‘{}’".format(  
–\> 366 type(self). **name** , name))  
367  
368 def **setattr** (self, name, value):

AttributeError: ‘DataParallel’ object has no attribute ‘fc’

How to fix it? thanks.  
and here is my model:

DataParallel(  
(module): DataParallel(  
(module): DataParallel(  
(module): DataParallel(  
(module): Net(  
(conv1): Conv2d (3, 64, kernel\_size=(7, 7), stride=(2, 2), padding=(3, 3), bias=False)  
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True)  
(relu): ReLU(inplace)  
(maxpool): MaxPool2d(kernel\_size=(3, 3), stride=(2, 2), padding=(1, 1), dilation=(1, 1))  
(layer1): Sequential(  
(0): BasicBlock(  
(conv1): Conv2d (64, 64, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True)  
(relu): ReLU(inplace)  
(conv2): Conv2d (64, 64, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True)  
)  
(1): BasicBlock(  
(conv1): Conv2d (64, 64, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True)  
(relu): ReLU(inplace)  
(conv2): Conv2d (64, 64, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True)  
)  
(2): BasicBlock(  
(conv1): Conv2d (64, 64, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True)  
(relu): ReLU(inplace)  
(conv2): Conv2d (64, 64, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True)  
)  
)  
(layer2): Sequential(  
(0): BasicBlock(  
(conv1): Conv2d (64, 128, kernel\_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)  
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)  
(relu): ReLU(inplace)  
(conv2): Conv2d (128, 128, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)  
(downsample): Sequential(  
(0): Conv2d (64, 128, kernel\_size=(1, 1), stride=(2, 2), bias=False)  
(1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)  
)  
)  
(1): BasicBlock(  
(conv1): Conv2d (128, 128, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)  
(relu): ReLU(inplace)  
(conv2): Conv2d (128, 128, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)  
)  
(2): BasicBlock(  
(conv1): Conv2d (128, 128, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)  
(relu): ReLU(inplace)  
(conv2): Conv2d (128, 128, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)  
)  
(3): BasicBlock(  
(conv1): Conv2d (128, 128, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)  
(relu): ReLU(inplace)  
(conv2): Conv2d (128, 128, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True)  
)  
)  
(layer3): Sequential(  
(0): BasicBlock(  
(conv1): Conv2d (128, 256, kernel\_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)  
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)  
(relu): ReLU(inplace)  
(conv2): Conv2d (256, 256, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)  
(downsample): Sequential(  
(0): Conv2d (128, 256, kernel\_size=(1, 1), stride=(2, 2), bias=False)  
(1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)  
)  
)  
(1): BasicBlock(  
(conv1): Conv2d (256, 256, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)  
(relu): ReLU(inplace)  
(conv2): Conv2d (256, 256, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)  
)  
(2): BasicBlock(  
(conv1): Conv2d (256, 256, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)  
(relu): ReLU(inplace)  
(conv2): Conv2d (256, 256, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)  
)  
(3): BasicBlock(  
(conv1): Conv2d (256, 256, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)  
(relu): ReLU(inplace)  
(conv2): Conv2d (256, 256, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)  
)  
(4): BasicBlock(  
(conv1): Conv2d (256, 256, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)  
(relu): ReLU(inplace)  
(conv2): Conv2d (256, 256, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)  
)  
(5): BasicBlock(  
(conv1): Conv2d (256, 256, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)  
(relu): ReLU(inplace)  
(conv2): Conv2d (256, 256, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True)  
)  
)  
(layer4): Sequential(  
(0): BasicBlock(  
(conv1): Conv2d (256, 512, kernel\_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)  
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True)  
(relu): ReLU(inplace)  
(conv2): Conv2d (512, 512, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True)  
(downsample): Sequential(  
(0): Conv2d (256, 512, kernel\_size=(1, 1), stride=(2, 2), bias=False)  
(1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True)  
)  
)  
(1): BasicBlock(  
(conv1): Conv2d (512, 512, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True)  
(relu): ReLU(inplace)  
(conv2): Conv2d (512, 512, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True)  
)  
(2): BasicBlock(  
(conv1): Conv2d (512, 512, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn1): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True)  
(relu): ReLU(inplace)  
(conv2): Conv2d (512, 512, kernel\_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)  
(bn2): BatchNorm2d(512, eps=1e-05, momentum=0.1, affine=True)  
)  
)  
(avgpool): AdaptiveAvgPool2d(output\_size=1)  
(fc): Linear(in\_features=512, out\_features=10)  
)  
)  
)  
)  
)

---

<div class="post-metadata">

**Author:** ![ptrblck](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ptrblck/32/1823_2.png) [@ptrblck](https://discuss.pytorch.org/u/ptrblck)\
**Post date:** [March 13, 2018, 8:59am UTC](https://discuss.pytorch.org/t/fine-tuning-resnet-dataparallel-object-has-no-attribute-fc/14842/2 "2018-03-13T08:59:36Z")

</div>

When using `DataParallel` your `nn.Module` will be in `.module`:

```auto
model = Net()
model.fc

model_parallel = nn.DataParallel(model)
model_parallel.module.fc

```

---

<div class="post-metadata">

**Author:** ![yang\_yang1](https://discuss.pytorch.org/letter_avatar_proxy/v4/letter/y/dbc845/32.png) [@yang\_yang1](https://discuss.pytorch.org/u/yang_yang1)\
**Post date:** [March 13, 2018, 12:31pm UTC](https://discuss.pytorch.org/t/fine-tuning-resnet-dataparallel-object-has-no-attribute-fc/14842/3 "2018-03-13T12:31:12Z")

</div>

Thanks for your reply, but after initialized with model = Net () , how to load my pretrained weights? my pretrained model is saved by torch.save()

---

<div class="post-metadata">

**Author:** ![zakaria\_laskar](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/zakaria_laskar/32/1515_2.png) [@zakaria\_laskar](https://discuss.pytorch.org/u/zakaria_laskar)\
**Post date:** [March 13, 2018, 3:22pm UTC](https://discuss.pytorch.org/t/fine-tuning-resnet-dataparallel-object-has-no-attribute-fc/14842/4 "2018-03-13T15:22:05Z")

</div>

model.load\_state\_dict(torch.load(’/path/to/model.pth.tar’))

---

<div class="post-metadata">

**Author:** ![Ivamcoder](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ivamcoder/32/13744_2.png) [@Ivamcoder](https://discuss.pytorch.org/u/Ivamcoder)\
**Post date:** [July 25, 2019, 3:15am UTC](https://discuss.pytorch.org/t/fine-tuning-resnet-dataparallel-object-has-no-attribute-fc/14842/5 "2019-07-25T03:15:33Z")

</div>

Hi @ptrblck

Assume that I have another attribute from a second model which is called in attribute of first model,  
How should I do that,  
example

```auto
model_parallel.module.inference(inputs_var)

```

and in inference attribute I have

```auto
    def inference(self, img):
        feat = self.feature_extractor(img)
        x = self.second_net.inference(feat)
        return x

```

I get the error that `second net` does not have `inference` attribute  
What should I do ?

---

<div class="post-metadata">

**Author:** ![ptrblck](https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/ptrblck/32/1823_2.png) [@ptrblck](https://discuss.pytorch.org/u/ptrblck)\
**Post date:** [July 25, 2019, 9:28pm UTC](https://discuss.pytorch.org/t/fine-tuning-resnet-dataparallel-object-has-no-attribute-fc/14842/6 "2019-07-25T21:28:29Z")

</div>

Could you post the complete model definition so that we can have a look?
