# How can I use class\_weights when training?

**URL:** </static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%3E%5C
**Category:** 🤗Transformers\
**Created:** [September 9, 2020, 2:29pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067 "2020-09-09T14:29:03Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![PhilipMay](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/philipmay/32/2324_2.png) [@PhilipMay](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2FPhilipMay)%5C
**Post date:** [September 9, 2020, 2:29pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F1 "2020-09-09T14:29:03Z")

</div>

I have an unbalanced dataset. When training I want to pass class\_weights so the update for rare classes is highen than for large classes. How is this possible in HF with PyTorch?

Thanks  
Philip

---

<div class="post-metadata">

**Author:** ![PhilipMay](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/philipmay/32/2324_2.png) [@PhilipMay](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2FPhilipMay)%5C
**Post date:** [September 29, 2020, 10:40am UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F2 "2020-09-29T10:40:31Z")

</div>

Answering my own question:  
Subclass `Trainer` and override the `compute_loss` method (see example [here](https://huggingface.co/transformers/master/main_classes/trainer.html)).

---

<div class="post-metadata">

**Author:** ![sgugger](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/sgugger/32/2291_2.png) [@sgugger](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fsgugger)%5C
**Post date:** [September 29, 2020, 1:58pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F3 "2020-09-29T13:58:53Z")

</div>

Sorry I missed your question and didn’t point you to this directly.

---

<div class="post-metadata">

**Author:** ![PhilipMay](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/philipmay/32/2324_2.png) [@PhilipMay](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2FPhilipMay)%5C
**Post date:** [September 29, 2020, 2:13pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F4 "2020-09-29T14:13:59Z")

</div>

No worries. You did on GitHub… 🙂 👍

---

<div class="post-metadata">

**Author:** ![theudster](https://avatars.discourse-cdn.com/v4/letter/t/97f17d/32.png) [@theudster](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Ftheudster)%5C
**Post date:** [March 1, 2021, 11:03pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F5 "2021-03-01T23:03:45Z")

</div>

Hi @PhilipMay !Do you mind pasting an example please, as I don’t really understand the documentation

---

<div class="post-metadata">

**Author:** ![Santarabantoosoo](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/santarabantoosoo/32/5489_2.png) [@Santarabantoosoo](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2FSantarabantoosoo)%5C
**Post date:** [October 28, 2021, 7:53pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F6 "2021-10-28T19:53:35Z")

</div>

@PhilipMay an example would be highly appreciated.

---

<div class="post-metadata">

**Author:** ![nielsr](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/nielsr/32/39617_2.png) [@nielsr](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fnielsr)%5C
**Post date:** [October 29, 2021, 8:32am UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F7 "2021-10-29T08:32:36Z")

</div>

Overwriting the Trainer can be done as follows (this is also explained in the [docs](https://huggingface.co/transformers/main_classes/trainer.html)):

```auto
from torch import nn
from transformers import Trainer

class CustomTrainer(Trainer):
    def compute_loss(self, model, inputs, return_outputs=False):
        labels = inputs.get("labels")
        # forward pass
        outputs = model(**inputs)
        logits = outputs.get('logits')
        # compute custom loss
        loss_fct = nn.CrossEntropyLoss(weight=torch.tensor([0.2, 0.3]))
        loss = loss_fct(logits.view(-1, self.model.config.num_labels), labels.view(-1))
        return (loss, outputs) if return_outputs else loss

```

---

<div class="post-metadata">

**Author:** ![Santarabantoosoo](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/santarabantoosoo/32/5489_2.png) [@Santarabantoosoo](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2FSantarabantoosoo)%5C
**Post date:** [October 29, 2021, 8:47am UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F8 "2021-10-29T08:47:00Z")

</div>

Thanks a million 🙂

---

<div class="post-metadata">

**Author:** ![para](https://avatars.discourse-cdn.com/v4/letter/p/d9b06d/32.png) [@para](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fpara)%5C
**Post date:** [January 27, 2022, 4:26pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F9 "2022-01-27T16:26:16Z")

</div>

can any help me with how can apply it to text classification?  
for ex: I have four classes  
class 1: 200 samples  
class 2: 100 samples  
class 3: 20 samples  
class 4: 10 samples  
so during predictions, most of my samples are predicting class 1 or 2 because samples are high even I have unlabeled samples of class3 and class4.  
How can I overcome this in HF?  
is it possible to tell me the model that concentrates more on class3 and class4?  
Help me very soon.  
Thank you in advance.

---

<div class="post-metadata">

**Author:** ![goerlitz](https://avatars.discourse-cdn.com/v4/letter/g/4af34b/32.png) [@goerlitz](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fgoerlitz)%5C
**Post date:** [January 27, 2022, 8:25pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F10 "2022-01-27T20:25:43Z")

</div>

Hi @para, the thread above explains exactly what you need to do if you want to use class weights to handle an imbalanced dataset.

But if you are not sure what class weights are, what they do or how to overwrite the Trainer yourself I’d suggest that you take more time first to really understand the concepts and how it works.

You can also have a look at Simpletransformer.ai - it already implements [class weight handling](https://simpletransformers.ai/docs/classification-models/#setting-class-weights). But be aware that blindly trying out something will probably not give you the best results.

Additional note: it seems to be a common rule of thumb that the largest class should be max 10 times bigger than the smallest class. If this is not the case, you can try sampling techniques on your data as suggested [here](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-to-give-equal-importance-of-all-labels-while-dealing-with-unbalanced-samples%2F14174).

---

<div class="post-metadata">

**Author:** ![marshmellow77](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/marshmellow77/32/3279_2.png) [@marshmellow77](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fmarshmellow77)%5C
**Post date:** [January 28, 2022, 5:42am UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F11 "2022-01-28T05:42:46Z")

</div>

Just to elaborate on the sampling techniques @goerlitz is mentioning:

It’s a common ML challenge and the standard approaches for sampling are:

1. Under-sampling: Randomly delete records from the over-represented classes
2. Over-sampling: Duplicate records in the under-represented classes
3. Synthetic sampling/data augmentation: In NLP, there are actually quite some interesting techniques with which you can augment your data in the under-represented classes to increase record count. Check out this library: [GitHub - makcedward/nlpaug: Data augmentation for NLP](https://github.com/makcedward/nlpaug)

---

<div class="post-metadata">

**Author:** ![marshmellow77](https://sea2.discourse-cdn.com/hellohellohello/user_avatar/discuss.huggingface.co/marshmellow77/32/3279_2.png) [@marshmellow77](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fmarshmellow77)%5C
**Post date:** [January 28, 2022, 5:45am UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F12 "2022-01-28T05:45:36Z")

</div>

With regards to using class weights, this tutorial might be helpful to understand the approach better: [How to use class weight in CrossEntropyLoss for an imbalanced dataset? - knowledge Transfer](https://androidkt.com/how-to-use-class-weight-in-crossentropyloss-for-an-imbalanced-dataset/)

---

<div class="post-metadata">

**Author:** ![para](https://avatars.discourse-cdn.com/v4/letter/p/d9b06d/32.png) [@para](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fpara)%5C
**Post date:** [January 28, 2022, 9:47am UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F13 "2022-01-28T09:47:22Z")

</div>

hi, @goerlitz Thank you for the reply.  
this simpletransformer.ai blog helps me to understand what are class weights and how they will impact the calculation of loss function while having unbalanced samples.  
all now I need is programmatic implementation.  
I am using ([Hugging Face DistilBert & Tensorflow for Custom Text Classification. | by Galina Blokh | Geek Culture | Medium](https://medium.com/geekculture/hugging-face-distilbert-tensorflow-for-custom-text-classification-1ad4a49e26a7)) this blog to create a text classification model.  
as well I am using Trainer API to train the model.  
sample code:  
class Dataset(torch.utils.data.Dataset):  
def **init** (self, encodings, labels=None):  
self.encodings = encodings  
self.labels = labels  
def **getitem** (self, idx):  
item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}  
if self.labels:  
item[“labels”] = torch.tensor(self.labels[idx])  
return item  
def **len** (self):  
return len(self.encodings[“input\_ids”])  
train\_dataset = Dataset(X\_train\_tokenized, y\_train)  
val\_dataset = Dataset(X\_val\_tokenized, y\_val)  
args = TrainingArguments(  
evaluation\_strategy=“steps”,  
eval\_steps=500,  
per\_device\_train\_batch\_size=8,  
per\_device\_eval\_batch\_size=8,  
num\_train\_epochs=1,  
seed=0,  
load\_best\_model\_at\_end=True,  
)  
trainer = Trainer(  
model=model,  
args=args,  
train\_dataset=train\_dataset,  
eval\_dataset=val\_dataset,  
compute\_metrics=compute\_metrics,)  
Can you please help me where to use custom trainer function in my code

---

<div class="post-metadata">

**Author:** ![goerlitz](https://avatars.discourse-cdn.com/v4/letter/g/4af34b/32.png) [@goerlitz](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fgoerlitz)%5C
**Post date:** [January 28, 2022, 8:18pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F14 "2022-01-28T20:18:40Z")

</div>

Hi @para, it is good practice format pasted code with the preformatted text option and make sure that the indentation is correct. Otherwise, your code is hart to read and other people are probably less likely to try to understand it. That means: make it as easy as possible for others to help you by giving enough context for the problem and only include relevant and readable code.  
**Tip** : you can still edit your previous post and format the code example in the right way. (see image)

 ![formatting](https://us1.discourse-cdn.com/hellohellohello/original/2X/6/6efe48563e71563833612734086fec1033d1c0a3.png)

Now looking at your code…

```auto
class Dataset(torch.utils.data.Dataset):
  def __init__ (self, encodings, labels=None):
    self.encodings = encodings
    self.labels = labels
  def __getitem__ (self, idx):
    item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}
    if self.labels:
      item[“labels”] = torch.tensor(self.labels[idx])
      return item
  def __len__ (self):
    return len(self.encodings[“input_ids”])

train_dataset = Dataset(X_train_tokenized, y_train)
val_dataset = Dataset(X_val_tokenized, y_val)
args = TrainingArguments(
  evaluation_strategy=“steps”,
  eval_steps=500,
  per_device_train_batch_size=8,
  per_device_eval_batch_size=8,
  num_train_epochs=1,
  seed=0,
  load_best_model_at_end=True,
)
trainer = Trainer(
  model=model,
  args=args,
  train_dataset=train_dataset,
  eval_dataset=val_dataset,
  compute_metrics=compute_metrics,)

```

I actually have several questions:

- What model are you using?
- What dataset are you using?
  - How many different categories does it have?
  - What is the highest and lowest frequency of categories?
  - How many examples do you have in training and validation set?

- what evaluation metrics are you using?
- what results do you get for your metrics at the end of training?
- did you look at training and validation loss curves to judge if your model is overfitting?
- did you try different values for `num_train_epochs` and `learning_rate`?

Actually, training for 1 epoch is only good for getting some preliminary results. You should try training with 2-4 epochs and different learning rates to get better results before trying out class weights.

But to answer your initial question:  
Your can copy the code [posted above](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F7) and then replace the line

```auto
trainer = Trainer(

```

with

```auto
trainer = CustomTrainer(

```

That should work.

---

<div class="post-metadata">

**Author:** ![para](https://avatars.discourse-cdn.com/v4/letter/p/d9b06d/32.png) [@para](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fpara)%5C
**Post date:** [January 29, 2022, 2:16pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F18 "2022-01-29T14:16:50Z")

</div>

Thank you. It really helps me.  
I am using my customer data and it has a total of 9 labels the distributions are,  
class-1: 223  
class-2: 119  
class-3: 42  
class-4: 37  
class-5: 24  
class-6: 23  
class-7: 16  
class-8: 12  
class-9: 4  
if I give all 9 classes to the model it treats the last 2-To 3 classes as outliers because it has very few samples.  
so now my task is to take only the last four classes and try a few-shot classification on those samples.  
and my assumption to perform few-shot classification is to use any pre-trained model so that it already has some knowledge(correct me if I am wrong and give any suggestions on how to do few-shot text classification)  
so for that, i am using (`model = TFDistilBertForSequenceClassification.from_pretrained('distilbert-base-uncased', num_labels=4)`)  
and here I am not doing any test and train split because:

1. my samples are very less
2. even I do test and train split and see the scores on test data we can’t conclude the model is performing well even it is giving a 90 f1 score.
3. so I am doing manual eyeball evaluation by giving unlabelled samples to the model.  
please suggest any other approaches to tackle this other than sampling.  
I have another approach in my mind:  
form classes, 1&2 take 5 samples calculate embeddings for 5 samples, and average it so that we get one embedding and map that embedding with class 1  
if we do the above for all samples then we get ~40 embeddings for class1 220%5=~40  
then we get balanced samples.  
can you suggest how to do this experiment with HF and if you feel this really works?

---

<div class="post-metadata">

**Author:** ![para](https://avatars.discourse-cdn.com/v4/letter/p/d9b06d/32.png) [@para](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fpara)%5C
**Post date:** [January 30, 2022, 5:39am UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F19 "2022-01-30T05:39:20Z")

</div>

Thank you for the answer

---

<div class="post-metadata">

**Author:** ![para](https://avatars.discourse-cdn.com/v4/letter/p/d9b06d/32.png) [@para](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fpara)%5C
**Post date:** [January 30, 2022, 6:55am UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F20 "2022-01-30T06:55:27Z")

</div>

In my dataset, there are a total of 9 classes and their distribution is,  
223,119,42,37,24,23,16,12,4.  
Instead of giving all classes to my model, I am giving the last four classes and trying a few-shot classification(my assumption is to try few-shot we have to pretrained model because the model already had some knowledge so that it can able to learn from a few samples). that is the reason I am an HF model  
Correct me if my assumption is wrong and give any suggestion to try a few-shot with HF, That will be greatly helpful.  
Here I am not splitting the data into train and validation because my samples are fewer. I am evaluating my model by manually giving unlabelled samples to the model.  
I am using TFdistilbert for the sequence classification model.

---

<div class="post-metadata">

**Author:** ![goerlitz](https://avatars.discourse-cdn.com/v4/letter/g/4af34b/32.png) [@goerlitz](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fgoerlitz)%5C
**Post date:** [February 2, 2022, 8:10pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F21 "2022-02-02T20:10:30Z")

</div>

Alright, you have a very imbalanced dataset with 500 examples and 9 classes.

I understand that you want to use it for training a classifier. But I’m not sure what you want to with it afterwards? Do you have a real world use case with another set of unlabeled documents that you want to classify?

The point is, if you have less than approx. 1000 unlabeled documents to be classified, you should rather label them manually than trying to train a classifier. That will be faster as it should only take a few days to complete.

If you have more than 1000 unlabeled documents I’d say that you should actually take the time to manually label more of them and thus increase the number of examples in your training set.

Why? For training a common classification model you should have at least 100 examples per class (more is better) and the most frequent class should not be 10x the least frequent class.  
Another option is to aggregate the classes with few examples into a single class. This will increase accuracy etc. but of course you can not further differentiate.

Now coming to few shot learning. Actually, I have no practical experience with few show learning so I can not point to code or tutorial. But, few shot learning is a different approach with a different training goal. You can find many good articles that explain how it works and also use the search function of this forum to find discussions like [this one](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Funderstanding-zero-shot-classification-in-one-shot%2F8851).

Anyway, the bottom line is that for few shot learning you should use a different model (NLI).

However, as I said before, you actual use case is not really clear. If this is for educational purposes, I’d recommend to try out different datasets, one that is suitable for training a regular classifier and a different one that is suitable for few show learning. If this is a real world use case, you can try few shot learning but otherwise you should acquire more data.

---

<div class="post-metadata">

**Author:** ![bonschorno](https://avatars.discourse-cdn.com/v4/letter/b/2bfe46/32.png) [@bonschorno](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2Fbonschorno)%5C
**Post date:** [February 11, 2022, 2:08pm UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F22 "2022-02-11T14:08:31Z")

</div>

Could anyone point me in the direction of how I’d go about addressing this issue (that is, using class weights) when working with Tensorflow?

---

<div class="post-metadata">

**Author:** ![BartimaeusTrains](https://avatars.discourse-cdn.com/v4/letter/b/c89c15/32.png) [@BartimaeusTrains](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Fu%2FBartimaeusTrains)%5C
**Post date:** [December 29, 2022, 9:13am UTC](/static-proxy?url=https%3A%2F%2Fdiscuss.huggingface.co%2Ft%2Fhow-can-i-use-class-weights-when-training%2F1067%2F23 "2022-12-29T09:13:12Z")

</div>

Looking for same
