Skip to content

Latest commit

 

History

History
506 lines (384 loc) · 19.4 KB

File metadata and controls

506 lines (384 loc) · 19.4 KB

Transfer Learning for Computer Vision

Slide 1: Understanding Transfer Learning in Computer Vision

Transfer Learning is a powerful technique that allows AI models to leverage knowledge gained from one task to perform better on a different, but related task. In computer vision, this approach has revolutionized how we train models to recognize objects, faces, and actions in images with less data and computational resources.

import tensorflow as tf
from tensorflow.keras.applications import VGG16
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
from tensorflow.keras.models import Model

# Load pre-trained VGG16 model
base_model = VGG16(weights='imagenet', include_top=False)

# Add custom layers
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation='relu')(x)
predictions = Dense(200, activation='softmax')(x)

# Create new model
model = Model(inputs=base_model.input, outputs=predictions)

# Freeze pre-trained layers
for layer in base_model.layers:
    layer.trainable = False

# Compile and train the model
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

Slide 2: The Power of Pre-trained Models

Pre-trained models form the backbone of transfer learning in computer vision. These models have been trained on massive datasets like ImageNet, which contains millions of images across thousands of categories. By leveraging these pre-trained models, we can achieve high accuracy on new tasks with far less data and training time.

import matplotlib.pyplot as plt
import numpy as np

# Simulating learning curves
def learning_curve(data_size, method):
    if method == 'transfer':
        return 1 - np.exp(-data_size / 1000)
    else:
        return 1 - np.exp(-data_size / 10000)

data_sizes = np.linspace(100, 10000, 100)
transfer_accuracy = learning_curve(data_sizes, 'transfer')
traditional_accuracy = learning_curve(data_sizes, 'traditional')

plt.figure(figsize=(10, 6))
plt.plot(data_sizes, transfer_accuracy, label='Transfer Learning')
plt.plot(data_sizes, traditional_accuracy, label='Traditional Learning')
plt.xlabel('Training Data Size')
plt.ylabel('Model Accuracy')
plt.title('Transfer Learning vs Traditional Learning')
plt.legend()
plt.show()

Slide 3: Fine-tuning for Specific Tasks

One of the key advantages of transfer learning is the ability to fine-tune pre-trained models for specific tasks. This process involves unfreezing some of the top layers of the pre-trained model and training them on the new task-specific data. This allows the model to adapt its learned features to the new task while retaining the general knowledge gained from the original training.

# Unfreeze the top layers of the base model
for layer in base_model.layers[-4:]:
    layer.trainable = True

