test_forward.py 13.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
Yuwei Hu committed
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
import numpy as np
import nnvm
import tvm
from tvm.contrib import graph_runtime
from nnvm.testing.config import ctx_list
import keras

# prevent keras from using up all gpu memory
import tensorflow as tf
from keras.backend.tensorflow_backend import set_session
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.5
set_session(tf.Session(config=config))


32
def verify_keras_frontend(keras_model, need_transpose=True):
33 34 35
    # Keras frontend currently supports tensorflow backend only.
    assert(keras.backend.backend() == 'tensorflow')

36
    in_shapes = []
37
    for layer in keras_model._input_layers:
38
        in_shapes.append(tuple(dim.value if dim.value is not None else 1 for dim in layer.input.shape))
39

40 41
    def get_keras_output(xs, dtype='float32'):
        return keras_model.predict(xs)
Yuwei Hu committed
42

43
    def get_tvm_output(xs, target, ctx, dtype='float32'):
Yuwei Hu committed
44
        sym, params = nnvm.frontend.from_keras(keras_model)
45
        shape_dict = {name: x.shape for (name, x) in zip(keras_model.input_names, xs)}
Yuwei Hu committed
46 47 48
        with nnvm.compiler.build_config(opt_level=2):
            graph, lib, params = nnvm.compiler.build(sym, target, shape_dict, params=params)
        m = graph_runtime.create(graph, lib, ctx)
49 50
        for name, x in zip(keras_model.input_names, xs):
            m.set_input(name, tvm.nd.array(x.astype(dtype)))
Yuwei Hu committed
51 52
        m.set_input(**params)
        m.run()
53

54 55 56 57 58 59 60
        return [m.get_output(i).asnumpy() for i in range(m.get_num_outputs())]

    def to_channels_first(arr):
        return arr.transpose([0, -1] + list(range(1, arr.ndim - 1)))

    def to_channels_last(arr):
        return arr.transpose([0] + list(range(2, arr.ndim)) + [1])
Yuwei Hu committed
61

62
    xs = [np.random.uniform(size=shape, low=-1.0, high=1.0) for shape in in_shapes]
63
    keras_out = get_keras_output(xs)
64

65
    keras_out = keras_out if isinstance(keras_out, list) else [keras_out]
Yuwei Hu committed
66
    for target, ctx in ctx_list():
67 68 69 70
        tvm_out = get_tvm_output([to_channels_first(x) for x in xs] if need_transpose else xs, target, ctx)
        for kout, tout in zip(keras_out, tvm_out):
            if need_transpose:
                tout = to_channels_last(tout)
71
            tvm.testing.assert_allclose(kout, tout, rtol=1e-5, atol=1e-5)
Yuwei Hu committed
72

73 74 75 76 77 78 79 80
def test_forward_elemwise_add():
    r = []
    data = keras.layers.Input(shape=(32,32,3))
    x = keras.layers.Conv2D(8, (3, 3), padding="same")(data)
    r.append(x)
    x = keras.layers.Conv2D(8, (3, 3), padding="same")(x)
    r.append(x)
    x = keras.layers.Conv2D(8, (3, 3), padding="same")(x)
81
    # add two symbols
82 83 84 85
    y = keras.layers.add([keras.layers.add([x, r[0]]), r[1]])
    y = keras.layers.GlobalAveragePooling2D()(y)
    keras_model = keras.models.Model(data, y)
    verify_keras_frontend(keras_model)
86
    # add three symbols
87 88 89 90 91
    y = keras.layers.add([x, r[0], r[1]])
    y = keras.layers.GlobalAveragePooling2D()(y)
    keras_model = keras.models.Model(data, y)
    verify_keras_frontend(keras_model)

92

93
def _test_forward_dense():
94 95
    data = keras.layers.Input(shape=(32,32,1))
    x = keras.layers.Flatten()(data)
96
    x = keras.layers.Dropout(0.5)(x)
