Switch to unified view

a b/darkflow/net/yolov2/train.py
1
import tf_slim as slim
2
import pickle
3
import tensorflow as tf
4
from ..yolo.misc import show
5
import numpy as np
6
import os
7
import math
8
9
tf = tf.compat.v1
10
tf.disable_v2_behavior()
11
12
13
def expit_tensor(x):
14
    return 1. / (1. + tf.exp(-x))
15
16
17
def loss(self, net_out):
18
    """
19
    Takes net.out and placeholders value
20
    returned in batch() func above,
21
    to build train_op and loss
22
    """
23
    # meta
24
    m = self.meta
25
    sprob = float(m['class_scale'])
26
    sconf = float(m['object_scale'])
27
    snoob = float(m['noobject_scale'])
28
    scoor = float(m['coord_scale'])
29
    H, W, _ = m['out_size']
30
    B, C = m['num'], m['classes']
31
    HW = H * W  # number of grid cells
32
    anchors = m['anchors']
33
34
    print('{} loss hyper-parameters:'.format(m['model']))
35
    print('\tH       = {}'.format(H))
36
    print('\tW       = {}'.format(W))
37
    print('\tbox     = {}'.format(m['num']))
38
    print('\tclasses = {}'.format(m['classes']))
39
    print('\tscales  = {}'.format([sprob, sconf, snoob, scoor]))
40
41
    size1 = [None, HW, B, C]
42
    size2 = [None, HW, B]
43
44
    # return the below placeholders
45
    _probs = tf.placeholder(tf.float32, size1)
46
    _confs = tf.placeholder(tf.float32, size2)
47
    _coord = tf.placeholder(tf.float32, size2 + [4])
48
    # weights term for L2 loss
49
    _proid = tf.placeholder(tf.float32, size1)
50
    # material calculating IOU
51
    _areas = tf.placeholder(tf.float32, size2)
52
    _upleft = tf.placeholder(tf.float32, size2 + [2])
53
    _botright = tf.placeholder(tf.float32, size2 + [2])
54
55
    self.placeholders = {
56
        'probs': _probs, 'confs': _confs, 'coord': _coord, 'proid': _proid,
57
        'areas': _areas, 'upleft': _upleft, 'botright': _botright
58
    }
59
60
    # Extract the coordinate prediction from net.out
61
    net_out_reshape = tf.reshape(net_out, [-1, H, W, B, (4 + 1 + C)])
62
    coords = net_out_reshape[:, :, :, :, :4]
63
    coords = tf.reshape(coords, [-1, H * W, B, 4])
64
    adjusted_coords_xy = expit_tensor(coords[:, :, :, 0:2])
65
    adjusted_coords_wh = tf.sqrt(
66
        tf.exp(coords[:, :, :, 2:4]) * np.reshape(anchors, [1, 1, B, 2]) / np.reshape([W, H], [1, 1, 1, 2]))
67
    coords = tf.concat([adjusted_coords_xy, adjusted_coords_wh], 3)
68
69
    adjusted_c = expit_tensor(net_out_reshape[:, :, :, :, 4])
70
    adjusted_c = tf.reshape(adjusted_c, [-1, H * W, B, 1])
71
72
    adjusted_prob = tf.nn.softmax(net_out_reshape[:, :, :, :, 5:])
73
    adjusted_prob = tf.reshape(adjusted_prob, [-1, H * W, B, C])
74
75
    adjusted_net_out = tf.concat([adjusted_coords_xy, adjusted_coords_wh, adjusted_c, adjusted_prob], 3)
76
77
    wh = tf.pow(coords[:, :, :, 2:4], 2) * np.reshape([W, H], [1, 1, 1, 2])
78
    area_pred = wh[:, :, :, 0] * wh[:, :, :, 1]
79
    centers = coords[:, :, :, 0:2]
80
    floor = centers - (wh * .5)
81
    ceil = centers + (wh * .5)
82
83
    # calculate the intersection areas
84
    intersect_upleft = tf.maximum(floor, _upleft)
85
    intersect_botright = tf.minimum(ceil, _botright)
86
    intersect_wh = intersect_botright - intersect_upleft
87
    intersect_wh = tf.maximum(intersect_wh, 0.0)
88
    intersect = tf.multiply(intersect_wh[:, :, :, 0], intersect_wh[:, :, :, 1])
89
90
    # calculate the best IOU, set 0.0 confidence for worse boxes
91
    iou = tf.truediv(intersect, _areas + area_pred - intersect)
92
    best_box = tf.equal(iou, tf.reduce_max(iou, [2], True))
93
    best_box = tf.to_float(best_box)
94
    confs = tf.multiply(best_box, _confs)
95
96
    # take care of the weight terms
97
    conid = snoob * (1. - confs) + sconf * confs
98
    weight_coo = tf.concat(4 * [tf.expand_dims(confs, -1)], 3)
99
    cooid = scoor * weight_coo
100
    weight_pro = tf.concat(C * [tf.expand_dims(confs, -1)], 3)
101
    proid = sprob * weight_pro
102
103
    self.fetch += [_probs, confs, conid, cooid, proid]
104
    true = tf.concat([_coord, tf.expand_dims(confs, 3), _probs], 3)
105
    wght = tf.concat([cooid, tf.expand_dims(conid, 3), proid], 3)
106
107
    print('Building {} loss'.format(m['model']))
108
    loss = tf.pow(adjusted_net_out - true, 2)
109
    loss = tf.multiply(loss, wght)
110
    loss = tf.reshape(loss, [-1, H * W * B * (4 + 1 + C)])
111
    loss = tf.reduce_sum(loss, 1)
112
    self.loss = .5 * tf.reduce_mean(loss)
113
    tf.summary.scalar('{} loss'.format(m['model']), self.loss)