{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"toc_visible": true,
"authorship_tag": "ABX9TyMy6eJcO6tG5bz/ZoOCzLY4",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
},
"accelerator": "GPU",
"gpuClass": "standard"
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
""
]
},
{
"cell_type": "markdown",
"source": [
"## Becoming one with data"
],
"metadata": {
"id": "s6TgLDGj0Tgs"
}
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"id": "FJT3_4AWzvrS"
},
"outputs": [],
"source": [
"import zipfile\n",
"\n",
"# Unzip the downloaded file from github or kaggle \"https://www.kaggle.com/datasets/die9origephit/nike-adidas-and-converse-imaged?resource=download\"\n",
"zip_ref = zipfile.ZipFile(\"Sneakers_CNN.zip\", \"r\")\n",
"zip_ref.extractall()\n",
"zip_ref.close()"
]
},
{
"cell_type": "code",
"source": [
"import os\n",
"\n",
"# Walk through directory and list number of files\n",
"print(\"TRAIN---\")\n",
"for dirpath, dirnames, filenames in os.walk(\"train\"):\n",
" print(f\"There are {len(dirnames)} directories and {len(filenames)} images in '{dirpath}'.\")\n",
"print(\"TEST---\")\n",
"for dirpath, dirnames, filenames in os.walk(\"test\"):\n",
" print(f\"There are {len(dirnames)} directories and {len(filenames)} images in '{dirpath}'.\")"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "L-BIxhaw0ATB",
"outputId": "b313a9a6-1ea9-49ca-81e1-8454f60a0da1"
},
"execution_count": 6,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"TRAIN---\n",
"There are 3 directories and 0 images in 'train'.\n",
"There are 0 directories and 237 images in 'train/nike'.\n",
"There are 0 directories and 237 images in 'train/converse'.\n",
"There are 0 directories and 237 images in 'train/adidas'.\n",
"TEST---\n",
"There are 3 directories and 0 images in 'test'.\n",
"There are 0 directories and 38 images in 'test/nike'.\n",
"There are 0 directories and 38 images in 'test/converse'.\n",
"There are 0 directories and 38 images in 'test/adidas'.\n"
]
}
]
},
{
"cell_type": "markdown",
"source": [
"## Preprocessing Data"
],
"metadata": {
"id": "CNka9U0d1d1g"
}
},
{
"cell_type": "code",
"source": [
"# Setup data inputs\n",
"from tensorflow.keras.preprocessing.image import ImageDataGenerator\n",
"\n",
"IMAGE_SHAPE = (224, 224)\n",
"BATCH_SIZE = 32\n",
"\n",
"train_dir = \"/content/train\"\n",
"test_dir = \"/content/test\"\n",
"\n",
"train_datagen = ImageDataGenerator(rescale=1/255.)\n",
"test_datagen = ImageDataGenerator(rescale=1/255.)\n",
"\n",
"print(\"Training images:\")\n",
"train_data_10_percent = train_datagen.flow_from_directory(train_dir,\n",
" target_size=IMAGE_SHAPE,\n",
" batch_size=BATCH_SIZE,\n",
" class_mode=\"categorical\")\n",
"\n",
"print(\"Testing images:\")\n",
"test_data = train_datagen.flow_from_directory(test_dir,\n",
" target_size=IMAGE_SHAPE,\n",
" batch_size=BATCH_SIZE,\n",
" class_mode=\"categorical\")"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "cEymnz7a1l71",
"outputId": "3facc161-d4da-4665-afa2-0008318b41ac"
},
"execution_count": 7,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Training images:\n",
"Found 711 images belonging to 3 classes.\n",
"Testing images:\n",
"Found 114 images belonging to 3 classes.\n"
]
}
]
},
{
"cell_type": "markdown",
"source": [
"## Setting Callbacks"
],
"metadata": {
"id": "Tf84Dlox1v-U"
}
},
{
"cell_type": "code",
"source": [
"# Create tensorboard callback (functionized because need to create a new one for each model)\n",
"import datetime\n",
"def create_tensorboard_callback(dir_name, experiment_name):\n",
" log_dir = dir_name + \"/\" + experiment_name + \"/\" + datetime.datetime.now().strftime(\"%Y%m%d-%H%M%S\")\n",
" tensorboard_callback = tf.keras.callbacks.TensorBoard(\n",
" log_dir=log_dir\n",
" )\n",
" print(f\"Saving TensorBoard log files to: {log_dir}\")\n",
" return tensorboard_callback\n",
" "
],
"metadata": {
"id": "LhzWxCb112ee"
},
"execution_count": 8,
"outputs": []
},
{
"cell_type": "code",
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"# Plot the validation and training data separately\n",
"def plot_loss_curves(history):\n",
" \"\"\"\n",
" Returns separate loss curves for training and validation metrics.\n",
" \"\"\" \n",
" loss = history.history['loss']\n",
" val_loss = history.history['val_loss']\n",
"\n",
" accuracy = history.history['accuracy']\n",
" val_accuracy = history.history['val_accuracy']\n",
"\n",
" epochs = range(len(history.history['loss']))\n",
"\n",
" # Plot loss\n",
" plt.plot(epochs, loss, label='training_loss')\n",
" plt.plot(epochs, val_loss, label='val_loss')\n",
" plt.title('Loss')\n",
" plt.xlabel('Epochs')\n",
" plt.legend()\n",
"\n",
" # Plot accuracy\n",
" plt.figure()\n",
" plt.plot(epochs, accuracy, label='training_accuracy')\n",
" plt.plot(epochs, val_accuracy, label='val_accuracy')\n",
" plt.title('Accuracy')\n",
" plt.xlabel('Epochs')\n",
" plt.legend();"
],
"metadata": {
"id": "k6gmZ13mpAo7"
},
"execution_count": 14,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"## Creating models using Tensorflow Hub"
],
"metadata": {
"id": "X579fHUS15Fe"
}
},
{
"cell_type": "code",
"source": [
"import tensorflow as tf\n",
"import tensorflow_hub as hub\n",
"from tensorflow.keras import layers"
],
"metadata": {
"id": "DeM4Iedx1_WM"
},
"execution_count": 9,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"Models used :\n",
"* Resnet V2 50\n",
"* EfficientNet B0 (version 1)\n",
"* EfficientNet B0 (version 2)\n",
"* MobileNet V2"
],
"metadata": {
"id": "WJaJre0q2CiA"
}
},
{
"cell_type": "code",
"source": [
"# Resnet 50 V2 feature vector\n",
"resnet_url = \"https://tfhub.dev/google/imagenet/resnet_v2_50/feature_vector/4\"\n",
"\n",
"# Original: EfficientNetB0 feature vector (version 1)\n",
"efficientnet_url = \"https://tfhub.dev/tensorflow/efficientnet/b0/feature-vector/1\"\n",
"\n",
"# New: EfficientNetB0 feature vector (version 2)\n",
"efficientnet_2_url = \"https://tfhub.dev/google/imagenet/efficientnet_v2_imagenet1k_b0/feature_vector/2\"\n",
"\n",
"# MobileNet V2 feature vector\n",
"mobilenet_url=\"https://tfhub.dev/google/imagenet/mobilenet_v2_100_224/feature_vector/5\""
],
"metadata": {
"id": "6xagt0Uj2epB"
},
"execution_count": 24,
"outputs": []
},
{
"cell_type": "code",
"source": [
"def create_model(model_url, num_classes=10):\n",
" \"\"\"Takes a TensorFlow Hub URL and creates a Keras Sequential model with it.\n",
" \n",
" Args:\n",
" model_url (str): A TensorFlow Hub feature extraction URL.\n",
" num_classes (int): Number of output neurons in output layer,\n",
" should be equal to number of target classes, default 10.\n",
"\n",
" Returns:\n",
" An uncompiled Keras Sequential model with model_url as feature\n",
" extractor layer and Dense output layer with num_classes outputs.\n",
" \"\"\"\n",
" # Download the pretrained model and save it as a Keras layer\n",
" feature_extractor_layer = hub.KerasLayer(model_url,\n",
" trainable=False, # freeze the underlying patterns\n",
" name='feature_extraction_layer',\n",
" input_shape=IMAGE_SHAPE+(3,)) # define the input image shape\n",
" \n",
" # Create our own model\n",
" model = tf.keras.Sequential([\n",
" feature_extractor_layer, # use the feature extraction layer as the base\n",
" layers.Dense(num_classes, activation='softmax', name='output_layer') # create our own output layer \n",
" ])\n",
"\n",
" return model"
],
"metadata": {
"id": "7RaajEUabHT9"
},
"execution_count": 11,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"#### Resnet"
],
"metadata": {
"id": "Zcywxx0sbQgw"
}
},
{
"cell_type": "code",
"source": [
"# Create model\n",
"resnet_model = create_model(resnet_url, num_classes=train_data_10_percent.num_classes)\n",
"\n",
"# Compile model\n",
"resnet_model.compile(loss='categorical_crossentropy',\n",
" optimizer=tf.keras.optimizers.Adam(),\n",
" metrics=['accuracy'])"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "6J6F8t5ebcnz",
"outputId": "881f05a0-5055-4bc0-941f-66c94e13848b"
},
"execution_count": 12,
"outputs": [
{
"output_type": "stream",
"name": "stderr",
"text": [
"WARNING:tensorflow:Please fix your imports. Module tensorflow.python.training.tracking.data_structures has been moved to tensorflow.python.trackable.data_structures. The old module will be deleted in version 2.11.\n",
"WARNING:tensorflow:From /usr/local/lib/python3.8/dist-packages/tensorflow/python/autograph/pyct/static_analysis/liveness.py:83: Analyzer.lamba_check (from tensorflow.python.autograph.pyct.static_analysis.liveness) is deprecated and will be removed after 2023-09-23.\n",
"Instructions for updating:\n",
"Lambda fuctions will be no more assumed to be used in the statement where they are used, or at least in the same block. https://github.com/tensorflow/tensorflow/issues/56089\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"# Fit the model\n",
"resnet_history = resnet_model.fit(train_data_10_percent,\n",
" epochs=5,\n",
" steps_per_epoch=len(train_data_10_percent),\n",
" validation_data=test_data,\n",
" validation_steps=len(test_data),\n",
" # Add TensorBoard callback to model (callbacks parameter takes a list)\n",
" callbacks=[create_tensorboard_callback(dir_name=\"tensorflow_hub\", # save experiment logs here\n",
" experiment_name=\"resnet50V2\")]) # name of log files"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "8rs8hNWObeWJ",
"outputId": "6756abd2-abcc-41b6-ab67-7859d812085e"
},
"execution_count": 13,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Saving TensorBoard log files to: tensorflow_hub/resnet50V2/20230228-152728\n",
"Epoch 1/5\n",
"23/23 [==============================] - 19s 219ms/step - loss: 0.9993 - accuracy: 0.5091 - val_loss: 0.8047 - val_accuracy: 0.6491\n",
"Epoch 2/5\n",
"23/23 [==============================] - 2s 106ms/step - loss: 0.6376 - accuracy: 0.7356 - val_loss: 0.6863 - val_accuracy: 0.7018\n",
"Epoch 3/5\n",
"23/23 [==============================] - 3s 108ms/step - loss: 0.5183 - accuracy: 0.8115 - val_loss: 0.6317 - val_accuracy: 0.7018\n",
"Epoch 4/5\n",
"23/23 [==============================] - 2s 105ms/step - loss: 0.4382 - accuracy: 0.8664 - val_loss: 0.6110 - val_accuracy: 0.7368\n",
"Epoch 5/5\n",
"23/23 [==============================] - 3s 131ms/step - loss: 0.3842 - accuracy: 0.8790 - val_loss: 0.5968 - val_accuracy: 0.7456\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"plot_loss_curves(resnet_history)"
],
"metadata": {
"id": "TWetSQXzl6IJ",
"outputId": "d7b9d426-410f-40ed-d121-c63e7f109496",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 573
}
},
"execution_count": 15,
"outputs": [
{
"output_type": "display_data",
"data": {
"text/plain": [
"