Yuwei Hu committed
97 98 99 100
    x = keras.layers.Dense(10, activation='relu', kernel_initializer='uniform')(x)
    keras_model = keras.models.Model(data, x)
    verify_keras_frontend(keras_model)

101 102 103 104 105 106 107 108 109
def _test_forward_dense_with_3d_inp():
    data = keras.layers.Input(shape=(1, 20))
    x = keras.layers.Dense(10, activation='relu', kernel_initializer='uniform')(data)
    keras_model = keras.models.Model(data, x)
    verify_keras_frontend(keras_model, need_transpose=False)

def test_forward_dense():
    _test_forward_dense()
    _test_forward_dense_with_3d_inp()
Yuwei Hu committed
110

111
def test_forward_pool():
112
    data = keras.layers.Input(shape=(32,32,1))
113 114 115 116 117 118 119 120 121 122
    # maxpool
    x = keras.layers.MaxPooling2D((3, 3), strides=(1, 1), padding='same')(data)
    keras_model = keras.models.Model(data, x)
    verify_keras_frontend(keras_model)
    # avgpool
    y = keras.layers.AveragePooling2D((3, 3), strides=(1, 1), padding='same')(data)
    keras_model = keras.models.Model(data, y)
    verify_keras_frontend(keras_model)


123
def test_forward_conv():
Yuwei Hu committed
124
    data = keras.layers.Input(shape=(32,32,3))
125 126 127 128 129 130 131 132 133 134 135
    conv_funcs = [keras.layers.Conv2D(filters=10, kernel_size=(3,3),
                                      strides=(2,2), padding='same'),
                  keras.layers.Conv2D(filters=10, kernel_size=(3,3),
                                      dilation_rate=(2,2), padding='same'),
                  keras.layers.DepthwiseConv2D(kernel_size=(3,3), padding='same'),
                  keras.layers.Conv2DTranspose(filters=10, kernel_size=(3,3), padding='valid'),
                  keras.layers.SeparableConv2D(filters=10, kernel_size=(3,3), padding='same')]
    for conv_func in conv_funcs:
        x = conv_func(data)
        keras_model = keras.models.Model(data, x)
        verify_keras_frontend(keras_model)
Yuwei Hu committed
136 137


138 139 140 141 142 143
def test_forward_upsample():
    data = keras.layers.Input(shape=(32,32,3))
    x = keras.layers.UpSampling2D(size=(3,3))(data)
    keras_model = keras.models.Model(data, x)
    verify_keras_frontend(keras_model)

144

145 146 147 148 149 150 151
def test_forward_reshape():
    data = keras.layers.Input(shape=(32,32,3))
    x = keras.layers.Reshape(target_shape=(32,32,3))(data)
    keras_model = keras.models.Model(data, x)
    verify_keras_frontend(keras_model)


152 153 154 155 156 157 158 159 160 161 162 163 164
def test_forward_crop():
    data = keras.layers.Input(shape=(32,32,3))
    x = keras.layers.Cropping2D(cropping=((1, 1), (1, 1)))(data)
    x = keras.layers.Cropping2D(cropping=(1, 1))(x)
    x = keras.layers.Cropping2D(cropping=1)(x)
    x = keras.layers.Cropping2D(cropping=((0, 1), (1, 0)))(x)
    x = keras.layers.Cropping2D(cropping=(1, 0))(x)
    x = keras.layers.Cropping2D(cropping=0)(x)
    x = keras.layers.Add()([x, x])
    keras_model = keras.models.Model(data, x)
    verify_keras_frontend(keras_model)


165
def test_forward_vgg16():
166
    keras_model = keras.applications.vgg16.VGG16(include_top=True, weights='imagenet',
Yuwei Hu committed
167 168 169 170
        input_shape=(224,224,3), classes=1000)
    verify_keras_frontend(keras_model)


171
def test_forward_xception():
172
    keras_model = keras.applications.xception.Xception(include_top=True, weights='imagenet',
Yuwei Hu committed
173 174 175 176
        input_shape=(299,299,3), classes=1000)
    verify_keras_frontend(keras_model)


