Skip to content
This repository has been archived by the owner on Aug 7, 2023. It is now read-only.

Add CLI params support + MobileNetV2 model + small refactoring #9

Merged
merged 10 commits into from
Mar 8, 2021
Next Next commit
Fix model params & add accuracy metric
  • Loading branch information
Remigiusz Poltorak committed Jan 22, 2021
commit 20e84cb955d0b3f2113dccef803b3e9a81033983
2 changes: 1 addition & 1 deletion mask_detector/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@


class MaskDataset(Dataset):
def __init__(self, csv_file, image_size=100):
def __init__(self, csv_file, image_size=32):
self.dataFrame = pd.read_csv(csv_file)

self.transform = Compose([
Expand Down
34 changes: 13 additions & 21 deletions mask_detector/mask_classifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from torch.utils.data import DataLoader, random_split
from torch.optim import Adam
from pytorch_lightning import LightningModule, Trainer, seed_everything
from pytorch_lightning.metrics import Accuracy
from pytorch_lightning.callbacks import ModelCheckpoint
from sklearn.metrics import accuracy_score

Expand All @@ -16,43 +17,37 @@
class MaskClassifier(LightningModule):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, probably it would be convenient to prepare some basic, semi-generic class for our DataModule.
It should define all the common operations for the task we have (image-processing), as probably most of them will be the same between different models.

Then we should extend this base class and overwrite specific methods for each Model we have (choosing correct datasets, defining some transformations etc).

What do you think?

def __init__(self, net, learning_rate=1e-3):
rpoltorak marked this conversation as resolved.
Show resolved Hide resolved
super().__init__()
self.save_hyperparameters()
self.net = net
self.learning_rate = learning_rate
self.accuracy = Accuracy()

def forward(self, x):
return self.net(x)

def training_step(self, batch, batch_idx):
x, y = batch
out = self.net(x)

loss = binary_cross_entropy(out, y)

self.log('train_loss', loss, on_epoch=True)

return loss
return {'loss': loss, 'accuracy': self.accuracy(out, y)}
rpoltorak marked this conversation as resolved.
Show resolved Hide resolved

def validation_step(self, batch, batch_idx):
x, y = batch
out = self.net(x)
loss = binary_cross_entropy(out, y)

self.log('valid_loss', loss, on_step=True)
return {'loss': loss, 'accuracy': self.accuracy(out, y)}
rpoltorak marked this conversation as resolved.
Show resolved Hide resolved

def test_step(self, batch, batch_idx):
x, y = batch
out = self.net(x)
loss = binary_cross_entropy(out, y)

_, out = torch.max(out, dim=1)
val_acc = accuracy_score(out.cpu(), y.cpu())
val_acc = torch.tensor(val_acc)

return {'test_loss': loss, 'test_acc': val_acc}
return {'loss': loss, 'accuracy': self.accuracy(out, y)}
rpoltorak marked this conversation as resolved.
Show resolved Hide resolved

def configure_optimizers(self):
# self.hparams available because we called self.save_hyperparameters()
return Adam(self.parameters(), lr=self.hparams.learning_rate)
return Adam(self.parameters(), lr=self.learning_rate)


def cli_main():
Expand All @@ -65,9 +60,9 @@ def cli_main():
ds_train, ds_validate, ds_test = train_val_test_split(
dataset, train_ratio=0.8, validate_ratio=0.1, test_ratio=0.1)

train_loader = DataLoader(ds_train, batch_size=128)
val_loader = DataLoader(ds_validate, batch_size=128)
test_loader = DataLoader(ds_test, batch_size=128)
train_loader = DataLoader(ds_train, batch_size=32)
val_loader = DataLoader(ds_validate, batch_size=32)
test_loader = DataLoader(ds_test, batch_size=32)

# ------------
# model
Expand All @@ -78,12 +73,9 @@ def cli_main():
# ------------
# training
# ------------
checkpoint_callback = ModelCheckpoint(
verbose=True,
monitor='test_acc',
mode='max'
)
trainer = Trainer(max_epochs=1, checkpoint_callback=checkpoint_callback)
gpus = 1 if torch.cuda.is_available() else 0

trainer = Trainer(gpus=gpus, max_epochs=3)
trainer.fit(model, train_loader, val_loader)

# ------------
Expand Down
13 changes: 2 additions & 11 deletions mask_detector/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,8 @@ def __init__(self):
MaxPool2d(kernel_size=(2, 2))
)

self.convLayers3 = Sequential(
Conv2d(64, 128, kernel_size=(3, 3), padding=(1, 1)),
ReLU(),
MaxPool2d(kernel_size=(2, 2))
)

self.linearLayers = Sequential(
Linear(in_features=128*25*25, out_features=2048),
ReLU(),
Linear(in_features=2048, out_features=1024),
Linear(in_features=64*8*8, out_features=1024),
ReLU(),
Linear(in_features=1024, out_features=1),
Softmax()
Expand All @@ -35,8 +27,7 @@ def __init__(self):
def forward(self, x):
x = self.convLayers1(x)
x = self.convLayers2(x)
x = self.convLayers3(x)
x = x.view(-1, 128*25*25)
x = x.view(-1, 64*8*8)
x = self.linearLayers(x)

return x