HemaAM commited on
Commit
9240536
·
1 Parent(s): 62b93e3

upload modified model

Browse files
Files changed (2) hide show
  1. utils.py +14 -5
  2. yolov3.py +174 -0
utils.py CHANGED
@@ -3,11 +3,22 @@ import torch
3
  import numpy as np
4
  import cv2
5
  import random
 
6
 
7
  from pytorch_grad_cam.base_cam import BaseCAM
8
  from pytorch_grad_cam.utils.svd_on_activations import get_2d_projection
9
  from pytorch_grad_cam.utils.model_targets import ClassifierOutputTarget
10
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  def cells_to_bboxes(predictions, anchors, S, is_preds=True):
13
  """
@@ -142,9 +153,7 @@ def non_max_suppression(bboxes, iou_threshold, threshold, box_format="corners"):
142
  return bboxes_after_nms
143
 
144
 
145
-
146
-
147
- def draw_prediction_boxes(image: np.ndarray, boxes: List[List], class_labels: List[str]) -> np.ndarray:
148
  """Plots predicted bounding boxes on the image"""
149
 
150
  colors = [[random.randint(0, 255) for _ in range(3)] for name in class_labels]
@@ -250,10 +259,10 @@ class YoloGradCAM(BaseCAM):
250
  # This gives you more flexibility in case you just want to
251
  # use all conv layers for example, all Batchnorm layers,
252
  # or something else.
253
- cam_per_layer = self.compute_cam_per_layer(input_tensor,
254
  targets,
255
  eigen_smooth)
256
- return self.aggregate_multi_layers(cam_per_layer)
257
 
258
  def get_cam_image(self,
259
  input_tensor,
 
3
  import numpy as np
4
  import cv2
5
  import random
6
+ import config
7
 
8
  from pytorch_grad_cam.base_cam import BaseCAM
9
  from pytorch_grad_cam.utils.svd_on_activations import get_2d_projection
10
  from pytorch_grad_cam.utils.model_targets import ClassifierOutputTarget
11
 
12
+ def load_checkpoint(checkpoint_file, model, optimizer, lr):
13
+ print("=> Loading checkpoint")
14
+ checkpoint = torch.load(checkpoint_file, map_location=config.DEVICE)
15
+ model.load_state_dict(checkpoint["state_dict"])
16
+ optimizer.load_state_dict(checkpoint["optimizer"])
17
+
18
+ # If we don't do this then it will just have learning rate of old checkpoint
19
+ # and it will lead to many hours of debugging \:
20
+ for param_group in optimizer.param_groups:
21
+ param_group["lr"] = lr
22
 
23
  def cells_to_bboxes(predictions, anchors, S, is_preds=True):
24
  """
 
153
  return bboxes_after_nms
154
 
155
 
156
+ def draw_bounding_boxes(image: np.ndarray, boxes: List[List], class_labels: List[str]) -> np.ndarray:
 
 
157
  """Plots predicted bounding boxes on the image"""
158
 
159
  colors = [[random.randint(0, 255) for _ in range(3)] for name in class_labels]
 
259
  # This gives you more flexibility in case you just want to
260
  # use all conv layers for example, all Batchnorm layers,
261
  # or something else.
262
+ grad_cam_per_layer = self.compute_cam_per_layer(input_tensor,
263
  targets,
264
  eigen_smooth)
265
+ return self.aggregate_multi_layers(grad_cam_per_layer)
266
 
