Skip to content

Commit 93c1013

Browse files
committed
Merge branch 'main' into Jan-doc
2 parents ff7ad56 + e6c2630 commit 93c1013

File tree

9 files changed

+75
-27
lines changed

9 files changed

+75
-27
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
on:
2+
push:
3+
# Sequence of patterns matched against refs/tags
4+
tags:
5+
- 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10
6+
7+
name: Create Release
8+
9+
jobs:
10+
build:
11+
name: Create Release
12+
runs-on: ubuntu-latest
13+
steps:
14+
- name: Checkout code
15+
uses: actions/checkout@master
16+
- name: Create Release
17+
id: create_release
18+
uses: actions/create-release@latest
19+
env:
20+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token
21+
with:
22+
tag_name: ${{ github.ref }}
23+
release_name: Release ${{ github.ref }}
24+
body: |
25+
Changes in this Release
26+
- First Change
27+
- Second Change
28+
draft: false
29+
prerelease: false

CollaborativeCoding/dataloaders/download.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,11 +102,11 @@ def download_svhn(path, train: bool = True):
102102
train_data = parent_path / "train_32x32.mat"
103103
test_data = parent_path / "test_32x32.mat"
104104

105-
if not train_data.is_file():
105+
if not train_data.exists():
106106
download_svhn(parent_path, train=True)
107-
if not test_data.is_file():
107+
if not test_data.exists():
108108
download_svhn(parent_path, train=False)
109-
print(test_data)
109+
110110
train_labels = loadmat(train_data)["y"]
111111
test_labels = loadmat(test_data)["y"]
112112

CollaborativeCoding/dataloaders/svhn.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
from PIL import Image
77
from scipy.io import loadmat
88
from torch.utils.data import Dataset
9-
from torchvision.datasets import SVHN
109

1110

1211
class SVHNDataset(Dataset):
@@ -31,7 +30,7 @@ def __init__(
3130
"""
3231
super().__init__()
3332

34-
self.data_path = data_path
33+
self.data_path = data_path / "SVHN"
3534
self.indexes = sample_ids
3635
self.split = "train" if train else "test"
3736

@@ -41,7 +40,7 @@ def __init__(
4140
if not os.path.exists(
4241
os.path.join(self.data_path, f"svhn_{self.split}data.h5")
4342
):
44-
self._download_data(self.data_path)
43+
self._create_h5py(self.data_path)
4544

4645
assert os.path.exists(
4746
os.path.join(self.data_path, f"svhn_{self.split}data.h5")
@@ -53,15 +52,14 @@ def __init__(
5352

5453
self.num_classes = len(np.unique(self.labels))
5554

56-
def _download_data(self, path: str):
55+
def _create_h5py(self, path: str):
5756
"""
5857
Downloads the SVHN dataset to the specified directory.
5958
Args:
6059
path (str): The directory where the dataset will be downloaded.
6160
"""
6261
print(f"Downloading SVHN data into {path}")
6362

64-
SVHN(path, split=self.split, download=True)
6563
data = loadmat(os.path.join(path, f"{self.split}_32x32.mat"))
6664

6765
images, labels = data["X"], data["y"]

CollaborativeCoding/dataloaders/uspsh5_7_9.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,3 @@ def __getitem__(self, id):
102102
image = self.transform(image)
103103

104104
return image, label
105-

CollaborativeCoding/metrics/F1.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ def __init__(self, num_classes, macro_averaging=False):
2323
self.y_true = []
2424
self.y_pred = []
2525

26-
2726
def forward(self, target, preds):
2827
"""
2928
Stores predictions and targets for computing the F1 score.
@@ -57,7 +56,11 @@ def compute_f1(self):
5756
y_true = torch.cat(self.y_true)
5857
y_pred = torch.cat(self.y_pred)
5958

60-
return self._macro_F1(y_true, y_pred) if self.macro_averaging else self._micro_F1(y_true, y_pred)
59+
return (
60+
self._macro_F1(y_true, y_pred)
61+
if self.macro_averaging
62+
else self._micro_F1(y_true, y_pred)
63+
)
6164

6265
def _micro_F1(self, target, preds):
6366
"""Computes Micro F1 Score (global TP, FP, FN)."""
@@ -111,9 +114,13 @@ def __returnmetric__(self):
111114
y_true = torch.cat([t.unsqueeze(0) if t.dim() == 0 else t for t in self.y_true])
112115
y_pred = torch.cat([t.unsqueeze(0) if t.dim() == 0 else t for t in self.y_pred])
113116

114-
return self._macro_F1(y_true, y_pred) if self.macro_averaging else self._micro_F1(y_true, y_pred)
117+
return (
118+
self._macro_F1(y_true, y_pred)
119+
if self.macro_averaging
120+
else self._micro_F1(y_true, y_pred)
121+
)
115122

116123
def __reset__(self):
117124
"""Resets stored predictions and targets."""
118125
self.y_true = []
119-
self.y_pred = []
126+
self.y_pred = []

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,26 @@
33
# Collaborative-Coding-Exam
44
Repository for final evaluation in the FYS-8805 Reproducible Research and Collaborative coding course
55

6+
## Installation
7+
8+
Install from:
9+
10+
```sh
11+
pip install git+https://github.com/SFI-Visual-Intelligence/Collaborative-Coding-Exam.git
12+
```
13+
14+
or using [uv](https://docs.astral.sh/uv/):
15+
16+
```sh
17+
uv add git+https://github.com/SFI-Visual-Intelligence/Collaborative-Coding-Exam.git
18+
```
19+
20+
To verify:
21+
22+
```sh
23+
python -c "import CollaborativeCoding"
24+
```
25+
626
## Usage
727

828
TODO: Fill in

doc/Magnus_page.md

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,24 +26,19 @@ Each input is flattened over the channel, height and width channels. Then they a
2626

2727

2828
## Entropy Metric In-Depth
29-
30-
The EntropyPrediction class' main job is to take some inputs and return the Shannon Entropy metric of those inputs. The class has four methods with the following jobs:
29+
The EntropyPrediction class' main job is to take some inputs from the MetricWrapper class and store the batchwise Shannon Entropy metric of those inputs. The class has four methods with the following jobs:
3130
* __init__ : Initialize the class.
3231
* __call__ : Main method which is used to calculate and store the batchwise shannon entropy.
3332
* __returnmetric__ : Returns the collected metric.
3433
* __reset__ : Removes all the stored values up until that point. Readies the instance for storing values from a new epoch.
3534

36-
The class is initialized with a single parameter called "averages". This is inspired from other PyTorch and NumPy implementations and controlls how values from different batches or within batches will be combined. The __init__ method checks the value of this argument with an assertion, which must be one of three string. We only allow "mean", "sum" and "none" as methods of combining the different entropy values. We'll come back to the specifics here.
37-
Furthermore, this method will also store the different Shannon Entropy values as we pass values into the __call__ method.
35+
The __init__ method has two arguments, both present for compatability issues. However, the num_classes argument is used as a check in the __call__ method to assert the input is of correctly assumed size.
36+
37+
In __call__ we get both true labels and model logit scores for each sample in the batch as input. We're calculating Shannon Entropy, not KL-divergence, so the true labels aren't actually needed.
38+
With permission I've used the scipy implementation to calculate entropy here. We apply a softmax over the logit values, then calculate the Shannon Entropy, and make sure to remove any Inf values which might arise from a perfect guess/distribution.
39+
3840

39-
In __call__ we get both true labels and model logit scores for each sample in the batch as input. We're calculating Shannon Entropy, not KL-divergence, so the true labels aren't needed.
40-
With permission I've used the scipy implementation to calculate entropy here. We apply a softmax over the logit values, then calculate the Shannon Entropy, and make sure to remove any NaN or Inf values which might arise from a perfect guess/distribution.
4141

42-
Next we have the __returnmetric__ method which is used to retrive the stored metric. Here the averages argument comes into play.
43-
Depending on what has been chosen as the averaging metric when initializing the class, one of the following operations will be applied to the stored values:
44-
* Mean: Calculate the mean of the stored entropy values.
45-
* Sum: Sum the stored entropy values.
46-
* None: Do nothing with the stored entropy values.
47-
Then the value(s) are returned.
42+
Next we have the __returnmetric__ method which is used to retrive the stored metric. This returns the mean over all stored values. Effectively, this will return the average Shannon Entropy of the dataset.
4843

4944
Lastly we have the __reset__ method which simply emptied the variable which stores the entropy values to prepare it for the next epoch.

main.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import numpy as np
22
import torch as th
33
import torch.nn as nn
4+
import wandb
45
from torch.utils.data import DataLoader
56
from torchvision import transforms
67
from tqdm import tqdm
78

8-
import wandb
99
from CollaborativeCoding import (
1010
MetricWrapper,
1111
createfolders,

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "collaborative-coding-exam"
33
version = "0.1.0"
44
description = "Exam project in the collaborative coding course."
55
readme = "README.md"
6-
requires-python = ">=3.12"
6+
requires-python = ">=3.11.5"
77
dependencies = [
88
"black>=25.1.0",
99
"h5py>=3.12.1",

0 commit comments

Comments
 (0)