177
def test_forward_resnet50():
178
    keras_model = keras.applications.resnet50.ResNet50(include_top=True, weights='imagenet',
Yuwei Hu committed
179 180 181 182
        input_shape=(224,224,3), classes=1000)
    verify_keras_frontend(keras_model)


183
def test_forward_mobilenet():
184
    keras_model = keras.applications.mobilenet.MobileNet(include_top=True, weights='imagenet',
185 186 187
        input_shape=(224,224,3), classes=1000)
    verify_keras_frontend(keras_model)

188

189 190 191 192 193
def test_forward_activations():
    data = keras.layers.Input(shape=(32,32,3))
    weights = np.random.rand(1, 32, 32, 3)
    act_funcs = [keras.layers.Activation('softmax'),
                 keras.layers.Activation('softplus'),
Siju committed
194
                 keras.layers.ReLU(),
195
                 keras.layers.ReLU(max_value=6.),
196 197 198 199 200 201 202 203 204 205 206 207 208 209
                 keras.layers.LeakyReLU(alpha=0.3),
                 keras.layers.PReLU(weights=weights, alpha_initializer="zero"),
                 keras.layers.ELU(alpha=0.5),
                 keras.layers.Activation('selu'),
                 keras.layers.ThresholdedReLU(theta=0.5),
                 keras.layers.Activation('softsign'),
                 keras.layers.Activation('hard_sigmoid'),
                 keras.layers.Activation('sigmoid'),
                 keras.layers.Activation('tanh'),
                 keras.layers.Activation('linear')]
    for act_func in act_funcs:
        x = act_func(data)
        keras_model = keras.models.Model(data, x)
        verify_keras_frontend(keras_model)
210

211

212 213 214 215 216 217 218 219 220 221 222
def test_forward_multi_inputs():
    data1 = keras.layers.Input(shape=(32,32,3))
    data2 = keras.layers.Input(shape=(32,32,3))
    x = keras.layers.Conv2D(8, (3, 3), padding="same")(data1)
    y = keras.layers.Conv2D(8, (3, 3), padding="same")(data2)
    z = keras.layers.add([x, y])
    z = keras.layers.GlobalAveragePooling2D()(z)
    keras_model = keras.models.Model([data1, data2], z)
    verify_keras_frontend(keras_model)


223 224 225 226 227 228 229 230 231 232
def test_forward_multi_outputs():
    data = keras.layers.Input(shape=(32,32,3))
    x = keras.layers.Conv2D(8, (3, 3), padding="same")(data)
    x = keras.layers.GlobalAveragePooling2D()(x)
    y = keras.layers.Conv2D(8, (3, 3), padding="same")(data)
    y = keras.layers.GlobalAveragePooling2D()(y)
    keras_model = keras.models.Model(data, [x, y])
    verify_keras_frontend(keras_model)


233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
def test_forward_reuse_layers():
    # reuse conv2d
    data = keras.layers.Input(shape=(32,32,3))
    conv2d = keras.layers.Conv2D(8, (3, 3), padding="same")
    x = conv2d(data)
    y = conv2d(data)
    z = keras.layers.add([x, y])
    z = keras.layers.GlobalAveragePooling2D()(z)
    keras_model = keras.models.Model(data, z)
    verify_keras_frontend(keras_model)

    # reuse add
    data = keras.layers.Input(shape=(32,32,3))
    x = keras.layers.Conv2D(8, (3, 3), padding="same")(data)
    add = keras.layers.Add()
    x = add([x, x])
    x = add([x, x])
    z = keras.layers.GlobalAveragePooling2D()(x)
    keras_model = keras.models.Model(data, z)
    verify_keras_frontend(keras_model)

254 255
def _test_LSTM(time_steps, inputs, hidden, return_state=True):
    data = keras.layers.Input(shape=(time_steps, inputs))
