<jupyter_start><jupyter_text>Hand Gastures.Predicting hand gastures based on the dataset found on [Kaggle](https://www.kaggle.com/flintytub49/hand-gestures-black-and-white) which contains images of 5 classes which are black and white. Imports<jupyter_code>import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.preprocessing import image, image_dataset_from_directory<jupyter_output><empty_output><jupyter_text>Data.We have 5 classes of images which are:    1. Blank2. First3. ThumpUp4. Two5. YoWE have a folder data that contain folders of each class. Basically the file structures looks as follows:    ```data    - Blank        ..    - Fist        ..    - ThumpUp        ..    - Two        ..    - Yo        ..```<jupyter_code>datagen = image.ImageDataGenerator(
    rescale=1.0 / 255,
    data_format="channels_last",
    dtype=tf.float32,
    validation_split=0.1,
)

train_ds = datagen.flow_from_directory(
    'data',
    target_size=(224, 224),
    color_mode='grayscale',
    class_mode='categorical',
    batch_size=32,
    shuffle=True,
    seed=42,
    subset='training',
    interpolation='nearest',
)
validation_ds = datagen.flow_from_directory(
    'data',
    target_size=(224, 224),
    color_mode='grayscale',
    class_mode='categorical',
    batch_size=32,
    shuffle=True,
    seed=42,
    subset='validation',
    interpolation='nearest',
)<jupyter_output><empty_output><jupyter_text>Class Names<jupyter_code>train_ds.class_indices
classes = dict([(v, k) for (k, v) in train_ds.class_indices.items() ])<jupyter_output><empty_output><jupyter_text>Displaying some images<jupyter_code>for batch in train_ds:
    break
batch[1][1]
def plot_images(images, labels_true, cols=5):
    rows = 3
    fig = plt.figure()
    fig.set_size_inches(cols * 2, rows * 2)
    labels_true = np.argmax(labels_true, axis=1)
    for i, (image, label_true) in enumerate(zip(images, labels_true)):
        plt.subplot(rows, cols, i + 1)
        plt.axis('off')
        plt.imshow(image, cmap="gray")
        plt.title(classes[label_true], color ='g', fontsize=16 )

plot_images(batch[0][:24], batch[1][:24], cols=8)
batch[0].shape<jupyter_output><empty_output><jupyter_text>Creating a `NN`The `NN` achitecture will look as follows:```        [ ConvBlock ] -> Conv2D -> BatchNormalization -> ReLU -> MaxPooling2D -> Dropout              |             |        [Flatten Layer / GlobalMaxPooling2D]             |        [Output Block] -> Dense Layers```<jupyter_code>class ConvBlock(keras.layers.Layer):
    def __init__(self, in_features, kernel_size=(3,3), dropout=.5):
        super(ConvBlock, self).__init__()
        self.conv        = keras.layers.Conv2D(in_features, kernel_size=kernel_size, padding='same')
        self.bn          = keras.layers.BatchNormalization()
        self.relu        = keras.layers.ReLU()
        self.max_pool_2d = keras.layers.MaxPooling2D()
        self.dropout     = keras.layers.Dropout(dropout)
        
    def call(self, in_tensor, training=False):
        x = self.conv(in_tensor)
        x = self.bn(x, training=training)
        x = self.relu(x)
        x = self.max_pool_2d(x)
        return self.dropout(x)
        

model = keras.Sequential([
    keras.layers.Input(shape=(224, 224, 1)),
    ConvBlock(64, kernel_size=(3,3), dropout=.5),
    ConvBlock(512, kernel_size=(3,3), dropout=.2),
    ConvBlock(128, kernel_size=(3,3), dropout=.3),
    keras.layers.Flatten(),
    keras.layers.Dense(512, activation='relu'),
    keras.layers.Dense(5, activation='softmax')
], name="hand_gesture_model")

model.summary()<jupyter_output><empty_output><jupyter_text>Trainning the model.<jupyter_code>model.compile(
    loss = keras.losses.SparseCategoricalCrossentropy(from_logits=False),
    optimizer = keras.optimizers.Adam(),
    metrics = ["acc"]
)

lr_reduction = keras.callbacks.ReduceLROnPlateau(
    monitor='val_acc', 
    patience=3, 
    verbose=1, 
    factor=0.5, 
    min_lr=0.00001
)

early_stopping = keras.callbacks.EarlyStopping(
    monitor='val_loss',
    min_delta=0,
    patience=5,
    verbose=0, mode='auto'
)

history = model.fit(
    train_ds,
    batch_size=32,
    epochs =5,
    validation_data = train_ds,
    verbose = 1,
    shuffle=True,
    callbacks = [lr_reduction, early_stopping]
)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12916570903240635, 'fraction_numerical': 0.02551137669501264, 'mean_word_length': 3.5192107995846316, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 31, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '543121', 'license': 'MIT', 'n_tokens_mistral': 1607, 'n_tokens_neox': 1524, 'n_words': 279, 'path': '01_Classification/04_Hand_Gasture/.ipynb_checkpoints/01_Hand_Gasture_Classification-checkpoint.ipynb', 'repo_name': 'CrispenGari/Computer-Vision-In-TensorFlow', 'size': '4351'}