# Recompile the model with a lower learning rate
model.compile(optimizer=tf.keras.optimizers.Adam(1e-5),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# Fine-tune the model
history = model.fit(train_generator,
                    steps_per_epoch=100,
                    epochs=10,
                    validation_data=validation_generator,
                    validation_steps=50)

Slide 4: Feature Extraction with Transfer Learning

Another approach in transfer learning is feature extraction. Instead of fine-tuning the pre-trained model, we use it as a fixed feature extractor. The pre-trained model's convolutional base is used to extract meaningful features from images, which are then fed into a new classifier trained on the specific task.

# Use pre-trained model as feature extractor
feature_extractor = tf.keras.Model(
    inputs=base_model.input,
    outputs=base_model.get_layer('block5_pool').output
)

# Extract features from your dataset
features = feature_extractor.predict(x_train)

# Train a new classifier on these features
classifier = tf.keras.Sequential([
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(256, activation='relu'),
    tf.keras.layers.Dropout(0.5),
    tf.keras.layers.Dense(num_classes, activation='softmax')
])

classifier.compile(optimizer='adam',
                   loss='categorical_crossentropy',
                   metrics=['accuracy'])

classifier.fit(features, y_train, epochs=20, validation_split=0.2)

Slide 5: Real-World Example: Medical Imaging

Transfer learning has made significant impacts in medical imaging. For instance, in diagnosing skin lesions, models pre-trained on general image datasets can be fine-tuned to classify different types of skin conditions with high accuracy, even with limited medical image data.

from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.preprocessing.image import ImageDataGenerator

# Load pre-trained MobileNetV2 model
base_model = MobileNetV2(weights='imagenet', include_top=False, input_shape=(224, 224, 3))

# Add custom layers for skin lesion classification
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(128, activation='relu')(x)
predictions = Dense(7, activation='softmax')(x)  # 7 classes of skin lesions

model = Model(inputs=base_model.input, outputs=predictions)

# Freeze base model layers
for layer in base_model.layers:
    layer.trainable = False

# Compile the model
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# Data augmentation for medical images
datagen = ImageDataGenerator(
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    horizontal_flip=True,
    zoom_range=0.2
)

# Train the model
model.fit(datagen.flow(x_train, y_train, batch_size=32),
          steps_per_epoch=len(x_train) // 32,
          epochs=20,
          validation_data=(x_val, y_val))

Slide 6: Real-World Example: Autonomous Vehicles

Transfer learning plays a crucial role in developing computer vision systems for autonomous vehicles. Pre-trained models can be adapted to recognize road signs, pedestrians, and other vehicles, significantly reducing the amount of training data needed for these specific tasks.

import tensorflow as tf
from tensorflow.keras.applications import ResNet50V2
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
from tensorflow.keras.models import Model

# Load pre-trained ResNet50V2 model
base_model = ResNet50V2(weights='imagenet', include_top=False, input_shape=(224, 224, 3))

# Add custom layers for road sign recognition
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(512, activation='relu')(x)
predictions = Dense(50, activation='softmax')(x)  # Assuming 50 types of road signs

model = Model(inputs=base_model.input, outputs=predictions)

# Freeze base model layers
for layer in base_model.layers:
    layer.trainable = False

# Compile the model
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# Custom data generator for road sign images
def road_sign_generator(batch_size=32):
    while True:
        # Load and preprocess batch of road sign images
        batch_x, batch_y = load_road_sign_batch(batch_size)
        yield batch_x, batch_y

# Train the model
model.fit(road_sign_generator(),
          steps_per_epoch=1000,
          epochs=20,
          validation_data=validation_generator,
          validation_steps=50)

Slide 7: Overcoming Limited Data with Transfer Learning

One of the most significant advantages of transfer learning is its ability to perform well with limited data. This is particularly useful in domains where large datasets are hard to come by or expensive to create. By leveraging pre-trained models, we can achieve high accuracy even with small, domain-specific datasets.

import numpy as np
import matplotlib.pyplot as plt

def accuracy_vs_data_size(data_sizes):
    transfer_learning = 1 - 0.5 * np.exp(-data_sizes / 1000)
    from_scratch = 1 - 0.9 * np.exp(-data_sizes / 10000)
    return transfer_learning, from_scratch

data_sizes = np.linspace(100, 10000, 100)
transfer, scratch = accuracy_vs_data_size(data_sizes)

plt.figure(figsize=(10, 6))
plt.plot(data_sizes, transfer, label='Transfer Learning')
plt.plot(data_sizes, scratch, label='Training from Scratch')
plt.xlabel('Training Data Size')
plt.ylabel('Model Accuracy')
plt.title('Accuracy vs. Training Data Size')
plt.legend()
plt.show()

Slide 8: Adapting Pre-trained Models to New Domains

While pre-trained models are often trained on general image datasets, they can be adapted to work well in specialized domains. This process, known as domain adaptation, involves fine-tuning the model on a smaller dataset from the target domain while preserving the general features learned from the larger dataset.

import tensorflow as tf
from tensorflow.keras.applications import InceptionV3
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
from tensorflow.keras.models import Model

# Load pre-trained InceptionV3 model
base_model = InceptionV3(weights='imagenet', include_top=False)

# Add custom layers for the new domain
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation='relu')(x)
predictions = Dense(num_classes, activation='softmax')(x)

model = Model(inputs=base_model.input, outputs=predictions)

# Freeze base model layers
for layer in base_model.layers:
    layer.trainable = False

# Compile the model
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])

# Custom data generator for the new domain
def domain_specific_generator(batch_size=32):
    while True:
        # Load and preprocess batch of domain-specific images
        batch_x, batch_y = load_domain_specific_batch(batch_size)
        yield batch_x, batch_y

# Train the model on the new domain
model.fit(domain_specific_generator(),
          steps_per_epoch=100,
          epochs=10,
          validation_data=validation_generator,
          validation_steps=50)

# Fine-tune the model by unfreezing some layers
for layer in model.layers[-20:]:
    layer.trainable = True

