File size: 8,570 Bytes
97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad 97dcf92 73666ad |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 |
import os
import optuna
import torch
import torch.nn as nn
import torch.optim as optim
import torch.utils.data
from configs import *
import data_loader
from torch.utils.tensorboard import SummaryWriter
import time
import numpy as np
import random
torch.cuda.empty_cache()
RANDOM_SEED1=42
random.seed(RANDOM_SEED1)
torch.cuda.manual_seed(RANDOM_SEED1)
torch.manual_seed(RANDOM_SEED1)
print("PyTorch Seed:", torch.initial_seed())
print("Random Seed:", random.getstate()[1][0])
print("PyTorch CUDA Seed:", torch.cuda.initial_seed())
# Define the constants for genetic algorithm
POPULATION_SIZE = 5
MUTATION_RATE = 0.05
CROSSOVER_RATE = 0.7
NUM_GENERATIONS = 5
EPOCHS = 5
EARLY_STOPPING_PATIENCE = 4
# Create a TensorBoard writer
writer = SummaryWriter(log_dir="output/tensorboard/tuning")
# Function to create or modify data loaders with the specified batch size
def create_data_loaders(batch_size):
train_loader, valid_loader = data_loader.load_data(
COMBINED_DATA_DIR + "1",
preprocess,
batch_size=batch_size,
)
return train_loader, valid_loader
# Create a TensorBoard writer
writer = SummaryWriter(log_dir="output/tensorboard/tuning")
model = MODEL.to(DEVICE)
# model.load_state_dict(torch.load(MODEL_SAVE_PATH, map_location=DEVICE))
def fitness_function(individual,model):
batch_size, lr,= individual
# Assuming you have a model, optimizer, and loss function defined
model = model.to(DEVICE)
optimizer = optim.Adam(model.parameters(), lr=lr)
criterion = nn.CrossEntropyLoss()
scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=NUM_EPOCHS)
# Define your data loaders using the given batch_size
train_loader, valid_loader = create_data_loaders(batch_size)
# Training loop
for epoch in range(EPOCHS):
model.train()
for batch_idx, (data, target) in enumerate(train_loader, 0):
data, target = data.to(DEVICE), target.to(DEVICE)
optimizer.zero_grad()
if model.__class__.__name__ == "GoogLeNet":
output = model(data).logits
else:
output = model(data)
loss = criterion(output, target)
loss.backward()
optimizer.step()
scheduler.step()
# Validation loop
model.eval()
correct = 0
with torch.no_grad():
for batch_idx, (data, target) in enumerate(valid_loader, 0):
data, target = data.to(DEVICE), target.to(DEVICE)
data, targets_a, targets_b, lam = cutmix_data(data, target, alpha=1)
output = model(data)
pred = output.argmax(dim=1, keepdim=True)
correct += pred.eq(target.view_as(pred)).sum().item()
accuracy = correct / len(valid_loader.dataset)
print(f"Epoch {epoch + 1}/{EPOCHS}, Accuracy: {accuracy:.4f}")
return accuracy,
def rand_bbox(size, lam):
W = size[2]
H = size[3]
cut_rat = np.sqrt(1.0 - lam)
cut_w = np.int_(W * cut_rat)
cut_h = np.int_(H * cut_rat)
# uniform
cx = np.random.randint(W)
cy = np.random.randint(H)
bbx1 = np.clip(cx - cut_w // 2, 0, W)
bby1 = np.clip(cy - cut_h // 2, 0, H)
bbx2 = np.clip(cx + cut_w // 2, 0, W)
bby2 = np.clip(cy + cut_h // 2, 0, H)
return bbx1, bby1, bbx2, bby2
def cutmix_data(input, target, alpha=1.0):
if alpha > 0:
lam = np.random.beta(alpha, alpha)
else:
lam = 1
batch_size = input.size()[0]
index = torch.randperm(batch_size)
rand_index = torch.randperm(input.size()[0])
bbx1, bby1, bbx2, bby2 = rand_bbox(input.size(), lam)
input[:, :, bbx1:bbx2, bby1:bby2] = input[rand_index, :, bbx1:bbx2, bby1:bby2]
lam = 1 - ((bbx2 - bbx1) * (bby2 - bby1) / (input.size()[-1] * input.size()[-2]))
targets_a = target
targets_b = target[rand_index]
return input, targets_a, targets_b, lam
def cutmix_criterion(criterion, outputs, targets_a, targets_b, lam):
return lam * criterion(outputs, targets_a) + (1 - lam) * criterion(outputs, targets_b)
# Function to create or modify data loaders with the specified batch size
def create_data_loaders(batch_size):
print(f"Batch Size (before conversion): {batch_size}")
batch_size = int(batch_size) # Ensure batch_size is an integer
print(f"Batch Size (after conversion): {batch_size}")
train_loader, valid_loader = data_loader.load_data(
COMBINED_DATA_DIR + "1",
preprocess,
batch_size=batch_size,
)
return train_loader, valid_loader
# Genetic algorithm initialization functions
def create_individual():
lr = abs(np.random.uniform(0.0006, 0.0009))
print(f"Generated lr: {lr}")
return creator.Individual([
int(np.random.choice([32])), # Choose a valid batch size
lr, # lr in log scale between 1e-4 and 1e-2
])
# Genetic algorithm evaluation function
def evaluate_individual(individual, model=MODEL):
batch_size, lr, = individual
lr=abs(lr)
# Assuming you have a model, optimizer, and loss function defined
model = model.to(DEVICE)
optimizer = optim.Adam(model.parameters(), lr=lr)
criterion = nn.CrossEntropyLoss()
# Define your data loaders using the given batch_size
train_loader, valid_loader = create_data_loaders(batch_size)
# Training loop
for epoch in range(EPOCHS):
model.train()
for batch_idx, (data, target) in enumerate(train_loader, 0):
data, target = data.to(DEVICE), target.to(DEVICE)
optimizer.zero_grad()
# Apply CutMix
data, targets_a, targets_b, lam = cutmix_data(data, target, alpha=1)
if model.__class__.__name__ == "GoogLeNet":
output = model(data).logits
else:
output = model(data)
loss = cutmix_criterion(criterion, output, targets_a, targets_b, lam)
loss.backward()
optimizer.step()
# Validation loop
model.eval()
correct = 0
with torch.no_grad():
for batch_idx, (data, target) in enumerate(valid_loader, 0):
data, target = data.to(DEVICE), target.to(DEVICE)
data, targets_a, targets_b, lam = cutmix_data(data, target, alpha=1)
output = model(data)
pred = output.argmax(dim=1, keepdim=True)
correct += pred.eq(target.view_as(pred)).sum().item()
accuracy = correct / len(valid_loader.dataset)
# Log accuracy or other metrics as needed
writer.add_scalar("Accuracy", accuracy, epoch)
print(f"Epoch {epoch + 1}/{EPOCHS}, Accuracy: {accuracy:.4f}")
# Return the accuracy (or any other metric you want to optimize)
return (accuracy,)
if __name__ == "__main__":
pruner = optuna.pruners.HyperbandPruner()
start_time = time.time()
study = optuna.create_study(
direction="maximize",
pruner=pruner,
study_name="hyperparameter_optimization",
storage="sqlite:///" + MODEL.__class__.__name__ + ".sqlite3",
)
from deap import base, creator, tools, algorithms
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", list, fitness=creator.FitnessMax)
toolbox = base.Toolbox()
toolbox.register("individual", create_individual)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
toolbox.register("evaluate", fitness_function, model=model)
toolbox.register("mate", tools.cxTwoPoint)
toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=0.1, indpb=MUTATION_RATE)
toolbox.register("select", tools.selTournament, tournsize=3)
population = toolbox.population(n=POPULATION_SIZE)
for ind in population:
print(type(ind))
fitness_value = evaluate_individual(ind, model)
ind.fitness.values = (fitness_value[0],)
algorithms.eaSimple(population, toolbox, cxpb=CROSSOVER_RATE, mutpb=MUTATION_RATE, ngen=NUM_GENERATIONS, stats=None, halloffame=None, verbose=True)
best_individual = tools.selBest(population, 1)[0]
best_batch_size, best_lr = best_individual
best_accuracy = evaluate_individual(best_individual, model)
print("Best Hyperparameters:")
print(f"Batch Size: {best_batch_size}")
print(f"Learning Rate: {best_lr}")
print(f"Best Accuracy: {best_accuracy[0]}")
end_time = time.time()
tuning_duration = end_time - start_time
print(f"Hyperparameter optimization took {tuning_duration:.2f} seconds.") |