Technical peers interested in practical AI/ML learning, model training, and AI security architecture

Cats and Dogs Image Classifier

A portfolio writeup on building, training, further-training, and safely presenting a TensorFlow/Keras image classifier as a learning project.

ai machine learning model training security architecture

This was a hands-on learning project: build a convolutional neural network, train it on image data, improve it with further training, and then think clearly about what it would take to expose that kind of model responsibly.

The old site presented this as an interactive classifier. The new site presents the writeup publicly as Portfolio evidence and gates live inference behind verified registered accounts. That is a deliberate architecture choice: anonymous visitors can read the thinking, while model execution requires account verification, MFA, upload controls, private preview storage, and audit records.

What I Built

The model was a binary image classifier for cats and dogs. It used a TensorFlow/Keras CNN trained on directory-structured image data, with augmentation and validation used to improve generalisation.

The original learning path had two main phases:

  • An initial training run on roughly 25,000 cat and dog images.
  • A further-training run with additional images, stronger augmentation, and class weighting.

Sample cat and dog training images

Data Preparation

The dataset was organised by class, so the training code could create batches directly from directories. The core preparation pattern was:

train_datagen = ImageDataGenerator(
    rescale=1.0 / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True,
    validation_split=0.1,
)

train_generator = train_datagen.flow_from_directory(
    base_dir,
    target_size=(200, 200),
    batch_size=32,
    class_mode="binary",
    subset="training",
)

That is a small piece of code, but architecturally it matters. The model only learns the world represented by the dataset. A security architect looking at an AI system has to ask where the data came from, whether it is representative, whether it can be poisoned, and whether the labels are trustworthy.

Model Shape

The first model used a straightforward CNN: convolutional layers, max pooling, a flattening stage, dense layers, batch normalisation, dropout, and a final sigmoid output for binary classification.

model = Sequential(
    [
        Conv2D(32, (3, 3), activation="relu", input_shape=(200, 200, 3)),
        MaxPooling2D(2, 2),
        Conv2D(64, (3, 3), activation="relu"),
        MaxPooling2D(2, 2),
        Conv2D(64, (3, 3), activation="relu"),
        MaxPooling2D(2, 2),
        Conv2D(64, (3, 3), activation="relu"),
        MaxPooling2D(2, 2),
        Flatten(),
        Dense(512, activation="relu"),
        BatchNormalization(),
        Dropout(0.2),
        Dense(1, activation="sigmoid"),
    ]
)

The old screenshots are useful because they show this was not only conceptual writing; it was training work with real model structure and measured output.

CNN model summary, first section

CNN model summary, parameter section

Training And Further Training

The training used ordinary but important discipline:

  • Adam as the optimiser.
  • Binary cross-entropy for the loss function.
  • Early stopping to reduce overfitting.
  • Learning-rate reduction when validation loss plateaued.
  • Checkpointing of the best validation model.

The later training pass added more aggressive augmentation and class weighting. That is where the project became more interesting from an architecture point of view: the system was no longer only a model, it was a training process with assumptions, controls, and operational choices.

class_weights = compute_class_weight(
    class_weight="balanced",
    classes=np.unique(train_class_counts),
    y=train_class_counts,
)

history = model.fit(
    new_train_generator,
    validation_data=new_validation_generator,
    epochs=10,
    callbacks=[early_stopping, reduce_lr, checkpoint],
    class_weight=dict(enumerate(class_weights)),
)

The old notes recorded validation accuracy moving from roughly the low-to-high 80s into the low 90s during further training. That should be read as learning evidence, not as a product benchmark: the dataset, split, lab conditions, and target use case all matter before any claim becomes operationally meaningful.

Initial training accuracy and loss graph

Further-training accuracy and loss graph

Why This Matters For Security Architecture

The useful security questions start around the model rather than inside the model:

  • What is the provenance of the training data?
  • Can the training set or labels be tampered with?
  • How is a saved model artifact protected, versioned, scanned, and promoted?
  • What happens when the input is outside the trained classes?
  • How are uploads constrained, scanned, retained, and deleted?
  • What confidence threshold changes the user experience?
  • What evidence would make a prediction trustworthy enough for the decision being made?

Those questions turn a hobby classifier into a practical conversation about AI security. The same thinking applies to larger enterprise AI systems: data lineage, artifact integrity, deployment guardrails, monitoring, failure modes, and audit evidence.

Current Rebuild Boundary

For this site, the article is public but model execution is not anonymous. The Portfolio keeps the learning signal and the live registered-user model keeps the unnecessary risk contained:

  • No anonymous upload form.
  • No public static upload path.
  • No model binary in the repository.
  • No TensorFlow runtime dependency in the Flask web app.
  • No request-time model loading in the web process.
  • No external fallback model.

The live Cats vs Dogs version runs through a separate inference service with strict file handling, resource limits, model-version evidence, private preview retention for recent runs, and registered-member access before any image can be tested.

Runnable model

Run the controlled model

Registered members can test the model through the gated inference service. Anonymous visitors can read the writeup, but uploads require verified email, MFA, feature flags, upload controls, and audit logging.