-
Notifications
You must be signed in to change notification settings - Fork 0
/
badwinner.py
125 lines (102 loc) · 3.4 KB
/
badwinner.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# Input 1×1000×80
# Conv(3×3) 16×998×78
# leaky relu
# ( after ll conv)
# Pool(3×3) 16×332×26
# Conv(3×3) 16×330×24
# Pool(3×3) 16×110×8
# Conv(3×1) 16×108×8
# Pool(3×1) 16×36×8
# Conv(3×1) 16×34×8
# Pool(3×1) 16×11×8
# Dense 256
# leaky relu (after all dense)
# Dense 32
# Dense 1
#
#
# leaky rectifier
# nonlinearity max(x, x/100)
import sys
import argparse
import logging
import tensorflow as tf
# Worth looking into lme pooling as proposed in https://github.com/f0k/birdclef2018/blob/master/experiments/model.py
# Research/2018-birdclef.pdf
class MagTransform(tf.keras.layers.Layer):
def __init__(self):
super(MagTransform, self).__init__()
self.a = self.add_weight(
initializer=tf.keras.initializers.Constant(value=0.0),
name="a-power",
dtype="float32",
shape=(),
trainable=True,
)
def call(self, inputs):
c = tf.math.pow(inputs, tf.math.sigmoid(self.a))
return c
def build_model(input_shape, norm_layer, num_labels, multi_label=False):
input = tf.keras.Input(shape=(*input_shape, 1), name="input")
# x = norm_layer(input)
filters = 16
# if multi_label:
# filters = 32
# y = x σ(a) , where σ(a) = 1/ (1 + exp(−a))
x = MagTransform()(input)
x = tf.keras.layers.BatchNormalization()(x)
x = tf.keras.layers.Conv2D(filters, (3, 3), activation=tf.keras.layers.LeakyReLU())(
x
)
x = tf.keras.layers.MaxPool2D((3, 3))(x)
x = tf.keras.layers.Conv2D(filters, (3, 3), activation=tf.keras.layers.LeakyReLU())(
x
)
x = tf.keras.layers.MaxPool2D((3, 3))(x)
x = tf.keras.layers.Conv2D(filters, (1, 3), activation=tf.keras.layers.LeakyReLU())(
x
)
x = tf.keras.layers.MaxPool2D((1, 3))(x)
#
# x = tf.keras.layers.Conv2D(filters, (1, 3), activation=tf.keras.layers.LeakyReLU())(x)
# x = tf.keras.layers.MaxPool2D((1, 3))(x)
x = tf.keras.layers.Dropout(0.5)(x)
# if num_labels > 1:
# dense = [1024, 512]
# else:
dense = [256, 32]
for d in dense:
x = tf.keras.layers.Dense(d, activation=tf.keras.layers.LeakyReLU())(x)
x = tf.keras.layers.Dropout(0.5)(x)
# x = tf.keras.layers.Dense(32, activation=tf.keras.layers.LeakyReLU())(x)
# x = tf.keras.layers.Dropout(0.5)(x)
x = tf.keras.layers.GlobalAveragePooling2D()(x)
activation = "softmax"
if multi_label:
activation = "sigmoid"
logging.info("Using %s activation", activation)
x = tf.keras.layers.Dense(num_labels, activation=activation)(x)
model = tf.keras.models.Model(input, outputs=x)
return model
def main():
init_logging()
args = parse_args()
model = build_model((120, 480), None, 2)
model.summary()
def parse_args():
parser = argparse.ArgumentParser()
parser.add_argument("--confusion", help="Save confusion matrix for model")
parser.add_argument("-w", "--weights", help="Weights to use")
parser.add_argument("-c", "--config-file", help="Path to config file to use")
args = parser.parse_args()
return args
def init_logging():
"""Set up logging for use by various classifier pipeline scripts.
Logs will go to stderr.
"""
fmt = "%(process)d %(thread)s:%(levelname)7s %(message)s"
logging.basicConfig(
stream=sys.stderr, level=logging.INFO, format=fmt, datefmt="%Y-%m-%d %H:%M:%S"
)
if __name__ == "__main__":
main()