{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":3362,"databundleVersionId":31148,"sourceType":"competition"}],"dockerImageVersionId":30626,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"Notebook create to practice different concepps from  https://www.coursera.org/learn/convolutional-neural-networks-tensorflow/\n\nVersion 1: \n* Pratice to work with folder and files in Python.\n* flow_from_directory with validation.\n* Simple model\n* shown training history and how Convolutionas layers extract the trining features.\n\nVersion 2:\n* Load images in grayscale\n\nVersion 3:\n* Add image augmentation with keras ImageDataGenerator","metadata":{}},{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\nimport os\nimport zipfile\nimport shutil\nimport imghdr\nimport random\n\nimport tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\n\n\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{"execution":{"iopub.status.busy":"2023-12-16T18:10:08.089608Z","iopub.execute_input":"2023-12-16T18:10:08.090383Z","iopub.status.idle":"2023-12-16T18:10:20.345765Z","shell.execute_reply.started":"2023-12-16T18:10:08.090338Z","shell.execute_reply":"2023-12-16T18:10:20.344821Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Create working folder structure for image files.\nbase_dir = '/kaggle/working/dogs_cats'\n\n# Empty directory to prevent FileExistsError is the function is run several times\nif os.path.exists(base_dir):\n    shutil.rmtree(base_dir)\n    \nos.mkdir(os.path.join(base_dir))","metadata":{"execution":{"iopub.status.busy":"2023-12-16T18:10:20.347441Z","iopub.execute_input":"2023-12-16T18:10:20.348063Z","iopub.status.idle":"2023-12-16T18:10:20.353687Z","shell.execute_reply.started":"2023-12-16T18:10:20.348031Z","shell.execute_reply":"2023-12-16T18:10:20.352455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#unzip image files and create working folder.\ntrain_images_file='/kaggle/input/dogs-vs-cats/train.zip'\ntest_images_file='/kaggle/input/dogs-vs-cats/test1.zip'\n\n#extract all images to cats folder\nzip_ref   = zipfile.ZipFile(train_images_file, 'r')\nzip_ref.extractall(base_dir)\nzip_ref.close()\n\n#extract all images to cats folder\nzip_ref   = zipfile.ZipFile(test_images_file, 'r')\nzip_ref.extractall(base_dir)\nzip_ref.close()\n\ntrain_dir=os.path.join(base_dir, 'train')\ntest_dir=os.path.join(base_dir, 'test1')\n\n# Directory with training cat/dog pictures\ntrain_cats_dir = os.path.join(train_dir, 'cats')\ntrain_dogs_dir = os.path.join(train_dir, 'dogs')\n\nos.mkdir(os.path.join(train_cats_dir))\nos.mkdir(os.path.join(train_dogs_dir)) \n\nfor rootdir, dirs, files in os.walk(base_dir):\n    for subdir in dirs:\n        print(os.path.join(rootdir, subdir))\n","metadata":{"execution":{"iopub.status.busy":"2023-12-16T18:10:20.355252Z","iopub.execute_input":"2023-12-16T18:10:20.355620Z","iopub.status.idle":"2023-12-16T18:10:36.052350Z","shell.execute_reply.started":"2023-12-16T18:10:20.355585Z","shell.execute_reply":"2023-12-16T18:10:36.051422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#get min image size in test data set.\nfile_list=[file for file in os.listdir(train_dir) if os.path.isfile(os.path.join(test_dir, file))]\nfiles_sorted_by_size = sorted(files, key=lambda filename: os.path.getsize(os.path.join(test_dir, filename)))  \nfor filename in files_sorted_by_size[:5]:\n    print(filename,os.path.getsize(os.path.join(test_dir, filename)))","metadata":{"execution":{"iopub.status.busy":"2023-12-16T18:10:36.054449Z","iopub.execute_input":"2023-12-16T18:10:36.054770Z","iopub.status.idle":"2023-12-16T18:10:36.268687Z","shell.execute_reply.started":"2023-12-16T18:10:36.054744Z","shell.execute_reply":"2023-12-16T18:10:36.267467Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def image_validator(image_path):\n    validation=False\n    image_type=imghdr.what(image_path)\n    image_size=os.path.getsize(image_path)\n    supported_image_types=['png', 'jpg', 'jpeg', 'bmp', 'ppm', 'tif', 'tiff']\n    min_image_size=1000\n    if (image_type in supported_image_types) & (image_size > min_image_size):  \n        validation=True    \n    return validation","metadata":{"execution":{"iopub.status.busy":"2023-12-16T18:10:36.270125Z","iopub.execute_input":"2023-12-16T18:10:36.270459Z","iopub.status.idle":"2023-12-16T18:10:36.278378Z","shell.execute_reply.started":"2023-12-16T18:10:36.270428Z","shell.execute_reply":"2023-12-16T18:10:36.277110Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Validate images files and move into two folders splited by it class.\nfile_list=[file for file in os.listdir(train_dir) if os.path.isfile(os.path.join(train_dir, file))]\nfor filename in file_list:\n    if image_validator(os.path.join(train_dir, filename)):\n        if filename.split('.')[0] == 'dog':\n            os.rename(os.path.join(train_dir, filename),os.path.join(train_dogs_dir, filename))\n        else:\n            os.rename(os.path.join(train_dir, filename),os.path.join(train_cats_dir, filename))\n    \n    else:        \n        print(f'{filename} is not valida image file,  so ignoring.')\n        print(imghdr.what(os.path.join(train_dir, filename)),  os.path.getsize(os.path.join(train_dir, filename)))\n        os.remove(os.path.join(train_dir, filename))\n        \n        \n# Training splits and test folders\nprint(f\"There are {len(os.listdir(train_cats_dir))} images of cats for training\")\nprint(f\"There are {len(os.listdir(train_dogs_dir))} images of dogs for training\")\nprint(f\"There are {len(os.listdir(test_dir))} images in test folder\")","metadata":{"execution":{"iopub.status.busy":"2023-12-16T18:10:36.279741Z","iopub.execute_input":"2023-12-16T18:10:36.280115Z","iopub.status.idle":"2023-12-16T18:10:37.894863Z","shell.execute_reply.started":"2023-12-16T18:10:36.280079Z","shell.execute_reply":"2023-12-16T18:10:37.893871Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Create imagen generator.\ndef train_val_generators(train_dir):\n    \n    train_datagen = ImageDataGenerator(rescale=1./255,\n                                       validation_split=0.2,\n                                        rotation_range=40,\n                                       width_shift_range=0.2,\n                                       height_shift_range=0.2,\n                                       shear_range=0.2,\n                                       zoom_range=0.2,\n                                       horizontal_flip=True,\n                                       fill_mode='nearest')    \n    \n    train_generator = train_datagen.flow_from_directory(directory=train_dir,\n                                                      batch_size=32,\n                                                      class_mode='binary',\n                                                      subset='training',\n                                                    color_mode=\"grayscale\",\n                                                      target_size=(150, 150))\n    \n    validation_generator = train_datagen.flow_from_directory(directory=train_dir,\n                                                                batch_size=32,\n                                                                class_mode='binary',\n                                                                subset='validation',\n                                                                 color_mode=\"grayscale\",\n                                                                target_size=(150, 150))\n    return train_generator, validation_generator","metadata":{"execution":{"iopub.status.busy":"2023-12-16T18:10:37.896412Z","iopub.execute_input":"2023-12-16T18:10:37.896725Z","iopub.status.idle":"2023-12-16T18:10:37.903639Z","shell.execute_reply.started":"2023-12-16T18:10:37.896696Z","shell.execute_reply":"2023-12-16T18:10:37.902697Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_generator, validation_generator = train_val_generators(train_dir)","metadata":{"execution":{"iopub.status.busy":"2023-12-16T18:10:37.904781Z","iopub.execute_input":"2023-12-16T18:10:37.905109Z","iopub.status.idle":"2023-12-16T18:10:38.935089Z","shell.execute_reply.started":"2023-12-16T18:10:37.905075Z","shell.execute_reply":"2023-12-16T18:10:38.934119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import keras_cv\n\ndef create_model():\n    model = tf.keras.models.Sequential([\n      tf.keras.layers.Conv2D(16, (3,3), activation='relu', input_shape=(150, 150, 1)),\n      tf.keras.layers.MaxPooling2D(2,2),\n      tf.keras.layers.Conv2D(32, (3,3), activation='relu'),\n      tf.keras.layers.MaxPooling2D(2,2),\n      tf.keras.layers.Conv2D(64, (3,3), activation='relu'),\n      tf.keras.layers.MaxPooling2D(2,2),\n      tf.keras.layers.Flatten(),\n      tf.keras.layers.Dense(512, activation='relu'),\n      tf.keras.layers.Dense(1, activation='sigmoid')\n  ])\n    model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001),\n                loss='binary_crossentropy',\n                metrics=['accuracy'])\n    \n    return model","metadata":{"execution":{"iopub.status.busy":"2023-12-16T18:10:38.936628Z","iopub.execute_input":"2023-12-16T18:10:38.937326Z","iopub.status.idle":"2023-12-16T18:10:44.166889Z","shell.execute_reply.started":"2023-12-16T18:10:38.937289Z","shell.execute_reply":"2023-12-16T18:10:44.165740Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = create_model()\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2023-12-16T18:10:44.169654Z","iopub.execute_input":"2023-12-16T18:10:44.170242Z","iopub.status.idle":"2023-12-16T18:10:50.416528Z","shell.execute_reply.started":"2023-12-16T18:10:44.170212Z","shell.execute_reply":"2023-12-16T18:10:50.414168Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(train_generator,\n                    epochs=20,\n                    verbose=1,\n                    validation_data=validation_generator)","metadata":{"execution":{"iopub.status.busy":"2023-12-16T18:10:50.417624Z","iopub.execute_input":"2023-12-16T18:10:50.417898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n#-----------------------------------------------------------\n# Retrieve a list of list results on training and test data\n# sets for each training epoch\n#-----------------------------------------------------------\nacc      = history.history[     'accuracy' ]\nval_acc  = history.history[ 'val_accuracy' ]\nloss     = history.history[    'loss' ]\nval_loss = history.history['val_loss' ]\n\nepochs   = range(len(acc)) # Get number of epochs\n\n#------------------------------------------------\n# Plot training and validation accuracy per epoch\n#------------------------------------------------\nplt.plot  ( epochs,     acc )\nplt.plot  ( epochs, val_acc )\nplt.title ('Training and validation accuracy')\nplt.figure()\n\n#------------------------------------------------\n# Plot training and validation loss per epoch\n#------------------------------------------------\nplt.plot  ( epochs,     loss )\nplt.plot  ( epochs, val_loss )\nplt.title ('Training and validation loss'   )","metadata":{"execution":{"iopub.status.busy":"2023-12-16T18:14:51.684354Z","iopub.execute_input":"2023-12-16T18:14:51.685699Z","iopub.status.idle":"2023-12-16T18:14:52.161968Z","shell.execute_reply.started":"2023-12-16T18:14:51.685650Z","shell.execute_reply":"2023-12-16T18:14:52.159895Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.utils import img_to_array, load_img\nnp.seterr(divide='ignore', invalid='ignore')\n\n# Define a new Model that will take an image as input, and will output\n# intermediate representations for all layers in the previous model\nsuccessive_outputs = [layer.output for layer in model.layers]\nvisualization_model = tf.keras.models.Model(inputs = model.input, outputs = successive_outputs)\n\n# Prepare a random input image from the training set.\ncat_img_files = [os.path.join(train_cats_dir, f) for f in os.listdir(train_cats_dir)]\ndog_img_files = [os.path.join(train_dogs_dir, f) for f in os.listdir(train_dogs_dir)]\nimg_path = random.choice(cat_img_files + dog_img_files)\nimg = load_img(img_path, target_size=(150, 150),color_mode=\"grayscale\",)  # this is a PIL image\nx   = img_to_array(img)                           # Numpy array with shape (150, 150, 3)\nx   = x.reshape((1,) + x.shape)                   # Numpy array with shape (1, 150, 150, 3)\n\n# Scale by 1/255\nx /= 255.0\n\n# Run the image through the network, thus obtaining all\n# intermediate representations for this image.\nsuccessive_feature_maps = visualization_model.predict(x)\n\n# These are the names of the layers, so you can have them as part of our plot\nlayer_names = [layer.name for layer in model.layers]\n\n# Display the representations\nfor layer_name, feature_map in zip(layer_names, successive_feature_maps):\n  \n  if len(feature_map.shape) == 4:\n    \n    #-------------------------------------------\n    # Just do this for the conv / maxpool layers, not the fully-connected layers\n    #-------------------------------------------\n    n_features = feature_map.shape[-1]  # number of features in the feature map\n    size       = feature_map.shape[ 1]  # feature map shape (1, size, size, n_features)\n    \n    # Tile the images in this matrix\n    display_grid = np.zeros((size, size * n_features))\n    \n    #-------------------------------------------------\n    # Postprocess the feature to be visually palatable\n    #-------------------------------------------------\n    for i in range(n_features):\n        x  = feature_map[0, :, :, i]\n        x -= x.mean()\n        x /= x.std ()\n        x *=  64\n        x += 128\n        x  = np.clip(x, 0, 255).astype('uint8')\n        display_grid[:, i * size : (i + 1) * size] = x # Tile each filter into a horizontal grid\n\n    #-----------------\n    # Display the grid\n    #-----------------\n    scale = 20. / n_features\n    plt.figure( figsize=(scale * n_features, scale) )\n    plt.title ( layer_name )\n    plt.grid  ( False )\n    plt.imshow( display_grid, aspect='auto', cmap='gray' ) ","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}