drsaikirant88
commited on
Commit
•
acbb319
1
Parent(s):
2676ede
Delete darknet.py
Browse files- darknet.py +0 -322
darknet.py
DELETED
@@ -1,322 +0,0 @@
|
|
1 |
-
# PyTorch implementation of Darknet
|
2 |
-
# This is a custom, hard-coded version of darknet with
|
3 |
-
# YOLOv3 implementation for openimages database. This
|
4 |
-
# was written to test viability of implementing YOLO
|
5 |
-
# for face detection followed by emotion / sentiment
|
6 |
-
# analysis.
|
7 |
-
#
|
8 |
-
# Configuration, weights and data are hardcoded.
|
9 |
-
# Additional options include, ability to create
|
10 |
-
# subset of data with faces exracted for labelling.
|
11 |
-
#
|
12 |
-
# Author : Saikiran Tharimena
|
13 |
-
# Co-Authors: Kjetil Marinius Sjulsen, Juan Carlos Calvet Lopez
|
14 |
-
# Project : Emotion / Sentiment Detection from news images
|
15 |
-
# Date : 12 September 2022
|
16 |
-
# Version : v0.1
|
17 |
-
#
|
18 |
-
# (C) Schibsted ASA
|
19 |
-
|
20 |
-
# Libraries
|
21 |
-
import torch
|
22 |
-
import torch.nn as nn
|
23 |
-
import torch.nn.functional as F
|
24 |
-
from torch.autograd import Variable
|
25 |
-
import numpy as np
|
26 |
-
from utils import *
|
27 |
-
|
28 |
-
|
29 |
-
def parse_cfg(cfgfile):
|
30 |
-
"""
|
31 |
-
Takes a configuration file
|
32 |
-
|
33 |
-
Returns a list of blocks. Each blocks describes a block in the neural
|
34 |
-
network to be built. Block is represented as a dictionary in the list
|
35 |
-
|
36 |
-
"""
|
37 |
-
|
38 |
-
file = open(cfgfile, 'r')
|
39 |
-
lines = file.read().split('\n') # store the lines in a list
|
40 |
-
lines = [x for x in lines if len(x) > 0] # get read of the empty lines
|
41 |
-
lines = [x for x in lines if x[0] != '#'] # get rid of comments
|
42 |
-
lines = [x.rstrip().lstrip() for x in lines] # get rid of fringe whitespaces
|
43 |
-
|
44 |
-
block = {}
|
45 |
-
blocks = []
|
46 |
-
|
47 |
-
for line in lines:
|
48 |
-
if line[0] == "[": # This marks the start of a new block
|
49 |
-
if len(block) != 0: # If block is not empty, implies it is storing values of previous block.
|
50 |
-
blocks.append(block) # add it the blocks list
|
51 |
-
block = {} # re-init the block
|
52 |
-
block["type"] = line[1:-1].rstrip()
|
53 |
-
else:
|
54 |
-
key,value = line.split("=")
|
55 |
-
block[key.rstrip()] = value.lstrip()
|
56 |
-
blocks.append(block)
|
57 |
-
|
58 |
-
return blocks
|
59 |
-
|
60 |
-
|
61 |
-
class EmptyLayer(nn.Module):
|
62 |
-
def __init__(self):
|
63 |
-
super(EmptyLayer, self).__init__()
|
64 |
-
|
65 |
-
|
66 |
-
class DetectionLayer(nn.Module):
|
67 |
-
def __init__(self, anchors):
|
68 |
-
super(DetectionLayer, self).__init__()
|
69 |
-
self.anchors = anchors
|
70 |
-
|
71 |
-
|
72 |
-
def create_modules(blocks):
|
73 |
-
net_info = blocks[0] #Captures the information about the input and pre-processing
|
74 |
-
module_list = nn.ModuleList()
|
75 |
-
prev_filters = 3
|
76 |
-
output_filters = []
|
77 |
-
|
78 |
-
for index, x in enumerate(blocks[1:]):
|
79 |
-
module = nn.Sequential()
|
80 |
-
|
81 |
-
#check the type of block
|
82 |
-
#create a new module for the block
|
83 |
-
#append to module_list
|
84 |
-
|
85 |
-
#If it's a convolutional layer
|
86 |
-
if (x["type"] == "convolutional"):
|
87 |
-
#Get the info about the layer
|
88 |
-
activation = x["activation"]
|
89 |
-
try:
|
90 |
-
batch_normalize = int(x["batch_normalize"])
|
91 |
-
bias = False
|
92 |
-
except:
|
93 |
-
batch_normalize = 0
|
94 |
-
bias = True
|
95 |
-
|
96 |
-
filters= int(x["filters"])
|
97 |
-
padding = int(x["pad"])
|
98 |
-
kernel_size = int(x["size"])
|
99 |
-
stride = int(x["stride"])
|
100 |
-
|
101 |
-
if padding:
|
102 |
-
pad = (kernel_size - 1) // 2
|
103 |
-
else:
|
104 |
-
pad = 0
|
105 |
-
|
106 |
-
#Add the convolutional layer
|
107 |
-
conv = nn.Conv2d(prev_filters, filters, kernel_size, stride, pad, bias = bias)
|
108 |
-
module.add_module("conv_{0}".format(index), conv)
|
109 |
-
|
110 |
-
#Add the Batch Norm Layer
|
111 |
-
if batch_normalize:
|
112 |
-
bn = nn.BatchNorm2d(filters)
|
113 |
-
module.add_module("batch_norm_{0}".format(index), bn)
|
114 |
-
|
115 |
-
#Check the activation.
|
116 |
-
#It is either Linear or a Leaky ReLU for YOLO
|
117 |
-
if activation == "leaky":
|
118 |
-
activn = nn.LeakyReLU(0.1, inplace = True)
|
119 |
-
module.add_module("leaky_{0}".format(index), activn)
|
120 |
-
|
121 |
-
#If it's an upsampling layer
|
122 |
-
#We use Bilinear2dUpsampling
|
123 |
-
elif (x["type"] == "upsample"):
|
124 |
-
stride = int(x["stride"])
|
125 |
-
upsample = nn.Upsample(scale_factor = 2, mode = "nearest")
|
126 |
-
module.add_module("upsample_{}".format(index), upsample)
|
127 |
-
|
128 |
-
#If it is a route layer
|
129 |
-
elif (x["type"] == "route"):
|
130 |
-
x["layers"] = x["layers"].split(',')
|
131 |
-
#Start of a route
|
132 |
-
start = int(x["layers"][0])
|
133 |
-
#end, if there exists one.
|
134 |
-
try:
|
135 |
-
end = int(x["layers"][1])
|
136 |
-
except:
|
137 |
-
end = 0
|
138 |
-
#Positive anotation
|
139 |
-
if start > 0:
|
140 |
-
start = start - index
|
141 |
-
if end > 0:
|
142 |
-
end = end - index
|
143 |
-
route = EmptyLayer()
|
144 |
-
module.add_module("route_{0}".format(index), route)
|
145 |
-
if end < 0:
|
146 |
-
filters = output_filters[index + start] + output_filters[index + end]
|
147 |
-
else:
|
148 |
-
filters= output_filters[index + start]
|
149 |
-
|
150 |
-
#shortcut corresponds to skip connection
|
151 |
-
elif x["type"] == "shortcut":
|
152 |
-
shortcut = EmptyLayer()
|
153 |
-
module.add_module("shortcut_{}".format(index), shortcut)
|
154 |
-
|
155 |
-
#Yolo is the detection layer
|
156 |
-
elif x["type"] == "yolo":
|
157 |
-
mask = x["mask"].split(",")
|
158 |
-
mask = [int(x) for x in mask]
|
159 |
-
|
160 |
-
anchors = x["anchors"].split(",")
|
161 |
-
anchors = [int(a) for a in anchors]
|
162 |
-
anchors = [(anchors[i], anchors[i+1]) for i in range(0, len(anchors),2)]
|
163 |
-
anchors = [anchors[i] for i in mask]
|
164 |
-
|
165 |
-
detection = DetectionLayer(anchors)
|
166 |
-
module.add_module("Detection_{}".format(index), detection)
|
167 |
-
|
168 |
-
module_list.append(module)
|
169 |
-
prev_filters = filters
|
170 |
-
output_filters.append(filters)
|
171 |
-
|
172 |
-
return (net_info, module_list)
|
173 |
-
|
174 |
-
class Darknet(nn.Module):
|
175 |
-
def __init__(self, cfgfile):
|
176 |
-
super(Darknet, self).__init__()
|
177 |
-
self.blocks = parse_cfg(cfgfile)
|
178 |
-
self.net_info, self.module_list = create_modules(self.blocks)
|
179 |
-
|
180 |
-
def forward(self, x, CUDA):
|
181 |
-
modules = self.blocks[1:]
|
182 |
-
outputs = {} #We cache the outputs for the route layer
|
183 |
-
|
184 |
-
write = 0
|
185 |
-
for i, module in enumerate(modules):
|
186 |
-
module_type = (module["type"])
|
187 |
-
|
188 |
-
if module_type == "convolutional" or module_type == "upsample":
|
189 |
-
x = self.module_list[i](x)
|
190 |
-
|
191 |
-
elif module_type == "route":
|
192 |
-
layers = module["layers"]
|
193 |
-
layers = [int(a) for a in layers]
|
194 |
-
|
195 |
-
if (layers[0]) > 0:
|
196 |
-
layers[0] = layers[0] - i
|
197 |
-
|
198 |
-
if len(layers) == 1:
|
199 |
-
x = outputs[i + (layers[0])]
|
200 |
-
|
201 |
-
else:
|
202 |
-
if (layers[1]) > 0:
|
203 |
-
layers[1] = layers[1] - i
|
204 |
-
|
205 |
-
map1 = outputs[i + layers[0]]
|
206 |
-
map2 = outputs[i + layers[1]]
|
207 |
-
x = torch.cat((map1, map2), 1)
|
208 |
-
|
209 |
-
|
210 |
-
elif module_type == "shortcut":
|
211 |
-
from_ = int(module["from"])
|
212 |
-
x = outputs[i-1] + outputs[i+from_]
|
213 |
-
|
214 |
-
elif module_type == 'yolo':
|
215 |
-
anchors = self.module_list[i][0].anchors
|
216 |
-
#Get the input dimensions
|
217 |
-
inp_dim = int (self.net_info["height"])
|
218 |
-
|
219 |
-
#Get the number of classes
|
220 |
-
num_classes = int (module["classes"])
|
221 |
-
|
222 |
-
#Transform
|
223 |
-
x = x.data
|
224 |
-
x = predict_transform(x, inp_dim, anchors, num_classes, CUDA)
|
225 |
-
if not write: #if no collector has been intialised.
|
226 |
-
detections = x
|
227 |
-
write = 1
|
228 |
-
|
229 |
-
else:
|
230 |
-
detections = torch.cat((detections, x), 1)
|
231 |
-
|
232 |
-
outputs[i] = x
|
233 |
-
|
234 |
-
return detections
|
235 |
-
|
236 |
-
|
237 |
-
def load_weights(self, weightfile):
|
238 |
-
#Open the weights file
|
239 |
-
fp = open(weightfile, "rb")
|
240 |
-
|
241 |
-
#The first 5 values are header information
|
242 |
-
# 1. Major version number
|
243 |
-
# 2. Minor Version Number
|
244 |
-
# 3. Subversion number
|
245 |
-
# 4,5. Images seen by the network (during training)
|
246 |
-
header = np.fromfile(fp, dtype = np.int32, count = 5)
|
247 |
-
self.header = torch.from_numpy(header)
|
248 |
-
self.seen = self.header[3]
|
249 |
-
|
250 |
-
weights = np.fromfile(fp, dtype = np.float32)
|
251 |
-
|
252 |
-
ptr = 0
|
253 |
-
for i in range(len(self.module_list)):
|
254 |
-
module_type = self.blocks[i + 1]["type"]
|
255 |
-
|
256 |
-
#If module_type is convolutional load weights
|
257 |
-
#Otherwise ignore.
|
258 |
-
|
259 |
-
if module_type == "convolutional":
|
260 |
-
model = self.module_list[i]
|
261 |
-
try:
|
262 |
-
batch_normalize = int(self.blocks[i+1]["batch_normalize"])
|
263 |
-
except:
|
264 |
-
batch_normalize = 0
|
265 |
-
|
266 |
-
conv = model[0]
|
267 |
-
|
268 |
-
|
269 |
-
if (batch_normalize):
|
270 |
-
bn = model[1]
|
271 |
-
|
272 |
-
#Get the number of weights of Batch Norm Layer
|
273 |
-
num_bn_biases = bn.bias.numel()
|
274 |
-
|
275 |
-
#Load the weights
|
276 |
-
bn_biases = torch.from_numpy(weights[ptr:ptr + num_bn_biases])
|
277 |
-
ptr += num_bn_biases
|
278 |
-
|
279 |
-
bn_weights = torch.from_numpy(weights[ptr: ptr + num_bn_biases])
|
280 |
-
ptr += num_bn_biases
|
281 |
-
|
282 |
-
bn_running_mean = torch.from_numpy(weights[ptr: ptr + num_bn_biases])
|
283 |
-
ptr += num_bn_biases
|
284 |
-
|
285 |
-
bn_running_var = torch.from_numpy(weights[ptr: ptr + num_bn_biases])
|
286 |
-
ptr += num_bn_biases
|
287 |
-
|
288 |
-
#Cast the loaded weights into dims of model weights.
|
289 |
-
bn_biases = bn_biases.view_as(bn.bias.data)
|
290 |
-
bn_weights = bn_weights.view_as(bn.weight.data)
|
291 |
-
bn_running_mean = bn_running_mean.view_as(bn.running_mean)
|
292 |
-
bn_running_var = bn_running_var.view_as(bn.running_var)
|
293 |
-
|
294 |
-
#Copy the data to model
|
295 |
-
bn.bias.data.copy_(bn_biases)
|
296 |
-
bn.weight.data.copy_(bn_weights)
|
297 |
-
bn.running_mean.copy_(bn_running_mean)
|
298 |
-
bn.running_var.copy_(bn_running_var)
|
299 |
-
|
300 |
-
else:
|
301 |
-
#Number of biases
|
302 |
-
num_biases = conv.bias.numel()
|
303 |
-
|
304 |
-
#Load the weights
|
305 |
-
conv_biases = torch.from_numpy(weights[ptr: ptr + num_biases])
|
306 |
-
ptr = ptr + num_biases
|
307 |
-
|
308 |
-
#reshape the loaded weights according to the dims of the model weights
|
309 |
-
conv_biases = conv_biases.view_as(conv.bias.data)
|
310 |
-
|
311 |
-
#Finally copy the data
|
312 |
-
conv.bias.data.copy_(conv_biases)
|
313 |
-
|
314 |
-
#Let us load the weights for the Convolutional layers
|
315 |
-
num_weights = conv.weight.numel()
|
316 |
-
|
317 |
-
#Do the same as above for weights
|
318 |
-
conv_weights = torch.from_numpy(weights[ptr:ptr+num_weights])
|
319 |
-
ptr = ptr + num_weights
|
320 |
-
|
321 |
-
conv_weights = conv_weights.view_as(conv.weight.data)
|
322 |
-
conv.weight.data.copy_(conv_weights)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|