Sendeky commited on
Commit
b2caf23
1 Parent(s): 472cd94

Added expModel.py with 75.58% accuracy at 33 epochs

Browse files
Files changed (3) hide show
  1. .gitignore +163 -0
  2. expModel.py +244 -0
  3. model.py +2 -5
.gitignore ADDED
@@ -0,0 +1,163 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # MacOS Stuff
2
+ .DS_Store
3
+
4
+ # Byte-compiled / optimized / DLL files
5
+ __pycache__/
6
+ *.py[cod]
7
+ *$py.class
8
+
9
+ # C extensions
10
+ *.so
11
+
12
+ # Distribution / packaging
13
+ .Python
14
+ build/
15
+ develop-eggs/
16
+ dist/
17
+ downloads/
18
+ eggs/
19
+ .eggs/
20
+ lib/
21
+ lib64/
22
+ parts/
23
+ sdist/
24
+ var/
25
+ wheels/
26
+ share/python-wheels/
27
+ *.egg-info/
28
+ .installed.cfg
29
+ *.egg
30
+ MANIFEST
31
+
32
+ # PyInstaller
33
+ # Usually these files are written by a python script from a template
34
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
35
+ *.manifest
36
+ *.spec
37
+
38
+ # Installer logs
39
+ pip-log.txt
40
+ pip-delete-this-directory.txt
41
+
42
+ # Unit test / coverage reports
43
+ htmlcov/
44
+ .tox/
45
+ .nox/
46
+ .coverage
47
+ .coverage.*
48
+ .cache
49
+ nosetests.xml
50
+ coverage.xml
51
+ *.cover
52
+ *.py,cover
53
+ .hypothesis/
54
+ .pytest_cache/
55
+ cover/
56
+
57
+ # Translations
58
+ *.mo
59
+ *.pot
60
+
61
+ # Django stuff:
62
+ *.log
63
+ local_settings.py
64
+ db.sqlite3
65
+ db.sqlite3-journal
66
+
67
+ # Flask stuff:
68
+ instance/
69
+ .webassets-cache
70
+
71
+ # Scrapy stuff:
72
+ .scrapy
73
+
74
+ # Sphinx documentation
75
+ docs/_build/
76
+
77
+ # PyBuilder
78
+ .pybuilder/
79
+ target/
80
+
81
+ # Jupyter Notebook
82
+ .ipynb_checkpoints
83
+
84
+ # IPython
85
+ profile_default/
86
+ ipython_config.py
87
+
88
+ # pyenv
89
+ # For a library or package, you might want to ignore these files since the code is
90
+ # intended to run in multiple environments; otherwise, check them in:
91
+ # .python-version
92
+
93
+ # pipenv
94
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
95
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
96
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
97
+ # install all needed dependencies.
98
+ #Pipfile.lock
99
+
100
+ # poetry
101
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
102
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
103
+ # commonly ignored for libraries.
104
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
105
+ #poetry.lock
106
+
107
+ # pdm
108
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
109
+ #pdm.lock
110
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
111
+ # in version control.
112
+ # https://pdm.fming.dev/#use-with-ide
113
+ .pdm.toml
114
+
115
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
116
+ __pypackages__/
117
+
118
+ # Celery stuff
119
+ celerybeat-schedule
120
+ celerybeat.pid
121
+
122
+ # SageMath parsed files
123
+ *.sage.py
124
+
125
+ # Environments
126
+ .env
127
+ .venv
128
+ env/
129
+ venv/
130
+ ENV/
131
+ env.bak/
132
+ venv.bak/
133
+
134
+ # Spyder project settings
135
+ .spyderproject
136
+ .spyproject
137
+
138
+ # Rope project settings
139
+ .ropeproject
140
+
141
+ # mkdocs documentation
142
+ /site
143
+
144
+ # mypy
145
+ .mypy_cache/
146
+ .dmypy.json
147
+ dmypy.json
148
+
149
+ # Pyre type checker
150
+ .pyre/
151
+
152
+ # pytype static type analyzer
153
+ .pytype/
154
+
155
+ # Cython debug symbols
156
+ cython_debug/
157
+
158
+ # PyCharm
159
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
160
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
161
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
162
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
163
+ #.idea/
expModel.py ADDED
@@ -0,0 +1,244 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import torch.nn.functional as F
4
+ import torch.optim as optim
5
+ import torchvision.transforms as transforms
6
+ from torch.utils.data import DataLoader, Dataset
7
+
8
+ from cifar10 import Cifar10
9
+ from CustomCIFAR10Dataset import CustomCIFAR10Dataset
10
+
11
+
12
+ # create dataset builder instance
13
+ cifar10_builder = Cifar10()
14
+ # downloads the dataset
15
+ cifar10_builder.download_and_prepare()
16
+
17
+ # generate the dataset ('train', 'test' portion)
18
+ train_data = cifar10_builder.as_dataset(split='train')
19
+ test_data = cifar10_builder.as_dataset(split='test')
20
+
21
+ train_images = train_data["img"]
22
+ train_labels = train_data["label"]
23
+
24
+ test_images = test_data["img"]
25
+ test_labels = test_data["label"]
26
+
27
+ # Cifar10 classes
28
+ classes = ("airplane", "automobile", "bird", "cat", "deer",
29
+ "dog", "frog", "horse", "ship", "truck")
30
+
31
+ # PARAMETERS
32
+ # batch size during training
33
+ batch_size = 128
34
+
35
+ # image size
36
+ img_size = 32
37
+
38
+ # number of channels in image (3, because RGB in this case)
39
+ nc = 3
40
+
41
+ # output size (10 classes)
42
+ output = len(classes)
43
+
44
+ # Num of GPUs (pick 0 for CPU)
45
+ ngpu = 1
46
+
47
+ # number of workers
48
+ nw = 0
49
+
50
+ # number of training epochs
51
+ num_epochs = 33
52
+
53
+ # learning rate
54
+ learning_rate = 0.0022
55
+
56
+ # chooses which device to use
57
+ device = torch.device("cuda:0" if (torch.cuda.is_available()) and (ngpu > 0) else "cpu")
58
+
59
+ # transforms for image. CONVERT TO TENSOR VERY IMPORTANT, OTHERWISE DATALOADER WON"T ACCEPT IMAGE
60
+ transform = transforms.Compose([
61
+ transforms.Resize((32, 32)), # Resize the image to 32x32 (required for CIFAR-10)
62
+ transforms.RandomResizedCrop(32, scale=(0.8, 0.8)), # Random crop (image augmentation)
63
+ transforms.RandomHorizontalFlip(), # Random hoizontal flip (image augmentation)
64
+ transforms.ToTensor(), # Convert PIL Image to a tensor
65
+ transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)), # Normalize the image to [-1, 1]
66
+ ])
67
+
68
+ # We use our custsom cifar10 dataset class to convert the dataset to a format that the torch dataloader can use
69
+ train_ds = CustomCIFAR10Dataset(train_data["img"], train_data["label"], transform=transform)
70
+ test_ds = CustomCIFAR10Dataset(test_data["img"], test_data["label"], transform=transform)
71
+
72
+ # LOADERS FOR DATASET
73
+ train_loader = DataLoader(train_ds, batch_size, shuffle=True, num_workers=nw)
74
+ test_loader = DataLoader(test_ds, batch_size, shuffle=True, num_workers=nw)
75
+
76
+
77
+ # The nueral net class
78
+ class Net(nn.Module):
79
+ def __init__(self):
80
+ super(Net, self).__init__()
81
+
82
+ self.network = nn.Sequential(
83
+ # first 2 concolutional layers
84
+ nn.Conv2d(nc, 16, kernel_size=3, stride=1, padding=1), # a convoltional layer with 3 input channels, 16 output channels,
85
+ # a kernel size of 3, a stride of 1, and padding of 1
86
+ nn.BatchNorm2d(16, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True),
87
+ nn.ReLU(),
88
+ nn.MaxPool2d(kernel_size=1, stride=1),
89
+ nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1),
90
+ nn.BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True),
91
+ nn.ReLU(),
92
+ nn.MaxPool2d(1, 1),
93
+ nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1),
94
+ nn.BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True),
95
+ nn.ReLU(),
96
+ nn.MaxPool2d(kernel_size=1, stride=1),
97
+ nn.Conv2d(64, 32, kernel_size=3, stride=1, padding=1),
98
+ nn.BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True),
99
+ nn.ReLU(),
100
+ nn.MaxPool2d(kernel_size=1, stride=1),
101
+ nn.Conv2d(32, 16, kernel_size=3, stride=1, padding=1),
102
+
103
+ # max pooling layers
104
+ nn.MaxPool2d(kernel_size=2, stride=2), # a max pooling layer with kernel size of 3 and stride of 2
105
+ # helps reduce spatial dimensions of feature maps
106
+ nn.Flatten(),
107
+ nn.Linear(16 * 16 * 16, 64), # adjust the input size based on the output of the last conv layer
108
+ nn.Linear(64, 128),
109
+ nn.Dropout(0.2),
110
+ nn.Linear(128, 16),
111
+ nn.Linear(16, output),
112
+ )
113
+
114
+
115
+ def forward(self, x):
116
+ return self.network(x)
117
+
118
+ # creates instance of the model
119
+ model = Net()
120
+
121
+ print("model parameters: ", model.parameters)
122
+
123
+ # create the optimizer and criterion
124
+ criterion = nn.CrossEntropyLoss()
125
+ # Adam optimizer yields much better results than SGD
126
+ optimizer = optim.Adam(model.parameters(), lr=learning_rate, weight_decay=0.001)
127
+
128
+ # moves model to device (ie. cpu/gpu)
129
+ model.to(device)
130
+
131
+ # accuracy array (for plotting)
132
+ accuracyArr = []
133
+
134
+ print("started training")
135
+ for epoch in range(num_epochs):
136
+ model.train() # set model to training mode (important when using dropout or batch normalization)
137
+
138
+ running_loss = 0.0
139
+ for batch_idx, (images, labels) in enumerate(train_loader):
140
+ inputs = images.to(device)
141
+ labels = labels.to(device)
142
+ # print("print inputs shape: ", inputs.shape)
143
+
144
+ optimizer.zero_grad() # reset gradients
145
+
146
+ # forward pass
147
+ predictions = model(inputs)
148
+
149
+ # compute loss
150
+ loss = criterion(predictions, labels)
151
+
152
+ # Backpropogation
153
+ loss.backward()
154
+
155
+ # update models parameters
156
+ optimizer.step()
157
+
158
+ # print statistics
159
+ running_loss += loss.item()
160
+
161
+ print(f"epoch: {epoch + 1}/{num_epochs} Loss: {running_loss}")
162
+
163
+ # After training, evaluate the model on the test dataset to get final performance metrics
164
+ model.eval() # Set the model to evaluation mode (important when using dropout or batch normalization)
165
+ correct = 0
166
+ total = 0
167
+
168
+ with torch.no_grad():
169
+ for batch_idx, (images, labels) in enumerate(test_loader):
170
+ images = images.to(device)
171
+ labels = labels.to(device)
172
+
173
+ # Forward pass
174
+ predictions = model(images)
175
+
176
+ # Compute evaluation metrics (e.g., accuracy, precision, recall, etc.)
177
+ # get predicted class for each image
178
+ _, predicted = torch.max(predictions.data, 1)
179
+
180
+ # Count the total number of labels in the test dataset
181
+ total += labels.size(0)
182
+
183
+ # Count the number of correct predictions
184
+ correct += (predicted == labels).sum().item()
185
+
186
+ # calculate the accuracy
187
+ accuracy = correct/total
188
+ accuracyArr.append(accuracy)
189
+ print(f"Accuracy on the test dataset: {accuracy:.2%}, epoch: {epoch + 1}")
190
+
191
+
192
+ # After training, evaluate the model on the test dataset to get final performance metrics
193
+ model.eval() # Set the model to evaluation mode (important when using dropout or batch normalization)
194
+ correct = 0
195
+ total = 0
196
+
197
+ with torch.no_grad():
198
+ for batch_idx, (images, labels) in enumerate(test_loader):
199
+ images = images.to(device)
200
+ labels = labels.to(device)
201
+
202
+ # Forward pass
203
+ predictions = model(images)
204
+
205
+ # Compute evaluation metrics (e.g., accuracy, precision, recall, etc.)
206
+ # get predicted class for each image
207
+ _, predicted = torch.max(predictions.data, 1)
208
+
209
+ # Count the total number of labels in the test dataset
210
+ total += labels.size(0)
211
+
212
+ # Count the number of correct predictions
213
+ correct += (predicted == labels).sum().item()
214
+
215
+ # calculate the accuracy
216
+ accuracy = correct/total
217
+ print(f"Accuracy on the test dataset: {accuracy:.2%}")
218
+
219
+
220
+ ## IMPROVEMENTS/DEGREDATIONS ##
221
+ # BASELINE: ~51-54%
222
+
223
+ # After AutoAugment(CIFAR10): ~40%
224
+
225
+ # After Dropout: ~51-52%
226
+
227
+ # After adding another fully connected layer (64 in, 16 out): ~50-51%
228
+
229
+ # After adding weight decay to optimizer: (0.01): ~51+%
230
+
231
+ # ADDED: After adding all layers to nn.Sequential: ~55-57%
232
+
233
+ # ADDED: After using optim.Adam instead of optim.SGD: ~61-62%
234
+
235
+ # ADDED: After mimicking VGG16 architecture with: Conv2d -> ReLU -> MaxPool -> REPEAT
236
+
237
+ # MAX CURRENT ACCURACY: 72.71%
238
+
239
+ # import numpy as np
240
+ # import matplotlib.pyplot as plt
241
+ # y = np.array(accuracyArr)
242
+ # x = num_epochs
243
+ # plt.plot(x, y)
244
+ # plt.show()
model.py CHANGED
@@ -1,12 +1,9 @@
1
- import os
2
- import datasets
3
  import torch
