[NNabla] How to add a quantization layer to the middle layer of a trained model

Introduction

This is the 4th post to qiita. (article4) Continuing from last time, while I was using nnabla, I managed to feel like "I wish I had this kind of information in qiita" Summary of what I found in nnabla reference and dir () (a standard python function that returns member variables and functions of arguments) I will.

1. Requirements

· OS: macOS Catalina (version 10.15.1) ・ Python: 3.5.4 ・ Nnabla: 1.3.0

2. Prepare the trained network

This time, from Nnabla trained model, use MobileNet_v1 as follows.

article4_add_quantization_for_network.py


import nnabla as nn
import nnabla.functions as F
import nnabla.parametric_functions as PF
from nnabla.models.imagenet import MobileNet

if __name__ == "__main__":
    # [load network]
    mobilenet = MobileNet()
    nnp = mobilenet.nnp
    net = nnp.get_network('Runtime', batch_size=1)
    y =  net.outputs['y\'']

Commentary

3. Add a quantization layer to the trained model

Add a quantization layer to each activation, pooling, and affine (identification output) of mobilenet_v1 obtained above. The actual code is below.

article4_add_quantization_for_network.py


class AddQuantizeLayer:
    def __init__(self, _net):
        self.net = _net

    def add_quantize_layer_all(self):
        # [quantize]
        count = 0
        for key in self.net.variables:
            var = self.net.variables[key]
            func = var.parent
            if type(func) != type(None):
                if func.info.type_name in ['ReLU', 'AveragePooling', 'Affine']:
                    count = self.add_quantize_layer_one(var, count)

    def add_quantize_layer_one(self, _var, _count):
        var_out_cur = _var.function_references[0].outputs[0]
        # [quantize]
        q_out = PF.min_max_quantize(_var, ql_min=0, ql_max=255, x_min_max=True, name='MinMaxQuantize_{}'.format(_count))
        # [redefine function]
        var_out_new = self.redefine_layer(var_out_cur.parent, q_out)
        var_out_cur.rewire_on(var_out_new)
        return _count + 1

    @staticmethod
    def redefine_layer(_func, _input):
        if _func.info.type_name == 'DepthwiseConvolution':
            return F.depthwise_convolution(_input, *_func.inputs[1:], **_func.info.args)
        elif _func.info.type_name == 'Convolution':
            return F.convolution(_input, *_func.inputs[1:], **_func.info.args)
        elif _func.info.type_name == 'AveragePooling':
            return F.average_pooling(_input, **_func.info.args)
        elif _func.info.type_name == 'Affine':
            return F.affine(_input, *_func.inputs[1:], **_func.info.args)
        elif _func.info.type_name == 'Softmax':
            return F.softmax(_input, **_func.info.args)
        else:
            print('[error] redefine_layer()')
            print('_func is unexpected layer.')
            print('_func.info.type_name = {}'.format(_func.info.type_name))
            exit(0)

# [quantize]
AddQuantizeLayer_class = AddQuantizeLayer(net)
AddQuantizeLayer_class.add_quantize_layer_all()

The operation check was done below.

article4_add_quantization_for_network.py


def print_func(f):
    print('{}'.format(f.name))

print('----- before -----')
y.visit(print_func)
print('')

# [quantize]
AddQuantizeLayer_class = AddQuantizeLayer(net)
AddQuantizeLayer_class.add_quantize_layer_all()

print('----- after -----')
y.visit(print_func)
print('')

Since the output is long, some parts will be omitted, but it will be in the following form. As a change, MinMaxQuantize (quantization layer) is added after ReLU, ʻAveragePooling, and ʻAffine.

----- before -----
ImageAugmentation
MulScalar
AddScalar
Convolution
BatchNormalization
ReLU
DepthwiseConvolution
BatchNormalization
ReLU
Convolution
...(The following is omitted)...

----- after -----
ImageAugmentation
MulScalar
AddScalar
Convolution
BatchNormalization
ReLU
MinMaxQuantize
DepthwiseConvolution
BatchNormalization
ReLU
MinMaxQuantize
Convolution
...(The following is omitted)...

Commentary

4. Summary

Using the content posted up to Last time, I introduced how to add a quantization layer to an existing network. It is undecided what to post next time.

Recommended Posts

[NNabla] How to add a quantization layer to the middle layer of a trained model
[NNabla] How to add a new layer between the middle layers of a pre-built network
[NNabla] How to get the output (variable) of the middle layer of a pre-built network
[NNabla] How to remove the middle tier of a pre-built network
How to calculate the volatility of a brand
How to visualize the decision tree model of scikit-learn
[Ubuntu] How to delete the entire contents of a directory
I made a function to check the model of DCGAN
How to find the scaling factor of a biorthogonal wavelet
How to connect the contents of a list into a string
How to determine the existence of a selenium element in Python
How to check the memory size of a variable in Python
How to check the memory size of a dictionary in Python
How to find the memory address of a Pandas dataframe value
How to output the output result of the Linux man command to a file
How to get the vertex coordinates of a feature in ArcPy
How to take a screenshot of the Chrome screen (prevent it from cutting off in the middle)
Learn the flow of Bayesian estimation and how to use Pystan through a simple regression model
How to add a package with PyCharm
How to check the version of Django
Get the value of the middle layer of NN
Add a layer using the Keras backend
[Introduction to Python] How to sort the contents of a list efficiently with list sort
How to put a line number at the beginning of a CSV file
How to create a wrapper that preserves the signature of the function to wrap
How to play a video while watching the number of frames (Mac)
How to pass the execution result of a shell command in a list in Python
A simple example of how to use ArgumentParser
How to find the area of the Voronoi diagram
How to mention a user group in slack notification, how to check the id of the user group
How to get the "name" of a field whose value is limited by the choice attribute in Django's model
Visualize the inner layer of a neural network
We have released a trained model of fastText
To output a value even in the middle of a cell with Jupyter Notebook
How to count the number of elements in Django and output to a template
How to access the contents of a Linux disk on a Mac (but read-only)
[python] How to sort by the Nth Mth element of a multidimensional array
How to add a Python module search path
A memorandum of how to execute the! Sudo magic command in Jupyter Notebook
I want to add silence to the beginning of a wav file for 1 second
[Numpy, scipy] How to calculate the square root of a semi-fixed definite matrix
How to make a Raspberry Pi that speaks the tweets of the specified user
[PyTorch] Sample ⑧ ~ How to build a complex model ~
[Wagtail] Add a login page to the Wagtail project
How to get a list of files in the same directory with python
I tried to create a model with the sample of Amazon SageMaker Autopilot
[Introduction to Python] How to get the index of data with a for statement
I tried to make something like a chatbot with the Seq2Seq model of TensorFlow
How to display the modification date of a file in C language up to nanoseconds
How to identify the element with the smallest number of characters in a Python list?
[Ruby] How to replace only a part of the string matched by the regular expression?
How to check in Python if one of the elements of a list is in another list
The world's most easy-to-understand explanation of how to make a LINE BOT (1) [Account preparation]
A memo on how to overcome the difficult problem of capturing FX with AI
A story about trying to introduce Linter in the middle of a Python (Flask) project
How to change the generated image of GAN to a high quality one to your liking
Add a function to tell the weather of today to slack bot (made by python)
Read the Python-Markdown source: How to create a parser
How to know the port number of the xinetd service
How to write a GUI using the maya command
How to get the number of digits in Python