Skip to content

Instantly share code, notes, and snippets.

@demacdolincoln
Created February 1, 2020 06:00
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save demacdolincoln/fd4c67f6b77bd16410a2d9e7a3e9524e to your computer and use it in GitHub Desktop.
Save demacdolincoln/fd4c67f6b77bd16410a2d9e7a3e9524e to your computer and use it in GitHub Desktop.
Copy of tensorboard-fastai.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"name": "Copy of tensorboard-fastai.ipynb",
"provenance": [],
"collapsed_sections": [],
"authorship_tag": "ABX9TyNyUoSw/amsycBkD+M47Z44",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"accelerator": "GPU"
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/demacdolincoln/fd4c67f6b77bd16410a2d9e7a3e9524e/copy-of-tensorboard-fastai.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "code",
"metadata": {
"id": "sFTfn-nqBe-i",
"colab_type": "code",
"colab": {}
},
"source": [
"!pip install captum tensorboardx"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "dBaveP2wQz01",
"colab_type": "code",
"colab": {}
},
"source": [
"%pylab inline\n",
"\n",
"import torch\n",
"\n",
"from torchvision import models, datasets\n",
"from torchvision.transforms.functional import to_pil_image, to_tensor\n",
"\n",
"from fastai.basics import *\n",
"from fastai.vision import *\n",
"from fastai.imports import *\n",
"\n",
"from captum.attr import IntegratedGradients\n",
"from captum.attr import visualization as viz\n",
"\n",
"from torch.utils.tensorboard import SummaryWriter\n",
"from fastai.callbacks.tensorboard import LearnerTensorboardWriter\n",
"from tensorboard import notebook\n",
"\n",
"import io\n",
"from PIL import Image"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "qBiBY0cG99Uy",
"colab_type": "code",
"colab": {}
},
"source": [
"logpath = \"logs/\"\n",
"%load_ext tensorboard\n",
"%tensorboard --logdir \"logs/\""
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "NPSu6LvnDcFx",
"colab_type": "code",
"colab": {}
},
"source": [
"def write_fig_tb(fig, tag, writer):\n",
" buf = io.BytesIO()\n",
" fig.savefig(buf, format='png')\n",
" img = Image.open(buf)\n",
" writer.add_image(tag, to_tensor(img))"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "W5wRxVDWKxfv",
"colab_type": "code",
"colab": {}
},
"source": [
"name=\"resnet\"\n",
"writer = SummaryWriter(log_dir=logpath+name)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "zdys2NHaVgNp",
"colab_type": "code",
"colab": {}
},
"source": [
"from google.colab import drive\n",
"drive.mount('/content/drive')"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "YThNt8rU1MyV",
"colab_type": "code",
"colab": {}
},
"source": [
"torch.cuda.set_device(0)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "GBOmheH7RO6o",
"colab_type": "text"
},
"source": [
"# Dataset\n",
"\n",
"## get dataset"
]
},
{
"cell_type": "code",
"metadata": {
"id": "9nP0STU7SOeQ",
"colab_type": "code",
"colab": {}
},
"source": [
"datasets.utils.download_and_extract_archive(\n",
" \"https://download.microsoft.com/download/3/E/1/3E1C3F21-ECDB-4869-8368-6DEBA77B919F/kagglecatsanddogs_3367a.zip\",\n",
" # 'http://files.fast.ai/data/dogscats.zip',\n",
" '/content/drive/My Drive/ia_pe/', './'\n",
" )"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "vCeezniq3MSe",
"colab_type": "code",
"colab": {}
},
"source": [
"# remove 0-byte files\n",
"!find ./PetImages/ -name '*.jpg' -size 0 -delete"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "1Q8XXOQjSXkK",
"colab_type": "code",
"colab": {}
},
"source": [
"!du -hs PetImages"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "51op0Vk12GhK",
"colab_type": "text"
},
"source": [
"## split data"
]
},
{
"cell_type": "code",
"metadata": {
"id": "j8ezbBYI4daR",
"colab_type": "code",
"colab": {}
},
"source": [
"from glob import glob\n",
"import pandas as pd"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "sYD1kn9k2FKF",
"colab_type": "code",
"colab": {}
},
"source": [
"filelist = glob('./PetImages/*/*.jpg')\n",
"\n",
"classes = list(map(lambda x: 0 if x.split('/')[1] == 'Cat' else 1, filelist))\n",
"\n",
"n_img = len(filelist)\n",
"print(f'total images: {n_img}')\n",
"\n",
"valid_idx = np.random.randint(0, n_img, 2500)\n",
"\n",
"df = pd.DataFrame({\n",
" \"name\":filelist,\n",
" \"label\":classes,\n",
" \"is_valid\":[False]*n_img\n",
"})\n",
"\n",
"df.is_valid[valid_idx] = True\n",
"\n",
"df.head(25)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "KNvGEJKn5WHN",
"colab_type": "code",
"colab": {}
},
"source": [
"classes[-10:-1], filelist[-10 :-1]\n",
"# classes[1:10], filelist[1 :10]\n"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "rzOILhtXwxac",
"colab_type": "text"
},
"source": [
"## Databunch"
]
},
{
"cell_type": "code",
"metadata": {
"id": "6IyeHfSqy7JX",
"colab_type": "code",
"colab": {}
},
"source": [
"tfms = get_transforms()"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "N96WkXKcgSFu",
"colab_type": "code",
"colab": {}
},
"source": [
"datab = (ImageList.from_df(df, \".\") \n",
" .split_from_df()\n",
" .label_from_folder()\n",
" .transform(tfms, size=224)\n",
" .databunch(bs=128, val_bs=128))"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "cbAk1ciiyOTR",
"colab_type": "code",
"colab": {}
},
"source": [
"datab"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "SQxo_ld7wTsS",
"colab_type": "code",
"colab": {}
},
"source": [
"datab.show_batch(5, figsize=(10, 10))"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "Xq3npobi83lm",
"colab_type": "text"
},
"source": [
"# Train\n",
"\n",
"## Prepare model"
]
},
{
"cell_type": "code",
"metadata": {
"id": "zgwegvZYw9vS",
"colab_type": "code",
"colab": {}
},
"source": [
"model = models.resnet18(pretrained=True)\n",
"model"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "f7FdRH2IxPzB",
"colab_type": "code",
"colab": {}
},
"source": [
"model.fc = torch.nn.Sequential(\n",
" torch.nn.Linear(512, 2),\n",
" torch.nn.Softmax(dim=1)\n",
")"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "tanIvumfxaWJ",
"colab_type": "code",
"colab": {}
},
"source": [
"learner = Learner(datab, model, metrics=[accuracy])\n",
"learner.lr_find()"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "yFVSvdXiFUst",
"colab_type": "code",
"colab": {}
},
"source": [
"learner.recorder.plot()"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "mqR2fCOfLlxs",
"colab_type": "code",
"colab": {}
},
"source": [
"learner.callback_fns.append(partial(LearnerTensorboardWriter, \n",
" base_dir=Path(logpath), \n",
" name=name))\n"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "LIHCDX95x31h",
"colab_type": "code",
"colab": {}
},
"source": [
"learner.fit_one_cycle(cyc_len=5, max_lr=1e-3)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "bAK_CA8kDkz5",
"colab_type": "code",
"colab": {}
},
"source": [
"learner.summary()"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "6ICmw881Exax",
"colab_type": "code",
"colab": {}
},
"source": [
"torch.save(model, 'model.pth')"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "gkpvAAqrFEYY",
"colab_type": "code",
"colab": {}
},
"source": [
"torch.save(model.state_dict(), \"model_weights.pth\")"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "k16dCdd_FVke",
"colab_type": "code",
"colab": {}
},
"source": [
"!ls -lh | grep pth"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "mi325j-_EcMC",
"colab_type": "text"
},
"source": [
"## Evaluating learning"
]
},
{
"cell_type": "code",
"metadata": {
"id": "wtjihRsv0Dr7",
"colab_type": "code",
"colab": {}
},
"source": [
"interp = learner.interpret()"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "2bzm-Q0K4mV_",
"colab_type": "code",
"colab": {}
},
"source": [
"conf_mat_fig = interp.plot_confusion_matrix(return_fig=True)\n",
"write_fig_tb(conf_mat_fig, 'confusion_matrix', writer=writer)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "Tp2X6Fs14sgI",
"colab_type": "code",
"colab": {}
},
"source": [
"interp.plot_multi_top_losses(figsize=(3, 10))"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "qc8fGm3a_tMX",
"colab_type": "code",
"colab": {}
},
"source": [
"ind, tens = interp.top_losses(15)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "Y0uMYn-tAeOT",
"colab_type": "code",
"colab": {}
},
"source": [
"tens"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "ofNAdNbLN4dQ",
"colab_type": "code",
"colab": {}
},
"source": [
"datab.valid_ds[1079][0]"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "vPgeGQjRjp01",
"colab_type": "code",
"colab": {}
},
"source": [
"test_model = model.cpu()\n",
"test_model.eval()\n",
"integrated_gradients = IntegratedGradients(test_model)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "ChvpsjxlVQmg",
"colab_type": "code",
"colab": {}
},
"source": [
"def write_int_grad(idx, datab, test_model, integrated_gradients):\n",
"\n",
" inpt = datab.valid_ds.x[idx].clone().crop(224).data.unsqueeze(0)\n",
" target = datab.valid_ds.y[idx]\n",
"\n",
" out = test_model(inpt)\n",
" prediction_score, pred_label_idx = torch.topk(out, 1)\n",
"\n",
" attributions_ig = integrated_gradients.attribute(inpt, target=pred_label_idx, n_steps=200)\n",
"\n",
" fig, (ax0, ax1) = plt.subplots(1, 2, figsize=(12, 6))\n",
"\n",
" fig.suptitle(f'idx: {idx} | target: {target} | predict: {pred_label_idx.item()} | score: {prediction_score.item():.3f}')\n",
"\n",
" ax0.imshow(to_pil_image(inpt.squeeze(0).cpu()))\n",
"\n",
" _ = viz.visualize_image_attr(np.transpose(attributions_ig.squeeze().cpu().detach().numpy(), (1,2,0)),\n",
" np.transpose(inpt.squeeze().cpu().detach().numpy(), (1,2,0)),\n",
" # method='heat_map',\n",
" # method='blended_heat_map',\n",
" cmap=cm.nipy_spectral,\n",
" show_colorbar=True,\n",
" sign='positive',\n",
" outlier_perc=1,\n",
" plt_fig_axis=(fig, ax1)) \n",
" return fig"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "vxaqhH5dAfSL",
"colab_type": "code",
"colab": {}
},
"source": [
"for idx in tens.detach().tolist():\n",
" fig = write_int_grad(idx, datab, test_model, integrated_gradients)\n",
" write_fig_tb(fig, \"integrated_gradients\", writer)"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "xzExNzidvId6",
"colab_type": "code",
"colab": {}
},
"source": [
"!zip -r logs.zip logs"
],
"execution_count": 0,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "xtaUlYQjRkID",
"colab_type": "code",
"colab": {}
},
"source": [
"notebook.start(args_string='--logdir=./logs')"
],
"execution_count": 0,
"outputs": []
}
]
}
@demacdolincoln
Copy link
Author

links recomendados:

  1. fast.ai
  2. modelos pré-treinados do torchvision
  3. Captum
  4. sobre o tensorboard:

Citei mas não mostrei a visualização do que o tensorboard chama de "hparams", na página da documentação do tensorboard tem umas imagens que ilustram bem, mas há uma ferramenta chamada hiplot que... bem... através do exemplo disponível por um link no README dá para entender como funciona, mas ainda assim acho a forma como essa forma de visualização é usada no tensorbard é melhor em alguns aspectos.

Também citei o ONNX e o what-if tool apesar de eu não ter mostrado nada a respeito

obs.: a documentação do tensorboardX e do pytorch.utils.tensorboard são bem semelhantes, mas para a visualização em 3D dos dados, a implementação do pytorch é melhor. por falar nisso, este é o link do 'projector' para a visualização dos dados, reforço que é possível usar online através de arquivos tsv

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment