cifar10-tools 0.4.0__tar.gz → 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cifar10_tools-0.4.0 → cifar10_tools-0.5.0}/PKG-INFO +10 -4
- {cifar10_tools-0.4.0 → cifar10_tools-0.5.0}/README.md +9 -3
- {cifar10_tools-0.4.0 → cifar10_tools-0.5.0}/pyproject.toml +12 -1
- {cifar10_tools-0.4.0 → cifar10_tools-0.5.0}/src/cifar10_tools/pytorch/hyperparameter_optimization.py +49 -18
- {cifar10_tools-0.4.0 → cifar10_tools-0.5.0}/LICENSE +0 -0
- {cifar10_tools-0.4.0 → cifar10_tools-0.5.0}/src/cifar10_tools/__init__.py +0 -0
- {cifar10_tools-0.4.0 → cifar10_tools-0.5.0}/src/cifar10_tools/pytorch/__init__.py +0 -0
- {cifar10_tools-0.4.0 → cifar10_tools-0.5.0}/src/cifar10_tools/pytorch/data.py +0 -0
- {cifar10_tools-0.4.0 → cifar10_tools-0.5.0}/src/cifar10_tools/pytorch/evaluation.py +0 -0
- {cifar10_tools-0.4.0 → cifar10_tools-0.5.0}/src/cifar10_tools/pytorch/plotting.py +0 -0
- {cifar10_tools-0.4.0 → cifar10_tools-0.5.0}/src/cifar10_tools/pytorch/training.py +0 -0
- {cifar10_tools-0.4.0 → cifar10_tools-0.5.0}/src/cifar10_tools/tensorflow/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cifar10_tools
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Tools for training neural networks on the CIFAR-10 task with PyTorch and TensorFlow
|
|
5
5
|
License: GPLv3
|
|
6
6
|
License-File: LICENSE
|
|
@@ -36,17 +36,23 @@ Description-Content-Type: text/markdown
|
|
|
36
36
|
|
|
37
37
|
A progressive deep learning tutorial for image classification on the CIFAR-10 dataset using PyTorch. This project demonstrates the evolution from basic deep neural networks to optimized convolutional neural networks with data augmentation. It also provides a set of utility functions as a PyPI package for use in other projects.
|
|
38
38
|
|
|
39
|
-
[View on PyPI](https://pypi.org/project/cifar10_tools)
|
|
39
|
+
[View on PyPI](https://pypi.org/project/cifar10_tools) | [Documentation](https://gperdrizet.github.io/CIFAR10/)
|
|
40
40
|
|
|
41
41
|
## Installation
|
|
42
42
|
|
|
43
|
-
Install the helper tools package locally in editable mode:
|
|
43
|
+
Install the helper tools package locally in editable mode to use in this repository:
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
46
|
pip install -e .
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
Or install from PyPI to use in other projects:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install cifar10_tools
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Project overview
|
|
50
56
|
|
|
51
57
|
This repository contains a series of Jupyter notebooks that progressively build more sophisticated neural network architectures for the CIFAR-10 image classification task. Each notebook builds upon concepts from the previous one, demonstrating key deep learning techniques.
|
|
52
58
|
|
|
@@ -2,17 +2,23 @@
|
|
|
2
2
|
|
|
3
3
|
A progressive deep learning tutorial for image classification on the CIFAR-10 dataset using PyTorch. This project demonstrates the evolution from basic deep neural networks to optimized convolutional neural networks with data augmentation. It also provides a set of utility functions as a PyPI package for use in other projects.
|
|
4
4
|
|
|
5
|
-
[View on PyPI](https://pypi.org/project/cifar10_tools)
|
|
5
|
+
[View on PyPI](https://pypi.org/project/cifar10_tools) | [Documentation](https://gperdrizet.github.io/CIFAR10/)
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
9
|
-
Install the helper tools package locally in editable mode:
|
|
9
|
+
Install the helper tools package locally in editable mode to use in this repository:
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
12
|
pip install -e .
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
Or install from PyPI to use in other projects:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pip install cifar10_tools
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Project overview
|
|
16
22
|
|
|
17
23
|
This repository contains a series of Jupyter notebooks that progressively build more sophisticated neural network architectures for the CIFAR-10 image classification task. Each notebook builds upon concepts from the previous one, demonstrating key deep learning techniques.
|
|
18
24
|
|
|
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
4
4
|
|
|
5
5
|
[tool.poetry]
|
|
6
6
|
name = "cifar10_tools"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.5.0"
|
|
8
8
|
description = "Tools for training neural networks on the CIFAR-10 task with PyTorch and TensorFlow"
|
|
9
9
|
authors = ["gperdrizet <george@perdrizet.org>"]
|
|
10
10
|
readme = "README.md"
|
|
@@ -33,6 +33,17 @@ torch = ">=2.0"
|
|
|
33
33
|
torchvision = ">=0.15"
|
|
34
34
|
numpy = ">=1.24"
|
|
35
35
|
|
|
36
|
+
[tool.poetry.group.docs]
|
|
37
|
+
optional = true
|
|
38
|
+
|
|
39
|
+
[tool.poetry.group.docs.dependencies]
|
|
40
|
+
sphinx = ">=7.0"
|
|
41
|
+
sphinx-rtd-theme = ">=2.0"
|
|
42
|
+
nbsphinx = ">=0.9"
|
|
43
|
+
sphinx-autodoc-typehints = ">=1.25"
|
|
44
|
+
ipykernel = ">=6.0"
|
|
45
|
+
pandoc = ">=2.0"
|
|
46
|
+
|
|
36
47
|
[tool.poetry.extras]
|
|
37
48
|
tensorflow = ["tensorflow"]
|
|
38
49
|
|
{cifar10_tools-0.4.0 → cifar10_tools-0.5.0}/src/cifar10_tools/pytorch/hyperparameter_optimization.py
RENAMED
|
@@ -46,6 +46,7 @@ def create_cnn(
|
|
|
46
46
|
Returns:
|
|
47
47
|
nn.Sequential model
|
|
48
48
|
'''
|
|
49
|
+
|
|
49
50
|
layers = []
|
|
50
51
|
current_channels = in_channels
|
|
51
52
|
current_size = input_size
|
|
@@ -58,6 +59,8 @@ def create_cnn(
|
|
|
58
59
|
|
|
59
60
|
# First conv in block
|
|
60
61
|
layers.append(nn.Conv2d(current_channels, out_channels, kernel_size=kernel_size, padding=padding))
|
|
62
|
+
# Update size after conv: output_size = (input_size + 2*padding - kernel_size) + 1
|
|
63
|
+
current_size = (current_size + 2 * padding - kernel_size) + 1
|
|
61
64
|
|
|
62
65
|
if use_batch_norm:
|
|
63
66
|
layers.append(nn.BatchNorm2d(out_channels))
|
|
@@ -66,6 +69,7 @@ def create_cnn(
|
|
|
66
69
|
|
|
67
70
|
# Second conv in block
|
|
68
71
|
layers.append(nn.Conv2d(out_channels, out_channels, kernel_size=kernel_size, padding=padding))
|
|
72
|
+
current_size = (current_size + 2 * padding - kernel_size) + 1
|
|
69
73
|
|
|
70
74
|
if use_batch_norm:
|
|
71
75
|
layers.append(nn.BatchNorm2d(out_channels))
|
|
@@ -81,11 +85,10 @@ def create_cnn(
|
|
|
81
85
|
layers.append(nn.Dropout(conv_dropout_rate))
|
|
82
86
|
|
|
83
87
|
current_channels = out_channels
|
|
84
|
-
current_size //= 2
|
|
88
|
+
current_size //= 2 # Pooling halves the size
|
|
85
89
|
|
|
86
|
-
# Calculate flattened size
|
|
87
|
-
|
|
88
|
-
flattened_size = final_channels * current_size * current_size
|
|
90
|
+
# Calculate flattened size using actual current_size
|
|
91
|
+
flattened_size = current_channels * current_size * current_size
|
|
89
92
|
|
|
90
93
|
# Classifier - dynamic FC layers with halving pattern
|
|
91
94
|
layers.append(nn.Flatten())
|
|
@@ -180,7 +183,8 @@ def create_objective(
|
|
|
180
183
|
n_epochs: int,
|
|
181
184
|
device: torch.device,
|
|
182
185
|
num_classes: int = 10,
|
|
183
|
-
in_channels: int = 3
|
|
186
|
+
in_channels: int = 3,
|
|
187
|
+
search_space: dict = None
|
|
184
188
|
) -> Callable[[optuna.Trial], float]:
|
|
185
189
|
'''Create an Optuna objective function for CNN hyperparameter optimization.
|
|
186
190
|
|
|
@@ -195,6 +199,7 @@ def create_objective(
|
|
|
195
199
|
device: Device to train on (cuda or cpu)
|
|
196
200
|
num_classes: Number of output classes (default: 10)
|
|
197
201
|
in_channels: Number of input channels (default: 3 for RGB)
|
|
202
|
+
search_space: Dictionary defining hyperparameter search space (default: None)
|
|
198
203
|
|
|
199
204
|
Returns:
|
|
200
205
|
Objective function for optuna.Study.optimize()
|
|
@@ -205,21 +210,43 @@ def create_objective(
|
|
|
205
210
|
>>> study.optimize(objective, n_trials=100)
|
|
206
211
|
'''
|
|
207
212
|
|
|
213
|
+
# Default search space if none provided
|
|
214
|
+
if search_space is None:
|
|
215
|
+
search_space = {
|
|
216
|
+
'batch_size': [64, 128, 256, 512, 1024],
|
|
217
|
+
'n_conv_blocks': (1, 5),
|
|
218
|
+
'initial_filters': [8, 16, 32, 64, 128],
|
|
219
|
+
'n_fc_layers': (1, 8),
|
|
220
|
+
'base_kernel_size': (3, 7),
|
|
221
|
+
'conv_dropout_rate': (0.0, 0.5),
|
|
222
|
+
'fc_dropout_rate': (0.2, 0.75),
|
|
223
|
+
'pooling_strategy': ['max', 'avg'],
|
|
224
|
+
'use_batch_norm': [True, False],
|
|
225
|
+
'learning_rate': (1e-5, 1e-1, 'log'),
|
|
226
|
+
'optimizer': ['Adam', 'SGD', 'RMSprop'],
|
|
227
|
+
'sgd_momentum': (0.8, 0.99)
|
|
228
|
+
}
|
|
229
|
+
|
|
208
230
|
def objective(trial: optuna.Trial) -> float:
|
|
209
231
|
'''Optuna objective function for CNN hyperparameter optimization.'''
|
|
210
232
|
|
|
211
|
-
# Suggest hyperparameters
|
|
212
|
-
batch_size = trial.suggest_categorical('batch_size', [
|
|
213
|
-
n_conv_blocks = trial.suggest_int('n_conv_blocks',
|
|
214
|
-
initial_filters = trial.suggest_categorical('initial_filters', [
|
|
215
|
-
n_fc_layers = trial.suggest_int('n_fc_layers',
|
|
216
|
-
base_kernel_size = trial.suggest_int('base_kernel_size',
|
|
217
|
-
conv_dropout_rate = trial.suggest_float('conv_dropout_rate',
|
|
218
|
-
fc_dropout_rate = trial.suggest_float('fc_dropout_rate',
|
|
219
|
-
pooling_strategy = trial.suggest_categorical('pooling_strategy', ['
|
|
220
|
-
use_batch_norm = trial.suggest_categorical('use_batch_norm', [
|
|
221
|
-
|
|
222
|
-
|
|
233
|
+
# Suggest hyperparameters from search space
|
|
234
|
+
batch_size = trial.suggest_categorical('batch_size', search_space['batch_size'])
|
|
235
|
+
n_conv_blocks = trial.suggest_int('n_conv_blocks', *search_space['n_conv_blocks'])
|
|
236
|
+
initial_filters = trial.suggest_categorical('initial_filters', search_space['initial_filters'])
|
|
237
|
+
n_fc_layers = trial.suggest_int('n_fc_layers', *search_space['n_fc_layers'])
|
|
238
|
+
base_kernel_size = trial.suggest_int('base_kernel_size', *search_space['base_kernel_size'])
|
|
239
|
+
conv_dropout_rate = trial.suggest_float('conv_dropout_rate', *search_space['conv_dropout_rate'])
|
|
240
|
+
fc_dropout_rate = trial.suggest_float('fc_dropout_rate', *search_space['fc_dropout_rate'])
|
|
241
|
+
pooling_strategy = trial.suggest_categorical('pooling_strategy', search_space['pooling_strategy'])
|
|
242
|
+
use_batch_norm = trial.suggest_categorical('use_batch_norm', search_space['use_batch_norm'])
|
|
243
|
+
|
|
244
|
+
# Handle learning rate with optional log scale
|
|
245
|
+
lr_params = search_space['learning_rate']
|
|
246
|
+
learning_rate = trial.suggest_float('learning_rate', lr_params[0], lr_params[1],
|
|
247
|
+
log=(lr_params[2] == 'log' if len(lr_params) > 2 else False))
|
|
248
|
+
|
|
249
|
+
optimizer_name = trial.suggest_categorical('optimizer', search_space['optimizer'])
|
|
223
250
|
|
|
224
251
|
# Create data loaders with suggested batch size
|
|
225
252
|
train_loader, val_loader, _ = make_data_loaders(
|
|
@@ -250,7 +277,7 @@ def create_objective(
|
|
|
250
277
|
optimizer = optim.Adam(model.parameters(), lr=learning_rate)
|
|
251
278
|
|
|
252
279
|
elif optimizer_name == 'SGD':
|
|
253
|
-
momentum = trial.suggest_float('sgd_momentum',
|
|
280
|
+
momentum = trial.suggest_float('sgd_momentum', *search_space['sgd_momentum'])
|
|
254
281
|
optimizer = optim.SGD(model.parameters(), lr=learning_rate, momentum=momentum)
|
|
255
282
|
|
|
256
283
|
else: # RMSprop
|
|
@@ -270,6 +297,10 @@ def create_objective(
|
|
|
270
297
|
trial=trial
|
|
271
298
|
)
|
|
272
299
|
|
|
300
|
+
except RuntimeError as e:
|
|
301
|
+
# Catch architecture errors (e.g., dimension mismatches)
|
|
302
|
+
raise optuna.TrialPruned(f'RuntimeError with params: {trial.params} - {str(e)}')
|
|
303
|
+
|
|
273
304
|
except torch.cuda.OutOfMemoryError:
|
|
274
305
|
# Clear CUDA cache and skip this trial
|
|
275
306
|
torch.cuda.empty_cache()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|