Skip to content

Instantly share code, notes, and snippets.

@bilzard
Last active December 30, 2022 08:58
Show Gist options
  • Save bilzard/ae572472c839628005ba530739ad91ca to your computer and use it in GitHub Desktop.
Save bilzard/ae572472c839628005ba530739ad91ca to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"%load_ext lab_black\n",
"%load_ext autoreload\n",
"%autoreload 2"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {},
"outputs": [],
"source": [
"import random\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"import torch\n",
"\n",
"\n",
"def seed_everything(seed=123):\n",
" random.seed(seed)\n",
" np.random.seed(seed)\n",
" torch.manual_seed(seed)"
]
},
{
"cell_type": "code",
"execution_count": 91,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[Text(0.5, 0, 'grad-CE'), Text(0, 0.5, 'grad-CE/KL')]"
]
},
"execution_count": 91,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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",
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"ce_loss = torch.nn.CrossEntropyLoss(reduction=\"none\")\n",
"kl_loss = torch.nn.KLDivLoss(reduction=\"none\", log_target=False)\n",
"\n",
"# calculate Cross Entropy Loss\n",
"seed_everything()\n",
"\n",
"x = torch.randn(1000, 5, requires_grad=True)\n",
"pred = x\n",
"gt = torch.randn(1000, 5).softmax(axis=1)\n",
"\n",
"loss_ce = ce_loss(pred, gt).sum()\n",
"loss_ce.backward()\n",
"grad_ce = x.grad.detach().numpy()\n",
"\n",
"# calculate Cross Entropy Loss (reproduce)\n",
"seed_everything()\n",
"\n",
"x = torch.randn(1000, 5, requires_grad=True)\n",
"pred = x\n",
"gt = torch.randn(1000, 5).softmax(axis=1)\n",
"\n",
"loss_ce = ce_loss(pred, gt).sum()\n",
"loss_ce.backward()\n",
"grad_ce_rep = x.grad.detach().numpy()\n",
"\n",
"# calculate KL-Divergence Loss\n",
"seed_everything()\n",
"\n",
"x = torch.randn(1000, 5, requires_grad=True)\n",
"pred = x.log_softmax(axis=1)\n",
"gt = torch.randn(1000, 5).softmax(axis=1)\n",
"\n",
"loss_kl = kl_loss(pred, gt).sum()\n",
"loss_kl.backward()\n",
"grad_kl = x.grad.detach().numpy()\n",
"\n",
"_, ax = plt.subplots()\n",
"ax.scatter(\n",
" grad_ce.reshape(-1),\n",
" grad_ce_rep.reshape(-1),\n",
" s=1,\n",
" color=\"blue\",\n",
" alpha=0.5,\n",
" label=\"grad-CE : grad-CE\",\n",
")\n",
"ax.scatter(\n",
" grad_ce.reshape(-1),\n",
" grad_kl.reshape(-1),\n",
" s=1,\n",
" color=\"red\",\n",
" alpha=0.5,\n",
" label=\"grad-CE : grad-KL\",\n",
")\n",
"ax.legend()\n",
"ax.set(xlabel=\"grad-CE\", ylabel=\"grad-CE/KL\")"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.16"
},
"orig_nbformat": 4,
"vscode": {
"interpreter": {
"hash": "f9f85f796d01129d0dd105a088854619f454435301f6ffec2fea96ecbd9be4ac"
}
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment