Coding style changes

This commit is contained in:
Heiko J Schick
2020-10-21 10:32:55 +02:00
parent 9cb0bcf853
commit 423982c9f9
+92 -74
View File
@@ -16,30 +16,40 @@ from matplotlib import pyplot
from matplotlib.patches import Rectangle from matplotlib.patches import Rectangle
# Step 1: # Step 1:
# WeightReader class is used to parse the "yolov3.weights" file and load the model weights into # Define WeightReader class
# memory in a format that we can set into keras model
class WeightReader: class WeightReader:
"""
WeightReader class is used to parse the "yolov3.weights" file and load the model weights into
memory in a format that we can set into keras model.
"""
def __init__(self, weight_file): def __init__(self, weight_file):
with open(weight_file, 'rb') as w_f: with open(weight_file, 'rb') as w_f:
major, = struct.unpack('i', w_f.read(4)) major, = struct.unpack('i', w_f.read(4))
minor, = struct.unpack('i', w_f.read(4)) minor, = struct.unpack('i', w_f.read(4))
revision, = struct.unpack('i', w_f.read(4)) w_f.read(4) # ignore revision
if (major*10 + minor) >= 2 and major < 1000 and minor < 1000: if (major * 10 + minor) >= 2 and major < 1000 and minor < 1000:
w_f.read(8) w_f.read(8)
else: else:
w_f.read(4) w_f.read(4)
transpose = (major > 1000) or (minor > 1000)
binary = w_f.read() binary = w_f.read()
self.offset = 0 self.offset = 0
self.all_weights = np.frombuffer(binary, dtype='float32') self.all_weights = np.frombuffer(binary, dtype='float32')
def read_bytes(self, size): def read_bytes(self, size):
"""
Helper function to read bytes from all_weights.
"""
self.offset = self.offset + size self.offset = self.offset + size
return self.all_weights[self.offset-size:self.offset]
return self.all_weights[self.offset - size:self.offset]
def load_weights(self, model): def load_weights(self, model):
"""
Load weights into created model
"""
for i in range(106): for i in range(106):
try: try:
conv_layer = model.get_layer('conv_' + str(i)) conv_layer = model.get_layer('conv_' + str(i))
@@ -52,7 +62,7 @@ class WeightReader:
gamma = self.read_bytes(size) # scale gamma = self.read_bytes(size) # scale
mean = self.read_bytes(size) # mean mean = self.read_bytes(size) # mean
var = self.read_bytes(size) # variance var = self.read_bytes(size) # variance
weights = norm_layer.set_weights([gamma, beta, mean, var]) norm_layer.set_weights([gamma, beta, mean, var])
if len(conv_layer.get_weights()) > 1: if len(conv_layer.get_weights()) > 1:
bias = self.read_bytes(np.prod(conv_layer.get_weights()[1].shape)) bias = self.read_bytes(np.prod(conv_layer.get_weights()[1].shape))
@@ -70,33 +80,36 @@ class WeightReader:
print("no convolution #" + str(i)) print("no convolution #" + str(i))
def reset(self): def reset(self):
"""
Resets offset to restart loading weights
"""
self.offset = 0 self.offset = 0
# Step 2: # Step 2:
# _conv_block(input, convs, skip=True) is a function to create convolutional layer # _conv_block(input, convs, skip=True) is a function to create convolutional layer
def _conv_block(inp, convs, skip=True): def _conv_block(input_layer, convs, skip=True):
x = inp tmp = input_layer
count = 0 count = 0
for conv in convs: for conv in convs:
if count == (len(convs) - 2) and skip: if count == (len(convs) - 2) and skip:
skip_connection = x skip_connection = tmp
count += 1 count += 1
if conv['stride'] > 1: x = ZeroPadding2D(((1,0),(1,0)))(x) # peculiar padding as darknet # Peculiar padding as darknet prefer left and top
# prefer left and top if conv['stride'] > 1: tmp = ZeroPadding2D(((1,0),(1,0)))(tmp)
x = Conv2D(conv['filter'], tmp = Conv2D(conv['filter'],
conv['kernel'], conv['kernel'],
strides=conv['stride'], strides=conv['stride'],
padding='valid' if conv['stride'] > 1 else 'same', # peculiar padding as darknet # Peculiar padding as darknet prefer left and top
# prefer left and top padding='valid' if conv['stride'] > 1 else 'same',
name='conv_' + str(conv['layer_idx']), name='conv_' + str(conv['layer_idx']),
use_bias=False if conv['bnorm'] else True)(x) use_bias=False if conv['bnorm'] else True)(tmp)
if conv['bnorm']: x = BatchNormalization(epsilon=0.001, name='bnorm_' if conv['bnorm']: tmp = BatchNormalization(epsilon=0.001, name='bnorm_'
+ str(conv['layer_idx']))(x) + str(conv['layer_idx']))(tmp)
if conv['leaky']: x = LeakyReLU(alpha=0.1, name='leaky_' if conv['leaky']: tmp = LeakyReLU(alpha=0.1, name='leaky_'
+ str(conv['layer_idx']))(x) + str(conv['layer_idx']))(tmp)
return add([skip_connection, x]) if skip else x return add([skip_connection, tmp]) if skip else tmp
# make_yolov3_model() is a function to create layers of convoluational and stack together as a # make_yolov3_model() is a function to create layers of convoluational and stack together as a
# whole yolo model # whole yolo model
@@ -218,28 +231,8 @@ def make_yolov3_model():
model = Model(input_image, [yolo_82, yolo_94, yolo_106]) model = Model(input_image, [yolo_82, yolo_94, yolo_106])
print(model.summary())
return model return model
"""**Step 3:**
- define the model
- load the weight
- save the model
"""
# define the yolo v3 model
yolov3 = make_yolov3_model()
# load the weights
weight_reader = WeightReader('yolov3.weights')
# set the weights
weight_reader.load_weights(yolov3)
# save the model to file
yolov3.save('model.h5')
"""**step 4:** Prediction """**step 4:** Prediction
by loading the image to model and make prediction by loading the image to model and make prediction
""" """
@@ -435,46 +428,71 @@ labels = ["person", "bicycle", "car", "motorbike", "aeroplane", "bus", "train",
"remote", "keyboard", "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator", "remote", "keyboard", "cell phone", "microwave", "oven", "toaster", "sink", "refrigerator",
"book", "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush"] "book", "clock", "vase", "scissors", "teddy bear", "hair drier", "toothbrush"]
"""**Step 8:** Make Prediction"""
# from google.colab import files def main():
# upload = files.upload() """
Defined starting point of source code.
"""
for photo_filename in glob.glob("images/test/dog/*"): # Step 3:
# (1) Define the model
# (2) Load the weight
# (3) Save the model
# for fn in upload.keys(): # Define the YOLO v3 model
# photo_filename = '/content/' + fn yolov3 = make_yolov3_model()
# photo_filename = 'test.jpg' print(yolov3.summary())
# define the expected input shape for the model # Load the weights
input_w, input_h = 416, 416 # Source: https://pjreddie.com/media/files/yolov3.weights
weight_reader = WeightReader('yolov3.weights')
image, image_w, image_h = load_image_pixels(photo_filename, (input_w, input_h)) # Set the weights
weight_reader.load_weights(yolov3)
# make prediction # Save the model to file
yhat = yolov3.predict(image) yolov3.save('yolov3.h5')
# summarize the shape of the list of arrays
print([a.shape for a in yhat])
boxes = list() # Step 8:
for i in range(len(yhat)): # Make Prediction
# decode the output of the network for photo_filename in glob.glob("images/test/dog/*"):
boxes += decode_netout(yhat[i][0], anchors[i], class_threshold, input_h, input_w)
# correct the sizes of the bounding boxes for the shape of the image # for fn in upload.keys():
correct_yolo_boxes(boxes, image_h, image_w, input_h, input_w) # photo_filename = '/content/' + fn
# photo_filename = 'test.jpg'
# suppress non-maximal boxes # define the expected input shape for the model
do_nms(boxes, 0.5) input_w, input_h = 416, 416
# get the details of the detected objects image, image_w, image_h = load_image_pixels(photo_filename, (input_w, input_h))
v_boxes, v_labels, v_scores = get_boxes(boxes, labels, class_threshold)
# summarize what we found # make prediction
for i in range(len(v_boxes)): yhat = yolov3.predict(image)
print(v_labels[i], v_scores[i]) # summarize the shape of the list of arrays
print([a.shape for a in yhat])
# draw what we found boxes = list()
draw_boxes(photo_filename, v_boxes, v_labels, v_scores) for i in range(len(yhat)):
# decode the output of the network
boxes += decode_netout(yhat[i][0], anchors[i], class_threshold, input_h, input_w)
print([a.shape for a in yhat]) # correct the sizes of the bounding boxes for the shape of the image
correct_yolo_boxes(boxes, image_h, image_w, input_h, input_w)
# suppress non-maximal boxes
do_nms(boxes, 0.5)
# get the details of the detected objects
v_boxes, v_labels, v_scores = get_boxes(boxes, labels, class_threshold)
# summarize what we found
for i in range(len(v_boxes)):
print(v_labels[i], v_scores[i])
# draw what we found
draw_boxes(photo_filename, v_boxes, v_labels, v_scores)
print([a.shape for a in yhat])
if __name__ == "__main__":
main()