Strugle to change `num_labels` of roberta-large-mnli
Author: nlpist
Pull request: no

- `transformers` version: 4.4.0
- Platform: Linux-5.8.0-45-generic-x86_64-with-debian-bullseye-sid
- Python version: 3.7.10
- PyTorch version (GPU?): 1.6.0 (True)
- Tensorflow version (GPU?): not installed (NA)
- Using GPU in script?: yes
- Using distributed or parallel set-up in script?: no

I am trying to build a simple binary classifies based on `roberta-large-mnli` that is initially fitted to three labels.

I found that the following snippet should work, but it doesn't

`config = AutoConfig.from_pretrained('roberta-large-mnli', num_labels=2)`
`model = AutoModelForSequenceClassification.from_pretrained('roberta-large-mnli', config=config)`

If fails with the following error message

`RuntimeError: Error(s) in loading state_dict for RobertaForSequenceClassification: size mismatch for classifier.out_proj.weight: copying a param with shape torch.Size([3, 1024]) from checkpoint, the shape in current model is torch.Size([2, 1024]).
size mismatch for classifier.out_proj.bias: copying a param with shape torch.Size([3]) from checkpoint, the shape in current model is torch.Size([2]).`

I prefer to build solution around `AutoModel` if possible.

@LysandreJik @sgugger

Comments:
Please have a look at [link](https://stackoverflow.com/questions/67158554/fine-tuning-models-classifier-layer-with-new-label/67187807#67187807). You can not resize a pre-trained model via config. You need to do it by yourself.

@cronoik , Thank you very for your response!

I've changed the code to the following 

`config = AutoConfig.from_pretrained(self.pretrained_bert,                                               output_attentions=False, output_hidden_states=False)`

`self.model = AutoModelForSequenceClassification.from_pretrained(self.pretrained_bert, config=config)`

`if self.n_classes != self.model.num_labels:`
`            self.model.classifier.out_proj.weight = nn.Parameter(torch.randn(self.n_classes,768))`
`            self.model.classifier.out_proj.bias = nn.Parameter(torch.randn(self.n_classes))`

However, it seems like this change doesn't make any difference. 
`print(self.model)` still outputs the same head

`(classifier): RobertaClassificationHead(`
`    (dense): Linear(in_features=768, out_features=768, bias=True)`
`    (dropout): Dropout(p=0.1, inplace=False)`
`    (out_proj): Linear(in_features=768, out_features=3, bias=True)`
`  )`

This is just static information that does not affect the code. Just run the model as you did before. It will now return `self.n_classes` values instead of 3. 
You can change the output with: 
```
classifier.out_proj.out_features =2
```

for some reason it still fails with the error
`py37/lib/python3.7/site-packages/transformers/modeling_roberta.py", line 1011, in forward`
`    loss = loss_fct(logits.view(-1, self.num_labels), labels.view(-1))`
`RuntimeError: shape '[-1, 3]' is invalid for input of size 16`

it seems like it still expects 3 labels, and 16 is twice the batch size 

Have you changed the config as well? self.num_labels is initialized from the config. I have tested it with roberta-large-mnli and it is working fine.

Nope, I tried the following, and apparently it fails, because `num_labels=2` doesn't fit the num_labels from the config itself.
`config = AutoConfig.from_pretrained('roberta-large-mnli', num_labels=2)`
`self.model = AutoModelForSequenceClassification.from_pretrained(self.pretrained_bert, config=config)`




@cronoik I've changed `num_labels` of the models and it started running.
I thought that replacing the head classifier is a routine process, but it seems not. I wonder if there is more "universal" approach, where there is no need to specify hidden size, `out_proj` and etc.?

Sorry, I think this is a bit of a misunderstanding. I thought that you wanted to reuse the weights of the classification head but in the example, you showed that you reinitialized them randomly. In this case, the "standard" procedure is the following (AFAIK):
```
from transformers import AutoModelForSequenceClassification
m = AutoModelForSequenceClassification.from_pretrained('roberta-large-mnli')
c = AutoConfig.from_pretrained('roberta-large-mnli')
s = m.state_dict
s = {k:v for k,v in s.items() if not k.startswith('classifier')}
c.num_labels = 2
m2  = AutoModelForSequenceClassification.from_pretrained(None, config = c, state_dict=s)
```

This issue has been automatically marked as stale because it has not had recent activity. If you think this still needs to be addressed please comment on this thread.

Please note that issues that do not follow the [contributing guidelines](https://github.com/huggingface/transformers/blob/master/CONTRIBUTING.md) are likely to be ignored.