267
  def get_cam_image(self,
268
  input_tensor,
yolov3.py ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Implementation of YOLOv3 architecture
3
+ """
4
+
5
+ import torch
6
+ import torch.nn as nn
7
+
8
+ import config as modelConfig
9
+
10
+ """
11
+ Information about architecture config:
12
+ Tuple is structured by (filters, kernel_size, stride)
13
+ Every conv is a same convolution.
14
+ List is structured by "B" indicating a residual block followed by the number of repeats
15
+ "S" is for scale prediction block and computing the yolo loss
16
+ "U" is for upsampling the feature map and concatenating with a previous layer
17
+ """
18
+
19
+ config = [
20
+ (32, 3, 1),
21
+ (64, 3, 2),
22
+ ["B", 1],
23
+ (128, 3, 2),
24
+ ["B", 2],
25
+ (256, 3, 2),
26
+ ["B", 8],
27
+ (512, 3, 2),
28
+ ["B", 8],
29
+ (1024, 3, 2),
30
+ ["B", 4], # To this point is Darknet-53
31
+ (512, 1, 1),
32
+ (1024, 3, 1),
33
+ "S",
34
+ (256, 1, 1),
35
+ "U",
36
+ (256, 1, 1),
37
+ (512, 3, 1),
38
+ "S",
39
+ (128, 1, 1),
40
+ "U",
41
+ (128, 1, 1),
42
+ (256, 3, 1),
43
+ "S",
44
+ ]
45
+
46
+
47
+ class CNNBlock(nn.Module):
48
+ @staticmethod
49
+ def get_activation_function(activation_type, param=0.1):
50
+ if activation_type == 'lrelu':
51
+ return nn.LeakyReLU(param)
52
+ elif activation_type == 'relu':
53
+ return nn.ReLU()
54
+
55
+ def __init__(self, in_channels, out_channels,
56
+ activation=modelConfig.ACTIVATION, bn_act=True,
57
+ **kwargs):
58
+ super(CNNBlock, self).__init__()
59
+
60
+ bias = not bn_act
61
+ layers = []
62
+
63
+ layers.append(nn.Conv2d(in_channels, out_channels, bias=bias, **kwargs))
64
+
65
+
66
+ if bn_act:
67
+ layers.append(nn.BatchNorm2d(out_channels))
68
+ layers.append(self.get_activation_function(activation))
69
+
70
+ self.layers = nn.Sequential(*layers)
71
+
72
+ def forward(self, x):
73
+ return self.layers(x)
74
+
75
+
76
+ class ResidualBlock(nn.Module):
77
+ def __init__(self, channels, use_residual=True, num_repeats=1):
78
+ super(ResidualBlock, self).__init__()
79
+ self.layers = nn.ModuleList()
80
+ for repeat in range(num_repeats):
81
+ self.layers += [
82
+ nn.Sequential(
83
+ CNNBlock(channels, channels // 2, kernel_size=1),
84
+ CNNBlock(channels // 2, channels, kernel_size=3, padding=1),
85
+ )
86
+ ]
87
+ self.use_residual = use_residual
88
+ self.num_repeats = num_repeats
89
+
90
+ def forward(self, x):
91
+ for layer in self.layers:
92
+ if self.use_residual:
93
+ x = x + layer(x)
94
+ else:
95
+ x = layer(x)
96
+ return x
97
+
98
+
99
+ class ScalePrediction(nn.Module):
100
+ def __init__(self, in_channels, num_classes):
101
+ super(ScalePrediction, self).__init__()
102
+ self.pred = nn.Sequential(
103
+ CNNBlock(in_channels, 2 * in_channels, kernel_size=3, padding=1),
104
+ CNNBlock(2 * in_channels, (num_classes + 5) * 3, kernel_size=1, bn_act=False),
105
+ )
106
+ self.num_classes = num_classes
107
+
108
+ def forward(self, x):
109
+ x = self.pred(x)
110
+ return x.reshape(x.shape[0], 3,
111
+ self.num_classes + 5, x.shape[2],
112
+ x.shape[3]).permute(0, 1, 3, 4, 2)
113
+
114
+
115
+ class YOLOv3(nn.Module):
116
+ def __init__(self, in_channels=3, num_classes=80):
117
+ super(YOLOv3, self).__init__()
118
+ self.num_classes = num_classes
119
+ self.in_channels = in_channels
120
+ self.layers = self._create_conv_layers()
121
+
122
+ def forward(self, x):
123
+ outputs = [] # for each scale
124
+ route_connections = []
125
+ for layer in self.layers:
126
+ x_ = layer(x)
127
+ if isinstance(layer, ScalePrediction):
128
+ outputs.append(x_)
129
+ continue
130
+
131
+ x = x_
132
+ if isinstance(layer, ResidualBlock) and layer.num_repeats == 8:
133
+ route_connections.append(x)
134
+
135
+ elif isinstance(layer, nn.Upsample):
136
+ x = torch.cat([x, route_connections[-1]], dim=1)
137
+ route_connections.pop()
138
+ return outputs
139
+
140
+ def _create_conv_layers(self):
141
+ layers = nn.ModuleList()
142
+ in_channels = self.in_channels
143
+
144
+ for module in config:
145
+ if isinstance(module, tuple):
146
+ out_channels, kernel_size, stride = module
147
+ layers.append(
148
+ CNNBlock(
149
+ in_channels,
150
+ out_channels,
151
+ kernel_size=kernel_size,
152
+ stride=stride,
153
+ padding=1 if kernel_size == 3 else 0,
154
+ )
155
+ )
156
+ in_channels = out_channels
157
+
158
+ elif isinstance(module, list):
159
+ num_repeats = module[1]
160
+ layers.append(ResidualBlock(in_channels, num_repeats=num_repeats,))
161
+
162
+ elif isinstance(module, str):
163
+ if module == "S":
164
+ layers += [
165
+ ResidualBlock(in_channels, use_residual=False, num_repeats=1),
166
+ CNNBlock(in_channels, in_channels // 2, kernel_size=1),
167
+ ScalePrediction(in_channels // 2, num_classes=self.num_classes),
168
+ ]
169
+ in_channels = in_channels // 2
170
+
171
+ elif module == "U":
172
+ layers.append(nn.Upsample(scale_factor=2),)
173
+ in_channels = in_channels * 3
174
+ return layers