4
  import torch.nn as nn
5
  import torch.nn.functional as F
6
  import torch.optim as optim
7
  import torchvision.transforms as transforms
8
  from torch.utils.data import DataLoader, Dataset
9
- from PIL import Image
10
 
11
  from cifar10 import Cifar10
12
  from CustomCIFAR10Dataset import CustomCIFAR10Dataset
@@ -148,7 +145,7 @@ for epoch in range(num_epochs):
148
  print(f'[{epoch + 1}, {batch_idx + 1:5d}] loss: {running_loss / 2000:.3f}')
149
  running_loss = 0.0
150
 
151
- print(f"epoch: {epoch}/{num_epochs}")
152
 
153
  print("finished training")
154
 
@@ -196,4 +193,4 @@ print(f"Accuracy on the test dataset: {accuracy:.2%}")
196
 
197
  # ADDED: After using optim.Adam instead of optim.SGD: ~61-62%
198
 
199
- # ADDED: After adding a nn.Linear(64, 16): ~62-63+%
 
 
 
1
  import torch
2
  import torch.nn as nn
3
  import torch.nn.functional as F
4
  import torch.optim as optim
5
  import torchvision.transforms as transforms
6
  from torch.utils.data import DataLoader, Dataset
 
7
 
8
  from cifar10 import Cifar10
9
  from CustomCIFAR10Dataset import CustomCIFAR10Dataset
 
145
  print(f'[{epoch + 1}, {batch_idx + 1:5d}] loss: {running_loss / 2000:.3f}')
146
  running_loss = 0.0
147
 
148
+ print(f"epoch: {epoch + 1}/{num_epochs}")
149
 
150
  print("finished training")
151
 
 
193
 
194
  # ADDED: After using optim.Adam instead of optim.SGD: ~61-62%
195
 
196
+ # MAX Observed accuracy: 63.20%