Spaces:
Runtime error
Runtime error
Update
Browse files
configs.py
CHANGED
@@ -7,16 +7,22 @@ import torch.nn as nn
|
|
7 |
from torchvision.models import (
|
8 |
squeezenet1_0,
|
9 |
SqueezeNet1_0_Weights,
|
|
|
|
|
|
|
|
|
10 |
mobilenet_v3_small,
|
11 |
MobileNet_V3_Small_Weights,
|
12 |
)
|
13 |
-
|
|
|
|
|
14 |
|
15 |
# Constants
|
16 |
RANDOM_SEED = 123
|
17 |
-
BATCH_SIZE =
|
18 |
-
NUM_EPOCHS =
|
19 |
-
LEARNING_RATE = 0.
|
20 |
STEP_SIZE = 10
|
21 |
GAMMA = 0.9
|
22 |
DEVICE = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
@@ -28,6 +34,8 @@ EXTERNAL_DATA_DIR = r"data/train/external/Task "
|
|
28 |
COMBINED_DATA_DIR = r"data/train/combined/Task "
|
29 |
TEMP_DATA_DIR = "data/temp/"
|
30 |
NUM_CLASSES = 7
|
|
|
|
|
31 |
EARLY_STOPPING_PATIENCE = 20
|
32 |
CLASSES = [
|
33 |
"Alzheimer Disease",
|
@@ -42,7 +50,7 @@ MODEL_SAVE_PATH = r"output/checkpoints/model.pth"
|
|
42 |
|
43 |
|
44 |
class SqueezeNet1_0WithDropout(nn.Module):
|
45 |
-
def __init__(self, num_classes=
|
46 |
super(SqueezeNet1_0WithDropout, self).__init__()
|
47 |
squeezenet = squeezenet1_0(weights=SqueezeNet1_0_Weights.DEFAULT)
|
48 |
self.features = squeezenet.features
|
@@ -52,79 +60,94 @@ class SqueezeNet1_0WithDropout(nn.Module):
|
|
52 |
nn.ReLU(inplace=True),
|
53 |
nn.AdaptiveAvgPool2d((1, 1)),
|
54 |
)
|
|
|
|
|
|
|
55 |
|
56 |
def forward(self, x):
|
57 |
x = self.features(x)
|
58 |
x = self.classifier(x)
|
|
|
59 |
x = torch.flatten(x, 1)
|
60 |
return x
|
61 |
|
62 |
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
|
|
|
|
|
|
74 |
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
|
|
80 |
|
81 |
|
82 |
-
class
|
83 |
-
def __init__(self, num_classes=
|
84 |
-
super(
|
85 |
-
|
86 |
-
self.features =
|
87 |
self.classifier = nn.Sequential(
|
88 |
-
nn.Conv2d(
|
89 |
nn.BatchNorm2d(num_classes), # add batch normalization
|
90 |
nn.ReLU(inplace=True),
|
91 |
nn.AdaptiveAvgPool2d((1, 1)),
|
92 |
)
|
|
|
|
|
|
|
93 |
|
94 |
def forward(self, x):
|
95 |
x = self.features(x)
|
96 |
x = self.classifier(x)
|
|
|
97 |
x = torch.flatten(x, 1)
|
98 |
return x
|
99 |
|
100 |
|
101 |
-
class
|
102 |
-
def __init__(self, num_classes=
|
103 |
-
super(
|
104 |
-
|
105 |
-
self.features =
|
106 |
-
*list(resnet.children())[:-2]
|
107 |
-
) # Remove last 2 layers (avgpool and fc)
|
108 |
self.classifier = nn.Sequential(
|
|
|
|
|
|
|
109 |
nn.AdaptiveAvgPool2d((1, 1)),
|
110 |
-
nn.Flatten(),
|
111 |
-
nn.Linear(512, num_classes),
|
112 |
-
nn.BatchNorm1d(num_classes), # Add batch normalization
|
113 |
)
|
|
|
|
|
|
|
114 |
|
115 |
def forward(self, x):
|
116 |
x = self.features(x)
|
117 |
x = self.classifier(x)
|
|
|
118 |
x = torch.flatten(x, 1)
|
119 |
return x
|
120 |
|
121 |
|
122 |
MODEL = SqueezeNet1_0WithDropout(num_classes=7)
|
|
|
123 |
print(CLASSES)
|
124 |
|
125 |
preprocess = transforms.Compose(
|
126 |
[
|
127 |
-
transforms.Resize((
|
128 |
transforms.ToTensor(), # Convert to tensor
|
129 |
transforms.Grayscale(num_output_channels=3), # Convert to 3 channels
|
130 |
# Normalize 3 channels
|
|
|
7 |
from torchvision.models import (
|
8 |
squeezenet1_0,
|
9 |
SqueezeNet1_0_Weights,
|
10 |
+
squeezenet1_1,
|
11 |
+
SqueezeNet1_1_Weights,
|
12 |
+
shufflenet_v2_x2_0,
|
13 |
+
ShuffleNet_V2_X2_0_Weights,
|
14 |
mobilenet_v3_small,
|
15 |
MobileNet_V3_Small_Weights,
|
16 |
)
|
17 |
+
|
18 |
+
import torch.nn.functional as F
|
19 |
+
from pytorchcv.model_provider import get_model as ptcv_get_model
|
20 |
|
21 |
# Constants
|
22 |
RANDOM_SEED = 123
|
23 |
+
BATCH_SIZE = 16
|
24 |
+
NUM_EPOCHS = 40
|
25 |
+
LEARNING_RATE = 0.00016662575248025378
|
26 |
STEP_SIZE = 10
|
27 |
GAMMA = 0.9
|
28 |
DEVICE = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
|
|
34 |
COMBINED_DATA_DIR = r"data/train/combined/Task "
|
35 |
TEMP_DATA_DIR = "data/temp/"
|
36 |
NUM_CLASSES = 7
|
37 |
+
LABEL_SMOOTHING_EPSILON = 0.1
|
38 |
+
MIXUP_ALPHA = 0.2
|
39 |
EARLY_STOPPING_PATIENCE = 20
|
40 |
CLASSES = [
|
41 |
"Alzheimer Disease",
|
|
|
50 |
|
51 |
|
52 |
class SqueezeNet1_0WithDropout(nn.Module):
|
53 |
+
def __init__(self, num_classes, dropout_prob=0.5):
|
54 |
super(SqueezeNet1_0WithDropout, self).__init__()
|
55 |
squeezenet = squeezenet1_0(weights=SqueezeNet1_0_Weights.DEFAULT)
|
56 |
self.features = squeezenet.features
|
|
|
60 |
nn.ReLU(inplace=True),
|
61 |
nn.AdaptiveAvgPool2d((1, 1)),
|
62 |
)
|
63 |
+
self.dropout = nn.Dropout(
|
64 |
+
dropout_prob
|
65 |
+
) # Add dropout layer with the specified probability
|
66 |
|
67 |
def forward(self, x):
|
68 |
x = self.features(x)
|
69 |
x = self.classifier(x)
|
70 |
+
x = F.dropout(x, training=self.training) # Apply dropout during training
|
71 |
x = torch.flatten(x, 1)
|
72 |
return x
|
73 |
|
74 |
|
75 |
+
class SqueezeNet1_1WithDropout(nn.Module):
|
76 |
+
def __init__(self, num_classes, dropout_prob=0.5):
|
77 |
+
super(SqueezeNet1_1WithDropout, self).__init__()
|
78 |
+
squeezenet = squeezenet1_1(weights=SqueezeNet1_1_Weights.DEFAULT)
|
79 |
+
self.features = squeezenet.features
|
80 |
+
self.classifier = nn.Sequential(
|
81 |
+
nn.Conv2d(512, num_classes, kernel_size=1),
|
82 |
+
nn.BatchNorm2d(num_classes), # add batch normalization
|
83 |
+
nn.ReLU(inplace=True),
|
84 |
+
nn.AdaptiveAvgPool2d((1, 1)),
|
85 |
+
)
|
86 |
+
self.dropout = nn.Dropout(
|
87 |
+
dropout_prob
|
88 |
+
) # Add dropout layer with the specified probability
|
89 |
|
90 |
+
def forward(self, x):
|
91 |
+
x = self.features(x)
|
92 |
+
x = self.classifier(x)
|
93 |
+
x = F.dropout(x, training=self.training) # Apply dropout during training
|
94 |
+
x = torch.flatten(x, 1)
|
95 |
+
return x
|
96 |
|
97 |
|
98 |
+
class ShuffleNetV2WithDropout(nn.Module):
|
99 |
+
def __init__(self, num_classes, dropout_prob=0.5):
|
100 |
+
super(ShuffleNetV2WithDropout, self).__init__()
|
101 |
+
shufflenet = shufflenet_v2_x2_0(weights=ShuffleNet_V2_X2_0_Weights.DEFAULT)
|
102 |
+
self.features = shufflenet.features
|
103 |
self.classifier = nn.Sequential(
|
104 |
+
nn.Conv2d(1024, num_classes, kernel_size=1),
|
105 |
nn.BatchNorm2d(num_classes), # add batch normalization
|
106 |
nn.ReLU(inplace=True),
|
107 |
nn.AdaptiveAvgPool2d((1, 1)),
|
108 |
)
|
109 |
+
self.dropout = nn.Dropout(
|
110 |
+
dropout_prob
|
111 |
+
) # Add dropout layer with the specified probability
|
112 |
|
113 |
def forward(self, x):
|
114 |
x = self.features(x)
|
115 |
x = self.classifier(x)
|
116 |
+
x = F.dropout(x, training=self.training) # Apply dropout during training
|
117 |
x = torch.flatten(x, 1)
|
118 |
return x
|
119 |
|
120 |
|
121 |
+
class MobileNetV3SmallWithDropout(nn.Module):
|
122 |
+
def __init__(self, num_classes, dropout_prob=0.5):
|
123 |
+
super(MobileNetV3SmallWithDropout, self).__init__()
|
124 |
+
mobilenet = mobilenet_v3_small(weights=MobileNet_V3_Small_Weights.DEFAULT)
|
125 |
+
self.features = mobilenet.features
|
|
|
|
|
126 |
self.classifier = nn.Sequential(
|
127 |
+
nn.Conv2d(576, num_classes, kernel_size=1),
|
128 |
+
nn.BatchNorm2d(num_classes), # add batch normalization
|
129 |
+
nn.ReLU(inplace=True),
|
130 |
nn.AdaptiveAvgPool2d((1, 1)),
|
|
|
|
|
|
|
131 |
)
|
132 |
+
self.dropout = nn.Dropout(
|
133 |
+
dropout_prob
|
134 |
+
) # Add dropout layer with the specified probability
|
135 |
|
136 |
def forward(self, x):
|
137 |
x = self.features(x)
|
138 |
x = self.classifier(x)
|
139 |
+
x = F.dropout(x, training=self.training) # Apply dropout during training
|
140 |
x = torch.flatten(x, 1)
|
141 |
return x
|
142 |
|
143 |
|
144 |
MODEL = SqueezeNet1_0WithDropout(num_classes=7)
|
145 |
+
# MODEL = ptcv_get_model("sqnxt23v5_w2", pretrained=False, num_classes=7)
|
146 |
print(CLASSES)
|
147 |
|
148 |
preprocess = transforms.Compose(
|
149 |
[
|
150 |
+
transforms.Resize((274, 274)), # Resize to 112x112
|
151 |
transforms.ToTensor(), # Convert to tensor
|
152 |
transforms.Grayscale(num_output_channels=3), # Convert to 3 channels
|
153 |
# Normalize 3 channels
|
eval.py
CHANGED
@@ -1,30 +1,31 @@
|
|
1 |
import os
|
2 |
import torch
|
3 |
-
|
4 |
import pathlib
|
5 |
from PIL import Image
|
6 |
-
from torchmetrics import ConfusionMatrix, Accuracy, F1Score
|
7 |
import matplotlib.pyplot as plt
|
8 |
from sklearn.metrics import (
|
9 |
classification_report,
|
10 |
precision_recall_curve,
|
|
|
|
|
|
|
|
|
11 |
roc_curve,
|
12 |
auc,
|
13 |
-
confusion_matrix,
|
14 |
)
|
|
|
15 |
from configs import *
|
16 |
from data_loader import load_data # Import the load_data function
|
17 |
-
import numpy as np
|
18 |
|
19 |
# Constants
|
20 |
DEVICE = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
21 |
|
22 |
# Load the model
|
23 |
MODEL = MODEL.to(DEVICE)
|
24 |
-
MODEL.load_state_dict(torch.load(
|
25 |
MODEL.eval()
|
26 |
|
27 |
-
|
28 |
def predict_image(image_path, model, transform):
|
29 |
model.eval()
|
30 |
correct_predictions = 0
|
@@ -38,9 +39,6 @@ def predict_image(image_path, model, transform):
|
|
38 |
predicted_labels = []
|
39 |
predicted_scores = [] # To store predicted class probabilities
|
40 |
|
41 |
-
accuracy_metric = Accuracy(num_classes=NUM_CLASSES, task="multiclass")
|
42 |
-
f1_metric = F1Score(num_classes=NUM_CLASSES, task="multiclass")
|
43 |
-
|
44 |
with torch.no_grad():
|
45 |
for image_file in images:
|
46 |
print("---------------------------")
|
@@ -67,22 +65,20 @@ def predict_image(image_path, model, transform):
|
|
67 |
correct_predictions += 1
|
68 |
|
69 |
# Calculate accuracy and f1 score
|
70 |
-
accuracy =
|
71 |
print("Accuracy:", accuracy)
|
72 |
-
f1 =
|
73 |
print("Weighted F1 Score:", f1)
|
74 |
|
75 |
# Convert the lists to tensors
|
76 |
predicted_labels_tensor = torch.tensor(predicted_labels)
|
77 |
true_classes_tensor = torch.tensor(true_classes)
|
78 |
|
79 |
-
#
|
80 |
-
conf_matrix =
|
81 |
-
conf_matrix(predicted_labels_tensor, true_classes_tensor)
|
82 |
|
83 |
# Plot the confusion matrix
|
84 |
-
conf_matrix.
|
85 |
-
conf_matrix.plot()
|
86 |
plt.title("Confusion Matrix")
|
87 |
plt.show()
|
88 |
|
@@ -92,8 +88,20 @@ def predict_image(image_path, model, transform):
|
|
92 |
true_classes, predicted_labels, target_names=class_names
|
93 |
)
|
94 |
print("Classification Report:\n", report)
|
95 |
-
|
96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
97 |
|
98 |
|
99 |
# Call predict_image function with your image path
|
|
|
1 |
import os
|
2 |
import torch
|
3 |
+
import numpy as np
|
4 |
import pathlib
|
5 |
from PIL import Image
|
|
|
6 |
import matplotlib.pyplot as plt
|
7 |
from sklearn.metrics import (
|
8 |
classification_report,
|
9 |
precision_recall_curve,
|
10 |
+
accuracy_score,
|
11 |
+
f1_score,
|
12 |
+
confusion_matrix,
|
13 |
+
ConfusionMatrixDisplay,
|
14 |
roc_curve,
|
15 |
auc,
|
|
|
16 |
)
|
17 |
+
from sklearn.preprocessing import label_binarize
|
18 |
from configs import *
|
19 |
from data_loader import load_data # Import the load_data function
|
|
|
20 |
|
21 |
# Constants
|
22 |
DEVICE = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
|
23 |
|
24 |
# Load the model
|
25 |
MODEL = MODEL.to(DEVICE)
|
26 |
+
MODEL.load_state_dict(torch.load(MODEL_SAVE_PATH, map_location=DEVICE))
|
27 |
MODEL.eval()
|
28 |
|
|
|
29 |
def predict_image(image_path, model, transform):
|
30 |
model.eval()
|
31 |
correct_predictions = 0
|
|
|
39 |
predicted_labels = []
|
40 |
predicted_scores = [] # To store predicted class probabilities
|
41 |
|
|
|
|
|
|
|
42 |
with torch.no_grad():
|
43 |
for image_file in images:
|
44 |
print("---------------------------")
|
|
|
65 |
correct_predictions += 1
|
66 |
|
67 |
# Calculate accuracy and f1 score
|
68 |
+
accuracy = accuracy_score(true_classes, predicted_labels)
|
69 |
print("Accuracy:", accuracy)
|
70 |
+
f1 = f1_score(true_classes, predicted_labels, average="weighted")
|
71 |
print("Weighted F1 Score:", f1)
|
72 |
|
73 |
# Convert the lists to tensors
|
74 |
predicted_labels_tensor = torch.tensor(predicted_labels)
|
75 |
true_classes_tensor = torch.tensor(true_classes)
|
76 |
|
77 |
+
# Calculate the confusion matrix
|
78 |
+
conf_matrix = confusion_matrix(true_classes, predicted_labels)
|
|
|
79 |
|
80 |
# Plot the confusion matrix
|
81 |
+
ConfusionMatrixDisplay(confusion_matrix=conf_matrix, display_labels=CLASSES).plot(cmap=plt.cm.Blues)
|
|
|
82 |
plt.title("Confusion Matrix")
|
83 |
plt.show()
|
84 |
|
|
|
88 |
true_classes, predicted_labels, target_names=class_names
|
89 |
)
|
90 |
print("Classification Report:\n", report)
|
91 |
+
|
92 |
+
# Calculate precision and recall for each class
|
93 |
+
true_classes_binary = label_binarize(true_classes, classes=range(NUM_CLASSES))
|
94 |
+
precision, recall, _ = precision_recall_curve(
|
95 |
+
true_classes_binary.ravel(), np.array(predicted_scores).ravel()
|
96 |
+
)
|
97 |
+
|
98 |
+
# Plot precision-recall curve
|
99 |
+
plt.figure(figsize=(10, 6))
|
100 |
+
plt.plot(recall, precision)
|
101 |
+
plt.title("Precision-Recall Curve")
|
102 |
+
plt.xlabel("Recall")
|
103 |
+
plt.ylabel("Precision")
|
104 |
+
plt.show()
|
105 |
|
106 |
|
107 |
# Call predict_image function with your image path
|
train.py
CHANGED
@@ -7,12 +7,44 @@ from models import *
|
|
7 |
from torch.utils.tensorboard import SummaryWriter
|
8 |
from configs import *
|
9 |
import data_loader
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
|
12 |
def setup_tensorboard():
|
13 |
return SummaryWriter(log_dir="output/tensorboard/training")
|
14 |
|
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
def load_and_preprocess_data():
|
17 |
return data_loader.load_data(
|
18 |
RAW_DATA_DIR + str(TASK),
|
@@ -26,7 +58,7 @@ def initialize_model_optimizer_scheduler():
|
|
26 |
model = MODEL.to(DEVICE)
|
27 |
criterion = nn.CrossEntropyLoss()
|
28 |
optimizer = optim.Adam(model.parameters(), lr=LEARNING_RATE)
|
29 |
-
scheduler = optim.lr_scheduler.
|
30 |
return model, criterion, optimizer, scheduler
|
31 |
|
32 |
|
@@ -35,7 +67,7 @@ def plot_and_log_metrics(metrics_dict, step, writer, prefix="Train"):
|
|
35 |
writer.add_scalar(f"{prefix}/{metric_name}", metric_value, step)
|
36 |
|
37 |
|
38 |
-
def train_one_epoch(model, criterion, optimizer, train_loader, epoch):
|
39 |
model.train()
|
40 |
running_loss = 0.0
|
41 |
total_train = 0
|
@@ -44,11 +76,15 @@ def train_one_epoch(model, criterion, optimizer, train_loader, epoch):
|
|
44 |
for i, (inputs, labels) in enumerate(train_loader, 0):
|
45 |
inputs, labels = inputs.to(DEVICE), labels.to(DEVICE)
|
46 |
optimizer.zero_grad()
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
|
|
|
|
|
|
|
|
52 |
loss.backward()
|
53 |
optimizer.step()
|
54 |
running_loss += loss.item()
|
@@ -107,7 +143,7 @@ def main_training_loop():
|
|
107 |
print("Learning rate:", scheduler.get_last_lr()[0])
|
108 |
|
109 |
avg_train_loss, train_accuracy = train_one_epoch(
|
110 |
-
model, criterion, optimizer, train_loader, epoch
|
111 |
)
|
112 |
AVG_TRAIN_LOSS_HIST.append(avg_train_loss)
|
113 |
TRAIN_ACC_HIST.append(train_accuracy)
|
@@ -154,7 +190,7 @@ def main_training_loop():
|
|
154 |
)
|
155 |
)
|
156 |
break
|
157 |
-
|
158 |
# Ensure the parent directory exists
|
159 |
os.makedirs(os.path.dirname(MODEL_SAVE_PATH), exist_ok=True)
|
160 |
torch.save(model.state_dict(), MODEL_SAVE_PATH)
|
|
|
7 |
from torch.utils.tensorboard import SummaryWriter
|
8 |
from configs import *
|
9 |
import data_loader
|
10 |
+
import torch.nn.functional as F
|
11 |
+
import numpy as np
|
12 |
+
|
13 |
+
|
14 |
+
class LabelSmoothingLoss(nn.Module):
|
15 |
+
def __init__(self, epsilon=0.1, num_classes=2):
|
16 |
+
super(LabelSmoothingLoss, self).__init__()
|
17 |
+
self.epsilon = epsilon
|
18 |
+
self.num_classes = num_classes
|
19 |
+
|
20 |
+
def forward(self, input, target):
|
21 |
+
target_smooth = (1 - self.epsilon) * target + self.epsilon / self.num_classes
|
22 |
+
return nn.CrossEntropyLoss()(input, target_smooth)
|
23 |
|
24 |
|
25 |
def setup_tensorboard():
|
26 |
return SummaryWriter(log_dir="output/tensorboard/training")
|
27 |
|
28 |
|
29 |
+
def mixup_data(x, y, alpha=1.0):
|
30 |
+
"""Returns mixed inputs, pairs of targets, and lambda"""
|
31 |
+
if alpha > 0:
|
32 |
+
lam = np.random.beta(alpha, alpha)
|
33 |
+
else:
|
34 |
+
lam = 1
|
35 |
+
|
36 |
+
batch_size = x.size()[0]
|
37 |
+
index = torch.randperm(batch_size)
|
38 |
+
|
39 |
+
mixed_x = lam * x + (1 - lam) * x[index, :]
|
40 |
+
y_a, y_b = y, y[index]
|
41 |
+
return mixed_x, y_a, y_b, lam
|
42 |
+
|
43 |
+
|
44 |
+
def mixup_criterion(criterion, pred, y_a, y_b, lam):
|
45 |
+
return lam * criterion(pred, y_a) + (1 - lam) * criterion(pred, y_b)
|
46 |
+
|
47 |
+
|
48 |
def load_and_preprocess_data():
|
49 |
return data_loader.load_data(
|
50 |
RAW_DATA_DIR + str(TASK),
|
|
|
58 |
model = MODEL.to(DEVICE)
|
59 |
criterion = nn.CrossEntropyLoss()
|
60 |
optimizer = optim.Adam(model.parameters(), lr=LEARNING_RATE)
|
61 |
+
scheduler = optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=NUM_EPOCHS)
|
62 |
return model, criterion, optimizer, scheduler
|
63 |
|
64 |
|
|
|
67 |
writer.add_scalar(f"{prefix}/{metric_name}", metric_value, step)
|
68 |
|
69 |
|
70 |
+
def train_one_epoch(model, criterion, optimizer, train_loader, epoch, alpha):
|
71 |
model.train()
|
72 |
running_loss = 0.0
|
73 |
total_train = 0
|
|
|
76 |
for i, (inputs, labels) in enumerate(train_loader, 0):
|
77 |
inputs, labels = inputs.to(DEVICE), labels.to(DEVICE)
|
78 |
optimizer.zero_grad()
|
79 |
+
|
80 |
+
# Apply mixup
|
81 |
+
inputs, targets_a, targets_b, lam = mixup_data(inputs, labels, alpha)
|
82 |
+
|
83 |
+
outputs = model(inputs)
|
84 |
+
|
85 |
+
# Calculate mixup loss
|
86 |
+
loss = mixup_criterion(criterion, outputs, targets_a, targets_b, lam)
|
87 |
+
|
88 |
loss.backward()
|
89 |
optimizer.step()
|
90 |
running_loss += loss.item()
|
|
|
143 |
print("Learning rate:", scheduler.get_last_lr()[0])
|
144 |
|
145 |
avg_train_loss, train_accuracy = train_one_epoch(
|
146 |
+
model, criterion, optimizer, train_loader, epoch, MIXUP_ALPHA
|
147 |
)
|
148 |
AVG_TRAIN_LOSS_HIST.append(avg_train_loss)
|
149 |
TRAIN_ACC_HIST.append(train_accuracy)
|
|
|
190 |
)
|
191 |
)
|
192 |
break
|
193 |
+
MODEL_SAVE_PATH = "output/checkpoints/model.pth"
|
194 |
# Ensure the parent directory exists
|
195 |
os.makedirs(os.path.dirname(MODEL_SAVE_PATH), exist_ok=True)
|
196 |
torch.save(model.state_dict(), MODEL_SAVE_PATH)
|
tuning.py
CHANGED
@@ -12,7 +12,7 @@ from torch.utils.tensorboard import SummaryWriter
|
|
12 |
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
13 |
EPOCHS = 10
|
14 |
N_TRIALS = 1000
|
15 |
-
TIMEOUT =
|
16 |
|
17 |
# Create a TensorBoard writer
|
18 |
writer = SummaryWriter(log_dir="output/tensorboard/tuning")
|
|
|
12 |
DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
|
13 |
EPOCHS = 10
|
14 |
N_TRIALS = 1000
|
15 |
+
TIMEOUT = 14400
|
16 |
|
17 |
# Create a TensorBoard writer
|
18 |
writer = SummaryWriter(log_dir="output/tensorboard/tuning")
|