๐ง Neural Networks Core Philosophy
๐ฏ The Universal Function Approximators
Neural Networks are computational systems inspired by biological neural networks. They consist of interconnected layers of neurons that learn complex patterns through training. The Universal Approximation Theorem states that a feedforward network with a single hidden layer can approximate any continuous function.
Why Neural Networks?
Deep Learning revolution โ Neural networks learn hierarchical feature representations automatically. Lower layers learn simple features, higher layers learn complex abstractions. This hierarchical learning enables breakthroughs in computer vision, NLP, and reinforcement learning.
import tensorflow as tf
from tensorflow import keras
# Simple MLP with Keras
model = keras.Sequential([
keras.layers.Dense(64, activation='relu', input_shape=(10,)),
keras.layers.Dense(32, activation='relu'),
keras.layers.Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
print(model.summary())๐งฌ The Perceptron & Neuron
๐ฏ The Fundamental Unit
Neuron: y = f(wยทx + b). Perceptron uses step function. Modern neurons use differentiable activations (ReLU, sigmoid).
Biological Inspiration
Dendrites receive inputs โ cell body sums them โ axon transmits output if threshold exceeded. Artificial neurons mimic this with weighted sums and activation functions.
import numpy as np
def neuron(x, w, b, activation='relu'):
z = np.dot(w, x) + b
if activation == 'relu':
return max(0, z)
elif activation == 'sigmoid':
return 1/(1 + np.exp(-z))
elif activation == 'linear':
return z
x = np.array([0.5, -0.2, 0.8])
w = np.array([0.1, -0.3, 0.5])
b = 0.1
print(f"Neuron output (ReLU): {neuron(x, w, b, 'relu')}")๐ Activation Functions
๐ฏ Introducing Non-Linearity
ReLU: max(0,x), Sigmoid: 1/(1+eโปหฃ), Tanh: (eหฃ-eโปหฃ)/(eหฃ+eโปหฃ), LeakyReLU, ELU, Swish.
Choosing Activations
ReLU is default for hidden layers (fast, avoids vanishing gradient). Sigmoid/Tanh for output (binary classification / bounded outputs). Use LeakyReLU to avoid dead neurons.
from tensorflow.keras.layers import Activation
import numpy as np
x = np.array([-2, -1, 0, 1, 2])
print(f"ReLU: {np.maximum(0, x)}")
print(f"Sigmoid: {1/(1 + np.exp(-x))}")
# In Keras: Dense(64, activation='relu')๐ Forward Propagation
๐ฏ Inference Pass
Input โ Layer 1 โ Activation โ Layer 2 โ Activation โ ... โ Output.
Matrix Operations
Forward pass is essentially matrix multiplications: aหก = f(Wหก ยท aหกโปยน + bหก). This is highly parallelizable on GPUs.
def forward_pass(X, weights, biases, activations):
A = X
for W, b, act in zip(weights, biases, activations):
Z = np.dot(A, W) + b
if act == 'relu': A = np.maximum(0, Z)
elif act == 'sigmoid': A = 1/(1 + np.exp(-Z))
elif act == 'linear': A = Z
return A
# X shape: (batch_size, input_dim)๐ Backpropagation & Chain Rule
๐ฏ Learning via Gradient Descent
Backprop computes gradients of loss w.r.t. weights using chain rule. ฮดหก = (Wหกโบยน)แต ยท ฮดหกโบยน โ f'(zหก).
Chain Rule at Scale
Backprop efficiently computes gradients by propagating errors backwards. This algorithm made deep learning possible โ it scales to millions of parameters.
# Backpropagation in PyTorch (conceptual)
import torch
x = torch.tensor([1.0, 2.0, 3.0], requires_grad=True)
w = torch.tensor([0.5, -0.2, 0.3], requires_grad=True)
b = torch.tensor(0.1, requires_grad=True)
y = torch.sum(x * w + b)
y.backward() # Computes gradients
print(f"Gradients: {w.grad}")โก Optimizers
๐ฏ Gradient Descent Variants
SGD, Momentum, RMSprop, Adam, AdamW, Nadam. Adam is the default choice.
Adaptive Learning Rates
Adam combines momentum and adaptive learning rates. It's robust to hyperparameters and works well for most tasks.
from tensorflow.keras.optimizers import Adam, SGD
# Adam optimizer
model.compile(optimizer=Adam(learning_rate=0.001))
# SGD with momentum
model.compile(optimizer=SGD(learning_rate=0.01, momentum=0.9))๐ Loss Functions
๐ฏ Measuring Prediction Error
MSE: (y - ลท)ยฒ. Cross-Entropy: -ฮฃ yแตข log(ลทแตข). Binary Cross-Entropy, Categorical Cross-Entropy.
Loss Selection Guide
MSE for regression. Binary Cross-Entropy for binary classification. Categorical Cross-Entropy for multi-class classification.
model.compile(loss='binary_crossentropy', metrics=['accuracy'])
# Regression: model.compile(loss='mse', metrics=['mae'])
# Multi-class: model.compile(loss='categorical_crossentropy')๐ก๏ธ Regularization
๐ฏ Preventing Overfitting
Dropout: randomly drop neurons during training. L1/L2 weight decay. Batch Normalization: normalize layer outputs.
Regularization Techniques
Dropout forces the network to learn redundant representations. Batch Normalization accelerates training and provides regularization. Early stopping is simple but effective.
model = keras.Sequential([
keras.layers.Dense(256, activation='relu', kernel_regularizer='l2'),
keras.layers.Dropout(0.5),
keras.layers.BatchNormalization(),
keras.layers.Dense(1, activation='sigmoid')
])๐ฏ Weight Initialization
๐ฏ Starting the Learning
Xavier/Glorot (for sigmoid/tanh), He initialization (for ReLU). Prevents vanishing/exploding gradients.
Initialization Importance
Poor initialization can stall training. He initialization sets variance = 2/n_in, suitable for ReLU.
from tensorflow.keras.initializers import HeNormal, GlorotUniform
# He initialization for ReLU
model.add(Dense(64, activation='relu', kernel_initializer=HeNormal()))
# Xavier for sigmoid/tanh
model.add(Dense(64, activation='tanh', kernel_initializer=GlorotUniform()))๐๏ธ Architectures
๐ฏ MLP, CNN, RNN, Transformers
MLP: fully connected. CNN: spatial hierarchies (images). RNN/LSTM: sequences (text, time series). Transformers: attention mechanism.
Architecture Selection
Choose CNN for images, RNN/LSTM for sequences, Transformers for language, MLP for tabular data.
# CNN example
cnn = keras.Sequential([
keras.layers.Conv2D(32, (3,3), activation='relu', input_shape=(28,28,1)),
keras.layers.MaxPooling2D(2,2),
keras.layers.Flatten(),
keras.layers.Dense(10, activation='softmax')
])
# RNN example
rnn = keras.Sequential([
keras.layers.SimpleRNN(64, input_shape=(None, 10)),
keras.layers.Dense(1, activation='sigmoid')
])๐ Transfer Learning & Fine-Tuning
๐ฏ Leveraging Pre-Trained Models
Use models pre-trained on large datasets (ImageNet, BERT). Fine-tune on your specific task with less data.
Transfer Learning Benefits
Reduces training time, works well with limited data, achieves state-of-the-art results.
from tensorflow.keras.applications import ResNet50
base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(224,224,3))
base_model.trainable = False
model = keras.Sequential([
base_model,
keras.layers.GlobalAveragePooling2D(),
keras.layers.Dense(10, activation='softmax')
])โ๏ธ Hyperparameter Tuning
๐ฏ Learning Rate, Batch Size, Layers
Use grid search, random search, or Bayesian optimization. Key: learning rate, batch size, number of layers/neurons.
Tuning Strategy
Start with learning rate (most important). Then optimize architecture. Use learning rate schedulers (ReduceLROnPlateau).
from tensorflow.keras.callbacks import ReduceLROnPlateau
lr_scheduler = ReduceLROnPlateau(factor=0.5, patience=5)
model.fit(X_train, y_train, epochs=50, callbacks=[lr_scheduler])
# Use Keras Tuner for advanced hyperparameter search๐ฆ TensorFlow/Keras API
๐ฏ High-Level Deep Learning API
Sequential API, Functional API, Subclassing API. Keras provides simple, intuitive interface for building neural networks.
Functional API for Complex Models
Use Functional API for multi-input/multi-output models, residual connections, shared layers.
# Functional API example
inputs = keras.Input(shape=(10,))
x = keras.layers.Dense(64, activation='relu')(inputs)
x = keras.layers.Dense(32, activation='relu')(x)
outputs = keras.layers.Dense(1, activation='sigmoid')(x)
model = keras.Model(inputs=inputs, outputs=outputs)
model.compile(optimizer='adam', loss='binary_crossentropy')๐ Deployment & Production
๐ฏ Serving Neural Networks
Save as SavedModel, ONNX, TensorFlow Serving, PyTorch Serve, TFLite for mobile, TensorRT for optimization.
Production Considerations
Model optimization: quantization, pruning, distillation. Monitor drift and retrain periodically.
# Save model
model.save('model.h5')
# Export to TensorFlow SavedModel
model.export('saved_model')
# Convert to TFLite (for mobile)
converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
# Save to file
with open('model.tflite', 'wb') as f:
f.write(tflite_model)