A public project title is often a poor description of the work that finally ships.

This engagement was publicly listed as age detection from Instagram bios. The technical delivery tells a broader and more useful story: a TensorFlow notebook that fine-tunes BERT to assign several themes to short social-media posts.

The target labels were is_personal, is_healthy_lifestyle, and is_medical. They were not mutually exclusive. One post could legitimately activate none, one, two, or all three.

That makes this a multilabel problem.

One input does not always have one correct class

In ordinary multiclass classification, the classes compete. An input is assigned to one category: this or that.

Multilabel classification asks a different question for every label: does this label apply or not?

Consider an illustrative post about returning to running after medical treatment. It may be personal, related to a healthy lifestyle, and medical at the same time. Forcing the model to choose only one theme would throw away valid information before training even begins.

This distinction affects the output layer, loss function, probability conversion, thresholding, and the way results are evaluated.

What the notebook implemented

The delivery loaded 31,982 labeled posts from a CSV file and tokenized the text with bert-base-uncased. It created token IDs and attention masks, padded or truncated sequences, and used an 80/20 holdout split.

The model was TFBertForSequenceClassification with three output labels. It was compiled with binary cross-entropy from logits and the Adam optimizer, then fine-tuned in Google Colab. The trained model and tokenizer were saved for later inference.

The notebook also included:

  • probability-based label prediction;
  • configurable decision thresholds;
  • overall accuracy, weighted F1, precision, and recall;
  • combined confusion matrices for the possible label combinations;
  • separate classification reports and confusion matrices for each theme.

That is a complete experimental path from a labeled CSV to a reusable model and an evaluation scaffold.

The evaluation detail that changes the meaning

The notebook contains two probability-conversion paths. The first correctly applies sigmoid independently to every output logit. A later validation block applies softmax and then thresholds the resulting scores.

Those operations do not mean the same thing.

Softmax makes outputs compete and forces their probabilities to sum to one. That is appropriate when exactly one class should win. Sigmoid treats every output independently, which matches a multilabel target where several themes may be true together.

For a production-ready evaluation, I would therefore keep sigmoid throughout inference, validate the threshold rather than choose it by convenience, and consider a different threshold for each label when their prevalence or error costs differ.

This is not a cosmetic implementation detail. It changes what the scores mean.

Splitting the data is part of the model

The notebook creates the holdout set by taking the first 80% of the rows for training and the remaining 20% for testing. That is only safe if the source file was already randomized appropriately.

If rows are ordered by time, source, author, or label, a simple slice can create a misleading test set. Today I would make that assumption explicit and use a reproducible shuffled or multilabel-stratified split. For text from repeated authors or sources, I would also check whether grouping is needed to prevent leakage.

The same caution applies to training duration. More epochs are not automatically better. Validation curves, early stopping, and per-label error analysis are more useful than selecting a large epoch count in advance.

What I can and cannot claim

The saved notebook contains the code needed to calculate the metrics, but it does not preserve the resulting metric outputs. I therefore do not publish an accuracy, F1 score, or production-impact claim for this engagement.

What the material does demonstrate is concrete: data preparation, BERT tokenization, TensorFlow fine-tuning, multilabel prediction, model persistence, and evaluation code were delivered in a Colab-friendly workflow. The client also left a public 5.0 review confirming satisfaction with the work and communication.

The broader lesson

“Use BERT” is not a complete solution. The model can only learn the target we define, and the evaluation can only answer the question encoded in its labels and metrics.

Before tuning a text classifier, I now ask:

  • Can more than one label be correct?
  • Who defined the labels, and are the definitions consistent?
  • How are rare combinations represented?
  • What do false positives and false negatives cost for each label?
  • Does inference use the same semantics as training?
  • Is the holdout set genuinely independent?

The architecture matters. The definition of “correct” matters more.

Mehmed Kadrić Founder, MESH Data Solutions

I write about concrete data and software problems, including what failed, what was built, and what I would change next time.

NEED EVIDENCE FROM YOUR OWN DATA?

Turn the checklist into a focused audit.

Request an Audit