deeplab2 / model /layers /convolutions_test.py
akhaliq3
spaces demo
506da10
# coding=utf-8
# Copyright 2021 The Deeplab2 Authors.
#
# Licensed 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.
"""Tests for convolutions."""
import numpy as np
import tensorflow as tf
from deeplab2.model.layers import convolutions
from deeplab2.utils import test_utils
class ConvolutionsTest(tf.test.TestCase):
def test_conv2dsame_logging(self):
with self.assertLogs(level='WARN'):
_ = convolutions.Conv2DSame(
output_channels=1,
kernel_size=8,
strides=2,
name='conv',
use_bn=False,
activation=None)
def test_conv2dsame_conv(self):
conv = convolutions.Conv2DSame(
output_channels=1,
kernel_size=1,
name='conv',
use_bn=False,
activation=None)
input_tensor = tf.random.uniform(shape=(2, 180, 180, 5))
predicted_tensor = conv(input_tensor)
expected_tensor = np.dot(input_tensor.numpy(),
conv._conv.get_weights()[0])[..., 0, 0]
# Compare only up to 5 decimal digits to account for numerical accuracy.
np.testing.assert_almost_equal(
predicted_tensor.numpy(), expected_tensor, decimal=5)
def test_conv2dsame_relu(self):
conv = convolutions.Conv2DSame(
output_channels=1,
kernel_size=1,
name='conv',
activation='relu',
use_bn=False)
input_tensor = tf.random.uniform(shape=(2, 180, 180, 5))
predicted_tensor = conv(input_tensor)
expected_tensor = np.dot(input_tensor.numpy(),
conv._conv.get_weights()[0])[..., 0, 0]
expected_tensor[expected_tensor < 0.0] = 0.0
# Compare only up to 5 decimal digits to account for numerical accuracy.
np.testing.assert_almost_equal(
predicted_tensor.numpy(), expected_tensor, decimal=5)
def test_conv2dsame_relu6(self):
conv = convolutions.Conv2DSame(
output_channels=1,
kernel_size=1,
name='conv',
activation='relu6',
use_bn=False)
input_tensor = tf.random.uniform(shape=(2, 180, 180, 5)) * 10.
predicted_tensor = conv(input_tensor)
expected_tensor = np.dot(input_tensor.numpy(),
conv._conv.get_weights()[0])[..., 0, 0]
expected_tensor[expected_tensor < 0.0] = 0.0
expected_tensor[expected_tensor > 6.0] = 6.0
# Compare only up to 5 decimal digits to account for numerical accuracy.
np.testing.assert_almost_equal(
predicted_tensor.numpy(), expected_tensor, decimal=5)
def test_conv2dsame_shape(self):
conv = convolutions.Conv2DSame(
output_channels=64,
kernel_size=7,
strides=2,
name='conv',
use_bias=False,
use_bn=True)
input_tensor = tf.random.uniform(shape=(2, 180, 180, 3))
predicted_tensor = conv(input_tensor)
expected_shape = [2, 90, 90, 64]
self.assertListEqual(predicted_tensor.shape.as_list(), expected_shape)
@test_utils.test_all_strategies
def test_conv2d_sync_bn(self, strategy):
input_tensor = tf.random.uniform(shape=(2, 180, 180, 3))
for bn_layer in test_utils.NORMALIZATION_LAYERS:
with strategy.scope():
conv = convolutions.Conv2DSame(
output_channels=64,
kernel_size=7,
strides=2,
name='conv',
use_bias=False,
use_bn=True,
bn_layer=bn_layer)
conv(input_tensor)
def test_depthwise_conv(self):
conv = convolutions.DepthwiseConv2DSame(
kernel_size=1, use_bn=False, use_bias=True, activation=None,
name='conv')
input_tensor = tf.random.uniform(shape=(2, 180, 180, 5))
predicted_tensor = conv(input_tensor)
expected_tensor = (
input_tensor.numpy() * conv._depthwise_conv.get_weights()[0][..., 0])
np.testing.assert_equal(predicted_tensor.numpy(), expected_tensor)
def test_depthwise_relu(self):
conv = convolutions.DepthwiseConv2DSame(
kernel_size=1, use_bn=False, activation='relu', name='conv')
input_tensor = tf.random.uniform(shape=(2, 180, 180, 5))
predicted_tensor = conv(input_tensor)
expected_tensor = (
input_tensor.numpy() * conv._depthwise_conv.get_weights()[0][..., 0])
expected_tensor[expected_tensor < 0.0] = 0.0
np.testing.assert_equal(predicted_tensor.numpy(), expected_tensor)
def test_depthwise_shape(self):
conv = convolutions.DepthwiseConv2DSame(
kernel_size=3, use_bn=True, use_bias=False, activation='relu',
name='conv')
input_shape = [2, 180, 180, 5]
input_tensor = tf.random.uniform(shape=input_shape)
predicted_tensor = conv(input_tensor)
expected_shape = input_shape
self.assertListEqual(predicted_tensor.shape.as_list(), expected_shape)
def test_depthwise_shape_with_stride2(self):
conv = convolutions.DepthwiseConv2DSame(
kernel_size=3, use_bn=True, use_bias=False, activation='relu',
strides=2, name='conv')
input_shape = [2, 181, 181, 5]
input_tensor = tf.random.uniform(shape=input_shape)
predicted_tensor = conv(input_tensor)
expected_shape = [2, 91, 91, 5]
self.assertListEqual(predicted_tensor.shape.as_list(), expected_shape)
@test_utils.test_all_strategies
def test_depthwise_sync_bn(self, strategy):
input_tensor = tf.random.uniform(shape=(2, 180, 180, 3))
for bn_layer in test_utils.NORMALIZATION_LAYERS:
with strategy.scope():
conv = convolutions.DepthwiseConv2DSame(
kernel_size=7,
name='conv',
use_bn=True,
use_bias=False,
bn_layer=bn_layer,
activation='relu')
_ = conv(input_tensor)
def test_global_context(self):
input_tensor = tf.random.uniform(shape=(2, 180, 180, 3))
global_context = convolutions.GlobalContext(name='global_context')
output_tensor = global_context(input_tensor)
# global_context is supposed to not change any values before training.
np.testing.assert_array_almost_equal(input_tensor.numpy(),
output_tensor.numpy())
def test_switchable_atrous_conv_class(self):
# Tests Switchable Atrous Convolution by equations.
input_tensor = tf.random.uniform(shape=(3, 180, 180, 32))
sac_layer = convolutions.SwitchableAtrousConvolution(
64,
kernel_size=3,
padding='same',
name='sac_conv')
switch_conv = sac_layer._switch
_ = switch_conv(input_tensor)
switch_conv.kernel = tf.random.uniform(
switch_conv.kernel.shape,
minval=-1,
maxval=1,
dtype=switch_conv.kernel.dtype)
switch_conv.bias = tf.random.uniform(
switch_conv.bias.shape,
minval=-1,
maxval=1,
dtype=switch_conv.bias.dtype)
small_conv = tf.keras.layers.Conv2D(
64,
kernel_size=3,
padding='same',
dilation_rate=1,
name='small_conv')
large_conv = tf.keras.layers.Conv2D(
64,
kernel_size=3,
padding='same',
dilation_rate=3,
name='large_conv')
_ = small_conv(input_tensor)
_ = large_conv(input_tensor)
outputs = sac_layer(input_tensor)
small_conv.kernel = sac_layer.kernel
large_conv.kernel = sac_layer.kernel
# Compute the expected outputs.
switch_outputs = sac_layer._switch(sac_layer._average_pool(input_tensor))
large_outputs = large_conv(input_tensor)
small_outputs = small_conv(input_tensor)
expected_outputs = (switch_outputs * large_outputs +
(1 - switch_outputs) * small_outputs)
np.testing.assert_array_almost_equal(expected_outputs.numpy(),
outputs.numpy())
def test_switchable_atrous_conv_in_conv2dsame(self):
# Tests Switchable Atrous Convolution in Conv2DSame.
input_tensor = tf.random.uniform(shape=(3, 180, 180, 32))
layer = convolutions.Conv2DSame(
output_channels=64,
kernel_size=7,
strides=1,
name='conv',
use_bias=False,
use_bn=True,
use_switchable_atrous_conv=True,
use_global_context_in_sac=True)
output_tensor = layer(input_tensor)
np.testing.assert_array_almost_equal(output_tensor.shape.as_list(),
[3, 180, 180, 64])
def test_conv1d_shape(self):
conv = convolutions.Conv1D(
output_channels=64,
name='conv',
use_bias=False,
use_bn=True)
input_tensor = tf.random.uniform(shape=(2, 180, 3))
predicted_tensor = conv(input_tensor)
expected_shape = [2, 180, 64]
self.assertListEqual(predicted_tensor.shape.as_list(), expected_shape)
def test_separable_conv2d_same_output_shape(self):
conv = convolutions.SeparableConv2DSame(
output_channels=64,
kernel_size=3,
name='conv')
input_tensor = tf.random.uniform(shape=(2, 5, 5, 3))
predicted_tensor = conv(input_tensor)
expected_shape = [2, 5, 5, 64]
self.assertListEqual(predicted_tensor.shape.as_list(), expected_shape)
def test_stacked_conv2d_same_output_shape(self):
conv = convolutions.StackedConv2DSame(
num_layers=2,
conv_type='depthwise_separable_conv',
output_channels=64,
kernel_size=3,
name='conv')
input_tensor = tf.random.uniform(shape=(2, 5, 5, 3))
predicted_tensor = conv(input_tensor)
expected_shape = [2, 5, 5, 64]
self.assertListEqual(predicted_tensor.shape.as_list(), expected_shape)
if __name__ == '__main__':
tf.test.main()