"""Translates the cmrnorm layer.""" from decaf.util.translator import registerer from decaf.layers import core_layers def translator_cmrnorm(cuda_layer, output_shapes): """Translates the cmrnorm layer. Note: we hard-code the constant in the local response normalization layer to be 1. This may be different from Krizhevsky's NIPS paper but matches the actual cuda convnet code. """ input_shape = output_shapes[cuda_layer['inputLayers'][0]['name']] output_shapes[cuda_layer['name']] = input_shape return core_layers.LocalResponseNormalizeLayer( name=cuda_layer['name'], size=cuda_layer['size'], k=1, alpha = cuda_layer['scale'] * cuda_layer['size'], beta = cuda_layer['pow']) registerer.register_translator('cmrnorm', translator_cmrnorm)
# We should return a simple convolution layer decaf_layer = core_layers.ConvolutionLayer( name=cuda_layer['name'], num_kernels=num_kernels, ksize=ksize, stride=stride, pad=pad) param = decaf_layer.param() param[0].mirror(converted_weight) param[1].mirror(bias) else: # We should return a grouped convolution layer num_divided_kernels = num_kernels / group decaf_layer = core_layers.GroupConvolutionLayer( name=cuda_layer['name'], num_kernels=num_divided_kernels, ksize=ksize, stride=stride, pad=pad, group=group) param = decaf_layer.param() curr = 0 for i in range(0, group * 2, 2): param[i].mirror( converted_weight[:, curr:curr+num_divided_kernels].copy()) param[i+1].mirror(bias[curr:curr+num_divided_kernels]) curr += num_divided_kernels return decaf_layer registerer.register_translator('conv', translator_conv)
"""Translates the neuron layers.""" from decaf.util.translator import registerer from decaf.layers import core_layers import logging def translator_neuron(cuda_layer, output_shapes): """Translates the neuron layers. Note: not all neuron layers are supported. We only implemented those that are needed for imagenet. """ output_shapes[cuda_layer['name']] = \ output_shapes[cuda_layer['inputLayers'][0]['name']] neurontype = cuda_layer['neuron']['type'] if neurontype == 'relu': return core_layers.ReLULayer( name=cuda_layer['name']) elif neurontype == 'dropout': return core_layers.DropoutLayer( name=cuda_layer['name'], ratio=cuda_layer['neuron']['params']['d']) else: raise NotImplementedError('Neuron type %s not implemented yet.' % neurontype) registerer.register_translator('neuron', translator_neuron)
"""Translates the softmax layers.""" from decaf.util.translator import registerer from decaf.layers import core_layers def translator_softmax(cuda_layer, output_shapes): """Translates the softmax layers.""" input_shape = output_shapes[cuda_layer['inputLayers'][0]['name']] output_shapes[cuda_layer['name']] = input_shape return core_layers.SoftmaxLayer( name=cuda_layer['name']) registerer.register_translator('softmax', translator_softmax)
"""Translates the cmrnorm layer.""" from decaf.util.translator import registerer from decaf.layers import core_layers def translator_cmrnorm(cuda_layer, output_shapes): """Translates the cmrnorm layer. Note: we hard-code the constant in the local response normalization layer to be 1. This may be different from Krizhevsky's NIPS paper but matches the actual cuda convnet code. """ input_shape = output_shapes[cuda_layer['inputLayers'][0]['name']] output_shapes[cuda_layer['name']] = input_shape return core_layers.LocalResponseNormalizeLayer(name=cuda_layer['name'], size=cuda_layer['size'], k=1, alpha=cuda_layer['scale'] * cuda_layer['size'], beta=cuda_layer['pow']) registerer.register_translator('cmrnorm', translator_cmrnorm)
# We should return a simple convolution layer decaf_layer = core_layers.ConvolutionLayer(name=cuda_layer['name'], num_kernels=num_kernels, ksize=ksize, stride=stride, pad=pad) param = decaf_layer.param() param[0].mirror(converted_weight) param[1].mirror(bias) else: # We should return a grouped convolution layer num_divided_kernels = num_kernels / group decaf_layer = core_layers.GroupConvolutionLayer( name=cuda_layer['name'], num_kernels=num_divided_kernels, ksize=ksize, stride=stride, pad=pad, group=group) param = decaf_layer.param() curr = 0 for i in range(0, group * 2, 2): param[i].mirror(converted_weight[:, curr:curr + num_divided_kernels].copy()) param[i + 1].mirror(bias[curr:curr + num_divided_kernels]) curr += num_divided_kernels return decaf_layer registerer.register_translator('conv', translator_conv)
if method == 'max': pass elif method == 'avg': # We have a slightly different name method = 'ave' else: raise NotImplementedError('Unrecognized pooling method: %s' % method) if cuda_layer['start'] != 0: raise NotImplementedError('Unsupported layer with a non-zero start.') # Check the outputsX size. output_size = math.ceil( float(cuda_layer['imgSize'] - cuda_layer['sizeX']) / cuda_layer['stride']) + 1 if cuda_layer['outputsX'] != output_size: raise NotImplementedError('Unsupported layer with custon output size.') # If all checks passed, we will return our pooling layer psize = cuda_layer['sizeX'] stride = cuda_layer['stride'] input_shape = output_shapes[cuda_layer['inputLayers'][0]['name']] output_shape = (int(math.ceil(float(input_shape[0] - psize) / stride)) + 1, int(math.ceil(float(input_shape[1] - psize) / stride)) + 1, input_shape[2]) output_shapes[cuda_layer['name']] = output_shape return core_layers.PoolingLayer(name=cuda_layer['name'], psize=psize, stride=stride, mode=method) registerer.register_translator('pool', translator_pool)
# put the parameters params = decaf_layer.param() # weight weight = cuda_layer['weights'][0] if weight.shape[0] != input_size or weight.shape[1] != num_output: raise ValueError('Incorrect shapes: weight shape %s, input shape %s,' ' num_output %d' % (weight.shape, input_shape, num_output)) if len(input_shape) == 3: # The original input is an image, so we will need to reshape it weight = weight.reshape( (input_shape[2], input_shape[0], input_shape[1], num_output)) converted_weight = np.empty(input_shape + (num_output,), weight.dtype) for i in range(input_shape[2]): converted_weight[:, :, i, :] = weight[i, :, :, :] converted_weight.resize(input_size, num_output) else: converted_weight = weight params[0].mirror(converted_weight) bias = cuda_layer['biases'][0] params[1].mirror(bias) if len(input_shape) == 1: return decaf_layer else: # If the input is not a vector, we need to have a flatten layer first. return [core_layers.FlattenLayer(name=cuda_layer['name'] + '_flatten'), decaf_layer] registerer.register_translator('fc', translator_fc)
elif method == 'avg': # We have a slightly different name method = 'ave' else: raise NotImplementedError('Unrecognized pooling method: %s' % method) if cuda_layer['start'] != 0: raise NotImplementedError('Unsupported layer with a non-zero start.') # Check the outputsX size. output_size = math.ceil( float(cuda_layer['imgSize'] - cuda_layer['sizeX']) / cuda_layer['stride']) + 1 if cuda_layer['outputsX'] != output_size: raise NotImplementedError('Unsupported layer with custon output size.') # If all checks passed, we will return our pooling layer psize = cuda_layer['sizeX'] stride = cuda_layer['stride'] input_shape = output_shapes[cuda_layer['inputLayers'][0]['name']] output_shape = ( int(math.ceil(float(input_shape[0] - psize) / stride)) + 1, int(math.ceil(float(input_shape[1] - psize) / stride)) + 1, input_shape[2]) output_shapes[cuda_layer['name']] = output_shape return core_layers.PoolingLayer( name=cuda_layer['name'], psize=psize, stride=stride, mode=method) registerer.register_translator('pool', translator_pool)
"""Translates the softmax layers.""" from decaf.util.translator import registerer from decaf.layers import core_layers def translator_softmax(cuda_layer, output_shapes): """Translates the softmax layers.""" input_shape = output_shapes[cuda_layer['inputLayers'][0]['name']] output_shapes[cuda_layer['name']] = input_shape return core_layers.SoftmaxLayer(name=cuda_layer['name']) registerer.register_translator('softmax', translator_softmax)