dadadar commited on
Commit
19ee4ae
·
1 Parent(s): ccdb773

Upload 13 files

Browse files
666cifar_model_resnet101_lr0.0001.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a9515f143f4ec8c254fe48d5ea0bc4a5bc7705e3365c41d98bda5a6d2f9e5589
3
+ size 170753573
666cifar_model_resnet18_lr0.00001.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cd360f167eb2b17432a47dcc3dd07d0e342b0afbe355a7c2eb41a023c6378c15
3
+ size 44816293
666cifar_model_resnet18_lr0.0001.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:91b3891b1ac4ced9ce43c424161b81a10e1c4acea53185e0bab0580b82d2af5e
3
+ size 44816169
666cifar_model_resnet18_lr0.0001_unbalanced_crossentropy.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:709788266979ebb93bbbeb97fca78af1aa297287992f02f7599d27b14c1ae701
3
+ size 44819145
666cifar_model_resnet18_lr0.0001_unbalanced_sampling.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:47add05ed4d32ae1d109b0a15b9ef8b2b363e7d4e99b0124bde2e3e1d33fd0f6
3
+ size 44818649
666cifar_model_resnet18_lr0.0001_unbalanced_without_trick.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:20f0fe2a58a2c637b84c5cd61dec47410cf09321b2ce935c75b197da0fe5fe75
3
+ size 44819269
cifar_resnet18.py ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch.optim as optim
2
+ import torch
3
+ import torch.nn as nn
4
+ import torch.nn.parallel
5
+ import torch.optim
6
+ import torch.utils.data
7
+ import torch.utils.data.distributed
8
+ import torchvision.transforms as transforms
9
+ import torchvision.models
10
+ from torch.autograd import Variable
11
+ from torch.utils.data import random_split
12
+ import os
13
+ import time
14
+ import numpy as np
15
+ import pandas as pd
16
+ import torch.nn.functional as F
17
+ from torch.utils.data import Dataset
18
+ from torch.utils.data import DataLoader
19
+ import matplotlib.pyplot as plt
20
+ from PIL import Image
21
+ import torchvision.datasets as dsets
22
+
23
+
24
+
25
+ #training parameters
26
+ modellr = 1e-5
27
+ BATCH_SIZE = 64
28
+ EPOCHS = 20
29
+ DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
30
+ # Add these variables to keep track of the best accuracy and epoch number
31
+ best_accuracy = 0
32
+ best_epoch = 0
33
+
34
+ np.random.seed(42)
35
+ torch.manual_seed(42)
36
+
37
+
38
+ #data preprocess
39
+ mean, std = [0.4914, 0.4822, 0.4465], [0.247, 0.243, 0.261]
40
+ # These values are mostly used by researchers as found to very useful in fast convergence
41
+
42
+ transform_train = transforms.Compose([
43
+ transforms.Resize((32, 32)),
44
+ transforms.RandomHorizontalFlip(),
45
+ transforms.RandomRotation(30),
46
+ #newly added
47
+ transforms.ColorJitter(brightness = 0.1, # Randomly adjust color jitter of the images
48
+ contrast = 0.1,
49
+ saturation = 0.1),
50
+ transforms.RandomAdjustSharpness(sharpness_factor = 2, p = 0.1), # Randomly adjust sharpness
51
+ transforms.ToTensor(),
52
+ transforms.Normalize(mean, std),
53
+ transforms.RandomErasing()
54
+ ])
55
+ transform_test = transforms.Compose([
56
+ transforms.Resize((32, 32)),
57
+ transforms.ToTensor(),
58
+ transforms.Normalize(mean, std),
59
+ ])
60
+
61
+ full_dataset = dsets.CIFAR10(root='./data', train=True, download=True, transform = transform_train)
62
+ test_dataset = dsets.CIFAR10(root='./data', train=False, download=True, transform = transform_test)
63
+
64
+ # Split the dataset into training and validation sets
65
+ train_size = int(0.9 * len(full_dataset))
66
+ val_size = len(full_dataset) - train_size
67
+ torch.manual_seed(42)
68
+ train_dataset, validation_dataset = random_split(full_dataset, [train_size, val_size])
69
+
70
+
71
+
72
+ train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=BATCH_SIZE, shuffle=True)
73
+ test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=BATCH_SIZE, shuffle=False)
74
+ val_loader = torch.utils.data.DataLoader(dataset=validation_dataset, batch_size=BATCH_SIZE, shuffle=False)
75
+
76
+
77
+
78
+
79
+
80
+ #model & training settings
81
+ criterion = nn.CrossEntropyLoss()
82
+ model = torchvision.models.resnet18(pretrained=True)
83
+ num_ftrs = model.fc.in_features
84
+ model.fc = nn.Linear(num_ftrs, 10)
85
+ model.to(DEVICE)
86
+
87
+ optimizer = optim.Adam(model.parameters(), lr=modellr)
88
+
89
+
90
+ #Learning rate adjust (no need)
91
+ def adjust_learning_rate(optimizer, epoch):
92
+ """Sets the learning rate to the initial LR decayed by 10 every 30 epochs"""
93
+ modellrnew = modellr * (0.1 ** (epoch // 50))
94
+ print("lr:", modellrnew)
95
+ for param_group in optimizer.param_groups:
96
+ param_group['lr'] = modellrnew
97
+
98
+
99
+ #Training method
100
+
101
+ def train(model, device, train_loader, optimizer, epoch):
102
+ model.train()
103
+ sum_loss = 0
104
+ correct = 0
105
+ total_num = len(train_loader.dataset)
106
+ print(total_num, len(train_loader))
107
+
108
+ for batch_idx, (data, target) in enumerate(train_loader):
109
+ data, target = Variable(data).to(device), Variable(target).to(device)
110
+ output = model(data)
111
+ loss = criterion(output, target)
112
+ optimizer.zero_grad()
113
+ loss.backward()
114
+ optimizer.step()
115
+
116
+ print_loss = loss.data.item()
117
+ sum_loss += print_loss
118
+
119
+ _, pred = torch.max(output.data, 1)
120
+ correct += torch.sum(pred == target)
121
+
122
+ if (batch_idx + 1) % 50 == 0:
123
+ print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
124
+ epoch, (batch_idx + 1) * len(data), len(train_loader.dataset),
125
+ 100. * (batch_idx + 1) / len(train_loader), loss.item()))
126
+
127
+ accuracy = correct / total_num
128
+ ave_loss = sum_loss / len(train_loader)
129
+ print('epoch:{}, loss:{}, Training Accuracy: {:.2%}'.format(epoch, ave_loss, accuracy))
130
+
131
+
132
+
133
+ # Modify the val function to update the best model when a higher accuracy is achieved
134
+
135
+
136
+
137
+ def val(model, device, test_loader, epoch):
138
+ global best_accuracy, best_epoch
139
+ model.eval()
140
+ test_loss = 0
141
+ correct = 0
142
+ total_num = len(test_loader.dataset)
143
+ print(total_num, len(test_loader))
144
+ with torch.no_grad():
145
+ for data, target in test_loader:
146
+ data, target = Variable(data).to(device), Variable(target).to(device)
147
+ output = model(data)
148
+ loss = criterion(output, target)
149
+ _, pred = torch.max(output.data, 1)
150
+ correct += torch.sum(pred == target)
151
+ print_loss = loss.data.item()
152
+ test_loss += print_loss
153
+ correct = correct.data.item()
154
+ acc = correct / total_num
155
+ avgloss = test_loss / len(test_loader)
156
+ print('\nVal set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
157
+ avgloss, correct, len(test_loader.dataset), 100 * acc))
158
+ # Check if this epoch's accuracy is better than the best so far
159
+ if acc > best_accuracy:
160
+ best_accuracy, best_epoch = acc, epoch
161
+ # Save the best model
162
+ torch.save(model, '666cifar_model_resnet18_lr0.00001.pth')
163
+
164
+
165
+ # Test the model on the test set
166
+ def test(model, device, test_loader):
167
+ model.eval()
168
+ correct = 0
169
+ total = 0
170
+ with torch.no_grad():
171
+ for data, target in test_loader:
172
+ data, target = data.to(device), target.to(device)
173
+ outputs = model(data)
174
+ _, predicted = torch.max(outputs.data, 1)
175
+ total += target.size(0)
176
+ correct += (predicted == target).sum().item()
177
+
178
+ accuracy = correct / total
179
+ print('Test Accuracy: {:.2%} ({}/{})'.format(accuracy, correct, total))
180
+
181
+
182
+
183
+ # Train the model and track the best model
184
+ for epoch in range(1, EPOCHS + 1):
185
+ adjust_learning_rate(optimizer, epoch)
186
+ train(model, DEVICE, train_loader, optimizer, epoch)
187
+ val(model, DEVICE, val_loader, epoch)
188
+ test(model, DEVICE, test_loader)
189
+
190
+
191
+ print(f"Best model achieved at epoch {best_epoch} with accuracy: {best_accuracy * 100:.2f}%")
192
+
193
+
194
+
cifar_unbalanced.py ADDED
@@ -0,0 +1,232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch.optim as optim
2
+ import torch
3
+ import torch.nn as nn
4
+ import torch.nn.parallel
5
+ import torch.optim
6
+ import torch.utils.data
7
+ import torch.utils.data.distributed
8
+ import torchvision.transforms as transforms
9
+ import torchvision.models
10
+ from torch.autograd import Variable
11
+ from torch.utils.data import random_split
12
+ import os
13
+ import time
14
+ import numpy as np
15
+ import pandas as pd
16
+ import torch.nn.functional as F
17
+ from torch.utils.data import Dataset
18
+ from torch.utils.data import DataLoader
19
+ import matplotlib.pyplot as plt
20
+ from PIL import Image
21
+ import torchvision.datasets as dsets
22
+
23
+
24
+
25
+ class ModifiedCIFAR10(Dataset):
26
+ def __init__(self, root, train=True, transform=None, target_classes=[0, 1, 2, 3,4,5,6,7,8,9], num_samples=[500, 500, 2500, 2500,5000,5000,5000,5000,5000,5000]):
27
+ self.original_dataset = dsets.CIFAR10(root=root, train=train, download=True, transform=transform)
28
+ self.target_classes = target_classes
29
+ self.num_samples = num_samples
30
+
31
+ self.sample_indices = []
32
+ for target_class, num_sample in zip(target_classes, num_samples):
33
+ class_indices = [i for i, label in enumerate(self.original_dataset.targets) if label == target_class]
34
+ self.sample_indices += class_indices[:num_sample]
35
+
36
+ def __len__(self):
37
+ return len(self.sample_indices)
38
+
39
+ def __getitem__(self, idx):
40
+ original_idx = self.sample_indices[idx]
41
+ return self.original_dataset[original_idx]
42
+
43
+
44
+
45
+
46
+
47
+ #training parameters
48
+ modellr = 1e-4
49
+ BATCH_SIZE = 64
50
+ EPOCHS = 20
51
+ DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
52
+ # Add these variables to keep track of the best accuracy and epoch number
53
+ best_accuracy = 0
54
+ best_epoch = 0
55
+
56
+ np.random.seed(42)
57
+ torch.manual_seed(42)
58
+
59
+
60
+ #data preprocess
61
+ mean, std = [0.4914, 0.4822, 0.4465], [0.247, 0.243, 0.261]
62
+ # These values are mostly used by researchers as found to very useful in fast convergence
63
+
64
+ transform_train = transforms.Compose([
65
+ transforms.Resize((32, 32)),
66
+ transforms.RandomHorizontalFlip(),
67
+ transforms.RandomRotation(30),
68
+ #newly added
69
+ transforms.ColorJitter(brightness = 0.1, # Randomly adjust color jitter of the images
70
+ contrast = 0.1,
71
+ saturation = 0.1),
72
+ transforms.RandomAdjustSharpness(sharpness_factor = 2, p = 0.1), # Randomly adjust sharpness
73
+ transforms.ToTensor(),
74
+ transforms.Normalize(mean, std),
75
+ transforms.RandomErasing()
76
+ ])
77
+ transform_test = transforms.Compose([
78
+ transforms.Resize((32, 32)),
79
+ transforms.ToTensor(),
80
+ transforms.Normalize(mean, std),
81
+ ])
82
+
83
+
84
+ test_dataset = dsets.CIFAR10(root='./data', train=False, download=True, transform = transform_test)
85
+
86
+ # Modify the number of samples for class 0 from 5000 to 500
87
+ modified_train_dataset = ModifiedCIFAR10(
88
+ root='./data',
89
+ train=True,
90
+ transform=transform_train,
91
+ target_classes=[0, 1, 2, 3,4,5,6,7,8,9],
92
+ num_samples=[500, 500, 2500, 2500,5000,5000,5000,5000,5000,5000]
93
+ )
94
+
95
+
96
+ # Split the dataset into training and validation sets
97
+ train_size = int(0.9 * len(modified_train_dataset))
98
+ val_size = len(modified_train_dataset) - train_size
99
+
100
+ torch.manual_seed(42)
101
+ train_dataset, validation_dataset = random_split(modified_train_dataset, [train_size, val_size])
102
+
103
+
104
+
105
+ train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=BATCH_SIZE, shuffle=True)
106
+ test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=BATCH_SIZE, shuffle=False)
107
+
108
+ val_loader = torch.utils.data.DataLoader(dataset=validation_dataset, batch_size=BATCH_SIZE, shuffle=False)
109
+
110
+
111
+
112
+
113
+
114
+ #model & training settings
115
+
116
+
117
+ criterion = nn.CrossEntropyLoss()
118
+
119
+ #num_samples = [500, 500, 2500, 2500, 5000, 5000, 5000, 5000, 5000, 5000]
120
+
121
+ #First balance method
122
+
123
+ # Calculate class weights
124
+ #class_weights = torch.FloatTensor([num_samples[i] / len(modified_train_dataset) for i in range(10)])
125
+ # Instantiate CrossEntropyLoss with class weights
126
+ #criterion = nn.CrossEntropyLoss(weight=class_weights.to(DEVICE))
127
+
128
+
129
+ model = torchvision.models.resnet18(pretrained=True)
130
+ num_ftrs = model.fc.in_features
131
+ model.fc = nn.Linear(num_ftrs, 10)
132
+ model.to(DEVICE)
133
+
134
+ optimizer = optim.Adam(model.parameters(), lr=modellr)
135
+
136
+
137
+ #Learning rate adjust (no need)
138
+ def adjust_learning_rate(optimizer, epoch):
139
+ """Sets the learning rate to the initial LR decayed by 10 every 30 epochs"""
140
+ modellrnew = modellr * (0.1 ** (epoch // 50))
141
+ print("lr:", modellrnew)
142
+ for param_group in optimizer.param_groups:
143
+ param_group['lr'] = modellrnew
144
+
145
+
146
+ #Training method
147
+
148
+ def train(model, device, train_loader, optimizer, epoch):
149
+ model.train()
150
+ sum_loss = 0
151
+ correct = 0
152
+ total_num = len(train_loader.dataset)
153
+ print(total_num, len(train_loader))
154
+
155
+ for batch_idx, (data, target) in enumerate(train_loader):
156
+ data, target = Variable(data).to(device), Variable(target).to(device)
157
+ output = model(data)
158
+ loss = criterion(output, target)
159
+ optimizer.zero_grad()
160
+ loss.backward()
161
+ optimizer.step()
162
+
163
+ print_loss = loss.data.item()
164
+ sum_loss += print_loss
165
+
166
+ _, pred = torch.max(output.data, 1)
167
+ correct += torch.sum(pred == target)
168
+
169
+ if (batch_idx + 1) % 50 == 0:
170
+ print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
171
+ epoch, (batch_idx + 1) * len(data), len(train_loader.dataset),
172
+ 100. * (batch_idx + 1) / len(train_loader), loss.item()))
173
+
174
+ accuracy = correct / total_num
175
+ ave_loss = sum_loss / len(train_loader)
176
+ print('epoch:{}, loss:{}, Training Accuracy: {:.2%}'.format(epoch, ave_loss, accuracy))
177
+
178
+
179
+ def val(model, device, test_loader, epoch):
180
+ global best_accuracy, best_epoch
181
+ model.eval()
182
+ test_loss = 0
183
+ correct = 0
184
+ total_num = len(test_loader.dataset)
185
+ print(total_num, len(test_loader))
186
+ with torch.no_grad():
187
+ for data, target in test_loader:
188
+ data, target = Variable(data).to(device), Variable(target).to(device)
189
+ output = model(data)
190
+ loss = criterion(output, target)
191
+ _, pred = torch.max(output.data, 1)
192
+ correct += torch.sum(pred == target)
193
+ print_loss = loss.data.item()
194
+ test_loss += print_loss
195
+ correct = correct.data.item()
196
+ acc = correct / total_num
197
+ avgloss = test_loss / len(test_loader)
198
+ print('\nVal set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
199
+ avgloss, correct, len(test_loader.dataset), 100 * acc))
200
+
201
+ if acc > best_accuracy:
202
+ best_accuracy, best_epoch = acc, epoch
203
+ torch.save(model, '666cifar_model_resnet18_lr0.0001_unbalanced_crossentropy.pth')
204
+
205
+
206
+ # Test the model on the test set
207
+ def test(model, device, test_loader):
208
+ model.eval()
209
+ correct = 0
210
+ total = 0
211
+ with torch.no_grad():
212
+ for data, target in test_loader:
213
+ data, target = data.to(device), target.to(device)
214
+ outputs = model(data)
215
+ _, predicted = torch.max(outputs.data, 1)
216
+ total += target.size(0)
217
+ correct += (predicted == target).sum().item()
218
+
219
+ accuracy = correct / total
220
+ print('Test Accuracy: {:.2%} ({}/{})'.format(accuracy, correct, total))
221
+
222
+
223
+
224
+ # Train the model and track the best model
225
+ for epoch in range(1, EPOCHS + 1):
226
+ adjust_learning_rate(optimizer, epoch)
227
+ train(model, DEVICE, train_loader, optimizer, epoch)
228
+ val(model, DEVICE, val_loader, epoch)
229
+ test(model, DEVICE, test_loader)
230
+
231
+
232
+ print(f"Best model achieved at epoch {best_epoch} with accuracy: {best_accuracy * 100:.2f}%")
cifar_unbalanced_sampling.py ADDED
@@ -0,0 +1,297 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch.optim as optim
2
+ import torch
3
+ import torch.nn as nn
4
+ import torch.nn.parallel
5
+ import torch.optim
6
+ import torch.utils.data
7
+ import torch.utils.data.distributed
8
+ import torchvision.transforms as transforms
9
+ import torchvision.models
10
+ from torch.autograd import Variable
11
+ from torch.utils.data import random_split
12
+ import os
13
+ import time
14
+ import numpy as np
15
+ import pandas as pd
16
+ import torch.nn.functional as F
17
+ from torch.utils.data import Dataset
18
+ from torch.utils.data import DataLoader
19
+ import matplotlib.pyplot as plt
20
+ from PIL import Image
21
+ import torchvision.datasets as dsets
22
+ from imblearn.over_sampling import RandomOverSampler
23
+
24
+
25
+
26
+ class ModifiedCIFAR10(Dataset):
27
+ def __init__(self, root, train=True, transform=None, target_classes=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], num_samples=[500, 500, 2500, 2500, 5000, 5000, 5000, 5000, 5000, 5000], oversample=True, undersample=True):
28
+ self.original_dataset = dsets.CIFAR10(root=root, train=train, download=True, transform=transform)
29
+ self.target_classes = target_classes
30
+ self.num_samples = num_samples
31
+ self.oversample = oversample
32
+ self.undersample = undersample
33
+
34
+ self.sample_indices = []
35
+ for target_class, num_sample in zip(target_classes, num_samples):
36
+ class_indices = [i for i, label in enumerate(self.original_dataset.targets) if label == target_class]
37
+ self.sample_indices += class_indices[:num_sample]
38
+
39
+ if self.oversample or self.undersample:
40
+ X = [self.original_dataset[i][0].numpy() for i in self.sample_indices]
41
+ y = [self.original_dataset[i][1] for i in self.sample_indices]
42
+
43
+ if self.oversample:
44
+ smote = SMOTE(sampling_strategy='auto', random_state=42, n_jobs=-1)
45
+ X_resampled, y_resampled = smote.fit_resample(np.array(X).reshape(-1, 32 * 32 * 3), y)
46
+ else:
47
+ X_resampled, y_resampled = np.array(X).reshape(-1, 32 * 32 * 3), y
48
+
49
+ if self.undersample:
50
+ enn = EditedNearestNeighbours(sampling_strategy='auto', n_neighbors=3, n_jobs=-1)
51
+ X_resampled, y_resampled = enn.fit_resample(X_resampled, y_resampled)
52
+
53
+ self.resampled_indices = [idx for i, idx in enumerate(self.sample_indices) if i in range(len(X_resampled))]
54
+ self.sample_indices = self.resampled_indices
55
+
56
+ def __len__(self):
57
+ return len(self.sample_indices)
58
+
59
+ def __getitem__(self, idx):
60
+ original_idx = self.sample_indices[idx]
61
+ return self.original_dataset[original_idx]
62
+
63
+
64
+
65
+
66
+
67
+ #training parameters
68
+ modellr = 1e-4
69
+ BATCH_SIZE = 64
70
+ EPOCHS = 20
71
+ DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
72
+ # Add these variables to keep track of the best accuracy and epoch number
73
+ best_accuracy = 0
74
+ best_epoch = 0
75
+
76
+ np.random.seed(42)
77
+ torch.manual_seed(42)
78
+
79
+
80
+ #data preprocess
81
+ mean, std = [0.4914, 0.4822, 0.4465], [0.247, 0.243, 0.261]
82
+ # These values are mostly used by researchers as found to very useful in fast convergence
83
+
84
+ transform_train = transforms.Compose([
85
+ transforms.Resize((32, 32)),
86
+ transforms.RandomHorizontalFlip(),
87
+ transforms.RandomRotation(30),
88
+ #newly added
89
+ transforms.ColorJitter(brightness = 0.1, # Randomly adjust color jitter of the images
90
+ contrast = 0.1,
91
+ saturation = 0.1),
92
+ transforms.RandomAdjustSharpness(sharpness_factor = 2, p = 0.1), # Randomly adjust sharpness
93
+ transforms.ToTensor(),
94
+ transforms.Normalize(mean, std),
95
+ transforms.RandomErasing()
96
+ ])
97
+ transform_test = transforms.Compose([
98
+ transforms.Resize((32, 32)),
99
+ transforms.ToTensor(),
100
+ transforms.Normalize(mean, std),
101
+ ])
102
+
103
+
104
+ test_dataset = dsets.CIFAR10(root='./data', train=False, download=True, transform = transform_test)
105
+
106
+ # Modify the number of samples for class 0 from 5000 to 500
107
+ modified_train_dataset = ModifiedCIFAR10(
108
+ root='./data',
109
+ train=True,
110
+ transform=transform_train,
111
+ target_classes=[0, 1, 2, 3,4,5,6,7,8,9],
112
+ num_samples=[500, 500, 2500, 2500,5000,5000,5000,5000,5000,5000]
113
+ )
114
+
115
+
116
+ # Split the dataset into training and validation sets
117
+ train_size = int(0.9 * len(modified_train_dataset))
118
+ val_size = len(modified_train_dataset) - train_size
119
+
120
+ torch.manual_seed(42)
121
+ train_dataset, validation_dataset = random_split(modified_train_dataset, [train_size, val_size])
122
+
123
+ ###
124
+ from imblearn.over_sampling import RandomOverSampler
125
+ from sklearn.utils import shuffle
126
+
127
+ # Extract class labels for oversampling
128
+ oversample_classes = [0, 1, 2, 3]
129
+
130
+
131
+ # Extract features and labels from the training dataset
132
+ X, y = zip(*[(x, y) for x, y in modified_train_dataset])
133
+ X = np.array([tensor.view(tensor.size(0), -1).numpy() for tensor in X])
134
+ y = np.array(y)
135
+
136
+ # Flatten each tensor in X
137
+ X_flattened = np.array([tensor.view(tensor.size(0), -1).numpy() for tensor in X])
138
+
139
+
140
+
141
+ # Oversample the flattened training dataset using RandomOverSampler
142
+ oversampler = RandomOverSampler(sampling_strategy='auto', random_state=42)
143
+ X_resampled, y_resampled = oversampler.fit_resample(X_flattened, y)
144
+
145
+
146
+
147
+
148
+ # Convert back to PyTorch dataset
149
+ oversampled_dataset = list(zip(X_resampled, y_resampled))
150
+ oversampled_dataset = torch.utils.data.TensorDataset(torch.from_numpy(X_resampled), torch.from_numpy(y_resampled))
151
+
152
+ # Split the oversampled dataset into training and validation sets
153
+ oversampled_train_size = int(0.9 * len(oversampled_dataset))
154
+ oversampled_val_size = len(oversampled_dataset) - oversampled_train_size
155
+ torch.manual_seed(42)
156
+ oversampled_train_dataset, oversampled_validation_dataset = random_split(oversampled_dataset,
157
+ [oversampled_train_size, oversampled_val_size])
158
+
159
+ # DataLoader for oversampled training set
160
+ oversampled_train_loader = torch.utils.data.DataLoader(dataset=oversampled_train_dataset,
161
+ batch_size=BATCH_SIZE, shuffle=True)
162
+
163
+ # DataLoader for oversampled validation set
164
+ oversampled_val_loader = torch.utils.data.DataLoader(dataset=oversampled_validation_dataset,
165
+ batch_size=BATCH_SIZE, shuffle=False)
166
+ ###
167
+
168
+
169
+
170
+ train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=BATCH_SIZE, shuffle=True)
171
+ test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=BATCH_SIZE, shuffle=False)
172
+
173
+ val_loader = torch.utils.data.DataLoader(dataset=validation_dataset, batch_size=BATCH_SIZE, shuffle=False)
174
+
175
+
176
+
177
+
178
+
179
+ #model & training settings
180
+
181
+
182
+ criterion = nn.CrossEntropyLoss()
183
+
184
+ num_samples = [500, 500, 2500, 2500, 5000, 5000, 5000, 5000, 5000, 5000]
185
+
186
+ #First balance method
187
+ num_samples = [500, 500, 2500, 2500, 5000, 5000, 5000, 5000, 5000, 5000]
188
+ # Calculate class weights
189
+ class_weights = torch.FloatTensor([num_samples[i] / len(modified_train_dataset) for i in range(10)])
190
+ # Instantiate CrossEntropyLoss with class weights
191
+ criterion = nn.CrossEntropyLoss(weight=class_weights.to(DEVICE))
192
+
193
+
194
+ model = torchvision.models.resnet18(pretrained=True)
195
+ num_ftrs = model.fc.in_features
196
+ model.fc = nn.Linear(num_ftrs, 10)
197
+ model.to(DEVICE)
198
+
199
+ optimizer = optim.Adam(model.parameters(), lr=modellr)
200
+
201
+
202
+ #Learning rate adjust (no need)
203
+ def adjust_learning_rate(optimizer, epoch):
204
+ """Sets the learning rate to the initial LR decayed by 10 every 30 epochs"""
205
+ modellrnew = modellr * (0.1 ** (epoch // 50))
206
+ print("lr:", modellrnew)
207
+ for param_group in optimizer.param_groups:
208
+ param_group['lr'] = modellrnew
209
+
210
+
211
+ #Training method
212
+
213
+ def train(model, device, train_loader, optimizer, epoch):
214
+ model.train()
215
+ sum_loss = 0
216
+ correct = 0
217
+ total_num = len(train_loader.dataset)
218
+ print(total_num, len(train_loader))
219
+
220
+ for batch_idx, (data, target) in enumerate(train_loader):
221
+ data, target = Variable(data).to(device), Variable(target).to(device)
222
+ output = model(data)
223
+ loss = criterion(output, target)
224
+ optimizer.zero_grad()
225
+ loss.backward()
226
+ optimizer.step()
227
+
228
+ print_loss = loss.data.item()
229
+ sum_loss += print_loss
230
+
231
+ _, pred = torch.max(output.data, 1)
232
+ correct += torch.sum(pred == target)
233
+
234
+ if (batch_idx + 1) % 50 == 0:
235
+ print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
236
+ epoch, (batch_idx + 1) * len(data), len(train_loader.dataset),
237
+ 100. * (batch_idx + 1) / len(train_loader), loss.item()))
238
+
239
+ accuracy = correct / total_num
240
+ ave_loss = sum_loss / len(train_loader)
241
+ print('epoch:{}, loss:{}, Training Accuracy: {:.2%}'.format(epoch, ave_loss, accuracy))
242
+
243
+
244
+ def val(model, device, test_loader, epoch):
245
+ global best_accuracy, best_epoch
246
+ model.eval()
247
+ test_loss = 0
248
+ correct = 0
249
+ total_num = len(test_loader.dataset)
250
+ print(total_num, len(test_loader))
251
+ with torch.no_grad():
252
+ for data, target in test_loader:
253
+ data, target = Variable(data).to(device), Variable(target).to(device)
254
+ output = model(data)
255
+ loss = criterion(output, target)
256
+ _, pred = torch.max(output.data, 1)
257
+ correct += torch.sum(pred == target)
258
+ print_loss = loss.data.item()
259
+ test_loss += print_loss
260
+ correct = correct.data.item()
261
+ acc = correct / total_num
262
+ avgloss = test_loss / len(test_loader)
263
+ print('\nVal set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
264
+ avgloss, correct, len(test_loader.dataset), 100 * acc))
265
+
266
+ if acc > best_accuracy:
267
+ best_accuracy, best_epoch = acc, epoch
268
+ torch.save(model, '666cifar_model_resnet18_lr0.0001_unbalanced_crossentropy.pth')
269
+
270
+
271
+ # Test the model on the test set
272
+ def test(model, device, test_loader):
273
+ model.eval()
274
+ correct = 0
275
+ total = 0
276
+ with torch.no_grad():
277
+ for data, target in test_loader:
278
+ data, target = data.to(device), target.to(device)
279
+ outputs = model(data)
280
+ _, predicted = torch.max(outputs.data, 1)
281
+ total += target.size(0)
282
+ correct += (predicted == target).sum().item()
283
+
284
+ accuracy = correct / total
285
+ print('Test Accuracy: {:.2%} ({}/{})'.format(accuracy, correct, total))
286
+
287
+
288
+
289
+ # Train the model and track the best model
290
+ for epoch in range(1, EPOCHS + 1):
291
+ adjust_learning_rate(optimizer, epoch)
292
+ train(model, DEVICE, oversampled_train_loader, optimizer, epoch)
293
+ val(model, DEVICE, oversampled_val_loader, epoch)
294
+ test(model, DEVICE, test_loader)
295
+
296
+
297
+ print(f"Best model achieved at epoch {best_epoch} with accuracy: {best_accuracy * 100:.2f}%")
plot_accuracy.py ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import matplotlib.pyplot as plt
2
+
3
+
4
+ epochs = list(range(1, 21))
5
+ train_losses = [1.3119755745442077, 0.9600333069366488, 0.8390481574460864, 0.7701934007504447, 0.717232290782373, 0.6732362943955443, 0.640223667872223, 0.6034004604443908, 0.5805023299868811, 0.5493806966749782, 0.5178858606483449, 0.500999446132813, 0.4832796, 0.460667, 0.47479944, 0.42715, 0.41295, 0.39818,0.387744, 0.383766]
6
+
7
+ train_accuracies = [53.27, 66.35, 71.0, 73.23, 74.88, 76.48, 77.46, 79.1, 79.7, 80.81, 81.81, 82.51, 83.02, 83.99, 83.45, 85.1, 85.44, 86.01, 86.52, 86.57]
8
+
9
+ val_losses = [1.0182, 0.8836, 0.8109, 0.775, 0.7249, 0.7244, 0.7125, 0.6808, 0.6616, 0.6461, 0.6628, 0.622, 0.6296, 0.6310, 0.6382, 0.6436, 0.6271, 0.7244, 0.7164, 0.6104]
10
+ val_accuracies = [63, 68, 71, 73, 75, 74, 75, 76, 77, 77, 76, 79, 78,77, 79, 78, 79, 78,77, 79]
11
+
12
+
13
+ plt.figure(figsize=(10, 5))
14
+ plt.subplot(1, 2, 1)
15
+ plt.plot(epochs, train_losses, label='Training Loss')
16
+ plt.plot(epochs, val_losses, label='Validation Loss')
17
+ plt.title('Training and Validation Loss')
18
+ plt.xlabel('Epoch')
19
+ plt.ylabel('Loss')
20
+ plt.legend()
21
+
22
+
23
+ plt.subplot(1, 2, 2)
24
+ plt.plot(epochs, train_accuracies, label='Training Accuracy')
25
+ plt.plot(epochs, val_accuracies, label='Validation Accuracy')
26
+ plt.title('Training and Validation Accuracy')
27
+ plt.xlabel('Epoch')
28
+ plt.ylabel('Accuracy')
29
+ plt.legend()
30
+
31
+
32
+ plt.tight_layout()
33
+ plt.show()
plot_normal.py ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch.optim as optim
2
+ import torch
3
+ import torch.nn as nn
4
+ import torch.nn.parallel
5
+ import torch.optim
6
+ import torch.utils.data
7
+ import torch.utils.data.distributed
8
+ import torchvision.transforms as transforms
9
+ import torchvision.models
10
+ from torch.autograd import Variable
11
+ from torch.utils.data import random_split
12
+ import os
13
+ import time
14
+ import numpy as np
15
+ import pandas as pd
16
+ import torch.nn.functional as F
17
+ from torch.utils.data import Dataset
18
+ from torch.utils.data import DataLoader
19
+ import matplotlib.pyplot as plt
20
+ from PIL import Image
21
+ import torchvision.datasets as dsets
22
+ import seaborn as sn
23
+
24
+
25
+
26
+
27
+ #training parameters
28
+ modellr = 1e-4
29
+ BATCH_SIZE = 64
30
+ EPOCHS = 20
31
+ DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
32
+ # Add these variables to keep track of the best accuracy and epoch number
33
+ best_accuracy = 0
34
+ best_epoch = 0
35
+
36
+ np.random.seed(42)
37
+ torch.manual_seed(42)
38
+
39
+
40
+ #data preprocess
41
+ mean, std = [0.4914, 0.4822, 0.4465], [0.247, 0.243, 0.261]
42
+ # These values are mostly used by researchers as found to very useful in fast convergence
43
+
44
+ transform_train = transforms.Compose([
45
+ transforms.Resize((32, 32)),
46
+ transforms.RandomHorizontalFlip(),
47
+ transforms.RandomRotation(30),
48
+ #newly added
49
+ transforms.ColorJitter(brightness = 0.1, # Randomly adjust color jitter of the images
50
+ contrast = 0.1,
51
+ saturation = 0.1),
52
+ transforms.RandomAdjustSharpness(sharpness_factor = 2, p = 0.1), # Randomly adjust sharpness
53
+ transforms.ToTensor(),
54
+ transforms.Normalize(mean, std),
55
+ transforms.RandomErasing()
56
+ ])
57
+ transform_test = transforms.Compose([
58
+ transforms.Resize((32, 32)),
59
+ transforms.ToTensor(),
60
+ transforms.Normalize(mean, std),
61
+ ])
62
+
63
+ full_dataset = dsets.CIFAR10(root='./data', train=True, download=True, transform = transform_train)
64
+ test_dataset = dsets.CIFAR10(root='./data', train=False, download=True, transform = transform_test)
65
+
66
+ # Split the dataset into training and validation sets
67
+ train_size = int(0.9 * len(full_dataset))
68
+ val_size = len(full_dataset) - train_size
69
+
70
+ torch.manual_seed(42)
71
+ train_dataset, validation_dataset = random_split(full_dataset, [train_size, val_size])
72
+
73
+
74
+
75
+ train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=BATCH_SIZE, shuffle=True)
76
+ test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=BATCH_SIZE, shuffle=False)
77
+
78
+ val_loader = torch.utils.data.DataLoader(dataset=validation_dataset, batch_size=BATCH_SIZE, shuffle=False)
79
+
80
+
81
+
82
+
83
+
84
+ #model & training settings
85
+ criterion = nn.CrossEntropyLoss()
86
+ model = torchvision.models.resnet18(pretrained=True)
87
+ num_ftrs = model.fc.in_features
88
+ model.fc = nn.Linear(num_ftrs, 10)
89
+ model.to(DEVICE)
90
+
91
+ optimizer = optim.Adam(model.parameters(), lr=modellr)
92
+
93
+
94
+ #Learning rate adjust (no need)
95
+ def adjust_learning_rate(optimizer, epoch):
96
+ """Sets the learning rate to the initial LR decayed by 10 every 30 epochs"""
97
+ modellrnew = modellr * (0.1 ** (epoch // 50))
98
+ print("lr:", modellrnew)
99
+ for param_group in optimizer.param_groups:
100
+ param_group['lr'] = modellrnew
101
+
102
+
103
+ model = torch.load("666cifar_model_resnet18_lr0.0001.pth")
104
+
105
+
106
+
107
+
108
+
109
+
110
+ from sklearn.metrics import confusion_matrix
111
+ import seaborn as sn
112
+ import matplotlib.pyplot as plt
113
+
114
+ def get_predictions(model, device, data_loader):
115
+ model.eval()
116
+ model.to(device)
117
+ all_predictions = []
118
+ all_targets = []
119
+
120
+ with torch.no_grad():
121
+ for data, target in data_loader:
122
+ data, target = data.to(device), target.to(device)
123
+ outputs = model(data)
124
+ _, predicted = torch.max(outputs.data, 1)
125
+ all_predictions.extend(predicted.cpu().numpy())
126
+ all_targets.extend(target.cpu().numpy())
127
+
128
+ return np.array(all_predictions), np.array(all_targets)
129
+
130
+ # Get predictions and targets
131
+ predictions, targets = get_predictions(model, DEVICE, test_loader)
132
+
133
+ # Create confusion matrix
134
+ conf_matrix = confusion_matrix(targets, predictions)
135
+
136
+ # Plot heatmap
137
+ plt.figure(figsize=(10, 8))
138
+ sn.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', xticklabels=range(10), yticklabels=range(10))
139
+ plt.xlabel('Predicted Label')
140
+ plt.ylabel('True Label')
141
+ plt.title('Confusion Matrix')
142
+ plt.show()
plot_unbalanced.py ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch.optim as optim
2
+ import torch
3
+ import torch.nn as nn
4
+ import torch.nn.parallel
5
+ import torch.optim
6
+ import torch.utils.data
7
+ import torch.utils.data.distributed
8
+ import torchvision.transforms as transforms
9
+ import torchvision.models
10
+ from torch.autograd import Variable
11
+ from torch.utils.data import random_split
12
+ import os
13
+ import time
14
+ import numpy as np
15
+ import pandas as pd
16
+ import torch.nn.functional as F
17
+ from torch.utils.data import Dataset
18
+ from torch.utils.data import DataLoader
19
+ import matplotlib.pyplot as plt
20
+ from PIL import ImageS
21
+ import torchvision.datasets as dsets
22
+
23
+
24
+
25
+ class ModifiedCIFAR10(Dataset):
26
+ def __init__(self, root, train=True, transform=None, target_classes=[0, 1, 2, 3,4,5,6,7,8,9], num_samples=[500, 500, 2500, 2500,5000,5000,5000,5000,5000,5000]):
27
+ self.original_dataset = dsets.CIFAR10(root=root, train=train, download=True, transform=transform)
28
+ self.target_classes = target_classes
29
+ self.num_samples = num_samples
30
+
31
+ self.sample_indices = []
32
+ for target_class, num_sample in zip(target_classes, num_samples):
33
+ class_indices = [i for i, label in enumerate(self.original_dataset.targets) if label == target_class]
34
+ self.sample_indices += class_indices[:num_sample]
35
+
36
+ def __len__(self):
37
+ return len(self.sample_indices)
38
+
39
+ def __getitem__(self, idx):
40
+ original_idx = self.sample_indices[idx]
41
+ return self.original_dataset[original_idx]
42
+
43
+
44
+
45
+
46
+
47
+ #training parameters
48
+ modellr = 1e-4
49
+ BATCH_SIZE = 64
50
+ EPOCHS = 20
51
+ DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
52
+ # Add these variables to keep track of the best accuracy and epoch number
53
+ best_accuracy = 0
54
+ best_epoch = 0
55
+
56
+ np.random.seed(42)
57
+ torch.manual_seed(42)
58
+
59
+
60
+ #data preprocess
61
+ mean, std = [0.4914, 0.4822, 0.4465], [0.247, 0.243, 0.261]
62
+ # These values are mostly used by researchers as found to very useful in fast convergence
63
+
64
+ transform_train = transforms.Compose([
65
+ transforms.Resize((32, 32)),
66
+ transforms.RandomHorizontalFlip(),
67
+ transforms.RandomRotation(30),
68
+ #newly added
69
+ transforms.ColorJitter(brightness = 0.1, # Randomly adjust color jitter of the images
70
+ contrast = 0.1,
71
+ saturation = 0.1),
72
+ transforms.RandomAdjustSharpness(sharpness_factor = 2, p = 0.1), # Randomly adjust sharpness
73
+ transforms.ToTensor(),
74
+ transforms.Normalize(mean, std),
75
+ transforms.RandomErasing()
76
+ ])
77
+ transform_test = transforms.Compose([
78
+ transforms.Resize((32, 32)),
79
+ transforms.ToTensor(),
80
+ transforms.Normalize(mean, std),
81
+ ])
82
+
83
+
84
+ test_dataset = dsets.CIFAR10(root='./data', train=False, download=True, transform = transform_test)
85
+
86
+ # Modify the number of samples for class 0 from 5000 to 500
87
+ modified_train_dataset = ModifiedCIFAR10(
88
+ root='./data',
89
+ train=True,
90
+ transform=transform_train,
91
+ target_classes=[0, 1, 2, 3,4,5,6,7,8,9],
92
+ num_samples=[500, 500, 2500, 2500,5000,5000,5000,5000,5000,5000]
93
+ )
94
+
95
+
96
+ # Split the dataset into training and validation sets
97
+ train_size = int(0.9 * len(modified_train_dataset))
98
+ val_size = len(modified_train_dataset) - train_size
99
+
100
+ torch.manual_seed(42)
101
+ train_dataset, validation_dataset = random_split(modified_train_dataset, [train_size, val_size])
102
+
103
+
104
+
105
+ train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=BATCH_SIZE, shuffle=True)
106
+ test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=BATCH_SIZE, shuffle=False)
107
+
108
+ val_loader = torch.utils.data.DataLoader(dataset=validation_dataset, batch_size=BATCH_SIZE, shuffle=False)
109
+
110
+
111
+
112
+
113
+
114
+ #model & training settings
115
+
116
+
117
+ criterion = nn.CrossEntropyLoss()
118
+ #First balance method
119
+
120
+ # Calculate class weights
121
+ #class_weights = torch.FloatTensor([num_samples[i] / len(modified_train_dataset) for i in range(10)])
122
+ # Instantiate CrossEntropyLoss with class weights
123
+ #criterion = nn.CrossEntropyLoss(weight=class_weights.to(DEVICE))
124
+
125
+
126
+ model = torchvision.models.resnet18(pretrained=True)
127
+ num_ftrs = model.fc.in_features
128
+ model.fc = nn.Linear(num_ftrs, 10)
129
+ model.to(DEVICE)
130
+
131
+ optimizer = optim.Adam(model.parameters(), lr=modellr)
132
+
133
+
134
+ #Learning rate adjust (no need)
135
+ def adjust_learning_rate(optimizer, epoch):
136
+ """Sets the learning rate to the initial LR decayed by 10 every 30 epochs"""
137
+ modellrnew = modellr * (0.1 ** (epoch // 50))
138
+ print("lr:", modellrnew)
139
+ for param_group in optimizer.param_groups:
140
+ param_group['lr'] = modellrnew
141
+
142
+
143
+
144
+ model = torch.load("666cifar_model_resnet18_lr0.0001_unbalanced_crossentropy.pth")
145
+
146
+
147
+
148
+
149
+
150
+
151
+ from sklearn.metrics import confusion_matrix
152
+ import seaborn as sn
153
+ import matplotlib.pyplot as plt
154
+
155
+ def get_predictions(model, device, data_loader):
156
+ model.eval()
157
+ model.to(device)
158
+ all_predictions = []
159
+ all_targets = []
160
+
161
+ with torch.no_grad():
162
+ for data, target in data_loader:
163
+ data, target = data.to(device), target.to(device)
164
+ outputs = model(data)
165
+ _, predicted = torch.max(outputs.data, 1)
166
+ all_predictions.extend(predicted.cpu().numpy())
167
+ all_targets.extend(target.cpu().numpy())
168
+
169
+ return np.array(all_predictions), np.array(all_targets)
170
+
171
+ # Get predictions and targets
172
+ predictions, targets = get_predictions(model, DEVICE, test_loader)
173
+
174
+ # Create confusion matrix
175
+ conf_matrix = confusion_matrix(targets, predictions)
176
+
177
+ # Plot heatmap
178
+ plt.figure(figsize=(10, 8))
179
+ sn.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', xticklabels=range(10), yticklabels=range(10))
180
+ plt.xlabel('Predicted Label')
181
+ plt.ylabel('True Label')
182
+ plt.title('Confusion Matrix')
183
+ plt.show()
resnet.py ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch.optim as optim
2
+ import torch
3
+ import torch.nn as nn
4
+ import torch.nn.parallel
5
+ import torch.optim
6
+ import torch.utils.data
7
+ import torch.utils.data.distributed
8
+ import torchvision.transforms as transforms
9
+ import torchvision.models
10
+ from torch.autograd import Variable
11
+ from torch.utils.data import random_split
12
+ import os
13
+ import time
14
+ import numpy as np
15
+ import pandas as pd
16
+ import torch.nn.functional as F
17
+ from torch.utils.data import Dataset
18
+ from torch.utils.data import DataLoader
19
+ import matplotlib.pyplot as plt
20
+ from PIL import Image
21
+ import torchvision.datasets as dsets
22
+
23
+
24
+
25
+ #training parameters
26
+ modellr = 1e-4
27
+ BATCH_SIZE = 64
28
+ EPOCHS = 20
29
+ DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
30
+ # Add these variables to keep track of the best accuracy and epoch number
31
+ best_accuracy = 0
32
+ best_epoch = 0
33
+
34
+ np.random.seed(42)
35
+ torch.manual_seed(42)
36
+
37
+
38
+ #data preprocess
39
+ mean, std = [0.4914, 0.4822, 0.4465], [0.247, 0.243, 0.261]
40
+ # These values are mostly used by researchers as found to very useful in fast convergence
41
+
42
+ transform_train = transforms.Compose([
43
+ transforms.Resize((32, 32)),
44
+ transforms.RandomHorizontalFlip(),
45
+ transforms.RandomRotation(30),
46
+ #newly added
47
+ transforms.ColorJitter(brightness = 0.1, # Randomly adjust color jitter of the images
48
+ contrast = 0.1,
49
+ saturation = 0.1),
50
+ transforms.RandomAdjustSharpness(sharpness_factor = 2, p = 0.1), # Randomly adjust sharpness
51
+ transforms.ToTensor(),
52
+ transforms.Normalize(mean, std),
53
+ transforms.RandomErasing()
54
+ ])
55
+ transform_test = transforms.Compose([
56
+ transforms.Resize((32, 32)),
57
+ transforms.ToTensor(),
58
+ transforms.Normalize(mean, std),
59
+ ])
60
+
61
+ full_dataset = dsets.CIFAR10(root='./data', train=True, download=True, transform = transform_train)
62
+ test_dataset = dsets.CIFAR10(root='./data', train=False, download=True, transform = transform_test)
63
+
64
+ # Split the dataset into training and validation sets
65
+ train_size = int(0.9 * len(full_dataset))
66
+ val_size = len(full_dataset) - train_size
67
+
68
+ torch.manual_seed(42)
69
+ train_dataset, validation_dataset = random_split(full_dataset, [train_size, val_size])
70
+
71
+
72
+
73
+ train_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=BATCH_SIZE, shuffle=True)
74
+ test_loader = torch.utils.data.DataLoader(dataset=test_dataset, batch_size=BATCH_SIZE, shuffle=False)
75
+
76
+ val_loader = torch.utils.data.DataLoader(dataset=validation_dataset, batch_size=BATCH_SIZE, shuffle=False)
77
+
78
+
79
+
80
+
81
+
82
+ #model & training settings
83
+ criterion = nn.CrossEntropyLoss()
84
+ model = torchvision.models.resnet101(pretrained=True)
85
+ num_ftrs = model.fc.in_features
86
+ model.fc = nn.Linear(num_ftrs, 10)
87
+ model.to(DEVICE)
88
+
89
+ optimizer = optim.Adam(model.parameters(), lr=modellr)
90
+
91
+
92
+ #Learning rate adjust (no need)
93
+ def adjust_learning_rate(optimizer, epoch):
94
+ """Sets the learning rate to the initial LR decayed by 10 every 30 epochs"""
95
+ modellrnew = modellr * (0.1 ** (epoch // 50))
96
+ print("lr:", modellrnew)
97
+ for param_group in optimizer.param_groups:
98
+ param_group['lr'] = modellrnew
99
+
100
+
101
+ #Training method
102
+
103
+ def train(model, device, train_loader, optimizer, epoch):
104
+ model.train()
105
+ sum_loss = 0
106
+ correct = 0
107
+ total_num = len(train_loader.dataset)
108
+ print(total_num, len(train_loader))
109
+
110
+ for batch_idx, (data, target) in enumerate(train_loader):
111
+ data, target = Variable(data).to(device), Variable(target).to(device)
112
+ output = model(data)
113
+ loss = criterion(output, target)
114
+ optimizer.zero_grad()
115
+ loss.backward()
116
+ optimizer.step()
117
+
118
+ print_loss = loss.data.item()
119
+ sum_loss += print_loss
120
+
121
+ _, pred = torch.max(output.data, 1)
122
+ correct += torch.sum(pred == target)
123
+
124
+ if (batch_idx + 1) % 50 == 0:
125
+ print('Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}'.format(
126
+ epoch, (batch_idx + 1) * len(data), len(train_loader.dataset),
127
+ 100. * (batch_idx + 1) / len(train_loader), loss.item()))
128
+
129
+ accuracy = correct / total_num
130
+ ave_loss = sum_loss / len(train_loader)
131
+ print('epoch:{}, loss:{}, Training Accuracy: {:.2%}'.format(epoch, ave_loss, accuracy))
132
+
133
+
134
+
135
+ # Modify the val function to update the best model when a higher accuracy is achieved
136
+
137
+
138
+
139
+ def val(model, device, test_loader, epoch):
140
+ global best_accuracy, best_epoch
141
+ model.eval()
142
+ test_loss = 0
143
+ correct = 0
144
+ total_num = len(test_loader.dataset)
145
+ print(total_num, len(test_loader))
146
+ with torch.no_grad():
147
+ for data, target in test_loader:
148
+ data, target = Variable(data).to(device), Variable(target).to(device)
149
+ output = model(data)
150
+ loss = criterion(output, target)
151
+ _, pred = torch.max(output.data, 1)
152
+ correct += torch.sum(pred == target)
153
+ print_loss = loss.data.item()
154
+ test_loss += print_loss
155
+ correct = correct.data.item()
156
+ acc = correct / total_num
157
+ avgloss = test_loss / len(test_loader)
158
+ print('\nVal set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
159
+ avgloss, correct, len(test_loader.dataset), 100 * acc))
160
+ # Check if this epoch's accuracy is better than the best so far
161
+ if acc > best_accuracy:
162
+ best_accuracy, best_epoch = acc, epoch
163
+ # Save the best model
164
+ torch.save(model, '666cifar_model_resnet101_lr0.0001.pth')
165
+
166
+
167
+ # Test the model on the test set
168
+ def test(model, device, test_loader):
169
+ model.eval()
170
+ correct = 0
171
+ total = 0
172
+ with torch.no_grad():
173
+ for data, target in test_loader:
174
+ data, target = data.to(device), target.to(device)
175
+ outputs = model(data)
176
+ _, predicted = torch.max(outputs.data, 1)
177
+ total += target.size(0)
178
+ correct += (predicted == target).sum().item()
179
+
180
+ accuracy = correct / total
181
+ print('Test Accuracy: {:.2%} ({}/{})'.format(accuracy, correct, total))
182
+
183
+
184
+
185
+ # Train the model and track the best model
186
+ for epoch in range(1, EPOCHS + 1):
187
+ adjust_learning_rate(optimizer, epoch)
188
+ train(model, DEVICE, train_loader, optimizer, epoch)
189
+ val(model, DEVICE, val_loader, epoch)
190
+ test(model, DEVICE, test_loader)
191
+
192
+
193
+ print(f"Best model achieved at epoch {best_epoch} with accuracy: {best_accuracy * 100:.2f}%")