-
Notifications
You must be signed in to change notification settings - Fork 0
/
utils.py
114 lines (95 loc) · 3.84 KB
/
utils.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
""" Utility functions. """
import numpy as np
import os
import random
import tensorflow as tf
from tensorflow.contrib.layers.python import layers as tf_layers
from tensorflow.python.platform import flags
FLAGS = flags.FLAGS
## Image helper
def get_images(paths, labels, nb_samples=None, shuffle=True):
""" Fetch list of tuples of image class and filepath
Args:
paths: List of strings of image filepaths
labels: List of integers of image classes
nb_samples: An integer equal to the amount of samples wanted
shuffle: A boolean to signify whether a random shuffle is wanted or not
returns:
list of tuples (class, filepath)
"""
if nb_samples is not None:
sampler = lambda x: random.sample(x, nb_samples)
else:
sampler = lambda x: x
images = [(i, os.path.join(path, image)) \
for i, path in zip(labels, paths) \
for image in sampler(os.listdir(path))]
if shuffle:
random.shuffle(images)
return images
## Network helpers
def conv_block(inp, cweight, bweight, reuse, scope, activation=tf.nn.relu, max_pool_pad='VALID', residual=False):
""" Construct a TensorFlow convolutional block
Pipeline: conv, batch norm, nonlinearity, and max pool
Args:
inp: Tensor input of convolutional block
cweight: Channel weights (filters)
bweight: Biases to be added to each filter
reuse: A boolean to reuse the batchnorm variables or not
scope: TensorFlow scope in which the variables reside
activation: TensorFlow nonlinearity function, default tf.nn.relu
max_pool_pad: Max pool padding setting, default = 'VALID'
residual: NOT USED
returns:
tensor output of convolutional block input
"""
stride, no_stride = [1,2,2,1], [1,1,1,1]
if FLAGS.max_pool:
conv_output = tf.nn.conv2d(inp, cweight, no_stride, 'SAME') + bweight
else:
conv_output = tf.nn.conv2d(inp, cweight, stride, 'SAME') + bweight
normed = normalize(conv_output, activation, reuse, scope)
if FLAGS.max_pool:
normed = tf.nn.max_pool(normed, stride, stride, max_pool_pad)
return normed
def normalize(inp, activation, reuse, scope):
""" Batch Normalization
Args:
inp: Tensor input of convolutional block
reuse: A boolean to reuse the batchnorm variables or not
scope: TensorFlow scope in which the variables reside
activation: TensorFlow nonlinearity function, default tf.nn.relu
returns:
tensor output of BatchNorm input
"""
if FLAGS.norm == 'batch_norm':
return tf_layers.batch_norm(inp, activation_fn=activation, reuse=reuse, scope=scope)
elif FLAGS.norm == 'layer_norm':
return tf_layers.layer_norm(inp, activation_fn=activation, reuse=reuse, scope=scope)
elif FLAGS.norm == 'None':
if activation is not None:
return activation(inp)
else:
return inp
## Loss functions
def mse(pred, label):
""" Calculates Mean Squared Error
Args:
pred: Tensor of label predictions
label: Tensor of golden labels (True values)
returns:
Mean Squared Error of predictions and labels
"""
pred = tf.reshape(pred, [-1])
label = tf.reshape(label, [-1])
return tf.reduce_mean(tf.square(pred-label))
def xent(pred, label):
""" Calculates Cross Entropy Loss
Args:
pred: Tensor of label predictions
label: Tensor of golden labels (True values)
returns:
Mean Squared Error of predictions and labels
"""
# Note - with tf version <=0.12, this loss has incorrect 2nd derivatives
return tf.nn.softmax_cross_entropy_with_logits(logits=pred, labels=label) / FLAGS.update_batch_size