model.compile(optimizer=tf.keras.optimizers.Adam(1e-5),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

model.fit(domain_specific_generator(),
          steps_per_epoch=100,
          epochs=5,
          validation_data=validation_generator,
          validation_steps=50)

Slide 9: Transfer Learning Architectures

Various architectures have been developed to facilitate transfer learning in computer vision. These include popular models like VGG, ResNet, Inception, and EfficientNet. Each of these architectures has its own strengths and is suited for different types of tasks.

import tensorflow as tf
from tensorflow.keras.applications import VGG16, ResNet50, InceptionV3, EfficientNetB0

def create_transfer_model(base_model, num_classes):
    x = base_model.output
    x = tf.keras.layers.GlobalAveragePooling2D()(x)
    x = tf.keras.layers.Dense(1024, activation='relu')(x)
    predictions = tf.keras.layers.Dense(num_classes, activation='softmax')(x)
    return tf.keras.Model(inputs=base_model.input, outputs=predictions)

# Create transfer learning models with different architectures
vgg_model = create_transfer_model(VGG16(weights='imagenet', include_top=False), 10)
resnet_model = create_transfer_model(ResNet50(weights='imagenet', include_top=False), 10)
inception_model = create_transfer_model(InceptionV3(weights='imagenet', include_top=False), 10)
efficientnet_model = create_transfer_model(EfficientNetB0(weights='imagenet', include_top=False), 10)

# Compare model sizes
models = [vgg_model, resnet_model, inception_model, efficientnet_model]
model_names = ['VGG16', 'ResNet50', 'InceptionV3', 'EfficientNetB0']

for name, model in zip(model_names, models):
    print(f"{name} parameters: {model.count_params():,}")

Slide 10: Handling Class Imbalance in Transfer Learning

Class imbalance is a common problem in many real-world datasets. Transfer learning can help mitigate this issue by providing a strong starting point, but additional techniques may be necessary to achieve optimal performance on imbalanced datasets.

import tensorflow as tf
from tensorflow.keras.applications import MobileNetV2
from tensorflow.keras.layers import Dense, GlobalAveragePooling2D
from tensorflow.keras.models import Model
from tensorflow.keras.utils import class_weight

# Load pre-trained MobileNetV2 model
base_model = MobileNetV2(weights='imagenet', include_top=False, input_shape=(224, 224, 3))

# Add custom layers
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(128, activation='relu')(x)
predictions = Dense(num_classes, activation='softmax')(x)

model = Model(inputs=base_model.input, outputs=predictions)

# Freeze base model layers
for layer in base_model.layers:
    layer.trainable = False

# Calculate class weights
class_weights = class_weight.compute_class_weight('balanced',
                                                  np.unique(y_train),
                                                  y_train)
class_weight_dict = dict(enumerate(class_weights))

# Compile the model
model.compile(optimizer='adam',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# Train the model with class weights
history = model.fit(x_train, y_train,
                    epochs=20,
                    validation_split=0.2,
                    class_weight=class_weight_dict)

# Plot training history
plt.plot(history.history['accuracy'], label='Training Accuracy')
plt.plot(history.history['val_accuracy'], label='Validation Accuracy')
plt.title('Model Accuracy')
plt.xlabel('Epoch')
plt.ylabel('Accuracy')
plt.legend()
plt.show()

Slide 11: Transfer Learning for Object Detection

Transfer learning is not limited to image classification; it's also widely used in object detection tasks. Popular object detection architectures like YOLO (You Only Look Once) and SSD (Single Shot Detector) can benefit from transfer learning to improve their performance on specific datasets.

import tensorflow as tf
from tensorflow.keras.applications.mobilenet_v2 import MobileNetV2
from tensorflow.keras.layers import Conv2D, Reshape

# Load pre-trained MobileNetV2 as base model
base_model = MobileNetV2(weights='imagenet', include_top=False, input_shape=(300, 300, 3))

# Add object detection heads
x = base_model.output
x = Conv2D(256, 3, padding='same', activation='relu')(x)
x = Conv2D(256, 3, padding='same', activation='relu')(x)

# Output layer for bounding box regression and class prediction
num_classes = 20  # Number of object classes to detect
num_boxes = 4  # Number of default boxes per cell
outputs = Conv2D(num_boxes * (4 + num_classes), 1, padding='same')(x)
outputs = Reshape((-1, 4 + num_classes))(outputs)

model = tf.keras.Model(inputs=base_model.input, outputs=outputs)

# Freeze base model layers
for layer in base_model.layers:
    layer.trainable = False

# Compile the model
model.compile(optimizer='adam', loss='mse')  # Simplified loss for demonstration

# Train the model (pseudo-code)
# model.fit(train_data, train_labels, epochs=10, validation_split=0.2)

Slide 12: Transfer Learning in Natural Language Processing

While our focus has been on computer vision, transfer learning has also revolutionized Natural Language Processing (NLP). Models like BERT and GPT, pre-trained on vast amounts of text data, can be fine-tuned for specific NLP tasks with remarkable results.

from transformers import BertTokenizer, TFBertForSequenceClassification
import tensorflow as tf

# Load pre-trained BERT model and tokenizer
model_name = 'bert-base-uncased'
tokenizer = BertTokenizer.from_pretrained(model_name)
model = TFBertForSequenceClassification.from_pretrained(model_name)

# Prepare text data
texts = ["I love this movie!", "This film was terrible."]
labels = [1, 0]  # 1 for positive, 0 for negative

# Tokenize and encode the texts
encodings = tokenizer(texts, truncation=True, padding=True)

# Convert to TensorFlow dataset
dataset = tf.data.Dataset.from_tensor_slices((
    dict(encodings),
    labels
)).batch(2)

# Compile and fine-tune the model
optimizer = tf.keras.optimizers.Adam(learning_rate=5e-5)
model.compile(optimizer=optimizer, loss=model.compute_loss, metrics=['accuracy'])
model.fit(dataset, epochs=3)

Slide 13: Challenges and Limitations of Transfer Learning

While transfer learning offers numerous benefits, it's important to be aware of its limitations. These include the potential for negative transfer, where pre-training on dissimilar tasks can harm performance, and the risk of overfitting when fine-tuning on small datasets.

import numpy as np
import matplotlib.pyplot as plt

def simulate_learning(transfer_similarity, dataset_size):
    transfer_perf = 1 - np.exp(-dataset_size / 1000) * transfer_similarity
    scratch_perf = 1 - np.exp(-dataset_size / 5000)
    return transfer_perf, scratch_perf

sizes = np.linspace(100, 10000, 100)

plt.figure(figsize=(12, 6))
for similarity in [0.2, 0.5, 0.8]:
    transfer, scratch = simulate_learning(similarity, sizes)
    plt.plot(sizes, transfer, label=f'Transfer (similarity={similarity})')

plt.plot(sizes, scratch, label='Training from scratch', linestyle='--')
plt.xlabel('Dataset Size')
plt.ylabel('Model Performance')
plt.title('Impact of Task Similarity on Transfer Learning')
plt.legend()
plt.show()

Slide 14: Future Directions in Transfer Learning

The field of transfer learning continues to evolve rapidly. Future directions include developing more efficient pre-training methods, exploring cross-modal transfer learning (e.g., from vision to language), and creating more adaptable models that can perform well across a wider range of tasks with minimal fine-tuning.

# Pseudocode for a hypothetical multi-modal transfer learning system

class MultiModalTransferModel:
    def __init__(self):
        self.vision_encoder = load_pretrained_vision_model()
        self.text_encoder = load_pretrained_text_model()
        self.joint_encoder = create_joint_encoder()
    
    def encode_image(self, image):
        return self.vision_encoder(image)
    
    def encode_text(self, text):
        return self.text_encoder(text)
    
    def joint_encode(self, image, text):
        vision_features = self.encode_image(image)
        text_features = self.encode_text(text)
        return self.joint_encoder(vision_features, text_features)
    
    def fine_tune(self, task, data):
        # Adapt the model for a specific task using the joint representation
        task_specific_model = create_task_specific_layers(task)
        for batch in data:
            joint_features = self.joint_encode(batch['image'], batch['text'])
            loss = task_specific_model(joint_features, batch['label'])
            update_model_parameters(loss)

# Usage
model = MultiModalTransferModel()
model.fine_tune('image_captioning', image_caption_dataset)
model.fine_tune('visual_question_answering', vqa_dataset)

Slide 15: Additional Resources

For those interested in delving deeper into transfer learning in computer vision, here are some valuable resources:

  1. "A Survey on Deep Transfer Learning" by Chuanqi Tan et al. (2018) ArXiv link: https://arxiv.org/abs/1808.01974
  2. "How transferable are features in deep neural networks?" by Jason Yosinski et al. (2014) ArXiv link: https://arxiv.org/abs/1411.1792
  3. "Taskonomy: Disentangling Task Transfer Learning" by Amir R. Zamir et al. (2018) ArXiv link: https://arxiv.org/abs/1804.08328

These papers provide in-depth insights into the theoretical foundations and practical applications of transfer learning in various domains of computer vision and beyond.