256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
    lstm_out = keras.layers.LSTM(hidden,
                                 return_state=return_state,
                                 recurrent_activation='sigmoid',
                                 activation='tanh')
    x = lstm_out(data)
    keras_model = keras.models.Model(data, x)
    verify_keras_frontend(keras_model, need_transpose=False)

def _test_LSTM_MultiLayer(inputs, hidden):
    inputs = keras.layers.Input(shape=(1, inputs))
    layer = keras.layers.LSTM(hidden, return_state=True, return_sequences=True,
                                 recurrent_activation='sigmoid',
                                 activation='tanh')
    outputs = layer(inputs)
    output, state = outputs[0], outputs[1:]
    output = keras.layers.LSTM(hidden, recurrent_activation='sigmoid',
                               activation='tanh')(output, initial_state=state)
    keras_model = keras.models.Model(inputs, output)
    verify_keras_frontend(keras_model, need_transpose=False)


def test_forward_LSTM():
278 279 280
    _test_LSTM(1, 8, 8, return_state=True)
    _test_LSTM(1, 4, 4, return_state=False)
    _test_LSTM(20, 16, 256, return_state=False)
281
    _test_LSTM_MultiLayer(4, 4)
282

283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334
def _test_RNN(inputs, units):
    data = keras.layers.Input(shape=(1, inputs))
    rnn_out = keras.layers.SimpleRNN(units, return_state=True,
                                 activation='tanh')
    x = rnn_out(data)
    keras_model = keras.models.Model(data, x)
    verify_keras_frontend(keras_model, need_transpose=False)

def _test_RNN_MultiLayer(inputs, units):
    inputs = keras.layers.Input(shape=(1, inputs))
    layer = keras.layers.SimpleRNN(units, return_state=True, return_sequences=True,
                                   activation='tanh')
    outputs = layer(inputs)
    output, state = outputs[0], outputs[1:]
    output = keras.layers.SimpleRNN(units, activation='tanh')(output, initial_state=state)
    keras_model = keras.models.Model(inputs, output)
    verify_keras_frontend(keras_model, need_transpose=False)

def test_forward_RNN():
    _test_RNN(2, 4)
    _test_RNN(4, 3)
    _test_RNN_MultiLayer(4, 12)

def _test_GRU(inputs, units):
    data = keras.layers.Input(shape=(1, inputs))
    gru_out = keras.layers.GRU(units,
                               return_state=True,
                               recurrent_activation='sigmoid',
                               activation='tanh')
    x = gru_out(data)
    keras_model = keras.models.Model(data, x)
    verify_keras_frontend(keras_model, need_transpose=False)

def _test_GRU_MultiLayer(inputs, units):
    inputs = keras.layers.Input(shape=(1, inputs))
    layer = keras.layers.GRU(units,
                             return_state=True,
                             return_sequences=True,
                             recurrent_activation='sigmoid',
                             activation='tanh')
    outputs = layer(inputs)
    output, state = outputs[0], outputs[1:]
    output = keras.layers.GRU(units, recurrent_activation='sigmoid',
                              activation='tanh')(output, initial_state=state)
    keras_model = keras.models.Model(inputs, output)
    verify_keras_frontend(keras_model, need_transpose=False)

def test_forward_GRU():
    _test_GRU(2, 4)
    _test_GRU(4, 3)
    _test_GRU_MultiLayer(4, 4)

Yuwei Hu committed
335
if __name__ == '__main__':
336
    test_forward_elemwise_add()
337
    test_forward_activations()
338
    test_forward_dense()
339
    test_forward_pool()
340
    test_forward_conv()
341
    test_forward_upsample()
342
    test_forward_reshape()
343
    test_forward_crop()
344 345 346
    test_forward_vgg16()
    test_forward_xception()
    test_forward_resnet50()
347
    test_forward_mobilenet()
348 349

    test_forward_multi_inputs()
350
    test_forward_multi_outputs()
351
    test_forward_reuse_layers()
352
    test_forward_LSTM()
353 354
    test_forward_RNN()
    test_forward_GRU()