-
Notifications
You must be signed in to change notification settings - Fork 41
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Clément Walter
committed
Mar 6, 2020
1 parent
c0d570c
commit 717b1f5
Showing
8 changed files
with
167 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import tensorflow as tf | ||
|
||
|
||
def yolo_loss(anchors, threshold): | ||
""" | ||
Args: | ||
anchors (pandas.DataFrame): dataframe of the anchors with width and height columns. | ||
threshold: | ||
""" | ||
def _yolo_loss(y_true, y_pred): | ||
""" | ||
y_true and y_pred are (batch_size, number of boxes, 4 (+ 1) + number of classes (+ anchor_id for y_pred)). | ||
The number of boxes is determined by the network architecture as in single-shot detection one can only predict | ||
grid_width x grid_height boxes per anchor. | ||
""" | ||
# 1. Find matching anchors: the anchor with the best IoU is chosen for predicting each true box | ||
y_true_broadcast = tf.expand_dims(y_true, axis=2) | ||
y_true_broadcast.shape | ||
y_true_broadcast[..., 2:4].shape | ||
|
||
anchors_tensor = tf.broadcast_to(anchors[['height', 'width']].values, [1, 1, len(anchors), 2]) | ||
anchors_tensor.shape | ||
|
||
height_width_min = tf.minimum(y_true_broadcast[..., 2:4], anchors_tensor) | ||
height_width_max = tf.maximum(y_true_broadcast[..., 2:4], anchors_tensor) | ||
height_width_min.shape | ||
height_width_max.shape | ||
intersection = tf.reduce_prod(height_width_min, axis=-1) | ||
intersection.shape | ||
true_box_area = tf.reduce_prod(y_true_broadcast[..., 2:4], axis=-1) | ||
true_box_area.shape | ||
anchor_boxes_area = tf.reduce_prod(anchors_tensor, axis=-1) | ||
anchor_boxes_area.shape | ||
union = true_box_area + anchor_boxes_area - intersection | ||
union.shape | ||
iou = intersection / union | ||
iou.shape | ||
best_anchor = tf.math.argmax(iou, axis=-1) | ||
best_anchor.shape | ||
best_anchor[0, 0] | ||
|
||
batch_size, boxes, _ = tf.shape(y_true) | ||
# 2. Find grid cell: for each selected anchor, select the prediction coming from the cell which contains the true box center | ||
for image in range(batch_size): | ||
for box in range(boxes): | ||
true_box_info = y_true[image, box] | ||
selected_anchor = tf.cast(best_anchor[image, box], y_pred.dtype) | ||
prediction_for_anchor = tf.boolean_mask(y_pred[image], y_pred[image, :, -1] == selected_anchor, axis=0) | ||
prediction_for_anchor.shape | ||
grid_size = prediction_for_anchor | ||
y_pred[..., -1].shape == best_anchor | ||
y_pred.shape | ||
|
||
# 3. For confidence loss: for each selected anchor, compute confidence loss for boxes with IoU < threshold | ||
non_empty_boxes_mask = tf.cast(tf.math.reduce_prod(y_true[..., 2:4], axis=-1) > 0, tf.bool) | ||
pass | ||
return _yolo_loss |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
from .feature_pyramid_net import FeaturePyramidNet | ||
from .siamese_nets import SiameseNets | ||
from .siamese_detector import SiameseDetector |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from .yolo_box import YoloBox | ||
from .yolo_coordinates import YoloCoordinates | ||
|
||
__all__ = [ | ||
'YoloBox', | ||
'YoloCoordinates', | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
""" | ||
Activation function for mapping feature into output coordinates as in Yolo V3 | ||
""" | ||
import tensorflow as tf | ||
from tensorflow.keras.models import Sequential | ||
from tensorflow.keras.layers import Activation, Lambda | ||
|
||
|
||
def YoloBox(anchor): | ||
""" | ||
Activation function for the box dimension regression. Dimensions are relative to the image dimension, ie. between 0 | ||
and 1 | ||
Args: | ||
anchor (Union[pandas.Series, collections.namedtuple]): with key width and height. Note that given a tensor with shape | ||
(batch_size, i, j, channels), i is related to height and j to width | ||
""" | ||
return Sequential([ | ||
Activation('exponential'), | ||
Lambda(lambda input_, anchor_=anchor: ( | ||
input_ * tf.convert_to_tensor([anchor_.height, anchor_.width], dtype=tf.float32) | ||
)), | ||
]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
""" | ||
Activation function for mapping feature into output coordinates as in Yolo V3 | ||
""" | ||
import tensorflow as tf | ||
from tensorflow.keras.models import Sequential | ||
from tensorflow.keras.layers import Activation, Lambda | ||
|
||
|
||
@tf.function | ||
def build_grid_coordinates(grid_shape): | ||
""" | ||
Build a grid coordinate tensor with shape (*grid_shape, 2) where grid[i, j, 0] = i and grid[i, j, 1] = j | ||
Args: | ||
grid_shape (Union[tuple, list, tensorflow.TensorShape]): to be passed to tf.range | ||
Returns: | ||
(tensorflow.Tensor) | ||
""" | ||
height, width = tf.meshgrid(tf.range(0, grid_shape[0]), tf.range(0, grid_shape[1])) | ||
width = tf.transpose(width) | ||
height = tf.transpose(height) | ||
return tf.stack([height, width], -1) | ||
|
||
|
||
def YoloCoordinates(): | ||
""" | ||
Activation function for the box center coordinates regression. Coordinates are relative to the image dimension, ie. between 0 | ||
and 1 | ||
""" | ||
return Sequential([ | ||
Activation('sigmoid'), | ||
Lambda(lambda input_: input_ + tf.cast(tf.expand_dims(build_grid_coordinates(tf.shape(input_)[1:3]), 0), input_.dtype)), | ||
Lambda(lambda input_: input_ / tf.cast(tf.shape(input_)[1:3], input_.dtype)), | ||
]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,3 @@ | ||
from tensorflow.keras.layers import * | ||
|
||
from .classification import Classification | ||
from .gram_matrix import GramMatrix | ||
from .slicing import CenterSlicing2D |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters