Introducing slackker! :fire:
Watching training metrics is a time killer and addictive. Have you ever found yourself walking back and forth to computer to monitor progress, only to find that the current epoch is not finished yet or that nothing has changed?
When you're in front of your screen, you start to look for patterns in the metrics to judge the progress, this way training spills over into the rest of your live. All the time the models are training, your brain works at 50% at most. So, I made slackker to make your life easy :grin:
Requirements: slack_sdk>=3.19.0
and matplotlib
slackker
is a python package for monitoring your python script & ML model training status in real-time on Slack & Telegram.
Features:
- Integrate within any .py function/script: You can integrate slackker with any python script or function.
- Real-time updates: Get updates on your training progress in real-time on Slack & Telegram.
- Exported Plots: Exported plots of training metrics and send it to your Slack channel.
- Customizable: Customize the metrics you want to track and notify.
- Easy to use: Just import the package, setup the slack/telegram and you are good to go.
So now you don't have to sit in front of the machine all the time. You can quickly go and grab coffee :coffee: downstairs or run some errands and still keep tracking the progress while on the move without loosing your peace of mind.
Table of contents :notebook:
Installation :arrow_down:
- Install slackker from PyPi is recommended. slackker is compatible with
Python >= 3.6
and runs on Linux, MacOS X and Windows. - Installing slackker in your environment is easy. Just use below pip command:
pip install slackker
Getting started with slackker callbacks
Setup slackker
Use slackker callbacks for any python functions
Import basic slackker callbacks with following line:
from slackker.callbacks.basic import SlackUpdate
from slackker.callbacks.basic import TelegramUpdate
Create slackker object.
slackker = SlackUpdate(token="xoxb-123234234235-123234234235-adedce74748c3844747aed",
channel="A04AAB77ABC")
or
slackker = TelegramUpdate(token="1234567890:AAAAA_A111BBBBBCCC2DD3eEe44f5GGGgGG")
token
: (string) Slack app/Telegram tokenchannel
: (string) Slack channel where you want to receive updatesverbose
: (int) default 0
: You can sent the verbose level up to 3.
verbose = 0
No loggingverbose = 1
Info loggingverbose = 2
Debug/In-depth logging
Now you can wrap your function with this slackker object.
@slackker.notifier
def your_function():
return value_1, value_2
following messages will be sent to your slack channel when the function executes.
Function 'your_function' from Script: 'your_script.py' executed.
Execution time: 5.006 Seconds
Returned 2 outputs:
Output 0:
value_1
Output 1:
value_2
You can also use slackker.notify(*args, **kwargs)
at the end of your script to notify the end of script execution.
if __name__ == "__main__":
your_function()
slackker.notify(arg1, f"This is argument 2 = {arg2}", value="This is a string")
following message will be sent to your slack channel when the script ends.
Your script: 'your_script.py' has been executed successfully at 14-10-2024 12:15:54
arg1
This is argument 2 = arg2
value: This is a string
Final code for python function
from slackker.callbacks.basic import SlackUpdate
from slackker.callbacks.basic import TelegramUpdate
slackker = SlackUpdate(token="xoxb-123234234235-123234234235-adedce74748c3844747aed",
channel="A04AAB77ABC")
slackker = TelegramUpdate(token="1234567890:AAAAA_A111BBBBBCCC2DD3eEe44f5GGGgGG")
@slackker.notifier
def your_function():
return value_1, value_2
slackker.notify(f"This is value 1: {value_1}", value=value_2)
Use slackker callbacks with Keras
Import slackker for Keras
Import slackker callbacks for keras with following line:
from slackker.callbacks.keras import SlackUpdate
from slackker.callbacks.keras import TelegramUpdate
Create slackker object for keras
Create slackker object.
slackker = SlackUpdate(token="xoxb-123234234235-123234234235-adedce74748c3844747aed",
channel="A04AAB77ABC",
ModelName='Keras_NN',
export='png',
SendPlot=True)
or
slackker = TelegramUpdate(token="1234567890:AAAAA_A111BBBBBCCC2DD3eEe44f5GGGgGG",
ModelName='Simple_NN',
export='png',
SendPlot=True)
token
: (string) Slack app/Telegram tokenchannel
: (string) Slack channel where you want to receive updatesModelName
: (string) Name for your model. This same name will be used in future for title of the generated plots.export
: (string) default "png"
: Format for plots to be exported. (supported formats: eps, jpeg, jpg, pdf, pgf, png, ps, raw, rgba, svg, svgz, tif, tiff)SendPlots
: (Bool) default False
: If set to True
it will export history of model, both training and validation, save it in the format given in export
argument and send graphs to slack channel when training ends. If set to False
it will not send exported graphs to slack channel.verbose
: (int) default 0
: You can sent the verbose level up to 3.
verbose = 0
No loggingverbose = 1
Info loggingverbose = 2
Debug/In-depth logging
Call slackker object into model.fit()
Now you can call slackker object into callbacks argument just like any other callbacks object.
history = model.fit(x_train,
y_train,
epochs = 3,
batch_size = 16,
verbose=1,
validation_data=(x_val,y_val),
callbacks=[slackker])
Final code for Keras
from slackker.callbacks.keras import slackUpdate
x_train, x_test, y_train, y_test = train_test_split(x, y, train_size=0.8)
x_train, x_val, y_train, y_val = train_test_split(x_train, y_train, train_size=0.8)
model = Sequential()
model.add(Dense(8,activation='relu',input_shape = (IMG_WIDTH, IMG_HEIGHT, DEPTH)))
model.add(Dense(3,activation='softmax'))
model.compile(optimizer = 'rmsprop', loss='categorical_crossentropy', metrics=['accuracy'])
slackker = slackUpdate(token="xoxb-123234234235-123234234235-adedce74748c3844747aed48499bb",
channel="A04AAB77ABC",
modelName='SampleModel',
export='png',
sendPlot=True)
history = model.fit(x_train,
y_train,
epochs = 3,
batch_size = 16,
verbose=1,
validation_data=(x_val,y_val),
callbacks=[slackker])
Use slackker callbacks with Lightning
Import slackker for Lightning
Import slackker callbacks for PyTorch Lightning with following line:
from slackker.callbacks.lightning import SlackUpdate
from slackker.callbacks.lightning import TelegramUpdate
Log your metrics to track
Log Training loop metrics
self.log("train_loss", loss, on_epoch=True)
self.log("train_acc", accuracy, on_epoch=True)
Make sure to set on_epoch=True
to in training step.
Log Validation loop metrics
self.log("val_loss", loss)
self.log("val_acc", accuracy)
In Validation step on_epoch=True
by default.
Create slackker object for lightning
slackker = SlackUpdate(token="xoxb-123234234235-123234234235-adedce74748c3844747aed",
channel="A04AAB77ABC",
ModelName='Lightning NN',
TrackLogs=['train_loss', 'train_acc', 'val_loss', 'val_acc'],
monitor="val_loss",
export='png',
SendPlot=True)
or
slackker = TelegramUpdate(token="1234567890:AAAAA_A111BBBBBCCC2DD3eEe44f5GGGgGG",
ModelName="Lightning NN Testing",
TrackLogs=['train_loss', 'train_acc', 'val_loss', 'val_acc'],
monitor="val_loss",
export='png',
SendPlot=True)
token
: (string) Slack app/Telegram tokenchannel
: (string) Slack channel where you want to receive updatesModelName
: (string) Name for your model. This same name will be used in future for title of the generated plots.TrackLogs
: (list) List of metrics you want slackker to track & notify.monitor
: (string) This metric will be used to determine best Epochexport
: (string) default "png"
: Format for plots to be exported. (supported formats: eps, jpeg, jpg, pdf, pgf, png, ps, raw, rgba, svg, svgz, tif, tiff)SendPlots
: (Bool) default False
: If set to True
it will export history of model, both training and validation, save it in the format given in export
argument and send graphs to slack channel when training ends. If set to False
it will not send exported graphs to slack channel.verbose
: (int) default 0
: You can sent the verbose level up to 3.
verbose = 0
No loggingverbose = 1
Info loggingverbose = 2
Debug/In-depth logging
Call slackker object in Trainer module
Now you can call slackker object into callbacks argument just like any other callbacks object.
trainer = Trainer(max_epochs=2,callbacks=[slackker])
Final code for Lightning
import torch
import torch.nn as nn
from torch.utils.data import DataLoader
import torchvision as tv
import torch.nn.functional as F
from lightning.pytorch import LightningModule, Trainer
from lightning.pytorch.callbacks import ModelCheckpoint, Callback
from lightning.pytorch.loggers import CSVLogger
from slackker.callbacks.lightning import SlackUpdate
from slackker.callbacks.lightning import TelegramUpdate
class LightningModel(LightningModule):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(28*28,256)
self.fc2 = nn.Linear(256,128)
self.out = nn.Linear(128,10)
def forward(self, x):
batch_size, _, _, _ = x.size()
x = x.view(batch_size,-1)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
return self.out(x)
def configure_optimizers(self):
optimizer = torch.optim.Adam(self.parameters(), lr=1e-3)
return optimizer
def training_step(self, batch, batch_idx):
x, y = batch
y_hat = self.forward(x)
loss = F.cross_entropy(y_hat,y)
_, predictions = torch.max(y_hat, dim=1)
correct_predictions = torch.sum(predictions == y)
accuracy = correct_predictions / y.shape[0]
self.log("train_loss", loss, on_epoch=True)
self.log("train_acc", accuracy, on_epoch=True)
return loss
def validation_step(self, batch, batch_idx):
x, y = batch
y_hat = self.forward(x)
loss = F.cross_entropy(y_hat,y)
_, predictions = torch.max(y_hat, dim=1)
correct_predictions = torch.sum(predictions == y)
accuracy = correct_predictions / y.shape[0]
self.log("val_loss", loss)
self.log("val_acc", accuracy)
return loss
train_data = tv.datasets.MNIST(".", train=True, download=True, transform=tv.transforms.ToTensor())
test_data = tv.datasets.MNIST(".", train=False, download=True, transform=tv.transforms.ToTensor())
train_loader = DataLoader(train_data, batch_size=128)
test_loader = DataLoader(test_data, batch_size=128)
model = LightningModel()
slackker = SlackUpdate(token="xoxb-123234234235-123234234235-adedce74748c3844747aed",
channel="A04AAB77ABC",
ModelName='Lightning NN',
TrackLogs=['train_loss', 'train_acc', 'val_loss', 'val_acc'],
monitor="val_loss",
export='png',
SendPlot=True)
trainer = Trainer(max_epochs=2, callbacks=[slackker])
trainer.fit(model, train_loader, test_loader)
Support :sparkles:
If you get stuck, we’re here to help. The following are the best ways to get assistance working through your issue:
- Use our Github Issue Tracker for reporting bugs or requesting features.
Contribution are the best way to keep
slackker
amazing :muscle: - If you want to contribute please refer Contributor's Guide for how to contribute in a helpful and collaborative way :innocent:
Citation :page_facing_up:
Please cite slackker in your publications if this is useful for your project/research. Here is an example BibTeX entry:
@misc{siddheshgunjal2023slackker,
title={slackker},
author={Siddhesh Gunjal},
year={2023},
howpublished={\url{https://github.com/siddheshgunjal/slackker}},
}
Maintainer :sunglasses: