Archives
Trending
Support
Login
clear text
XML
Django
JavaScript
MATLAB
C
C++
C#
Python
SQL
Shell
Bash
Markdown
YAML
JSON
HTML
CSS
PHP
Java
Ruby
Go
Rust
Swift
Kotlin
Arduino
TypeScript
Perl
Autohotkey
Lua
SQF
R
Scala
Haskell
Groovy
Dart
Clojure
VB.NET
Objective-C
PowerShell
Bash
CoffeeScript
Verilog
""" Font Classification using CNN - Detailed Parameter Explanations ============================================================== This script implements a Convolutional Neural Network (CNN) to classify alphabetic characters (A-Z) from font images with comprehensive parameter explanations. """ # ============================================================================= # 1. IMPORT REQUIRED LIBRARIES # ============================================================================= import tensorflow as tf import numpy as np from tensorflow import keras from keras import Sequential from keras.layers import Conv2D, MaxPooling2D, Dense, Dropout, Flatten from keras.preprocessing import image # Library Explanations: # - tensorflow: Main deep learning framework # - numpy: For numerical operations and array manipulations # - keras: High-level neural network API (part of TensorFlow) # - Sequential: Model type that allows stacking layers linearly # - Conv2D: 2D convolution layer for feature extraction # - MaxPooling2D: Pooling layer for dimension reduction # - Dense: Fully connected layer for classification # - Dropout: Regularization layer to prevent overfitting # - Flatten: Converts 2D feature maps to 1D vector # - image: Utilities for image loading and preprocessing # ============================================================================= # 2. LOAD AND PREPARE DATASET # ============================================================================= train_ds, val_ds = keras.utils.image_dataset_from_directory( "E:/Maroon/College/S9/DL/Fonts", # directory: Path to dataset folder # PURPOSE: Location of image dataset with subdirectories as classes # WHEN TO CHANGE: Update path to your actual dataset location # STRUCTURE: Each subdirectory (A/, B/, C/, etc.) becomes a class color_mode="grayscale", # color_mode: Image color format # PURPOSE: Determines number of color channels # OPTIONS: "grayscale" (1 channel), "rgb" (3 channels), "rgba" (4 channels) # WHEN TO CHANGE: Use "rgb" for colored images, "grayscale" for B&W subset="both", # subset: Which data splits to return # PURPOSE: Specifies training/validation split output # OPTIONS: "training", "validation", "both" # WHEN TO CHANGE: Use specific subset if you want only one split image_size=(28, 28), # image_size: Target image dimensions (height, width) # PURPOSE: Resizes all images to this size # IMPACT: Affects model input shape and computational requirements # WHEN TO CHANGE: Larger (64x64, 224x224) for more detail, smaller for speed validation_split=0.2, # validation_split: Fraction for validation set # PURPOSE: Percentage of data reserved for validation (20% here) # RANGE: 0.0 to 1.0 (typically 0.1 to 0.3) # WHEN TO CHANGE: 0.1-0.15 for large datasets, 0.2-0.3 for smaller datasets seed=1337 # seed: Random seed for reproducible splits # PURPOSE: Ensures same train/val split across runs # WHEN TO CHANGE: Different values for different splits, remove for random ) # ============================================================================= # 3. DATA NORMALIZATION # ============================================================================= train_ds = train_ds.map(lambda x, y: (tf.cast(x, tf.float32)/255.0, y)) val_ds = val_ds.map(lambda x, y: (tf.cast(x, tf.float32)/255.0, y)) # Parameter Explanations: # # .map() function: # - PURPOSE: Applies transformation to each batch in the dataset # - lambda x, y: Anonymous function where x=images, y=labels # # tf.cast(x, tf.float32): # - PURPOSE: Converts image data type from uint8 to float32 # - WHEN TO CHANGE: Use tf.float16 for memory savings, tf.float64 for precision # - WHY NEEDED: Neural networks work better with floating-point numbers # # /255.0: # - PURPOSE: Normalizes pixel values from [0,255] to [0,1] # - WHY CRITICAL: Prevents gradient explosion, helps faster convergence # - ALTERNATIVES: /127.5 - 1 for [-1,1] range, custom normalization for specific needs # ============================================================================= # 4. BUILD CNN MODEL ARCHITECTURE # ============================================================================= model = Sequential([ Conv2D(32, # filters: Number of feature detectors (kernels) # PURPOSE: How many different features to detect # WHEN TO INCREASE: More complex datasets (64, 128, 256) # WHEN TO DECREASE: Simpler datasets or less computation (16, 8) (5, 5), # kernel_size: Size of convolution window (height, width) # PURPOSE: Defines the receptive field size # OPTIONS: (3,3) for fine details, (5,5) for broader features, (7,7) for large patterns # WHEN TO CHANGE: Smaller for detailed features, larger for global patterns activation="relu", # activation: Non-linear activation function # PURPOSE: Introduces non-linearity for complex pattern learning # OPTIONS: "relu" (most common), "tanh", "sigmoid", "leaky_relu" # WHEN TO CHANGE: "leaky_relu" for dying ReLU, "tanh" for [-1,1] outputs padding="same", # padding: Controls output size after convolution # PURPOSE: Determines spatial dimension preservation # OPTIONS: "same" (keeps size), "valid" (reduces size) # WHEN TO USE: "same" to preserve dimensions, "valid" to reduce them input_shape=(28, 28, 1)), # input_shape: Input tensor dimensions (height, width, channels) # PURPOSE: Defines the expected input format # WHEN TO CHANGE: Must match your image dimensions and channels MaxPooling2D(padding="same"), # MaxPooling2D: Downsampling layer # pool_size: Default (2,2) - size of pooling window # PURPOSE: Reduces spatial dimensions while retaining features # WHEN TO CHANGE: (3,3) for aggressive downsampling, (1,1) for minimal # padding: Same options as Conv2D Conv2D(64, # filters: Increased to 64 for more complex feature detection # PURPOSE: Detects combinations of basic features from previous layer (5, 5), activation="relu", padding="same"), MaxPooling2D(padding="same"), # Second pooling layer for further dimension reduction Flatten(), # Flatten: Converts 2D feature maps to 1D vector # PURPOSE: Prepares data for dense layers # NO PARAMETERS: Automatically handles reshaping Dense(1024, # units: Number of neurons in dense layer # PURPOSE: Learning capacity of the layer # WHEN TO INCREASE: More complex patterns (2048, 4096) # WHEN TO DECREASE: Simpler datasets or prevent overfitting (512, 256) activation="relu"), # activation: Activation function for dense layer # PURPOSE: Non-linearity for complex pattern learning # TYPICAL: "relu" for hidden layers Dropout(0.2), # rate: Fraction of neurons to randomly disable # PURPOSE: Prevents overfitting during training # RANGE: 0.0 to 0.8 (typically 0.2 to 0.5) # WHEN TO INCREASE: If overfitting (0.3, 0.4, 0.5) # WHEN TO DECREASE: If underfitting (0.1, 0.15) Dense(26, # units: 26 for output classes (A-Z letters) # PURPOSE: One neuron per class for classification # WHEN TO CHANGE: Match number of classes in your dataset activation="sigmoid") # activation: Output layer activation # PURPOSE: Produces probability-like outputs # OPTIONS: "sigmoid" for multi-label, "softmax" for multi-class # NOTE: "softmax" might be more appropriate for single-class prediction ]) # ============================================================================= # 5. COMPILE AND TRAIN THE MODEL # ============================================================================= model.compile( optimizer="adam", # optimizer: Weight update algorithm # PURPOSE: How the model learns from errors # OPTIONS: "adam" (adaptive), "sgd" (basic), "rmsprop" (RNN-friendly) # WHEN TO CHANGE: "sgd" with momentum for fine-tuning # CUSTOM: keras.optimizers.Adam(learning_rate=0.001) for custom LR loss="sparse_categorical_crossentropy", # loss: Error measurement function # PURPOSE: Quantifies prediction errors # WHEN TO USE: Multi-class with integer labels (0,1,2,...) # ALTERNATIVES: "categorical_crossentropy" for one-hot, # "binary_crossentropy" for binary classification metrics=["accuracy"] # metrics: Additional monitoring metrics # PURPOSE: Track performance during training # OPTIONS: ["accuracy"], ["precision"], ["recall"], ["f1_score"] # WHEN TO ADD: Use precision/recall for imbalanced datasets ) model.fit( train_ds, # x: Training data # PURPOSE: Data used to update model weights # FORMAT: tf.data.Dataset with (images, labels) epochs=20, # epochs: Number of complete training passes # PURPOSE: How many times to see entire dataset # WHEN TO INCREASE: If loss still decreasing (30, 50, 100) # WHEN TO DECREASE: If overfitting early (10, 15) # MONITORING: Watch validation loss to avoid overfitting validation_data=val_ds # validation_data: Data for performance monitoring # PURPOSE: Evaluates model during training without affecting weights # WHY IMPORTANT: Detects overfitting, monitors generalization # WHEN TO SKIP: Only for very small datasets (not recommended) ) # Additional useful parameters (not used but available): # batch_size: Number of samples per weight update (default from dataset) # callbacks: [EarlyStopping, ModelCheckpoint, ReduceLROnPlateau] for automation # verbose: 0 (silent), 1 (progress bar), 2 (one line per epoch) # ============================================================================= # 6. LOAD TEST IMAGE FOR PREDICTION # ============================================================================= img = image.load_img( "E:/Maroon/College/S9/DL/Fonts/test1.png", # path: File path to test image # PURPOSE: Location of image to classify # WHEN TO CHANGE: Test different images # FORMATS: PNG, JPG, JPEG, BMP, GIF supported target_size=(28, 28), # target_size: Resize dimensions (height, width) # PURPOSE: Match model's expected input size # MUST MATCH: Model's input_shape requirements # WHEN TO CHANGE: Only if model input size changes color_mode="grayscale" # color_mode: Color channel specification # PURPOSE: Match model's expected channels # OPTIONS: "grayscale" (1), "rgb" (3), "rgba" (4) # MUST MATCH: Model's input channel requirements ) img_array = np.expand_dims( image.img_to_array(img)/255.0, # array: Preprocessed image array # img_to_array(): PIL image → numpy array (28,28,1) # /255.0: Normalize to [0,1] (CRITICAL: match training preprocessing) axis=0 # axis: Dimension to expand # PURPOSE: Add batch dimension for model input # RESULT: (28,28,1) → (1,28,28,1) # WHY NEEDED: Model expects batched input even for single image # OPTIONS: axis=0 (beginning), axis=-1 (end) ) # ============================================================================= # 7. MAKE PREDICTION # ============================================================================= pred = model.predict( img_array # x: Input data for prediction # PURPOSE: Preprocessed image ready for classification # EXPECTED SHAPE: (batch_size, height, width, channels) # DATA TYPE: Must be float32 and normalized ) # Additional predict() parameters (not used but available): # batch_size: Control memory usage for large datasets (32, 64, 128) # verbose: 0 (silent), 1 (progress bar), 2 (one line per batch) # steps: Number of batches (for generator inputs) pred_class = np.argmax( pred, # a: Prediction array with probability scores # PURPOSE: Array of class probabilities # SHAPE: (1, 26) - 1 sample, 26 class probabilities axis=1 # axis: Dimension for finding maximum # PURPOSE: Find class with highest probability # OPTIONS: axis=0 (across samples), axis=1 (across classes) # RESULT: Index of most confident prediction )[0] # [0]: Extract scalar from array # PURPOSE: Get single prediction from batch # WHY NEEDED: argmax returns shape (1,), we want scalar # ============================================================================= # 8. DISPLAY PREDICTION RESULT # ============================================================================= class_values = [chr(i) for i in range(65, 91)] # Create A-Z mapping # chr(): Converts ASCII code to character # range(65, 91): ASCII codes for A(65) through Z(90) # WHEN TO CHANGE: range(97, 123) for lowercase a-z # ALTERNATIVES: # - import string; class_values = list(string.ascii_uppercase) # - Manual list: ['A', 'B', 'C', ..., 'Z'] print("Predicted values:", class_values[pred_class]) # print() parameters (not used but available): # sep: Separator between arguments (default ' ') # end: String at end (default '\n') # file: Output destination (default stdout) # ============================================================================= # SUMMARY OF KEY PARAMETER TUNING GUIDELINES # ============================================================================= """ COMMON PARAMETER ADJUSTMENTS: 1. OVERFITTING (High training accuracy, low validation accuracy): - Increase dropout rate (0.3, 0.4, 0.5) - Reduce model complexity (fewer filters, smaller dense layers) - Add more data augmentation - Reduce epochs 2. UNDERFITTING (Low training and validation accuracy): - Increase model complexity (more filters, larger dense layers) - Decrease dropout rate (0.1, 0.15) - Increase epochs - Adjust learning rate 3. SLOW TRAINING: - Increase batch_size (64, 128) - Use smaller image_size (16x16 instead of 28x28) - Reduce model complexity 4. MEMORY ISSUES: - Decrease batch_size (16, 8) - Use tf.float16 instead of tf.float32 - Reduce image_size - Reduce model complexity 5. POOR ACCURACY: - Try different optimizers (sgd, rmsprop) - Adjust learning rate - Use data augmentation - Ensure proper data normalization """
Mark as private (unlisted)
for 30 minutes
for 6 hours
for 1 day
for 1 week
for 1 month
for 1 year
everlasting (like CCCP)