Commit
·
e40e8f3
1
Parent(s):
092365e
Initial commit
Browse files- metadata.json +12 -0
- model.pth +3 -0
- quant_model.py +107 -0
metadata.json
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"framework": "pytorch",
|
3 |
+
"classifier": "image-classifier",
|
4 |
+
"shape": [1, 3, 224, 224],
|
5 |
+
"quantize": "True",
|
6 |
+
"module": "resnet50",
|
7 |
+
"flags": {
|
8 |
+
"--compute-softmax": "",
|
9 |
+
"--location": "artifact",
|
10 |
+
"--library": "@cwd@/quant_model.py"
|
11 |
+
}
|
12 |
+
}
|
model.pth
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:07d62a4aeeaf09c99cbe1d2d6b6ddc9bd4203592ac9cb12fc8214e8cf95e529f
|
3 |
+
size 138419231
|
quant_model.py
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import torch
|
3 |
+
from torch import Tensor
|
4 |
+
import torch.nn as nn
|
5 |
+
import torchvision
|
6 |
+
from torch.utils.data import DataLoader
|
7 |
+
from torchvision import datasets
|
8 |
+
import torchvision.transforms as transforms
|
9 |
+
import os
|
10 |
+
import time
|
11 |
+
import sys
|
12 |
+
import torch.quantization
|
13 |
+
from typing import Any, Callable, List, Optional, Type, Union
|
14 |
+
from torch.quantization.observer import MinMaxObserver, MovingAverageMinMaxObserver, HistogramObserver
|
15 |
+
from typing import Dict, cast
|
16 |
+
from torchvision.models.vgg import VGG
|
17 |
+
|
18 |
+
# # Setup warnings
|
19 |
+
import warnings
|
20 |
+
warnings.filterwarnings(
|
21 |
+
action = 'ignore',
|
22 |
+
category = DeprecationWarning,
|
23 |
+
module = r'.*'
|
24 |
+
)
|
25 |
+
warnings.filterwarnings(
|
26 |
+
action = 'default',
|
27 |
+
module = r'torch.quantization'
|
28 |
+
)
|
29 |
+
from torch.quantization import QuantStub, DeQuantStub
|
30 |
+
|
31 |
+
def make_layers(cfg: List[Union[str, int]], batch_norm: bool = False) -> nn.Sequential:
|
32 |
+
layers: List[nn.Module] = []
|
33 |
+
in_channels = 3
|
34 |
+
for v in cfg:
|
35 |
+
if v == "M":
|
36 |
+
layers += [nn.MaxPool2d(kernel_size = 2, stride = 2)]
|
37 |
+
else:
|
38 |
+
v = cast(int, v)
|
39 |
+
conv2d = nn.Conv2d(in_channels, v, kernel_size = 3, padding = 1)
|
40 |
+
if batch_norm:
|
41 |
+
layers += [conv2d, nn.BatchNorm2d(v), nn.ReLU(inplace = True)]
|
42 |
+
else:
|
43 |
+
layers += [conv2d, nn.ReLU(inplace = True)]
|
44 |
+
in_channels = v
|
45 |
+
return nn.Sequential(*layers)
|
46 |
+
|
47 |
+
cfgs: Dict[str, List[Union[str, int]]] = {
|
48 |
+
"A": [64, "M", 128, "M", 256, 256, "M", 512, 512, "M", 512, 512, "M"],
|
49 |
+
"B": [64, 64, "M", 128, 128, "M", 256, 256, "M", 512, 512, "M", 512, 512, "M"],
|
50 |
+
"D": [64, 64, "M", 128, 128, "M", 256, 256, 256, "M", 512, 512, 512, "M", 512, 512, 512, "M"],
|
51 |
+
"E": [64, 64, "M", 128, 128, "M", 256, 256, 256, 256, "M", 512, 512, 512, 512, "M", 512, 512, 512, 512, "M"],
|
52 |
+
}
|
53 |
+
|
54 |
+
class qVGG(nn.Module):
|
55 |
+
def __init__(
|
56 |
+
self, num_classes: int = 1000, init_weights: bool = True, dropout: float = 0.5
|
57 |
+
) -> None:
|
58 |
+
super().__init__()
|
59 |
+
#_log_api_usage_once(self)
|
60 |
+
self.features = make_layers(cfgs["D"], batch_norm = True)
|
61 |
+
self.avgpool = nn.AdaptiveAvgPool2d((7, 7))
|
62 |
+
self.classifier = nn.Sequential(
|
63 |
+
nn.Linear(512 * 7 * 7, 4096),
|
64 |
+
nn.ReLU(True),
|
65 |
+
nn.Dropout(p = dropout),
|
66 |
+
nn.Linear(4096, 4096),
|
67 |
+
nn.ReLU(True),
|
68 |
+
nn.Dropout(p = dropout),
|
69 |
+
nn.Linear(4096, num_classes),
|
70 |
+
)
|
71 |
+
qconfig = torch.quantization.QConfig(
|
72 |
+
activation = MinMaxObserver.with_args(qscheme = torch.per_tensor_symmetric, dtype = torch.quint8),
|
73 |
+
weight = MinMaxObserver.with_args(qscheme = torch.per_tensor_symmetric, dtype = torch.qint8)
|
74 |
+
)
|
75 |
+
self.quant = torch.quantization.QuantStub(qconfig)
|
76 |
+
self.dequant = DeQuantStub()
|
77 |
+
|
78 |
+
if init_weights:
|
79 |
+
for m in self.modules():
|
80 |
+
if isinstance(m, nn.Conv2d):
|
81 |
+
nn.init.kaiming_normal_(m.weight, mode = "fan_out", nonlinearity = "relu")
|
82 |
+
if m.bias is not None:
|
83 |
+
nn.init.constant_(m.bias, 0)
|
84 |
+
elif isinstance(m, nn.BatchNorm2d):
|
85 |
+
nn.init.constant_(m.weight, 1)
|
86 |
+
nn.init.constant_(m.bias, 0)
|
87 |
+
elif isinstance(m, nn.Linear):
|
88 |
+
nn.init.normal_(m.weight, 0, 0.01)
|
89 |
+
nn.init.constant_(m.bias, 0)
|
90 |
+
|
91 |
+
def forward(self, x: torch.Tensor) -> torch.Tensor:
|
92 |
+
x = self.quant(x)
|
93 |
+
x = self.features(x)
|
94 |
+
x = self.avgpool(x)
|
95 |
+
x = torch.flatten(x, 1)
|
96 |
+
x = self.classifier(x)
|
97 |
+
x = self.dequant(x)
|
98 |
+
return x
|
99 |
+
|
100 |
+
#We define the function to fuse models
|
101 |
+
def fuse_model(self) -> None:
|
102 |
+
for m, n in zip(self.modules(), self.named_modules()):
|
103 |
+
if type(m) == nn.Conv2d:
|
104 |
+
k = int(n[0].split('.')[-1])
|
105 |
+
torch.quantization.fuse_modules(self, [["features." + str(k), "features." + str(k + 1), "features." + str(k + 2)]], inplace = True)
|
106 |
+
|
107 |
+
|