├── .gitignore
├── LICENSE
├── README.md
├── Update Records.md
├── demos
├── Bayesian Neural Network Classification.ipynb
├── Bayesian Neural Network Regression.ipynb
├── Convert to Bayesian Neural Network.ipynb
├── Custom KL loss with Iris Data.ipynb
└── Freeze Bayesian Neural Network.ipynb
├── docs
├── Makefile
├── conf.py
├── functional.rst
├── index.rst
├── make.bat
├── modules.rst
└── utils.rst
├── requirements.txt
└── torchbnn
├── __init__.py
├── functional.py
├── modules
├── __init__.py
├── batchnorm.py
├── conv.py
├── linear.py
├── loss.py
└── module.py
└── utils
├── __init__.py
└── freeze_model.py
/.gitignore:
--------------------------------------------------------------------------------
1 | build/*
2 | _*
3 | _*/
4 | dist/*
5 | torchbnn.egg-info/*
6 | demos/data/MNIST/*
7 | demos/data/cifar*
8 | */.*
9 | MENIFEST.in
10 | setup.cfg
11 | setup.py
12 | .gitattributes
13 | .*/
14 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Harry Kim
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Bayesian-Neural-Network-Pytorch
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | This is a lightweight repository of bayesian neural network for PyTorch.
10 |
11 | ## Usage
12 |
13 | ### :clipboard: Dependencies
14 |
15 | - torch 1.2.0
16 | - python 3.6
17 |
18 |
19 |
20 | ### :hammer: Installation
21 |
22 | - `pip install torchbnn` or
23 | - `git clone https://github.com/Harry24k/bayesian-neural-network-pytorch`
24 |
25 | ```python
26 | import torchbnn
27 | ```
28 |
29 |
30 |
31 | ### :rocket: Demos
32 |
33 | * **Bayesian Neural Network Regression** ([code](https://github.com/Harry24k/bayesian-neural-network-pytorch/blob/master/demos/Bayesian%20Neural%20Network%20Regression.ipynb)):
34 | In this demo, two-layer bayesian neural network is constructed and trained on simple custom data. It shows how bayesian-neural-network works and randomness of the model.
35 | * **Bayesian Neural Network Classification** ([code](https://github.com/Harry24k/bayesian-neural-network-pytorch/blob/master/demos/Bayesian%20Neural%20Network%20Classification.ipynb)):
36 | To classify Iris data, in this demo, two-layer bayesian neural network is constructed and trained on the Iris data. It shows how bayesian-neural-network works and randomness of the model.
37 | * **Convert to Bayesian Neural Network** ([code](https://github.com/Harry24k/bayesian-neural-network-pytorch/blob/master/demos/Convert%20to%20Bayesian%20Neural%20Network.ipynb)):
38 | To convert a basic neural network to a bayesian neural network, this demo shows how `nonbayes_to_bayes` and `bayes_to_nonbayes` work.
39 | * **Freeze Bayesian Neural Network** ([code](https://github.com/Harry24k/bayesian-neural-network-pytorch/blob/master/demos/Freeze%20Bayesian%20Neural%20Network.ipynb)):
40 | To freeze a bayesian neural network, which means force a bayesian neural network to output same result for same input, this demo shows the effect of `freeze` and `unfreeze`.
41 |
42 |
43 | ## Citation
44 | If you use this package, please cite the following BibTex (SemanticScholar, GoogleScholar):
45 |
46 | ```
47 | @article{lee2022graddiv,
48 | title={Graddiv: Adversarial robustness of randomized neural networks via gradient diversity regularization},
49 | author={Lee, Sungyoon and Kim, Hoki and Lee, Jaewook},
50 | journal={IEEE Transactions on Pattern Analysis and Machine Intelligence},
51 | year={2022},
52 | publisher={IEEE}
53 | }
54 | ```
55 |
56 | ## :mag_right: Update Records
57 |
58 | Here is [update records](Update%20Records.md) of this package.
59 |
60 |
61 | ## Thanks to
62 |
63 | * @kumar-shridhar [github:PyTorch-BayesianCNN](https://github.com/kumar-shridhar/PyTorch-BayesianCNN)
64 | * @xuanqing94 [github:BayesianDefense](https://github.com/xuanqing94/BayesianDefense)
65 |
--------------------------------------------------------------------------------
/Update Records.md:
--------------------------------------------------------------------------------
1 | ### ~~v0.1~~
2 |
3 | * ~~**modules** : BayesLinear, BayesConv2d, BayesBatchNorm2d are added.~~
4 | * ~~**utils** : convert_model(nonbayes_to_bayes, bayes_to_nonbayes) is added.~~
5 | * ~~**functional.py** : bayesian_kl_loss is added.~~
6 |
7 |
8 |
9 | ### ~~v0.2~~
10 |
11 | * ~~**prior_sigma** is used when initialize modules and functions instead of **prior_log_sigma**.~~
12 | * ~~**modules** are re-defined with prior_sigma instead of prior_log_sigma.~~
13 | * ~~**utils/convert_model.py** is also changed with prior_sigma instead of prior_log_sigma.~~
14 | * ~~**modules** : Base initialization method is changed to the method of Adv-BNN from the original torch method.~~
15 | * ~~**functional.py** : **bayesian_kl_loss** is changed similar to ones in **torch.functional**.~~
16 | * ~~**modules/loss.py** : **BKLLoss** is added based on bayesian_kl_loss similar to ones in **torch.loss**.~~
17 |
18 |
19 |
20 | ### ~~v0.3~~
21 |
22 | * ~~**functional.py** :~~
23 | * ~~**'bayesian_kl_loss' returns tensor.Tensor([0]) as default** : In the previous version, bayesian_kl_loss returns 0 of int type if there is no Bayesian layers. However, considering all torch loss returns tensor and .item() is used to make them to int type, they are changed to return tensor.Tensor([0]) if there is no Bayesian layers.~~
24 |
25 |
26 | ### ~~v0.4~~
27 |
28 | * ~~**functional.py** :~~
29 | * ~~**'bayesian_kl_loss' is modified** : In some cases, the device(cuda/cpu) error has occurred. Thus, losses are initialized with tensor.Tensor([0]) on the device on which the model is.~~
30 |
31 |
32 |
33 | ### ~~v0.5~~
34 |
35 | * ~~**utils/convert_model.py** :~~
36 | * ~~**'nonbayes_to_bayes', 'bayes_to_nonbayes' methods are modified** : Before this version, they always replace the original model. From now on, we can handle it with the 'inplace' argument. Set 'inplace=True' for replace the input model and 'inplace=False' for getting a new model. 'inplace=True' is recommended cause it shortens memories and there is no future problems with deepcopy.~~
37 |
38 |
39 |
40 | ### ~~v0.6~~
41 |
42 | * ~~**utils/freeze_model.py** :~~
43 | * ~~**'freeze', 'unfreeze' methods are added** : Bayesian modules always returns different outputs even if inputs are same. It is because of their randomized forward propagation. Sometimes, however, we need to freeze this randomized process for analyzing the model deeply. Then you can use this freeze method for changing the bayesian model into non-bayesian model with same parameters.~~
44 | * ~~**modules** : For supporting **freeze** method, freeze, weight_eps and bias_eps is added to each modules. If freeze is False (Defalt), weight_eps and bias_eps will be initialized with normal noise at every forward. If freeze is True, weight_eps and bias_eps won't be changed.~~
45 |
46 |
47 |
48 | ### ~~v0.8~~
49 |
50 | * ~~**modules** : To support **freeze** method, weight_eps and bias_eps is changed to buffer with register_buffer method. Thorugh this change, it provides save and load even if bayesian neural network is freezed.~~
51 | * ~~**BayesModule is added** : Bayesian version of torch.nn.Module. Not being used currently.~~
52 | * ~~**utils/freeze_model.py** :~~
53 | * ~~**'freeze', 'unfreeze' methods are modified** : Previous methods didn't work on single layer network.~~
54 | * ~~**Demos are uploaded** : "Bayesian Neural Network with Iris Data".~~
55 |
56 |
57 |
58 |
59 | ### ~~v0.9~~
60 |
61 | * ~~**modules** :~~
62 | * ~~**Variable 'freeze' is deleted** : The status, which indicates whether this bayesian module is freezed, is deleted. Instead of 'freeze', we can determine by checking 'eps' is set to None. For example, if 'weight_eps' is None, the BayesLinear module is freezed now. The reason of this update is to solve backpropagation error occured by inplacing eps.~~
63 | * ~~**Method 'freeze' and 'unfreeze' are added** : These methods will change 'eps' to None or random normal values.~~
64 | * ~~**utils/freeze_model.py** :~~
65 | * ~~**freeze, unfreeze methods are modified** : These methods in utils are changed due to the above.~~
66 | * ~~**Demos are uploaded** : "Convert to Bayesian Neural Network", "Freeze Bayesian Neural Network".~~
67 |
68 |
69 |
70 |
71 | ### ~~v1.0~~
72 |
73 | * ~~**modules** : BayesLinear, BayesConv2d are modified.~~
74 | * ~~**BayesLinear** : Bias will set to False if the bias in args is None or Flase. Otherwise, it set to True.~~
75 | * ~~**BayesConv2d** : Bias will set to False if the bias in args is None or Flase. Otherwise, it set to True. In addition, re-defined with prior_sigma instead of prior_log_sigma.~~
76 |
77 | * ~~**utils/convert_model.py** :~~
78 | * ~~Depreciated. Please refer the [modified demo](https://github.com/Harry24k/bayesian-neural-network-pytorch/blob/master/demos/Convert%20to%20Bayesian%20Neural%20Network.ipynb).~~
79 |
80 |
81 |
82 |
83 | ### v1.1
84 |
85 | * **Pip Package Re-uploaded**
86 |
87 |
88 |
89 |
90 | ### v1.2
91 |
92 | * **[Bug fixed](https://github.com/Harry24k/bayesian-neural-network-pytorch/issues/4)**
93 |
--------------------------------------------------------------------------------
/demos/Bayesian Neural Network Classification.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Demo - Bayesian Neural Network Classification"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": 1,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import numpy as np\n",
17 | "from sklearn import datasets\n",
18 | "\n",
19 | "import torch\n",
20 | "import torch.nn as nn\n",
21 | "import torch.optim as optim\n",
22 | "\n",
23 | "import torchbnn as bnn"
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": 2,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "import matplotlib.pyplot as plt\n",
33 | "%matplotlib inline"
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {},
39 | "source": [
40 | "## 1. Load Iris Data"
41 | ]
42 | },
43 | {
44 | "cell_type": "code",
45 | "execution_count": 3,
46 | "metadata": {},
47 | "outputs": [],
48 | "source": [
49 | "iris = datasets.load_iris()"
50 | ]
51 | },
52 | {
53 | "cell_type": "code",
54 | "execution_count": 4,
55 | "metadata": {},
56 | "outputs": [],
57 | "source": [
58 | "X = iris.data\n",
59 | "Y = iris.target "
60 | ]
61 | },
62 | {
63 | "cell_type": "code",
64 | "execution_count": 5,
65 | "metadata": {},
66 | "outputs": [
67 | {
68 | "data": {
69 | "text/plain": [
70 | "(torch.Size([150, 4]), torch.Size([150]))"
71 | ]
72 | },
73 | "execution_count": 5,
74 | "metadata": {},
75 | "output_type": "execute_result"
76 | }
77 | ],
78 | "source": [
79 | "x, y = torch.from_numpy(X).float(), torch.from_numpy(Y).long()\n",
80 | "x.shape, y.shape"
81 | ]
82 | },
83 | {
84 | "cell_type": "markdown",
85 | "metadata": {},
86 | "source": [
87 | "## 2. Define Model"
88 | ]
89 | },
90 | {
91 | "cell_type": "code",
92 | "execution_count": 6,
93 | "metadata": {},
94 | "outputs": [],
95 | "source": [
96 | "model = nn.Sequential(\n",
97 | " bnn.BayesLinear(prior_mu=0, prior_sigma=0.1, in_features=4, out_features=100),\n",
98 | " nn.ReLU(),\n",
99 | " bnn.BayesLinear(prior_mu=0, prior_sigma=0.1, in_features=100, out_features=3),\n",
100 | ")"
101 | ]
102 | },
103 | {
104 | "cell_type": "code",
105 | "execution_count": 7,
106 | "metadata": {},
107 | "outputs": [],
108 | "source": [
109 | "ce_loss = nn.CrossEntropyLoss()\n",
110 | "kl_loss = bnn.BKLLoss(reduction='mean', last_layer_only=False)\n",
111 | "kl_weight = 0.01\n",
112 | "\n",
113 | "optimizer = optim.Adam(model.parameters(), lr=0.01)"
114 | ]
115 | },
116 | {
117 | "cell_type": "markdown",
118 | "metadata": {},
119 | "source": [
120 | "## 3. Train Model"
121 | ]
122 | },
123 | {
124 | "cell_type": "code",
125 | "execution_count": 8,
126 | "metadata": {},
127 | "outputs": [],
128 | "source": [
129 | "kl_weight = 0.1"
130 | ]
131 | },
132 | {
133 | "cell_type": "code",
134 | "execution_count": 9,
135 | "metadata": {},
136 | "outputs": [
137 | {
138 | "name": "stdout",
139 | "output_type": "stream",
140 | "text": [
141 | "- Accuracy: 96.666667 %\n",
142 | "- CE : 0.11, KL : 1.31\n"
143 | ]
144 | }
145 | ],
146 | "source": [
147 | "for step in range(3000):\n",
148 | " pre = model(x)\n",
149 | " ce = ce_loss(pre, y)\n",
150 | " kl = kl_loss(model)\n",
151 | " cost = ce + kl_weight*kl\n",
152 | " \n",
153 | " optimizer.zero_grad()\n",
154 | " cost.backward()\n",
155 | " optimizer.step()\n",
156 | " \n",
157 | "_, predicted = torch.max(pre.data, 1)\n",
158 | "total = y.size(0)\n",
159 | "correct = (predicted == y).sum()\n",
160 | "print('- Accuracy: %f %%' % (100 * float(correct) / total))\n",
161 | "print('- CE : %2.2f, KL : %2.2f' % (ce.item(), kl.item()))"
162 | ]
163 | },
164 | {
165 | "cell_type": "markdown",
166 | "metadata": {},
167 | "source": [
168 | "## 4. Test Model"
169 | ]
170 | },
171 | {
172 | "cell_type": "code",
173 | "execution_count": 10,
174 | "metadata": {},
175 | "outputs": [],
176 | "source": [
177 | "def draw_plot(predicted) :\n",
178 | " fig = plt.figure(figsize = (16, 5))\n",
179 | "\n",
180 | " ax1 = fig.add_subplot(1, 2, 1)\n",
181 | " ax2 = fig.add_subplot(1, 2, 2)\n",
182 | "\n",
183 | " z1_plot = ax1.scatter(X[:, 0], X[:, 1], c = Y)\n",
184 | " z2_plot = ax2.scatter(X[:, 0], X[:, 1], c = predicted)\n",
185 | "\n",
186 | " plt.colorbar(z1_plot,ax=ax1)\n",
187 | " plt.colorbar(z2_plot,ax=ax2)\n",
188 | "\n",
189 | " ax1.set_title(\"REAL\")\n",
190 | " ax2.set_title(\"PREDICT\")\n",
191 | "\n",
192 | " plt.show()"
193 | ]
194 | },
195 | {
196 | "cell_type": "code",
197 | "execution_count": 11,
198 | "metadata": {},
199 | "outputs": [
200 | {
201 | "data": {
202 | "image/png": "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\n",
203 | "text/plain": [
204 | ""
205 | ]
206 | },
207 | "metadata": {},
208 | "output_type": "display_data"
209 | }
210 | ],
211 | "source": [
212 | "pre = model(x)\n",
213 | "_, predicted = torch.max(pre.data, 1)\n",
214 | "draw_plot(predicted)"
215 | ]
216 | },
217 | {
218 | "cell_type": "code",
219 | "execution_count": 12,
220 | "metadata": {},
221 | "outputs": [
222 | {
223 | "data": {
224 | "image/png": "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\n",
225 | "text/plain": [
226 | ""
227 | ]
228 | },
229 | "metadata": {},
230 | "output_type": "display_data"
231 | }
232 | ],
233 | "source": [
234 | "# Bayesian Neural Network will return different outputs even if inputs are same.\n",
235 | "# In other words, different plots will be shown every time forward method is called.\n",
236 | "pre = model(x)\n",
237 | "_, predicted = torch.max(pre.data, 1)\n",
238 | "draw_plot(predicted)"
239 | ]
240 | }
241 | ],
242 | "metadata": {
243 | "kernelspec": {
244 | "display_name": "Python 3",
245 | "language": "python",
246 | "name": "python3"
247 | },
248 | "language_info": {
249 | "codemirror_mode": {
250 | "name": "ipython",
251 | "version": 3
252 | },
253 | "file_extension": ".py",
254 | "mimetype": "text/x-python",
255 | "name": "python",
256 | "nbconvert_exporter": "python",
257 | "pygments_lexer": "ipython3",
258 | "version": "3.6.5"
259 | }
260 | },
261 | "nbformat": 4,
262 | "nbformat_minor": 2
263 | }
264 |
--------------------------------------------------------------------------------
/demos/Bayesian Neural Network Regression.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Demo - Bayesian Neural Network Regression"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": 1,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import numpy as np\n",
17 | "from sklearn import datasets\n",
18 | "\n",
19 | "import torch\n",
20 | "import torch.nn as nn\n",
21 | "import torch.optim as optim\n",
22 | "\n",
23 | "import torchbnn as bnn"
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": 2,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "import matplotlib.pyplot as plt\n",
33 | "%matplotlib inline"
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {},
39 | "source": [
40 | "## 1. Generate Sample Data"
41 | ]
42 | },
43 | {
44 | "cell_type": "code",
45 | "execution_count": 3,
46 | "metadata": {},
47 | "outputs": [
48 | {
49 | "data": {
50 | "image/png": "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\n",
51 | "text/plain": [
52 | ""
53 | ]
54 | },
55 | "metadata": {},
56 | "output_type": "display_data"
57 | }
58 | ],
59 | "source": [
60 | "x = torch.linspace(-2, 2, 500)\n",
61 | "y = x.pow(3) - x.pow(2) + 3*torch.rand(x.size())\n",
62 | "x = torch.unsqueeze(x, dim=1)\n",
63 | "y = torch.unsqueeze(y, dim=1)\n",
64 | "\n",
65 | "plt.scatter(x.data.numpy(), y.data.numpy())\n",
66 | "plt.show()"
67 | ]
68 | },
69 | {
70 | "cell_type": "markdown",
71 | "metadata": {},
72 | "source": [
73 | "## 2. Define Model"
74 | ]
75 | },
76 | {
77 | "cell_type": "code",
78 | "execution_count": 4,
79 | "metadata": {},
80 | "outputs": [],
81 | "source": [
82 | "model = nn.Sequential(\n",
83 | " bnn.BayesLinear(prior_mu=0, prior_sigma=0.1, in_features=1, out_features=100),\n",
84 | " nn.ReLU(),\n",
85 | " bnn.BayesLinear(prior_mu=0, prior_sigma=0.1, in_features=100, out_features=1),\n",
86 | ")"
87 | ]
88 | },
89 | {
90 | "cell_type": "code",
91 | "execution_count": 5,
92 | "metadata": {},
93 | "outputs": [],
94 | "source": [
95 | "mse_loss = nn.MSELoss()\n",
96 | "kl_loss = bnn.BKLLoss(reduction='mean', last_layer_only=False)\n",
97 | "kl_weight = 0.01\n",
98 | "\n",
99 | "optimizer = optim.Adam(model.parameters(), lr=0.01)"
100 | ]
101 | },
102 | {
103 | "cell_type": "markdown",
104 | "metadata": {},
105 | "source": [
106 | "## 3. Train Model"
107 | ]
108 | },
109 | {
110 | "cell_type": "code",
111 | "execution_count": 6,
112 | "metadata": {},
113 | "outputs": [],
114 | "source": [
115 | "kl_weight = 0.1"
116 | ]
117 | },
118 | {
119 | "cell_type": "code",
120 | "execution_count": 7,
121 | "metadata": {},
122 | "outputs": [
123 | {
124 | "name": "stdout",
125 | "output_type": "stream",
126 | "text": [
127 | "- MSE : 0.89, KL : 5.19\n"
128 | ]
129 | }
130 | ],
131 | "source": [
132 | "for step in range(3000):\n",
133 | " pre = model(x)\n",
134 | " mse = mse_loss(pre, y)\n",
135 | " kl = kl_loss(model)\n",
136 | " cost = mse + kl_weight*kl\n",
137 | " \n",
138 | " optimizer.zero_grad()\n",
139 | " cost.backward()\n",
140 | " optimizer.step()\n",
141 | " \n",
142 | "print('- MSE : %2.2f, KL : %2.2f' % (mse.item(), kl.item()))"
143 | ]
144 | },
145 | {
146 | "cell_type": "markdown",
147 | "metadata": {},
148 | "source": [
149 | "## 4. Test Model"
150 | ]
151 | },
152 | {
153 | "cell_type": "code",
154 | "execution_count": 8,
155 | "metadata": {},
156 | "outputs": [],
157 | "source": [
158 | "x_test = torch.linspace(-2, 2, 500)\n",
159 | "y_test = x_test.pow(3) - x_test.pow(2) + 3*torch.rand(x_test.size())\n",
160 | "\n",
161 | "x_test = torch.unsqueeze(x_test, dim=1)\n",
162 | "y_test = torch.unsqueeze(y_test, dim=1)"
163 | ]
164 | },
165 | {
166 | "cell_type": "code",
167 | "execution_count": 9,
168 | "metadata": {},
169 | "outputs": [
170 | {
171 | "data": {
172 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZYAAAEKCAYAAAAxXHOuAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4yLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvhp/UCwAAIABJREFUeJzs3XlcVOX+wPHPwyLgiuK+a5q74pKI5ZYpZGbp1cxsUW+atljWrWv2uyK3W9dWq9tqlpZZmqaVLWKmlgouWGjuW2pqbiiuIALf3x/D0ABnYAaG/ft+vebFzDnPOec7A5zvPM9zzvMYEUEppZTyFK+iDkAppVTpoolFKaWUR2liUUop5VGaWJRSSnmUJhallFIepYlFKaWUR2liUUop5VGaWJRSSnmUJhallFIe5VPUARSF6tWrS+PGjYs6DKWUKlE2b958WkRq5FauTCaWxo0bExsbW9RhKKVUiWKMOeRKOW0KU0op5VGaWJRSSnmUJhallFIeVSb7WKxcvXqVI0eOkJSUVNShqELi7+9P/fr18fX1LepQlCpVNLGkO3LkCJUqVaJx48YYY4o6HFXARIT4+HiOHDlCkyZNijocpUoVbQpLl5SURFBQkCaVMsIYQ1BQkNZQlSoAmlgcaFIpW/T3rVTB0MSilFKlXExMDOHh4cTExBTK8TSxFCPe3t4EBwdnPA4ePEhsbCwTJ050eR8JCQm8/fbbuR6jbdu2DBs2jMuXL+c53tWrVzNw4EAAvv76a6ZPn+5yXMeOHWPo0KF5PrZSynWRkZFERUURGRlZOAcUkTL36Ny5s2S1Y8eObMsKW4UKFVwue/XqVcvlv//+u7Rp08alY9x1113yyiuvZFqflpYmqampLsWwatUqueWWW1wqm1tcRaU4/N6VKmjR0dESFhYm0dHR+doPECsunGO1xpKVMQX/cINjrWDatGmMGzeO/v37c++997J9+3a6du1KcHAw7du3Z+/evUyePJn9+/cTHBzMk08+meO+e/Towb59+zh48CCtWrXiwQcfpFOnTvzxxx8sX76c0NBQOnXqxLBhw7h48SIAy5Yto2XLltxwww0sXrw4Y19z5szh4YcfBuDEiRMMHjyYDh060KFDB6Kjo7PFdfDgQdq2bQvYLpwYPXo07dq1o2PHjqxatSpjn0OGDCE8PJzmzZvz1FNPufXZKVXW2ZvAwPa/GxoaWijH1cuNi5HExESCg4MBaNKkCUuWLMlWZvPmzaxdu5aAgAAeeeQRHn30UUaOHElycjKpqalMnz6dbdu2ERcXl+OxUlJS+P777zP+6Hbv3s3s2bN5++23OX36NP/5z39YsWIFFSpU4IUXXuDVV1/lqaeeYuzYsaxcuZJmzZoxfPhwy31PnDiRXr16sWTJElJTU7l48WK2uA4ePJhR/q233gLgt99+Y9euXfTv3589e/YAEBcXx6+//oqfnx8tWrTgkUceoUGDBu59sEqVUfYmMLAllsKiNZZiJCAggLi4OOLi4iyTCsCgQYMICAgAIDQ0lOeff54XXniBQ4cOZSzPiT15denShYYNG/L3v/8dgEaNGtGtWzcA1q9fz44dO7j++usJDg7mo48+4tChQ+zatYsmTZrQvHlzjDHcfffdlsdYuXIlEyZMAGx9OlWqVMkxprVr13LPPfcA0LJlSxo1apSRWPr27UuVKlXw9/endevWHDrk0hh4SikgIiKCsLAwIiIiCrUDX2ssJUyFChUynt91112EhITw7bffEhYWxqxZs2jatGmO29uTV077FRH69evHZ599lqlMXFxcgVyia2u6tebn55fx3Nvbm5SUFI8fX6nSKjQ0NKOmEh4eXmi1F62xlGAHDhygadOmTJw4kUGDBrF161YqVarEhQsX8rXfbt26sW7dOvbt2wfA5cuX2bNnDy1btuT3339n//79ANkSj13fvn155513AEhNTeX8+fM5xtWzZ0/mzZsHwJ49ezh8+DAtWrTI13tQqiyzqp041l4KmiaWrEQK/uEhCxYsoG3btgQHB7Nr1y7uvfdegoKCuP7662nbtm2unffO1KhRgzlz5jBixAjat29Pt27d2LVrF/7+/sycOZNbbrmFG264gUaNGllu//rrr7Nq1SratWtH586d2b59e45xPfjgg6SmptKuXTuGDx/OnDlzMtVUlFLumTRpElFRUUyaNKlIOvBNTs0QpVWXLl0k60RfO3fupFWrVkUUkSoq+ntXJVVMTAyRkZFERERkSxbdunVjw4YNhISEEBgYSFRUVMZzq/KuMsZsFpEuuZXTPhallCqBcrria8aMGRlJxy4hIaHQ+lg0sSilVAlkTxpWfSaOnfZgSySONZyCpolFKaVKoKzJw9Pl80M775VSqpQo7MEm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\n",
173 | "text/plain": [
174 | ""
175 | ]
176 | },
177 | "metadata": {},
178 | "output_type": "display_data"
179 | }
180 | ],
181 | "source": [
182 | "plt.xlabel(r'$x$')\n",
183 | "plt.ylabel(r'$y$')\n",
184 | "\n",
185 | "plt.scatter(x_test.data.numpy(), y_test.data.numpy(), color='k', s=2) \n",
186 | "\n",
187 | "y_predict = model(x_test)\n",
188 | "plt.plot(x_test.data.numpy(), y_predict.data.numpy(), 'r-', linewidth=5, label='First Prediction')\n",
189 | "\n",
190 | "y_predict = model(x_test)\n",
191 | "plt.plot(x_test.data.numpy(), y_predict.data.numpy(), 'b-', linewidth=5, label='Second Prediction')\n",
192 | "\n",
193 | "y_predict = model(x_test)\n",
194 | "plt.plot(x_test.data.numpy(), y_predict.data.numpy(), 'g-', linewidth=5, label='Third Prediction')\n",
195 | "\n",
196 | "plt.legend()\n",
197 | "\n",
198 | "plt.show()"
199 | ]
200 | }
201 | ],
202 | "metadata": {
203 | "kernelspec": {
204 | "display_name": "Python 3",
205 | "language": "python",
206 | "name": "python3"
207 | },
208 | "language_info": {
209 | "codemirror_mode": {
210 | "name": "ipython",
211 | "version": 3
212 | },
213 | "file_extension": ".py",
214 | "mimetype": "text/x-python",
215 | "name": "python",
216 | "nbconvert_exporter": "python",
217 | "pygments_lexer": "ipython3",
218 | "version": "3.6.5"
219 | }
220 | },
221 | "nbformat": 4,
222 | "nbformat_minor": 2
223 | }
224 |
--------------------------------------------------------------------------------
/demos/Convert to Bayesian Neural Network.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Demo - Convert to Bayesian Neural Network"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": 1,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import numpy as np\n",
17 | "\n",
18 | "import torch\n",
19 | "import torch.nn as nn\n",
20 | "import torch.optim as optim\n",
21 | "\n",
22 | "import torchbnn as bnn\n",
23 | "from torchhk import transform_model"
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": 2,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "import matplotlib.pyplot as plt\n",
33 | "%matplotlib inline"
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {},
39 | "source": [
40 | "## 2. Define Model"
41 | ]
42 | },
43 | {
44 | "cell_type": "code",
45 | "execution_count": 3,
46 | "metadata": {},
47 | "outputs": [],
48 | "source": [
49 | "class CNN(nn.Module):\n",
50 | " def __init__(self):\n",
51 | " super(CNN, self).__init__()\n",
52 | " \n",
53 | " self.conv_layer = nn.Sequential(\n",
54 | " nn.Conv2d(1,3,3),\n",
55 | " nn.ReLU(),\n",
56 | " nn.MaxPool2d(2,2)\n",
57 | " )\n",
58 | " \n",
59 | " self.fc_layer = nn.Sequential(\n",
60 | " nn.Linear(3*2*2,3*2),\n",
61 | " nn.ReLU(),\n",
62 | " nn.Linear(3*2,2)\n",
63 | " ) \n",
64 | " \n",
65 | " def forward(self,x):\n",
66 | " out = self.conv_layer(x)\n",
67 | " out = out.view(-1,3*2*2)\n",
68 | " out = self.fc_layer(out)\n",
69 | "\n",
70 | " return out"
71 | ]
72 | },
73 | {
74 | "cell_type": "code",
75 | "execution_count": 4,
76 | "metadata": {},
77 | "outputs": [],
78 | "source": [
79 | "model = CNN()"
80 | ]
81 | },
82 | {
83 | "cell_type": "code",
84 | "execution_count": 5,
85 | "metadata": {},
86 | "outputs": [
87 | {
88 | "data": {
89 | "text/plain": [
90 | "CNN(\n",
91 | " (conv_layer): Sequential(\n",
92 | " (0): Conv2d(1, 3, kernel_size=(3, 3), stride=(1, 1))\n",
93 | " (1): ReLU()\n",
94 | " (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
95 | " )\n",
96 | " (fc_layer): Sequential(\n",
97 | " (0): Linear(in_features=12, out_features=6, bias=True)\n",
98 | " (1): ReLU()\n",
99 | " (2): Linear(in_features=6, out_features=2, bias=True)\n",
100 | " )\n",
101 | ")"
102 | ]
103 | },
104 | "execution_count": 5,
105 | "metadata": {},
106 | "output_type": "execute_result"
107 | }
108 | ],
109 | "source": [
110 | "model"
111 | ]
112 | },
113 | {
114 | "cell_type": "markdown",
115 | "metadata": {},
116 | "source": [
117 | "## 3. Convert Model"
118 | ]
119 | },
120 | {
121 | "cell_type": "markdown",
122 | "metadata": {},
123 | "source": [
124 | "### 3.1. Nonbayes to Bayes"
125 | ]
126 | },
127 | {
128 | "cell_type": "code",
129 | "execution_count": 6,
130 | "metadata": {},
131 | "outputs": [
132 | {
133 | "name": "stderr",
134 | "output_type": "stream",
135 | "text": [
136 | "C:\\Users\\slcf\\Anaconda3\\lib\\site-packages\\torchhk\\transform.py:31: Warning: \n",
137 | " * Caution : The Input Model is CHANGED because inplace=True.\n",
138 | " warnings.warn(\"\\n * Caution : The Input Model is CHANGED because inplace=True.\", Warning)\n"
139 | ]
140 | },
141 | {
142 | "data": {
143 | "text/plain": [
144 | "CNN(\n",
145 | " (conv_layer): Sequential(\n",
146 | " (0): BayesConv2d(0, 0.1, 1, 3, kernel_size=(3, 3), stride=(1, 1))\n",
147 | " (1): ReLU()\n",
148 | " (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
149 | " )\n",
150 | " (fc_layer): Sequential(\n",
151 | " (0): Linear(in_features=12, out_features=6, bias=True)\n",
152 | " (1): ReLU()\n",
153 | " (2): Linear(in_features=6, out_features=2, bias=True)\n",
154 | " )\n",
155 | ")"
156 | ]
157 | },
158 | "execution_count": 6,
159 | "metadata": {},
160 | "output_type": "execute_result"
161 | }
162 | ],
163 | "source": [
164 | "# Convert Conv2d -> BayesConv2d\n",
165 | "transform_model(model, nn.Conv2d, bnn.BayesConv2d, \n",
166 | " args={\"prior_mu\":0, \"prior_sigma\":0.1, \"in_channels\" : \".in_channels\",\n",
167 | " \"out_channels\" : \".out_channels\", \"kernel_size\" : \".kernel_size\",\n",
168 | " \"stride\" : \".stride\", \"padding\" : \".padding\", \"bias\":\".bias\"\n",
169 | " }, \n",
170 | " attrs={\"weight_mu\" : \".weight\"})"
171 | ]
172 | },
173 | {
174 | "cell_type": "code",
175 | "execution_count": 7,
176 | "metadata": {},
177 | "outputs": [
178 | {
179 | "name": "stderr",
180 | "output_type": "stream",
181 | "text": [
182 | "C:\\Users\\slcf\\Anaconda3\\lib\\site-packages\\torchhk\\transform.py:31: Warning: \n",
183 | " * Caution : The Input Model is CHANGED because inplace=True.\n",
184 | " warnings.warn(\"\\n * Caution : The Input Model is CHANGED because inplace=True.\", Warning)\n"
185 | ]
186 | },
187 | {
188 | "data": {
189 | "text/plain": [
190 | "CNN(\n",
191 | " (conv_layer): Sequential(\n",
192 | " (0): BayesConv2d(0, 0.1, 1, 3, kernel_size=(3, 3), stride=(1, 1))\n",
193 | " (1): ReLU()\n",
194 | " (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
195 | " )\n",
196 | " (fc_layer): Sequential(\n",
197 | " (0): BayesLinear(prior_mu=0, prior_sigma=0.1, in_features=12, out_features=6, bias=True)\n",
198 | " (1): ReLU()\n",
199 | " (2): BayesLinear(prior_mu=0, prior_sigma=0.1, in_features=6, out_features=2, bias=True)\n",
200 | " )\n",
201 | ")"
202 | ]
203 | },
204 | "execution_count": 7,
205 | "metadata": {},
206 | "output_type": "execute_result"
207 | }
208 | ],
209 | "source": [
210 | "# Convert Linear -> BayesLinear\n",
211 | "transform_model(model, nn.Linear, bnn.BayesLinear, \n",
212 | " args={\"prior_mu\":0, \"prior_sigma\":0.1, \"in_features\" : \".in_features\",\n",
213 | " \"out_features\" : \".out_features\", \"bias\":\".bias\"\n",
214 | " }, \n",
215 | " attrs={\"weight_mu\" : \".weight\"})"
216 | ]
217 | },
218 | {
219 | "cell_type": "code",
220 | "execution_count": 8,
221 | "metadata": {},
222 | "outputs": [
223 | {
224 | "data": {
225 | "text/plain": [
226 | "CNN(\n",
227 | " (conv_layer): Sequential(\n",
228 | " (0): BayesConv2d(0, 0.1, 1, 3, kernel_size=(3, 3), stride=(1, 1))\n",
229 | " (1): ReLU()\n",
230 | " (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
231 | " )\n",
232 | " (fc_layer): Sequential(\n",
233 | " (0): BayesLinear(prior_mu=0, prior_sigma=0.1, in_features=12, out_features=6, bias=True)\n",
234 | " (1): ReLU()\n",
235 | " (2): BayesLinear(prior_mu=0, prior_sigma=0.1, in_features=6, out_features=2, bias=True)\n",
236 | " )\n",
237 | ")"
238 | ]
239 | },
240 | "execution_count": 8,
241 | "metadata": {},
242 | "output_type": "execute_result"
243 | }
244 | ],
245 | "source": [
246 | "model"
247 | ]
248 | },
249 | {
250 | "cell_type": "markdown",
251 | "metadata": {},
252 | "source": [
253 | "### 3.2. Bayes to Nonbayes"
254 | ]
255 | },
256 | {
257 | "cell_type": "code",
258 | "execution_count": 9,
259 | "metadata": {},
260 | "outputs": [
261 | {
262 | "name": "stderr",
263 | "output_type": "stream",
264 | "text": [
265 | "C:\\Users\\slcf\\Anaconda3\\lib\\site-packages\\torchhk\\transform.py:31: Warning: \n",
266 | " * Caution : The Input Model is CHANGED because inplace=True.\n",
267 | " warnings.warn(\"\\n * Caution : The Input Model is CHANGED because inplace=True.\", Warning)\n"
268 | ]
269 | },
270 | {
271 | "data": {
272 | "text/plain": [
273 | "CNN(\n",
274 | " (conv_layer): Sequential(\n",
275 | " (0): Conv2d(1, 3, kernel_size=(3, 3), stride=(1, 1))\n",
276 | " (1): ReLU()\n",
277 | " (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
278 | " )\n",
279 | " (fc_layer): Sequential(\n",
280 | " (0): BayesLinear(prior_mu=0, prior_sigma=0.1, in_features=12, out_features=6, bias=True)\n",
281 | " (1): ReLU()\n",
282 | " (2): BayesLinear(prior_mu=0, prior_sigma=0.1, in_features=6, out_features=2, bias=True)\n",
283 | " )\n",
284 | ")"
285 | ]
286 | },
287 | "execution_count": 9,
288 | "metadata": {},
289 | "output_type": "execute_result"
290 | }
291 | ],
292 | "source": [
293 | "# Convert BayesConv2d -> Conv2d\n",
294 | "transform_model(model, bnn.BayesConv2d, nn.Conv2d,\n",
295 | " args={\"in_channels\" : \".in_channels\", \"out_channels\" : \".out_channels\",\n",
296 | " \"kernel_size\" : \".kernel_size\",\n",
297 | " \"padding\" : \".padding\", \"bias\":\".bias\"\n",
298 | " }, \n",
299 | " attrs={\"weight\" : \".weight_mu\"})"
300 | ]
301 | },
302 | {
303 | "cell_type": "code",
304 | "execution_count": 10,
305 | "metadata": {},
306 | "outputs": [
307 | {
308 | "name": "stderr",
309 | "output_type": "stream",
310 | "text": [
311 | "C:\\Users\\slcf\\Anaconda3\\lib\\site-packages\\torchhk\\transform.py:31: Warning: \n",
312 | " * Caution : The Input Model is CHANGED because inplace=True.\n",
313 | " warnings.warn(\"\\n * Caution : The Input Model is CHANGED because inplace=True.\", Warning)\n"
314 | ]
315 | },
316 | {
317 | "data": {
318 | "text/plain": [
319 | "CNN(\n",
320 | " (conv_layer): Sequential(\n",
321 | " (0): Conv2d(1, 3, kernel_size=(3, 3), stride=(1, 1))\n",
322 | " (1): ReLU()\n",
323 | " (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
324 | " )\n",
325 | " (fc_layer): Sequential(\n",
326 | " (0): Linear(in_features=12, out_features=6, bias=True)\n",
327 | " (1): ReLU()\n",
328 | " (2): Linear(in_features=6, out_features=2, bias=True)\n",
329 | " )\n",
330 | ")"
331 | ]
332 | },
333 | "execution_count": 10,
334 | "metadata": {},
335 | "output_type": "execute_result"
336 | }
337 | ],
338 | "source": [
339 | "# Convert BayesLinear -> Linear\n",
340 | "transform_model(model, bnn.BayesLinear, nn.Linear, \n",
341 | " args={\"in_features\" : \".in_features\", \"out_features\" : \".out_features\",\n",
342 | " \"bias\":\".bias\"\n",
343 | " }, \n",
344 | " attrs={\"weight\" : \".weight_mu\"})"
345 | ]
346 | },
347 | {
348 | "cell_type": "code",
349 | "execution_count": 11,
350 | "metadata": {},
351 | "outputs": [
352 | {
353 | "data": {
354 | "text/plain": [
355 | "CNN(\n",
356 | " (conv_layer): Sequential(\n",
357 | " (0): Conv2d(1, 3, kernel_size=(3, 3), stride=(1, 1))\n",
358 | " (1): ReLU()\n",
359 | " (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
360 | " )\n",
361 | " (fc_layer): Sequential(\n",
362 | " (0): Linear(in_features=12, out_features=6, bias=True)\n",
363 | " (1): ReLU()\n",
364 | " (2): Linear(in_features=6, out_features=2, bias=True)\n",
365 | " )\n",
366 | ")"
367 | ]
368 | },
369 | "execution_count": 11,
370 | "metadata": {},
371 | "output_type": "execute_result"
372 | }
373 | ],
374 | "source": [
375 | "model"
376 | ]
377 | }
378 | ],
379 | "metadata": {
380 | "kernelspec": {
381 | "display_name": "Python 3",
382 | "language": "python",
383 | "name": "python3"
384 | },
385 | "language_info": {
386 | "codemirror_mode": {
387 | "name": "ipython",
388 | "version": 3
389 | },
390 | "file_extension": ".py",
391 | "mimetype": "text/x-python",
392 | "name": "python",
393 | "nbconvert_exporter": "python",
394 | "pygments_lexer": "ipython3",
395 | "version": "3.6.5"
396 | }
397 | },
398 | "nbformat": 4,
399 | "nbformat_minor": 2
400 | }
401 |
--------------------------------------------------------------------------------
/demos/Freeze Bayesian Neural Network.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {},
6 | "source": [
7 | "# Demo - Freeze Bayesian Neural Network"
8 | ]
9 | },
10 | {
11 | "cell_type": "code",
12 | "execution_count": 1,
13 | "metadata": {},
14 | "outputs": [],
15 | "source": [
16 | "import numpy as np\n",
17 | "\n",
18 | "import torch\n",
19 | "import torch.nn as nn\n",
20 | "import torch.optim as optim\n",
21 | "\n",
22 | "import torchbnn as bnn\n",
23 | "from torchbnn.utils import freeze, unfreeze"
24 | ]
25 | },
26 | {
27 | "cell_type": "code",
28 | "execution_count": 2,
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "import matplotlib.pyplot as plt\n",
33 | "%matplotlib inline"
34 | ]
35 | },
36 | {
37 | "cell_type": "markdown",
38 | "metadata": {},
39 | "source": [
40 | "## 2. Define Model"
41 | ]
42 | },
43 | {
44 | "cell_type": "code",
45 | "execution_count": 3,
46 | "metadata": {},
47 | "outputs": [],
48 | "source": [
49 | "model = nn.Sequential(\n",
50 | " bnn.BayesLinear(prior_mu=0, prior_sigma=0.05, in_features=2, out_features=2),\n",
51 | " nn.ReLU(),\n",
52 | " bnn.BayesLinear(prior_mu=0, prior_sigma=0.05, in_features=2, out_features=1),\n",
53 | ")"
54 | ]
55 | },
56 | {
57 | "cell_type": "markdown",
58 | "metadata": {},
59 | "source": [
60 | "## 3. Forward Model"
61 | ]
62 | },
63 | {
64 | "cell_type": "code",
65 | "execution_count": 4,
66 | "metadata": {},
67 | "outputs": [
68 | {
69 | "data": {
70 | "text/plain": [
71 | "tensor([[-0.4672]], grad_fn=)"
72 | ]
73 | },
74 | "execution_count": 4,
75 | "metadata": {},
76 | "output_type": "execute_result"
77 | }
78 | ],
79 | "source": [
80 | "model(torch.ones(1, 2))"
81 | ]
82 | },
83 | {
84 | "cell_type": "code",
85 | "execution_count": 5,
86 | "metadata": {},
87 | "outputs": [
88 | {
89 | "data": {
90 | "text/plain": [
91 | "tensor([[-0.3220]], grad_fn=)"
92 | ]
93 | },
94 | "execution_count": 5,
95 | "metadata": {},
96 | "output_type": "execute_result"
97 | }
98 | ],
99 | "source": [
100 | "model(torch.ones(1, 2))"
101 | ]
102 | },
103 | {
104 | "cell_type": "markdown",
105 | "metadata": {},
106 | "source": [
107 | "## 3. Freeze Model"
108 | ]
109 | },
110 | {
111 | "cell_type": "code",
112 | "execution_count": 6,
113 | "metadata": {},
114 | "outputs": [],
115 | "source": [
116 | "freeze(model)"
117 | ]
118 | },
119 | {
120 | "cell_type": "code",
121 | "execution_count": 7,
122 | "metadata": {},
123 | "outputs": [
124 | {
125 | "data": {
126 | "text/plain": [
127 | "tensor([[-0.4340]], grad_fn=)"
128 | ]
129 | },
130 | "execution_count": 7,
131 | "metadata": {},
132 | "output_type": "execute_result"
133 | }
134 | ],
135 | "source": [
136 | "model(torch.ones(1, 2))"
137 | ]
138 | },
139 | {
140 | "cell_type": "code",
141 | "execution_count": 8,
142 | "metadata": {},
143 | "outputs": [
144 | {
145 | "data": {
146 | "text/plain": [
147 | "tensor([[-0.4340]], grad_fn=)"
148 | ]
149 | },
150 | "execution_count": 8,
151 | "metadata": {},
152 | "output_type": "execute_result"
153 | }
154 | ],
155 | "source": [
156 | "model(torch.ones(1, 2))"
157 | ]
158 | },
159 | {
160 | "cell_type": "code",
161 | "execution_count": 9,
162 | "metadata": {},
163 | "outputs": [],
164 | "source": [
165 | "freeze(model)"
166 | ]
167 | },
168 | {
169 | "cell_type": "code",
170 | "execution_count": 10,
171 | "metadata": {},
172 | "outputs": [
173 | {
174 | "data": {
175 | "text/plain": [
176 | "tensor([[-0.2875]], grad_fn=)"
177 | ]
178 | },
179 | "execution_count": 10,
180 | "metadata": {},
181 | "output_type": "execute_result"
182 | }
183 | ],
184 | "source": [
185 | "model(torch.ones(1, 2))"
186 | ]
187 | },
188 | {
189 | "cell_type": "code",
190 | "execution_count": 11,
191 | "metadata": {},
192 | "outputs": [
193 | {
194 | "data": {
195 | "text/plain": [
196 | "tensor([[-0.2875]], grad_fn=)"
197 | ]
198 | },
199 | "execution_count": 11,
200 | "metadata": {},
201 | "output_type": "execute_result"
202 | }
203 | ],
204 | "source": [
205 | "model(torch.ones(1, 2))"
206 | ]
207 | },
208 | {
209 | "cell_type": "markdown",
210 | "metadata": {},
211 | "source": [
212 | "## 4. Unfreeze Model"
213 | ]
214 | },
215 | {
216 | "cell_type": "code",
217 | "execution_count": 12,
218 | "metadata": {},
219 | "outputs": [],
220 | "source": [
221 | "unfreeze(model)"
222 | ]
223 | },
224 | {
225 | "cell_type": "code",
226 | "execution_count": 13,
227 | "metadata": {},
228 | "outputs": [
229 | {
230 | "data": {
231 | "text/plain": [
232 | "tensor([[-0.4530]], grad_fn=)"
233 | ]
234 | },
235 | "execution_count": 13,
236 | "metadata": {},
237 | "output_type": "execute_result"
238 | }
239 | ],
240 | "source": [
241 | "model(torch.ones(1, 2))"
242 | ]
243 | },
244 | {
245 | "cell_type": "code",
246 | "execution_count": 14,
247 | "metadata": {},
248 | "outputs": [
249 | {
250 | "data": {
251 | "text/plain": [
252 | "tensor([[-0.4920]], grad_fn=)"
253 | ]
254 | },
255 | "execution_count": 14,
256 | "metadata": {},
257 | "output_type": "execute_result"
258 | }
259 | ],
260 | "source": [
261 | "model(torch.ones(1, 2))"
262 | ]
263 | }
264 | ],
265 | "metadata": {
266 | "kernelspec": {
267 | "display_name": "Python 3",
268 | "language": "python",
269 | "name": "python3"
270 | },
271 | "language_info": {
272 | "codemirror_mode": {
273 | "name": "ipython",
274 | "version": 3
275 | },
276 | "file_extension": ".py",
277 | "mimetype": "text/x-python",
278 | "name": "python",
279 | "nbconvert_exporter": "python",
280 | "pygments_lexer": "ipython3",
281 | "version": "3.6.5"
282 | }
283 | },
284 | "nbformat": 4,
285 | "nbformat_minor": 2
286 | }
287 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Minimal makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | SPHINXPROJ = torchbnn
8 | SOURCEDIR = .
9 | BUILDDIR = _build
10 |
11 | # Put it first so that "make" without argument is like "make help".
12 | help:
13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14 |
15 | .PHONY: help Makefile
16 |
17 | # Catch-all target: route all unknown targets to Sphinx using the new
18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19 | %: Makefile
20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | #
3 | # Configuration file for the Sphinx documentation builder.
4 | #
5 | # This file does only contain a selection of the most common options. For a
6 | # full list see the documentation:
7 | # http://www.sphinx-doc.org/en/master/config
8 |
9 | # -- Path setup --------------------------------------------------------------
10 |
11 | # If extensions (or modules to document with autodoc) are in another directory,
12 | # add these directories to sys.path here. If the directory is relative to the
13 | # documentation root, use os.path.abspath to make it absolute, like shown here.
14 | #
15 | import os
16 | import sys
17 | sys.path.insert(0, os.path.abspath('..'))
18 |
19 |
20 | # -- Project information -----------------------------------------------------
21 |
22 | project = 'torchbnn'
23 | copyright = '2020, harrykim'
24 | author = 'harrykim'
25 |
26 | # The short X.Y version
27 | version = 'v1.1'
28 | # The full version, including alpha/beta/rc tags
29 | release = 'v1.1'
30 |
31 |
32 | # -- General configuration ---------------------------------------------------
33 |
34 | # If your documentation needs a minimal Sphinx version, state it here.
35 | #
36 | # needs_sphinx = '1.0'
37 |
38 | # Add any Sphinx extension module names here, as strings. They can be
39 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
40 | # ones.
41 | extensions = [
42 | 'sphinx.ext.napoleon',
43 | 'sphinx.ext.autodoc',
44 | 'sphinx.ext.todo',
45 | 'sphinx.ext.mathjax',
46 | 'sphinx.ext.viewcode',
47 | 'sphinx.ext.githubpages',
48 | ]
49 |
50 | # Add any paths that contain templates here, relative to this directory.
51 | templates_path = ['_templates']
52 |
53 | # The suffix(es) of source filenames.
54 | # You can specify multiple suffix as a list of string:
55 | #
56 | # source_suffix = ['.rst', '.md']
57 | source_suffix = '.rst'
58 |
59 | # The master toctree document.
60 | master_doc = 'index'
61 |
62 | # The language for content autogenerated by Sphinx. Refer to documentation
63 | # for a list of supported languages.
64 | #
65 | # This is also used if you do content translation via gettext catalogs.
66 | # Usually you set "language" from the command line for these cases.
67 | language = None
68 |
69 | # List of patterns, relative to source directory, that match files and
70 | # directories to ignore when looking for source files.
71 | # This pattern also affects html_static_path and html_extra_path .
72 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
73 |
74 | # The name of the Pygments (syntax highlighting) style to use.
75 | pygments_style = 'sphinx'
76 |
77 |
78 | # -- Options for HTML output -------------------------------------------------
79 |
80 | # The theme to use for HTML and HTML Help pages. See the documentation for
81 | # a list of builtin themes.
82 | #
83 | html_theme = 'sphinx_rtd_theme'
84 |
85 | # Theme options are theme-specific and customize the look and feel of a theme
86 | # further. For a list of options available for each theme, see the
87 | # documentation.
88 | #
89 | # html_theme_options = {}
90 |
91 | # Add any paths that contain custom static files (such as style sheets) here,
92 | # relative to this directory. They are copied after the builtin static files,
93 | # so a file named "default.css" will overwrite the builtin "default.css".
94 | html_static_path = ['_static']
95 |
96 | # Custom sidebar templates, must be a dictionary that maps document names
97 | # to template names.
98 | #
99 | # The default sidebars (for documents that don't match any pattern) are
100 | # defined by theme itself. Builtin themes are using these templates by
101 | # default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
102 | # 'searchbox.html']``.
103 | #
104 | # html_sidebars = {}
105 |
106 |
107 | # -- Options for HTMLHelp output ---------------------------------------------
108 |
109 | # Output file base name for HTML help builder.
110 | htmlhelp_basename = 'torchbnndoc'
111 |
112 |
113 | # -- Options for LaTeX output ------------------------------------------------
114 |
115 | latex_elements = {
116 | # The paper size ('letterpaper' or 'a4paper').
117 | #
118 | # 'papersize': 'letterpaper',
119 |
120 | # The font size ('10pt', '11pt' or '12pt').
121 | #
122 | # 'pointsize': '10pt',
123 |
124 | # Additional stuff for the LaTeX preamble.
125 | #
126 | # 'preamble': '',
127 |
128 | # Latex figure (float) alignment
129 | #
130 | # 'figure_align': 'htbp',
131 | }
132 |
133 | # Grouping the document tree into LaTeX files. List of tuples
134 | # (source start file, target name, title,
135 | # author, documentclass [howto, manual, or own class]).
136 | latex_documents = [
137 | (master_doc, 'torchbnn.tex', 'torchbnn Documentation',
138 | 'harrykim', 'manual'),
139 | ]
140 |
141 |
142 | # -- Options for manual page output ------------------------------------------
143 |
144 | # One entry per manual page. List of tuples
145 | # (source start file, name, description, authors, manual section).
146 | man_pages = [
147 | (master_doc, 'torchbnn', 'torchbnn Documentation',
148 | [author], 1)
149 | ]
150 |
151 |
152 | # -- Options for Texinfo output ----------------------------------------------
153 |
154 | # Grouping the document tree into Texinfo files. List of tuples
155 | # (source start file, target name, title, author,
156 | # dir menu entry, description, category)
157 | texinfo_documents = [
158 | (master_doc, 'torchbnn', 'torchbnn Documentation',
159 | author, 'torchbnn', 'One line description of project.',
160 | 'Miscellaneous'),
161 | ]
162 |
163 |
164 | # -- Extension configuration -------------------------------------------------
165 |
166 | # -- Options for todo extension ----------------------------------------------
167 |
168 | # If true, `todo` and `todoList` produce output, else they produce nothing.
169 | todo_include_todos = True
--------------------------------------------------------------------------------
/docs/functional.rst:
--------------------------------------------------------------------------------
1 | .. torchattacks documentation master file, created by
2 | sphinx-quickstart on Sun Apr 12 23:38:13 2020.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Functional
7 | ========================================
8 |
9 | Bayesian KL Loss
10 | ~~~~~~~~~~~~~~~~~~~~~
11 | .. automodule:: torchbnn.functional
12 | :members:
13 | :undoc-members:
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. torchbnn documentation master file, created by
2 | sphinx-quickstart on Tue Apr 21 13:12:54 2020.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | torchbnn v1.1
7 | ====================================
8 |
9 | .. toctree::
10 | :maxdepth: 2
11 | :caption: Contents:
12 |
13 | modules
14 | utils
15 | functional
16 |
17 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | pushd %~dp0
4 |
5 | REM Command file for Sphinx documentation
6 |
7 | if "%SPHINXBUILD%" == "" (
8 | set SPHINXBUILD=sphinx-build
9 | )
10 | set SOURCEDIR=.
11 | set BUILDDIR=_build
12 | set SPHINXPROJ=torchbnn
13 |
14 | if "%1" == "" goto help
15 |
16 | %SPHINXBUILD% >NUL 2>NUL
17 | if errorlevel 9009 (
18 | echo.
19 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
20 | echo.installed, then set the SPHINXBUILD environment variable to point
21 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
22 | echo.may add the Sphinx directory to PATH.
23 | echo.
24 | echo.If you don't have Sphinx installed, grab it from
25 | echo.http://sphinx-doc.org/
26 | exit /b 1
27 | )
28 |
29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
30 | goto end
31 |
32 | :help
33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
34 |
35 | :end
36 | popd
37 |
--------------------------------------------------------------------------------
/docs/modules.rst:
--------------------------------------------------------------------------------
1 | .. torchattacks documentation master file, created by
2 | sphinx-quickstart on Sun Apr 12 23:38:13 2020.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Modules
7 | ========================================
8 |
9 | Bayes Module
10 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11 | .. automodule:: torchbnn.modules.module
12 | :members:
13 |
14 | Bayes Linear
15 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
16 | .. automodule:: torchbnn.modules.linear
17 | :members:
18 |
19 | Bayes Conv
20 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21 | .. automodule:: torchbnn.modules.conv
22 | :members:
23 |
24 | Bayes Batchnorm
25 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
26 | .. automodule:: torchbnn.modules.batchnorm
27 | :members:
28 |
29 | BKLLoss
30 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
31 | .. automodule:: torchbnn.modules.loss
32 | :members:
--------------------------------------------------------------------------------
/docs/utils.rst:
--------------------------------------------------------------------------------
1 | .. torchattacks documentation master file, created by
2 | sphinx-quickstart on Sun Apr 12 23:38:13 2020.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Utils
7 | ========================================
8 |
9 | Freeze Model
10 | ~~~~~~~~~~~~~~~~~~~~~
11 | .. automodule:: torchbnn.utils.freeze_model
12 | :members:
13 | :undoc-members:
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | torch==1.2.0
--------------------------------------------------------------------------------
/torchbnn/__init__.py:
--------------------------------------------------------------------------------
1 | from .modules import *
2 | from . import utils
3 |
4 | __version__ = 1.2
--------------------------------------------------------------------------------
/torchbnn/functional.py:
--------------------------------------------------------------------------------
1 | import math
2 | import torch
3 |
4 | from .modules import *
5 |
6 | def _kl_loss(mu_0, log_sigma_0, mu_1, log_sigma_1) :
7 | """
8 | An method for calculating KL divergence between two Normal distribtuion.
9 |
10 | Arguments:
11 | mu_0 (Float) : mean of normal distribution.
12 | log_sigma_0 (Float): log(standard deviation of normal distribution).
13 | mu_1 (Float): mean of normal distribution.
14 | log_sigma_1 (Float): log(standard deviation of normal distribution).
15 |
16 | """
17 | kl = log_sigma_1 - log_sigma_0 + \
18 | (torch.exp(log_sigma_0)**2 + (mu_0-mu_1)**2)/(2*math.exp(log_sigma_1)**2) - 0.5
19 | return kl.sum()
20 |
21 | def bayesian_kl_loss(model, reduction='mean', last_layer_only=False) :
22 | """
23 | An method for calculating KL divergence of whole layers in the model.
24 |
25 |
26 | Arguments:
27 | model (nn.Module): a model to be calculated for KL-divergence.
28 | reduction (string, optional): Specifies the reduction to apply to the output:
29 | ``'mean'``: the sum of the output will be divided by the number of
30 | elements of the output.
31 | ``'sum'``: the output will be summed.
32 | last_layer_only (Bool): True for return only the last layer's KL divergence.
33 |
34 | """
35 | device = torch.device("cuda" if next(model.parameters()).is_cuda else "cpu")
36 | kl = torch.Tensor([0]).to(device)
37 | kl_sum = torch.Tensor([0]).to(device)
38 | n = torch.Tensor([0]).to(device)
39 |
40 | for m in model.modules() :
41 | if isinstance(m, (BayesLinear, BayesConv2d)):
42 | kl = _kl_loss(m.weight_mu, m.weight_log_sigma, m.prior_mu, m.prior_log_sigma)
43 | kl_sum += kl
44 | n += len(m.weight_mu.view(-1))
45 |
46 | if m.bias :
47 | kl = _kl_loss(m.bias_mu, m.bias_log_sigma, m.prior_mu, m.prior_log_sigma)
48 | kl_sum += kl
49 | n += len(m.bias_mu.view(-1))
50 |
51 | if isinstance(m, BayesBatchNorm2d):
52 | if m.affine :
53 | kl = _kl_loss(m.weight_mu, m.weight_log_sigma, m.prior_mu, m.prior_log_sigma)
54 | kl_sum += kl
55 | n += len(m.weight_mu.view(-1))
56 |
57 | kl = _kl_loss(m.bias_mu, m.bias_log_sigma, m.prior_mu, m.prior_log_sigma)
58 | kl_sum += kl
59 | n += len(m.bias_mu.view(-1))
60 |
61 | if last_layer_only or n == 0 :
62 | return kl
63 |
64 | if reduction == 'mean' :
65 | return kl_sum/n
66 | elif reduction == 'sum' :
67 | return kl_sum
68 | else :
69 | raise ValueError(reduction + " is not valid")
70 |
71 |
72 |
--------------------------------------------------------------------------------
/torchbnn/modules/__init__.py:
--------------------------------------------------------------------------------
1 | from .linear import BayesLinear
2 | from .conv import BayesConv2d
3 | from .batchnorm import BayesBatchNorm2d
4 | from .loss import BKLLoss
--------------------------------------------------------------------------------
/torchbnn/modules/batchnorm.py:
--------------------------------------------------------------------------------
1 | import math
2 |
3 | import torch
4 | from torch.nn import Module, Parameter
5 | import torch.nn.init as init
6 | import torch.nn.functional as F
7 |
8 | class _BayesBatchNorm(Module):
9 | r"""
10 | Applies Bayesian Batch Normalization over a 2D or 3D input
11 |
12 | Arguments:
13 | prior_mu (Float): mean of prior normal distribution.
14 | prior_sigma (Float): sigma of prior normal distribution.
15 |
16 | .. note:: other arguments are following batchnorm of pytorch 1.2.0.
17 | https://github.com/pytorch/pytorch/blob/master/torch/nn/modules/batchnorm.py
18 |
19 | """
20 |
21 | _version = 2
22 | __constants__ = ['prior_mu', 'prior_sigma', 'track_running_stats',
23 | 'momentum', 'eps', 'weight', 'bias',
24 | 'running_mean', 'running_var', 'num_batches_tracked',
25 | 'num_features', 'affine']
26 |
27 | def __init__(self, prior_mu, prior_sigma, num_features, eps=1e-5, momentum=0.1, affine=True, track_running_stats=True):
28 | super(_BayesBatchNorm, self).__init__()
29 | self.num_features = num_features
30 | self.eps = eps
31 | self.momentum = momentum
32 | self.affine = affine
33 | self.track_running_stats = track_running_stats
34 | if self.affine:
35 | self.prior_mu = prior_mu
36 | self.prior_sigma = prior_sigma
37 | self.prior_log_sigma = math.log(prior_sigma)
38 |
39 | self.weight_mu = Parameter(torch.Tensor(num_features))
40 | self.weight_log_sigma = Parameter(torch.Tensor(num_features))
41 | self.register_buffer('weight_eps', None)
42 |
43 | self.bias_mu = Parameter(torch.Tensor(num_features))
44 | self.bias_log_sigma = Parameter(torch.Tensor(num_features))
45 | self.register_buffer('bias_eps', None)
46 | else:
47 | self.register_parameter('weight_mu', None)
48 | self.register_parameter('weight_log_sigma', None)
49 | self.register_buffer('weight_eps', None)
50 | self.register_parameter('bias_mu', None)
51 | self.register_parameter('bias_log_sigma', None)
52 | self.register_buffer('bias_eps', None)
53 | if self.track_running_stats:
54 | self.register_buffer('running_mean', torch.zeros(num_features))
55 | self.register_buffer('running_var', torch.ones(num_features))
56 | self.register_buffer('num_batches_tracked', torch.tensor(0, dtype=torch.long))
57 | else:
58 | self.register_parameter('running_mean', None)
59 | self.register_parameter('running_var', None)
60 | self.register_parameter('num_batches_tracked', None)
61 | self.reset_parameters()
62 |
63 | def reset_running_stats(self):
64 | if self.track_running_stats:
65 | self.running_mean.zero_()
66 | self.running_var.fill_(1)
67 | self.num_batches_tracked.zero_()
68 |
69 | def reset_parameters(self):
70 | self.reset_running_stats()
71 | if self.affine:
72 | # Initialization method of Adv-BNN.
73 | self.weight_mu.data.uniform_()
74 | self.weight_log_sigma.data.fill_(self.prior_log_sigma)
75 | self.bias_mu.data.zero_()
76 | self.bias_log_sigma.data.fill_(self.prior_log_sigma)
77 |
78 | # Initilization method of the original torch nn.batchnorm.
79 | # init.ones_(self.weight_mu)
80 | # self.weight_log_sigma.data.fill_(self.prior_log_sigma)
81 | # init.zeros_(self.bias_mu)
82 | # self.bias_log_sigma.data.fill_(self.prior_log_sigma)
83 |
84 | def freeze(self) :
85 | if self.affine :
86 | self.weight_eps = torch.randn_like(self.weight_log_sigma)
87 | self.bias_eps = torch.randn_like(self.bias_log_sigma)
88 |
89 | def unfreeze(self) :
90 | if self.affine :
91 | self.weight_eps = None
92 | self.bias_eps = None
93 |
94 | def _check_input_dim(self, input):
95 | raise NotImplementedError
96 |
97 | def forward(self, input):
98 | self._check_input_dim(input)
99 |
100 | if self.momentum is None:
101 | exponential_average_factor = 0.0
102 | else:
103 | exponential_average_factor = self.momentum
104 |
105 | if self.training and self.track_running_stats:
106 | if self.num_batches_tracked is not None:
107 | self.num_batches_tracked += 1
108 | if self.momentum is None:
109 | exponential_average_factor = 1.0 / float(self.num_batches_tracked)
110 | else:
111 | exponential_average_factor = self.momentum
112 |
113 | if self.affine :
114 | if self.weight_eps is None :
115 | weight = self.weight_mu + torch.exp(self.weight_log_sigma) * torch.randn_like(self.weight_log_sigma)
116 | bias = self.bias_mu + torch.exp(self.bias_log_sigma) * torch.randn_like(self.bias_log_sigma)
117 | else :
118 | weight = self.weight_mu + torch.exp(self.weight_log_sigma) * self.weight_eps
119 | bias = self.bias_mu + torch.exp(self.bias_log_sigma) * self.bias_eps
120 | else :
121 | weight = None
122 | bias = None
123 |
124 | return F.batch_norm(
125 | input, self.running_mean, self.running_var, weight, bias,
126 | self.training or not self.track_running_stats,
127 | exponential_average_factor, self.eps)
128 |
129 | def extra_repr(self):
130 | return '{prior_mu}, {prior_sigma}, {num_features}, ' \
131 | 'eps={eps}, momentum={momentum}, affine={affine}, ' \
132 | 'track_running_stats={track_running_stats}'.format(**self.__dict__)
133 |
134 | def _load_from_state_dict(self, state_dict, prefix, local_metadata, strict,
135 | missing_keys, unexpected_keys, error_msgs):
136 | version = local_metadata.get('version', None)
137 |
138 | if (version is None or version < 2) and self.track_running_stats:
139 | num_batches_tracked_key = prefix + 'num_batches_tracked'
140 | if num_batches_tracked_key not in state_dict:
141 | state_dict[num_batches_tracked_key] = torch.tensor(0, dtype=torch.long)
142 |
143 | super(_BayesBatchNorm, self)._load_from_state_dict(
144 | state_dict, prefix, local_metadata, strict,
145 | missing_keys, unexpected_keys, error_msgs)
146 |
147 | class BayesBatchNorm2d(_BayesBatchNorm):
148 | r"""
149 | Applies Bayesian Batch Normalization over a 2D input
150 |
151 | Arguments:
152 | prior_mu (Float): mean of prior normal distribution.
153 | prior_sigma (Float): sigma of prior normal distribution.
154 |
155 | .. note:: other arguments are following batchnorm of pytorch 1.2.0.
156 | https://github.com/pytorch/pytorch/blob/master/torch/nn/modules/batchnorm.py
157 |
158 | """
159 |
160 | def _check_input_dim(self, input):
161 | if input.dim() != 4:
162 | raise ValueError('expected 4D input (got {}D input)'
163 | .format(input.dim()))
--------------------------------------------------------------------------------
/torchbnn/modules/conv.py:
--------------------------------------------------------------------------------
1 | import math
2 |
3 | import torch
4 | import torch.nn.init as init
5 | from torch.nn import Module, Parameter
6 | import torch.nn.functional as F
7 |
8 | from torch.nn.modules.utils import _single, _pair, _triple
9 |
10 |
11 | class _BayesConvNd(Module):
12 | r"""
13 | Applies Bayesian Convolution
14 |
15 | Arguments:
16 | prior_mu (Float): mean of prior normal distribution.
17 | prior_sigma (Float): sigma of prior normal distribution.
18 |
19 | .. note:: other arguments are following conv of pytorch 1.2.0.
20 | https://github.com/pytorch/pytorch/blob/master/torch/nn/modules/conv.py
21 | """
22 | __constants__ = ['prior_mu', 'prior_sigma', 'stride', 'padding', 'dilation',
23 | 'groups', 'bias', 'padding_mode', 'output_padding', 'in_channels',
24 | 'out_channels', 'kernel_size']
25 |
26 | def __init__(self, prior_mu, prior_sigma, in_channels, out_channels, kernel_size, stride,
27 | padding, dilation, transposed, output_padding,
28 | groups, bias, padding_mode):
29 | super(_BayesConvNd, self).__init__()
30 | if in_channels % groups != 0:
31 | raise ValueError('in_channels must be divisible by groups')
32 | if out_channels % groups != 0:
33 | raise ValueError('out_channels must be divisible by groups')
34 | self.in_channels = in_channels
35 | self.out_channels = out_channels
36 | self.kernel_size = kernel_size
37 | self.stride = stride
38 | self.padding = padding
39 | self.dilation = dilation
40 | self.transposed = transposed
41 | self.output_padding = output_padding
42 | self.groups = groups
43 | self.padding_mode = padding_mode
44 |
45 | self.prior_mu = prior_mu
46 | self.prior_sigma = prior_sigma
47 | self.prior_log_sigma = math.log(prior_sigma)
48 |
49 | if transposed:
50 | self.weight_mu = Parameter(torch.Tensor(
51 | in_channels, out_channels // groups, *kernel_size))
52 | self.weight_log_sigma = Parameter(torch.Tensor(
53 | in_channels, out_channels // groups, *kernel_size))
54 | self.register_buffer('weight_eps', None)
55 | else:
56 | self.weight_mu = Parameter(torch.Tensor(
57 | out_channels, in_channels // groups, *kernel_size))
58 | self.weight_log_sigma = Parameter(torch.Tensor(
59 | out_channels, in_channels // groups, *kernel_size))
60 | self.register_buffer('weight_eps', None)
61 |
62 | if bias is None or bias is False :
63 | self.bias = False
64 | else :
65 | self.bias = True
66 |
67 | if self.bias:
68 | self.bias_mu = Parameter(torch.Tensor(out_channels))
69 | self.bias_log_sigma = Parameter(torch.Tensor(out_channels))
70 | self.register_buffer('bias_eps', None)
71 | else:
72 | self.register_parameter('bias_mu', None)
73 | self.register_parameter('bias_log_sigma', None)
74 | self.register_buffer('bias_eps', None)
75 |
76 | self.reset_parameters()
77 |
78 | def reset_parameters(self):
79 | # Initialization method of Adv-BNN.
80 | n = self.in_channels
81 | n *= self.kernel_size[0] ** 2
82 | stdv = 1.0 / math.sqrt(n)
83 | self.weight_mu.data.uniform_(-stdv, stdv)
84 | self.weight_log_sigma.data.fill_(self.prior_log_sigma)
85 |
86 | if self.bias :
87 | self.bias_mu.data.uniform_(-stdv, stdv)
88 | self.bias_log_sigma.data.fill_(self.prior_log_sigma)
89 |
90 | # Initialization method of the original torch nn.conv.
91 | # init.kaiming_uniform_(self.weight_mu, a=math.sqrt(5))
92 | # self.weight_log_sigma.data.fill_(self.prior_log_sigma)
93 |
94 | # if self.bias :
95 | # fan_in, _ = init._calculate_fan_in_and_fan_out(self.weight_mu)
96 | # bound = 1 / math.sqrt(fan_in)
97 | # init.uniform_(self.bias_mu, -bound, bound)
98 |
99 | # self.bias_log_sigma.data.fill_(self.prior_log_sigma)
100 |
101 | def freeze(self) :
102 | self.weight_eps = torch.randn_like(self.weight_log_sigma)
103 | if self.bias :
104 | self.bias_eps = torch.randn_like(self.bias_log_sigma)
105 |
106 | def unfreeze(self) :
107 | self.weight_eps = None
108 | if self.bias :
109 | self.bias_eps = None
110 |
111 | def extra_repr(self):
112 | s = ('{prior_mu}, {prior_sigma}'
113 | ', {in_channels}, {out_channels}, kernel_size={kernel_size}'
114 | ', stride={stride}')
115 | if self.padding != (0,) * len(self.padding):
116 | s += ', padding={padding}'
117 | if self.dilation != (1,) * len(self.dilation):
118 | s += ', dilation={dilation}'
119 | if self.output_padding != (0,) * len(self.output_padding):
120 | s += ', output_padding={output_padding}'
121 | if self.groups != 1:
122 | s += ', groups={groups}'
123 | if self.bias is False:
124 | s += ', bias=False'
125 | return s.format(**self.__dict__)
126 |
127 | def __setstate__(self, state):
128 | super(_BayesConvNd, self).__setstate__(state)
129 | if not hasattr(self, 'padding_mode'):
130 | self.padding_mode = 'zeros'
131 |
132 | class BayesConv2d(_BayesConvNd):
133 | r"""
134 | Applies Bayesian Convolution for 2D inputs
135 |
136 | Arguments:
137 | prior_mu (Float): mean of prior normal distribution.
138 | prior_sigma (Float): sigma of prior normal distribution.
139 |
140 | .. note:: other arguments are following conv of pytorch 1.2.0.
141 | https://github.com/pytorch/pytorch/blob/master/torch/nn/modules/conv.py
142 |
143 | """
144 | def __init__(self, prior_mu, prior_sigma, in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode='zeros'):
145 | kernel_size = _pair(kernel_size)
146 | stride = _pair(stride)
147 | padding = _pair(padding)
148 | dilation = _pair(dilation)
149 | super(BayesConv2d, self).__init__(
150 | prior_mu, prior_sigma, in_channels, out_channels, kernel_size, stride,
151 | padding, dilation, False, _pair(0), groups, bias, padding_mode)
152 |
153 | def conv2d_forward(self, input, weight):
154 |
155 | if self.bias:
156 | if self.bias_eps is None :
157 | bias = self.bias_mu + torch.exp(self.bias_log_sigma) * torch.randn_like(self.bias_log_sigma)
158 | else :
159 | bias = self.bias_mu + torch.exp(self.bias_log_sigma) * self.bias_eps
160 | else :
161 | bias = None
162 |
163 | if self.padding_mode == 'circular':
164 | expanded_padding = ((self.padding[1] + 1) // 2, self.padding[1] // 2,
165 | (self.padding[0] + 1) // 2, self.padding[0] // 2)
166 | return F.conv2d(F.pad(input, expanded_padding, mode='circular'),
167 | weight, bias, self.stride,
168 | _pair(0), self.dilation, self.groups)
169 | return F.conv2d(input, weight, bias, self.stride,
170 | self.padding, self.dilation, self.groups)
171 |
172 | def forward(self, input):
173 | r"""
174 | Overriden.
175 | """
176 | if self.weight_eps is None :
177 | weight = self.weight_mu + torch.exp(self.weight_log_sigma) * torch.randn_like(self.weight_log_sigma)
178 | else :
179 | weight = self.weight_mu + torch.exp(self.weight_log_sigma) * self.weight_eps
180 |
181 | return self.conv2d_forward(input, weight)
--------------------------------------------------------------------------------
/torchbnn/modules/linear.py:
--------------------------------------------------------------------------------
1 | import math
2 |
3 | import torch
4 | from torch.nn import Module, Parameter
5 | import torch.nn.init as init
6 | import torch.nn.functional as F
7 |
8 | class BayesLinear(Module):
9 | r"""
10 | Applies Bayesian Linear
11 |
12 | Arguments:
13 | prior_mu (Float): mean of prior normal distribution.
14 | prior_sigma (Float): sigma of prior normal distribution.
15 |
16 | .. note:: other arguments are following linear of pytorch 1.2.0.
17 | https://github.com/pytorch/pytorch/blob/master/torch/nn/modules/linear.py
18 |
19 | """
20 | __constants__ = ['prior_mu', 'prior_sigma', 'bias', 'in_features', 'out_features']
21 |
22 | def __init__(self, prior_mu, prior_sigma, in_features, out_features, bias=True):
23 | super(BayesLinear, self).__init__()
24 | self.in_features = in_features
25 | self.out_features = out_features
26 |
27 | self.prior_mu = prior_mu
28 | self.prior_sigma = prior_sigma
29 | self.prior_log_sigma = math.log(prior_sigma)
30 |
31 | self.weight_mu = Parameter(torch.Tensor(out_features, in_features))
32 | self.weight_log_sigma = Parameter(torch.Tensor(out_features, in_features))
33 | self.register_buffer('weight_eps', None)
34 |
35 | if bias is None or bias is False :
36 | self.bias = False
37 | else :
38 | self.bias = True
39 |
40 | if self.bias:
41 | self.bias_mu = Parameter(torch.Tensor(out_features))
42 | self.bias_log_sigma = Parameter(torch.Tensor(out_features))
43 | self.register_buffer('bias_eps', None)
44 | else:
45 | self.register_parameter('bias_mu', None)
46 | self.register_parameter('bias_log_sigma', None)
47 | self.register_buffer('bias_eps', None)
48 |
49 | self.reset_parameters()
50 |
51 | def reset_parameters(self):
52 | # Initialization method of Adv-BNN
53 | stdv = 1. / math.sqrt(self.weight_mu.size(1))
54 | self.weight_mu.data.uniform_(-stdv, stdv)
55 | self.weight_log_sigma.data.fill_(self.prior_log_sigma)
56 | if self.bias :
57 | self.bias_mu.data.uniform_(-stdv, stdv)
58 | self.bias_log_sigma.data.fill_(self.prior_log_sigma)
59 |
60 | # Initialization method of the original torch nn.linear.
61 | # init.kaiming_uniform_(self.weight_mu, a=math.sqrt(5))
62 | # self.weight_log_sigma.data.fill_(self.prior_log_sigma)
63 |
64 | # if self.bias :
65 | # fan_in, _ = init._calculate_fan_in_and_fan_out(self.weight_mu)
66 | # bound = 1 / math.sqrt(fan_in)
67 | # init.uniform_(self.bias_mu, -bound, bound)
68 |
69 | # self.bias_log_sigma.data.fill_(self.prior_log_sigma)
70 |
71 | def freeze(self) :
72 | self.weight_eps = torch.randn_like(self.weight_log_sigma)
73 | if self.bias :
74 | self.bias_eps = torch.randn_like(self.bias_log_sigma)
75 |
76 | def unfreeze(self) :
77 | self.weight_eps = None
78 | if self.bias :
79 | self.bias_eps = None
80 |
81 | def forward(self, input):
82 | r"""
83 | Overriden.
84 | """
85 | if self.weight_eps is None :
86 | weight = self.weight_mu + torch.exp(self.weight_log_sigma) * torch.randn_like(self.weight_log_sigma)
87 | else :
88 | weight = self.weight_mu + torch.exp(self.weight_log_sigma) * self.weight_eps
89 |
90 | if self.bias:
91 | if self.bias_eps is None :
92 | bias = self.bias_mu + torch.exp(self.bias_log_sigma) * torch.randn_like(self.bias_log_sigma)
93 | else :
94 | bias = self.bias_mu + torch.exp(self.bias_log_sigma) * self.bias_eps
95 | else :
96 | bias = None
97 |
98 | return F.linear(input, weight, bias)
99 |
100 | def extra_repr(self):
101 | r"""
102 | Overriden.
103 | """
104 | return 'prior_mu={}, prior_sigma={}, in_features={}, out_features={}, bias={}'.format(self.prior_mu, self.prior_sigma, self.in_features, self.out_features, self.bias is not None)
--------------------------------------------------------------------------------
/torchbnn/modules/loss.py:
--------------------------------------------------------------------------------
1 | import warnings
2 |
3 | from torch.nn import Module
4 | from torch.nn import functional as F
5 | from torch.nn import _reduction as _Reduction
6 |
7 | from .. import functional as BF
8 |
9 | class _Loss(Module):
10 | def __init__(self, reduction='mean'):
11 | super(_Loss, self).__init__()
12 | self.reduction = reduction
13 |
14 | class BKLLoss(_Loss):
15 | """
16 | Loss for calculating KL divergence of baysian neural network model.
17 |
18 | Arguments:
19 | reduction (string, optional): Specifies the reduction to apply to the output:
20 | ``'mean'``: the sum of the output will be divided by the number of
21 | elements of the output.
22 | ``'sum'``: the output will be summed.
23 | last_layer_only (Bool): True for return only the last layer's KL divergence.
24 | """
25 | __constants__ = ['reduction']
26 |
27 | def __init__(self, reduction='mean', last_layer_only=False):
28 | super(BKLLoss, self).__init__(reduction)
29 | self.last_layer_only = last_layer_only
30 |
31 | def forward(self, model):
32 | """
33 | Arguments:
34 | model (nn.Module): a model to be calculated for KL-divergence.
35 | """
36 | return BF.bayesian_kl_loss(model, reduction=self.reduction, last_layer_only=self.last_layer_only)
--------------------------------------------------------------------------------
/torchbnn/modules/module.py:
--------------------------------------------------------------------------------
1 | import torch
2 | from torch.nn import Module
3 |
4 |
5 | class BayesModule(Module) :
6 | r"""
7 | Applies Bayesian Module
8 | Currently this module is not being used as base of bayesian modules because it has not many utilies yet,
9 | However, it can be used in the near future for convenience.
10 | """
11 |
12 | def freeze(self):
13 | r"""Sets the module in freezed mode.
14 | This has effect on bayesian modules. It will fix epsilons, e.g. weight_eps, bias_eps.
15 | Thus, bayesian neural networks will return same results with same inputs.
16 | """
17 | self.freeze = True
18 | for module in self.children():
19 | module.freeze(mode)
20 | return self
21 |
22 | def unfreeze(self):
23 | r"""Sets the module in unfreezed mode.
24 | This has effect on bayesian modules. It will unfix epsilons, e.g. weight_eps, bias_eps.
25 | Thus, bayesian neural networks will return different results even if same inputs are given.
26 | """
27 | self.freeze = False
28 | for module in self.children():
29 | module.unfreeze(mode)
30 | return self
--------------------------------------------------------------------------------
/torchbnn/utils/__init__.py:
--------------------------------------------------------------------------------
1 | from .freeze_model import freeze, unfreeze
--------------------------------------------------------------------------------
/torchbnn/utils/freeze_model.py:
--------------------------------------------------------------------------------
1 | import torch
2 | import torch.nn as nn
3 | from ..modules import *
4 |
5 | bayes_layer = (BayesLinear, BayesConv2d, BayesBatchNorm2d)
6 |
7 | def freeze(module):
8 | """
9 | Methods for freezing bayesian-model.
10 |
11 | Arguments:
12 | model (nn.Module): a model to be freezed.
13 |
14 | """
15 |
16 | if isinstance(module, bayes_layer) :
17 | module.freeze()
18 | for submodule in module.children() :
19 | freeze(submodule)
20 |
21 |
22 | def unfreeze(module):
23 | """
24 | Methods for unfreezing bayesian-model.
25 |
26 | Arguments:
27 | model (nn.Module): a model to be unfreezed.
28 |
29 | """
30 | if isinstance(module, bayes_layer) :
31 | module.unfreeze()
32 | for submodule in module.children() :
33 | unfreeze(submodule)
--------------------------------------------------------------------------------