merge master

This commit is contained in:
ly119399
2022-06-12 14:55:32 +08:00
184 changed files with 5726 additions and 734 deletions

View File

@@ -4,5 +4,5 @@ rm -rf build
# update api rst
#rm -rf source/api/
#sphinx-apidoc --module-first -o source/api/ ../maas_lib/
#sphinx-apidoc --module-first -o source/api/ ../modelscope/
make html

View File

@@ -1,3 +1,3 @@
yapf -r -i maas_lib/ configs/ tests/ setup.py
isort -rc maas_lib/ configs/ tests/ setup.py
flake8 maas_lib/ configs/ tests/ setup.py
yapf -r -i modelscope/ configs/ tests/ setup.py
isort -rc modelscope/ configs/ tests/ setup.py
flake8 modelscope/ configs/ tests/ setup.py

View File

@@ -1,4 +1,4 @@
Copyright 2022-2023 Alibaba MaaS. All rights reserved.
Copyright 2022-2023 Alibaba ModelScope. All rights reserved.
Apache License
Version 2.0, January 2004
@@ -188,7 +188,7 @@ Copyright 2022-2023 Alibaba MaaS. All rights reserved.
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2020-2022 Alibaba MaaS.
Copyright 2020-2022 Alibaba ModelScope.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -1 +1 @@
recursive-include maas_lib/configs *.py
recursive-include modelscope/configs *.py

View File

@@ -1,6 +1,6 @@
# Introduction
MaaS library is targeted to support training, evaluation and inference for the state of the art models provided by Mind and further support third-party models provided by users outside alibaba.
ModelScope library is targeted to support training, evaluation and inference for the state of the art models provided by Mind and further support third-party models provided by users outside alibaba.
# Design doc

View File

@@ -1 +1 @@
This folder will host example configs for each model supported by maas_lib.
This folder will host example configs for each model supported by modelscope.

View File

@@ -1,34 +0,0 @@
maas\_lib.fileio.format package
===============================
.. automodule:: maas_lib.fileio.format
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
maas\_lib.fileio.format.base module
-----------------------------------
.. automodule:: maas_lib.fileio.format.base
:members:
:undoc-members:
:show-inheritance:
maas\_lib.fileio.format.json module
-----------------------------------
.. automodule:: maas_lib.fileio.format.json
:members:
:undoc-members:
:show-inheritance:
maas\_lib.fileio.format.yaml module
-----------------------------------
.. automodule:: maas_lib.fileio.format.yaml
:members:
:undoc-members:
:show-inheritance:

View File

@@ -1,34 +0,0 @@
maas\_lib.fileio package
========================
.. automodule:: maas_lib.fileio
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
:maxdepth: 4
maas_lib.fileio.format
Submodules
----------
maas\_lib.fileio.file module
----------------------------
.. automodule:: maas_lib.fileio.file
:members:
:undoc-members:
:show-inheritance:
maas\_lib.fileio.io module
--------------------------
.. automodule:: maas_lib.fileio.io
:members:
:undoc-members:
:show-inheritance:

View File

@@ -1,18 +0,0 @@
maas\_lib.models.nlp package
============================
.. automodule:: maas_lib.models.nlp
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
maas\_lib.models.nlp.sequence\_classification\_model module
-----------------------------------------------------------
.. automodule:: maas_lib.models.nlp.sequence_classification_model
:members:
:undoc-members:
:show-inheritance:

View File

@@ -1,34 +0,0 @@
maas\_lib.models package
========================
.. automodule:: maas_lib.models
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
:maxdepth: 4
maas_lib.models.nlp
Submodules
----------
maas\_lib.models.base module
----------------------------
.. automodule:: maas_lib.models.base
:members:
:undoc-members:
:show-inheritance:
maas\_lib.models.builder module
-------------------------------
.. automodule:: maas_lib.models.builder
:members:
:undoc-members:
:show-inheritance:

View File

@@ -1,7 +0,0 @@
maas\_lib.pipelines.audio package
=================================
.. automodule:: maas_lib.pipelines.audio
:members:
:undoc-members:
:show-inheritance:

View File

@@ -1,18 +0,0 @@
maas\_lib.pipelines.cv package
==============================
.. automodule:: maas_lib.pipelines.cv
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
maas\_lib.pipelines.cv.image\_matting module
--------------------------------------------
.. automodule:: maas_lib.pipelines.cv.image_matting
:members:
:undoc-members:
:show-inheritance:

View File

@@ -1,7 +0,0 @@
maas\_lib.pipelines.multi\_modal package
========================================
.. automodule:: maas_lib.pipelines.multi_modal
:members:
:undoc-members:
:show-inheritance:

View File

@@ -1,50 +0,0 @@
maas\_lib.preprocessors package
===============================
.. automodule:: maas_lib.preprocessors
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
maas\_lib.preprocessors.base module
-----------------------------------
.. automodule:: maas_lib.preprocessors.base
:members:
:undoc-members:
:show-inheritance:
maas\_lib.preprocessors.builder module
--------------------------------------
.. automodule:: maas_lib.preprocessors.builder
:members:
:undoc-members:
:show-inheritance:
maas\_lib.preprocessors.common module
-------------------------------------
.. automodule:: maas_lib.preprocessors.common
:members:
:undoc-members:
:show-inheritance:
maas\_lib.preprocessors.image module
------------------------------------
.. automodule:: maas_lib.preprocessors.image
:members:
:undoc-members:
:show-inheritance:
maas\_lib.preprocessors.nlp module
----------------------------------
.. automodule:: maas_lib.preprocessors.nlp
:members:
:undoc-members:
:show-inheritance:

View File

@@ -1,30 +0,0 @@
maas\_lib package
=================
.. automodule:: maas_lib
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
:maxdepth: 4
maas_lib.fileio
maas_lib.models
maas_lib.pipelines
maas_lib.preprocessors
maas_lib.utils
Submodules
----------
maas\_lib.version module
------------------------
.. automodule:: maas_lib.version
:members:
:undoc-members:
:show-inheritance:

View File

@@ -1,18 +0,0 @@
maas\_lib.trainers.nlp package
==============================
.. automodule:: maas_lib.trainers.nlp
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
maas\_lib.trainers.nlp.sequence\_classification\_trainer module
---------------------------------------------------------------
.. automodule:: maas_lib.trainers.nlp.sequence_classification_trainer
:members:
:undoc-members:
:show-inheritance:

View File

@@ -1,34 +0,0 @@
maas\_lib.trainers package
==========================
.. automodule:: maas_lib.trainers
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
:maxdepth: 4
maas_lib.trainers.nlp
Submodules
----------
maas\_lib.trainers.base module
------------------------------
.. automodule:: maas_lib.trainers.base
:members:
:undoc-members:
:show-inheritance:
maas\_lib.trainers.builder module
---------------------------------
.. automodule:: maas_lib.trainers.builder
:members:
:undoc-members:
:show-inheritance:

View File

@@ -1,58 +0,0 @@
maas\_lib.utils package
=======================
.. automodule:: maas_lib.utils
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
maas\_lib.utils.config module
-----------------------------
.. automodule:: maas_lib.utils.config
:members:
:undoc-members:
:show-inheritance:
maas\_lib.utils.constant module
-------------------------------
.. automodule:: maas_lib.utils.constant
:members:
:undoc-members:
:show-inheritance:
maas\_lib.utils.logger module
-----------------------------
.. automodule:: maas_lib.utils.logger
:members:
:undoc-members:
:show-inheritance:
maas\_lib.utils.pymod module
----------------------------
.. automodule:: maas_lib.utils.pymod
:members:
:undoc-members:
:show-inheritance:
maas\_lib.utils.registry module
-------------------------------
.. automodule:: maas_lib.utils.registry
:members:
:undoc-members:
:show-inheritance:
maas\_lib.utils.type\_assert module
-----------------------------------
.. automodule:: maas_lib.utils.type_assert
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,34 @@
modelscope.fileio.format package
================================
.. automodule:: modelscope.fileio.format
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
modelscope.fileio.format.base module
------------------------------------
.. automodule:: modelscope.fileio.format.base
:members:
:undoc-members:
:show-inheritance:
modelscope.fileio.format.json module
------------------------------------
.. automodule:: modelscope.fileio.format.json
:members:
:undoc-members:
:show-inheritance:
modelscope.fileio.format.yaml module
------------------------------------
.. automodule:: modelscope.fileio.format.yaml
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,34 @@
modelscope.fileio package
=========================
.. automodule:: modelscope.fileio
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
:maxdepth: 4
modelscope.fileio.format
Submodules
----------
modelscope.fileio.file module
-----------------------------
.. automodule:: modelscope.fileio.file
:members:
:undoc-members:
:show-inheritance:
modelscope.fileio.io module
---------------------------
.. automodule:: modelscope.fileio.io
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,18 @@
modelscope.models.cv.cartoon.facelib.LK package
===============================================
.. automodule:: modelscope.models.cv.cartoon.facelib.LK
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
modelscope.models.cv.cartoon.facelib.LK.lk module
-------------------------------------------------
.. automodule:: modelscope.models.cv.cartoon.facelib.LK.lk
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,50 @@
modelscope.models.cv.cartoon.facelib package
============================================
.. automodule:: modelscope.models.cv.cartoon.facelib
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
:maxdepth: 4
modelscope.models.cv.cartoon.facelib.LK
Submodules
----------
modelscope.models.cv.cartoon.facelib.config module
--------------------------------------------------
.. automodule:: modelscope.models.cv.cartoon.facelib.config
:members:
:undoc-members:
:show-inheritance:
modelscope.models.cv.cartoon.facelib.face\_detector module
----------------------------------------------------------
.. automodule:: modelscope.models.cv.cartoon.facelib.face_detector
:members:
:undoc-members:
:show-inheritance:
modelscope.models.cv.cartoon.facelib.face\_landmark module
----------------------------------------------------------
.. automodule:: modelscope.models.cv.cartoon.facelib.face_landmark
:members:
:undoc-members:
:show-inheritance:
modelscope.models.cv.cartoon.facelib.facer module
-------------------------------------------------
.. automodule:: modelscope.models.cv.cartoon.facelib.facer
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,15 @@
modelscope.models.cv.cartoon.mtcnn\_pytorch package
===================================================
.. automodule:: modelscope.models.cv.cartoon.mtcnn_pytorch
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
:maxdepth: 4
modelscope.models.cv.cartoon.mtcnn_pytorch.src

View File

@@ -0,0 +1,26 @@
modelscope.models.cv.cartoon.mtcnn\_pytorch.src package
=======================================================
.. automodule:: modelscope.models.cv.cartoon.mtcnn_pytorch.src
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
modelscope.models.cv.cartoon.mtcnn\_pytorch.src.align\_trans module
-------------------------------------------------------------------
.. automodule:: modelscope.models.cv.cartoon.mtcnn_pytorch.src.align_trans
:members:
:undoc-members:
:show-inheritance:
modelscope.models.cv.cartoon.mtcnn\_pytorch.src.matlab\_cp2tform module
-----------------------------------------------------------------------
.. automodule:: modelscope.models.cv.cartoon.mtcnn_pytorch.src.matlab_cp2tform
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,27 @@
modelscope.models.cv.cartoon package
====================================
.. automodule:: modelscope.models.cv.cartoon
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
:maxdepth: 4
modelscope.models.cv.cartoon.facelib
modelscope.models.cv.cartoon.mtcnn_pytorch
Submodules
----------
modelscope.models.cv.cartoon.utils module
-----------------------------------------
.. automodule:: modelscope.models.cv.cartoon.utils
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,15 @@
modelscope.models.cv package
============================
.. automodule:: modelscope.models.cv
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
:maxdepth: 4
modelscope.models.cv.cartoon

View File

@@ -0,0 +1,26 @@
modelscope.models.nlp package
=============================
.. automodule:: modelscope.models.nlp
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
modelscope.models.nlp.sequence\_classification\_model module
------------------------------------------------------------
.. automodule:: modelscope.models.nlp.sequence_classification_model
:members:
:undoc-members:
:show-inheritance:
modelscope.models.nlp.text\_generation\_model module
----------------------------------------------------
.. automodule:: modelscope.models.nlp.text_generation_model
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,35 @@
modelscope.models package
=========================
.. automodule:: modelscope.models
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
:maxdepth: 4
modelscope.models.cv
modelscope.models.nlp
Submodules
----------
modelscope.models.base module
-----------------------------
.. automodule:: modelscope.models.base
:members:
:undoc-members:
:show-inheritance:
modelscope.models.builder module
--------------------------------
.. automodule:: modelscope.models.builder
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,7 @@
modelscope.pipelines.audio package
==================================
.. automodule:: modelscope.pipelines.audio
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,26 @@
modelscope.pipelines.cv package
===============================
.. automodule:: modelscope.pipelines.cv
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
modelscope.pipelines.cv.image\_cartoon\_pipeline module
-------------------------------------------------------
.. automodule:: modelscope.pipelines.cv.image_cartoon_pipeline
:members:
:undoc-members:
:show-inheritance:
modelscope.pipelines.cv.image\_matting\_pipeline module
-------------------------------------------------------
.. automodule:: modelscope.pipelines.cv.image_matting_pipeline
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,18 @@
modelscope.pipelines.multi\_modal package
=========================================
.. automodule:: modelscope.pipelines.multi_modal
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
modelscope.pipelines.multi\_modal.image\_captioning module
----------------------------------------------------------
.. automodule:: modelscope.pipelines.multi_modal.image_captioning
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,26 @@
modelscope.pipelines.nlp package
================================
.. automodule:: modelscope.pipelines.nlp
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
modelscope.pipelines.nlp.sequence\_classification\_pipeline module
------------------------------------------------------------------
.. automodule:: modelscope.pipelines.nlp.sequence_classification_pipeline
:members:
:undoc-members:
:show-inheritance:
modelscope.pipelines.nlp.text\_generation\_pipeline module
----------------------------------------------------------
.. automodule:: modelscope.pipelines.nlp.text_generation_pipeline
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,53 @@
modelscope.pipelines package
============================
.. automodule:: modelscope.pipelines
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
:maxdepth: 4
modelscope.pipelines.audio
modelscope.pipelines.cv
modelscope.pipelines.multi_modal
modelscope.pipelines.nlp
Submodules
----------
modelscope.pipelines.base module
--------------------------------
.. automodule:: modelscope.pipelines.base
:members:
:undoc-members:
:show-inheritance:
modelscope.pipelines.builder module
-----------------------------------
.. automodule:: modelscope.pipelines.builder
:members:
:undoc-members:
:show-inheritance:
modelscope.pipelines.default module
-----------------------------------
.. automodule:: modelscope.pipelines.default
:members:
:undoc-members:
:show-inheritance:
modelscope.pipelines.util module
--------------------------------
.. automodule:: modelscope.pipelines.util
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,50 @@
modelscope.preprocessors package
================================
.. automodule:: modelscope.preprocessors
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
modelscope.preprocessors.base module
------------------------------------
.. automodule:: modelscope.preprocessors.base
:members:
:undoc-members:
:show-inheritance:
modelscope.preprocessors.builder module
---------------------------------------
.. automodule:: modelscope.preprocessors.builder
:members:
:undoc-members:
:show-inheritance:
modelscope.preprocessors.common module
--------------------------------------
.. automodule:: modelscope.preprocessors.common
:members:
:undoc-members:
:show-inheritance:
modelscope.preprocessors.image module
-------------------------------------
.. automodule:: modelscope.preprocessors.image
:members:
:undoc-members:
:show-inheritance:
modelscope.preprocessors.nlp module
-----------------------------------
.. automodule:: modelscope.preprocessors.nlp
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,18 @@
modelscope.pydatasets package
=============================
.. automodule:: modelscope.pydatasets
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
modelscope.pydatasets.py\_dataset module
----------------------------------------
.. automodule:: modelscope.pydatasets.py_dataset
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,32 @@
modelscope package
==================
.. automodule:: modelscope
:members:
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
:maxdepth: 4
modelscope.fileio
modelscope.models
modelscope.pipelines
modelscope.preprocessors
modelscope.pydatasets
modelscope.trainers
modelscope.utils
Submodules
----------
modelscope.version module
-------------------------
.. automodule:: modelscope.version
:members:
:undoc-members:
:show-inheritance:

View File

@@ -1,7 +1,7 @@
maas\_lib.pipelines.nlp package
modelscope.trainers.nlp package
===============================
.. automodule:: maas_lib.pipelines.nlp
.. automodule:: modelscope.trainers.nlp
:members:
:undoc-members:
:show-inheritance:
@@ -9,10 +9,10 @@ maas\_lib.pipelines.nlp package
Submodules
----------
maas\_lib.pipelines.nlp.sequence\_classification\_pipeline module
-----------------------------------------------------------------
modelscope.trainers.nlp.sequence\_classification\_trainer module
----------------------------------------------------------------
.. automodule:: maas_lib.pipelines.nlp.sequence_classification_pipeline
.. automodule:: modelscope.trainers.nlp.sequence_classification_trainer
:members:
:undoc-members:
:show-inheritance:

View File

@@ -1,7 +1,7 @@
maas\_lib.pipelines package
modelscope.trainers package
===========================
.. automodule:: maas_lib.pipelines
.. automodule:: modelscope.trainers
:members:
:undoc-members:
:show-inheritance:
@@ -12,25 +12,23 @@ Subpackages
.. toctree::
:maxdepth: 4
maas_lib.pipelines.cv
maas_lib.pipelines.multi_modal
maas_lib.pipelines.nlp
modelscope.trainers.nlp
Submodules
----------
maas\_lib.pipelines.base module
modelscope.trainers.base module
-------------------------------
.. automodule:: maas_lib.pipelines.base
.. automodule:: modelscope.trainers.base
:members:
:undoc-members:
:show-inheritance:
maas\_lib.pipelines.builder module
modelscope.trainers.builder module
----------------------------------
.. automodule:: maas_lib.pipelines.builder
.. automodule:: modelscope.trainers.builder
:members:
:undoc-members:
:show-inheritance:

View File

@@ -0,0 +1,66 @@
modelscope.utils package
========================
.. automodule:: modelscope.utils
:members:
:undoc-members:
:show-inheritance:
Submodules
----------
modelscope.utils.config module
------------------------------
.. automodule:: modelscope.utils.config
:members:
:undoc-members:
:show-inheritance:
modelscope.utils.constant module
--------------------------------
.. automodule:: modelscope.utils.constant
:members:
:undoc-members:
:show-inheritance:
modelscope.utils.hub module
---------------------------
.. automodule:: modelscope.utils.hub
:members:
:undoc-members:
:show-inheritance:
modelscope.utils.logger module
------------------------------
.. automodule:: modelscope.utils.logger
:members:
:undoc-members:
:show-inheritance:
modelscope.utils.pymod module
-----------------------------
.. automodule:: modelscope.utils.pymod
:members:
:undoc-members:
:show-inheritance:
modelscope.utils.registry module
--------------------------------
.. automodule:: modelscope.utils.registry
:members:
:undoc-members:
:show-inheritance:
modelscope.utils.type\_assert module
------------------------------------
.. automodule:: modelscope.utils.type_assert
:members:
:undoc-members:
:show-inheritance:

View File

@@ -1,7 +1,7 @@
maas_lib
========
modelscope
==========
.. toctree::
:maxdepth: 4
maas_lib
modelscope

View File

@@ -18,10 +18,10 @@ import sphinx_rtd_theme
sys.path.insert(0, os.path.abspath('../../'))
# -- Project information -----------------------------------------------------
project = 'maas_lib'
copyright = '2022-2023, Alibaba MaaS'
author = 'maas_lib Authors'
version_file = '../../maas_lib/version.py'
project = 'modelscope'
copyright = '2022-2023, Alibaba ModelScope'
author = 'modelscope Authors'
version_file = '../../modelscope/version.py'
def get_version():
@@ -88,7 +88,7 @@ html_static_path = ['_static']
# -- Options for HTMLHelp output ---------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'maas_lib_doc'
htmlhelp_basename = 'modelscope_doc'
# -- Extension configuration -------------------------------------------------
# Ignore >>> when copying code

View File

@@ -10,39 +10,86 @@ We use the following toolsseed isortseed isortseed isort for linting and formatt
Style configurations of yapf and isort can be found in [setup.cfg](../../setup.cfg).
We use [pre-commit hook](https://pre-commit.com/) that checks and formats for `flake8`, `yapf`, `seed-isort-config`, `isort`, `trailing whitespaces`,
fixes `end-of-files`, sorts `requirments.txt` automatically on every commit.
The config for a pre-commit hook is stored in [.pre-commit-config](../../.pre-commit-config.yaml).
After you clone the repository, you will need to install initialize pre-commit hook.
```bash
pip install -r requirements/tests.txt
```
From the repository folder
```bash
pre-commit install
```
fixes `end-of-files`, sorts `requirments.txt` automatically on every commit.
The config for a pre-commit hook is stored in [.pre-commit-config](../../.pre-commit-config.yaml).
After you clone the repository, you will need to install initialize pre-commit hook.
```bash
pip install -r requirements/tests.txt
```
From the repository folder
```bash
pre-commit install
```
After this on every commit check code linters and formatter will be enforced.
After this on every commit check code linters and formatter will be enforced.
If you want to use pre-commit to check all the files, you can run
```bash
pre-commit run --all-files
```
If you want to use pre-commit to check all the files, you can run
```bash
pre-commit run --all-files
```
If you only want to format and lint your code, you can run
```bash
make linter
```
If you only want to format and lint your code, you can run
```bash
make linter
```
## 2. Test
### 2.1 Unit test
```bash
make test
```
## 2. Test
### 2.1 Unit test
```bash
make test
```
### 2.2 Test data
TODO
### 2.2 Test data
TODO
## 3. Build pip package
```bash
make whl
```
## Code Review
1. Run following command to create an aone CR, replace `TARGET_BRANCH` and `CR_NAME` with the one you want.
```shell
git push origin HEAD:refs/for/TARGET_BRANCH/CR_NAME
```
Please refer to [https://yuque.antfin.com/aone/platform/lcg8yr](https://yuque.antfin.com/aone/platform/lcg8yr) for more details.
The following output is expected.
```shell
Counting objects: 5, done.
Delta compression using up to 96 threads.
Compressing objects: 100% (5/5), done.
Writing objects: 100% (5/5), 543 bytes | 0 bytes/s, done.
Total 5 (delta 4), reused 0 (delta 0)
remote: +------------------------------------------------------------------------+
remote: | Merge Request #8949062 was created or updated. |
remote: | View merge request at URL: |
remote: | https://code.aone.alibaba-inc.com/Ali-MaaS/MaaS-lib/codereview/8949062 |
remote: +------------------------------------------------------------------------+
To git@gitlab.alibaba-inc.com:Ali-MaaS/MaaS-lib.git
* [new branch] HEAD -> refs/for/master/support_kwargs_pipeline
```
2. Open the remote url `https://code.aone.alibaba-inc.com/Ali-MaaS/MaaS-lib/codereview/ID` and edit the title of CR with following format before merging your code:
* Feature
```shell
[to #AONE_ID] feat: commit title
Link: https://code.alibaba-inc.com/Ali-MaaS/MaaS-lib/codereview/8949062
* commit msg1
* commit msg2
```
* Bugfix
```shell
[to #AONE_ID] fix: commit title
Link: https://code.alibaba-inc.com/Ali-MaaS/MaaS-lib/codereview/8949062
* commit msg1
* commit msg2
```
## Build pip package
```bash
make whl
```

View File

@@ -1,11 +1,11 @@
.. maas_lib documentation file,
.. modelscope documentation file,
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
MaasLib DOCUMENTATION
ModelScope DOCUMENTATION
=======================================
MaasLib doc
ModelScope doc
.. toctree::
:maxdepth: 2
@@ -30,11 +30,11 @@ MaasLib doc
:maxdepth: 10
:caption: API Doc
api/maas_lib.preprocessors
api/maas_lib.models
api/maas_lib.pipelines
api/maas_lib.fileio
api/maas_lib.utils
api/modelscope.preprocessors
api/modelscope.models
api/modelscope.pipelines
api/modelscope.fileio
api/modelscope.utils
Indices and tables

View File

@@ -5,39 +5,39 @@
安装完成后执行如下命令为maas library创建对应的python环境。
```shell
conda create -n maas python=3.6
conda activate maas
conda create -n modelscope python=3.6
conda activate modelscope
```
检查python和pip命令是否切换到conda环境下。
```shell
which python
# ~/workspace/anaconda3/envs/maas/bin/python
# ~/workspace/anaconda3/envs/modelscope/bin/python
which pip
# ~/workspace/anaconda3/envs/maas/bin/pip
# ~/workspace/anaconda3/envs/modelscope/bin/pip
```
注: 本项目只支持`python3`环境请勿使用python2环境。
## 第三方依赖安装
MaaS Library目前支持tensorflowpytorch两大深度学习框架进行模型训练、推理 在Python 3.6+, Pytorch 1.8+, Tensorflow 2.6上测试可运行,用户可以根据所选模型对应的计算框架进行安装,可以参考如下链接进行安装所需框架:
ModelScope Library目前支持tensorflowpytorch两大深度学习框架进行模型训练、推理 在Python 3.6+, Pytorch 1.8+, Tensorflow 2.6上测试可运行,用户可以根据所选模型对应的计算框架进行安装,可以参考如下链接进行安装所需框架:
* [Pytorch安装指导](https://pytorch.org/get-started/locally/)
* [Tensorflow安装指导](https://www.tensorflow.org/install/pip)
## MaaS library 安装
## ModelScope library 安装
注: 如果在安装过程中遇到错误,请前往[常见问题](faq.md)查找解决方案。
### pip安装
```shell
pip install -r http://pai-vision-data-hz.oss-cn-zhangjiakou.aliyuncs.com/release/maas/maas.txt
pip install -r http://pai-vision-data-hz.oss-cn-zhangjiakou.aliyuncs.com/release/maas/modelscope.txt
```
安装成功后,可以执行如下命令进行验证安装是否正确
```shell
python -c "from maas_lib.pipelines import pipeline;print(pipeline('image-matting',model='damo/image-matting-person')('http://pai-vision-data-hz.oss-cn-zhangjiakou.aliyuncs.com/data/test/maas/image_matting/test.png'))"
python -c "from modelscope.pipelines import pipeline;print(pipeline('image-matting',model='damo/image-matting-person')('http://pai-vision-data-hz.oss-cn-zhangjiakou.aliyuncs.com/data/test/maas/image_matting/test.png'))"
```
@@ -45,11 +45,11 @@ python -c "from maas_lib.pipelines import pipeline;print(pipeline('image-matting
适合本地开发调试使用,修改源码后可以直接执行
```shell
git clone git@gitlab.alibaba-inc.com:Ali-MaaS/MaaS-lib.git maaslib
git clone git@gitlab.alibaba-inc.com:Ali-MaaS/MaaS-lib.git modelscope
git fetch origin master
git checkout master
cd maaslib
cd modelscope
#安装依赖
pip install -r requirements.txt
@@ -60,7 +60,7 @@ export PYTHONPATH=`pwd`
安装成功后,可以执行如下命令进行验证安装是否正确
```shell
python -c "from maas_lib.pipelines import pipeline;print(pipeline('image-matting',model='damo/image-matting-person')('http://pai-vision-data-hz.oss-cn-zhangjiakou.aliyuncs.com/data/test/maas/image_matting/test.png'))"
python -c "from modelscope.pipelines import pipeline;print(pipeline('image-matting',model='damo/image-matting-person')('http://pai-vision-data-hz.oss-cn-zhangjiakou.aliyuncs.com/data/test/maas/image_matting/test.png'))"
```
@@ -79,8 +79,8 @@ pipeline函数提供了简洁的推理接口示例如下 更多pipeline介
```python
import cv2
import os.path as osp
from maas_lib.pipelines import pipeline
from maas_lib.utils.constant import Tasks
from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks
# 根据任务名创建pipeline
img_matting = pipeline(Tasks.image_matting, model='damo/image-matting-person')
@@ -95,12 +95,13 @@ print(f'Output written to {osp.abspath("result.png")}')
```
此外pipeline接口也能接收Dataset作为输入上面的代码同样可以实现为
```python
import cv2
import os.path as osp
from maas_lib.pipelines import pipeline
from maas_lib.utils.constant import Tasks
from ali_maas_datasets import PyDataset
from modelscope.pipelines import pipeline
from modelscope.utils.constant import Tasks
from modelscope.pydatasets import PyDataset
# 使用图像url构建PyDataset此处也可通过 input_location = '/dir/to/images' 来使用本地文件夹
input_location = [

View File

@@ -19,7 +19,7 @@
1. pipeline函数支持指定特定任务名称加载任务默认模型创建对应Pipeline对象
执行如下python代码
```python
>>> from maas_lib.pipelines import pipeline
>>> from modelscope.pipelines import pipeline
>>> img_matting = pipeline(task='image-matting', model='damo/image-matting-person')
```
@@ -65,8 +65,8 @@ wget https://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/easynlp_modelz
创建tokenizer和模型
```python
>>> from maas_lib.models import Model
>>> from maas_lib.preprocessors import SequenceClassificationPreprocessor
>>> from modelscope.models import Model
>>> from modelscope.preprocessors import SequenceClassificationPreprocessor
>>> model = Model.from_pretrained('damo/bert-base-sst2')
>>> tokenizer = SequenceClassificationPreprocessor(
model.model_dir, first_sequence='sentence', second_sequence=None)
@@ -74,7 +74,7 @@ wget https://atp-modelzoo-sh.oss-cn-shanghai.aliyuncs.com/release/easynlp_modelz
使用tokenizer和模型对象创建pipeline
```python
>>> from maas_lib.pipelines import pipeline
>>> from modelscope.pipelines import pipeline
>>> semantic_cls = pipeline('text-classification', model=model, preprocessor=tokenizer)
>>> semantic_cls("Hello world!")
```

View File

@@ -1,87 +0,0 @@
# Copyright (c) Alibaba, Inc. and its affiliates.
import os.path as osp
from typing import Union
import json
from maas_hub.file_download import model_file_download
from maas_lib.models.base import Model
from maas_lib.utils.config import Config, ConfigDict
from maas_lib.utils.constant import CONFIGFILE, Tasks
from maas_lib.utils.registry import Registry, build_from_cfg
from .base import Pipeline
from .util import is_model_name
PIPELINES = Registry('pipelines')
def build_pipeline(cfg: ConfigDict,
task_name: str = None,
default_args: dict = None):
""" build pipeline given model config dict.
Args:
cfg (:obj:`ConfigDict`): config dict for model object.
task_name (str, optional): task name, refer to
:obj:`Tasks` for more details.
default_args (dict, optional): Default initialization arguments.
"""
return build_from_cfg(
cfg, PIPELINES, group_key=task_name, default_args=default_args)
def pipeline(task: str = None,
model: Union[str, Model] = None,
preprocessor=None,
config_file: str = None,
pipeline_name: str = None,
framework: str = None,
device: int = -1,
**kwargs) -> Pipeline:
""" Factory method to build a obj:`Pipeline`.
Args:
task (str): Task name defining which pipeline will be returned.
model (str or obj:`Model`): model name or model object.
preprocessor: preprocessor object.
config_file (str, optional): path to config file.
pipeline_name (str, optional): pipeline class name or alias name.
framework (str, optional): framework type.
device (int, optional): which device is used to do inference.
Return:
pipeline (obj:`Pipeline`): pipeline object for certain task.
Examples:
```python
>>> p = pipeline('image-classification')
>>> p = pipeline('text-classification', model='distilbert-base-uncased')
>>> # Using model object
>>> resnet = Model.from_pretrained('Resnet')
>>> p = pipeline('image-classification', model=resnet)
"""
if task is None and pipeline_name is None:
raise ValueError('task or pipeline_name is required')
if pipeline_name is None:
# get default pipeline for this task
assert task in PIPELINES.modules, f'No pipeline is registerd for Task {task}'
pipeline_name = get_default_pipeline(task)
cfg = ConfigDict(type=pipeline_name)
if model:
assert isinstance(model, (str, Model)), \
f'model should be either str or Model, but got {type(model)}'
cfg.model = model
if preprocessor is not None:
cfg.preprocessor = preprocessor
return build_pipeline(cfg, task_name=task)
def get_default_pipeline(task):
return list(PIPELINES.modules[task].keys())[0]

View File

@@ -1 +0,0 @@
from .image_matting import ImageMatting

View File

@@ -1,29 +0,0 @@
# Copyright (c) Alibaba, Inc. and its affiliates.
import os.path as osp
import json
from maas_hub.file_download import model_file_download
from maas_lib.utils.constant import CONFIGFILE
def is_model_name(model):
if osp.exists(model):
if osp.exists(osp.join(model, CONFIGFILE)):
return True
else:
return False
else:
# try:
# cfg_file = model_file_download(model, CONFIGFILE)
# except Exception:
# cfg_file = None
# TODO @wenmeng.zwm use exception instead of
# following tricky logic
cfg_file = model_file_download(model, CONFIGFILE)
with open(cfg_file, 'r') as infile:
cfg = json.load(infile)
if 'Code' in cfg:
return False
else:
return True

View File

@@ -2,4 +2,4 @@
from .base import Model
from .builder import MODELS, build_model
from .nlp import SequenceClassificationModel
from .nlp import BertForSequenceClassification

View File

@@ -7,9 +7,10 @@ from typing import Dict, List, Tuple, Union
from maas_hub.file_download import model_file_download
from maas_hub.snapshot_download import snapshot_download
from maas_lib.models.builder import build_model
from maas_lib.utils.config import Config
from maas_lib.utils.constant import CONFIGFILE
from modelscope.models.builder import build_model
from modelscope.utils.config import Config
from modelscope.utils.constant import CONFIGFILE
from modelscope.utils.hub import get_model_cache_dir
Tensor = Union['torch.Tensor', 'tf.Tensor']
@@ -39,8 +40,9 @@ class Model(ABC):
if osp.exists(model_name_or_path):
local_model_dir = model_name_or_path
else:
local_model_dir = snapshot_download(model_name_or_path)
cache_path = get_model_cache_dir(model_name_or_path)
local_model_dir = cache_path if osp.exists(
cache_path) else snapshot_download(model_name_or_path)
# else:
# raise ValueError(
# 'Remote model repo {model_name_or_path} does not exists')
@@ -48,7 +50,7 @@ class Model(ABC):
cfg = Config.from_file(osp.join(local_model_dir, CONFIGFILE))
task_name = cfg.task
model_cfg = cfg.model
# TODO @wenmeng.zwm may should mannually initialize model after model building
# TODO @wenmeng.zwm may should manually initialize model after model building
if hasattr(model_cfg, 'model_type') and not hasattr(model_cfg, 'type'):
model_cfg.type = model_cfg.model_type
model_cfg.model_dir = local_model_dir

View File

@@ -1,7 +1,7 @@
# Copyright (c) Alibaba, Inc. and its affiliates.
from maas_lib.utils.config import ConfigDict
from maas_lib.utils.registry import Registry, build_from_cfg
from modelscope.utils.config import ConfigDict
from modelscope.utils.registry import Registry, build_from_cfg
MODELS = Registry('models')

View File

@@ -0,0 +1,4 @@
Copyright (c) Peppa_Pig_Face_Engine
https://github.com/610265158/Peppa_Pig_Face_Engine

View File

@@ -0,0 +1,97 @@
import numpy as np
from ..config import config as cfg
class GroupTrack():
def __init__(self):
self.old_frame = None
self.previous_landmarks_set = None
self.with_landmark = True
self.thres = cfg.TRACE.pixel_thres
self.alpha = cfg.TRACE.smooth_landmark
self.iou_thres = cfg.TRACE.iou_thres
def calculate(self, img, current_landmarks_set):
if self.previous_landmarks_set is None:
self.previous_landmarks_set = current_landmarks_set
result = current_landmarks_set
else:
previous_lm_num = self.previous_landmarks_set.shape[0]
if previous_lm_num == 0:
self.previous_landmarks_set = current_landmarks_set
result = current_landmarks_set
return result
else:
result = []
for i in range(current_landmarks_set.shape[0]):
not_in_flag = True
for j in range(previous_lm_num):
if self.iou(current_landmarks_set[i],
self.previous_landmarks_set[j]
) > self.iou_thres:
result.append(
self.smooth(current_landmarks_set[i],
self.previous_landmarks_set[j]))
not_in_flag = False
break
if not_in_flag:
result.append(current_landmarks_set[i])
result = np.array(result)
self.previous_landmarks_set = result
return result
def iou(self, p_set0, p_set1):
rec1 = [
np.min(p_set0[:, 0]),
np.min(p_set0[:, 1]),
np.max(p_set0[:, 0]),
np.max(p_set0[:, 1])
]
rec2 = [
np.min(p_set1[:, 0]),
np.min(p_set1[:, 1]),
np.max(p_set1[:, 0]),
np.max(p_set1[:, 1])
]
# computing area of each rectangles
S_rec1 = (rec1[2] - rec1[0]) * (rec1[3] - rec1[1])
S_rec2 = (rec2[2] - rec2[0]) * (rec2[3] - rec2[1])
# computing the sum_area
sum_area = S_rec1 + S_rec2
# find the each edge of intersect rectangle
x1 = max(rec1[0], rec2[0])
y1 = max(rec1[1], rec2[1])
x2 = min(rec1[2], rec2[2])
y2 = min(rec1[3], rec2[3])
# judge if there is an intersect
intersect = max(0, x2 - x1) * max(0, y2 - y1)
iou = intersect / (sum_area - intersect)
return iou
def smooth(self, now_landmarks, previous_landmarks):
result = []
for i in range(now_landmarks.shape[0]):
x = now_landmarks[i][0] - previous_landmarks[i][0]
y = now_landmarks[i][1] - previous_landmarks[i][1]
dis = np.sqrt(np.square(x) + np.square(y))
if dis < self.thres:
result.append(previous_landmarks[i])
else:
result.append(
self.do_moving_average(now_landmarks[i],
previous_landmarks[i]))
return np.array(result)
def do_moving_average(self, p_now, p_previous):
p = self.alpha * p_now + (1 - self.alpha) * p_previous
return p

View File

@@ -0,0 +1,23 @@
import os
import numpy as np
from easydict import EasyDict as edict
config = edict()
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
config.DETECT = edict()
config.DETECT.topk = 10
config.DETECT.thres = 0.8
config.DETECT.input_shape = (512, 512, 3)
config.KEYPOINTS = edict()
config.KEYPOINTS.p_num = 68
config.KEYPOINTS.base_extend_range = [0.2, 0.3]
config.KEYPOINTS.input_shape = (160, 160, 3)
config.TRACE = edict()
config.TRACE.pixel_thres = 1
config.TRACE.smooth_box = 0.3
config.TRACE.smooth_landmark = 0.95
config.TRACE.iou_thres = 0.5
config.DATA = edict()
config.DATA.pixel_means = np.array([123., 116., 103.]) # RGB

View File

@@ -0,0 +1,116 @@
import time
import cv2
import numpy as np
import tensorflow as tf
from .config import config as cfg
if tf.__version__ >= '2.0':
tf = tf.compat.v1
class FaceDetector:
def __init__(self, dir):
self.model_path = dir + '/detector.pb'
self.thres = cfg.DETECT.thres
self.input_shape = cfg.DETECT.input_shape
self._graph = tf.Graph()
with self._graph.as_default():
self._graph, self._sess = self.init_model(self.model_path)
self.input_image = tf.get_default_graph().get_tensor_by_name(
'tower_0/images:0')
self.training = tf.get_default_graph().get_tensor_by_name(
'training_flag:0')
self.output_ops = [
tf.get_default_graph().get_tensor_by_name('tower_0/boxes:0'),
tf.get_default_graph().get_tensor_by_name('tower_0/scores:0'),
tf.get_default_graph().get_tensor_by_name(
'tower_0/num_detections:0'),
]
def __call__(self, image):
image, scale_x, scale_y = self.preprocess(
image,
target_width=self.input_shape[1],
target_height=self.input_shape[0])
image = np.expand_dims(image, 0)
boxes, scores, num_boxes = self._sess.run(
self.output_ops,
feed_dict={
self.input_image: image,
self.training: False
})
num_boxes = num_boxes[0]
boxes = boxes[0][:num_boxes]
scores = scores[0][:num_boxes]
to_keep = scores > self.thres
boxes = boxes[to_keep]
scores = scores[to_keep]
y1 = self.input_shape[0] / scale_y
x1 = self.input_shape[1] / scale_x
y2 = self.input_shape[0] / scale_y
x2 = self.input_shape[1] / scale_x
scaler = np.array([y1, x1, y2, x2], dtype='float32')
boxes = boxes * scaler
scores = np.expand_dims(scores, 0).reshape([-1, 1])
for i in range(boxes.shape[0]):
boxes[i] = np.array(
[boxes[i][1], boxes[i][0], boxes[i][3], boxes[i][2]])
return np.concatenate([boxes, scores], axis=1)
def preprocess(self, image, target_height, target_width, label=None):
h, w, c = image.shape
bimage = np.zeros(
shape=[target_height, target_width, c],
dtype=image.dtype) + np.array(
cfg.DATA.pixel_means, dtype=image.dtype)
long_side = max(h, w)
scale_x = scale_y = target_height / long_side
image = cv2.resize(image, None, fx=scale_x, fy=scale_y)
h_, w_, _ = image.shape
bimage[:h_, :w_, :] = image
return bimage, scale_x, scale_y
def init_model(self, *args):
pb_path = args[0]
def init_pb(model_path):
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.2
compute_graph = tf.Graph()
compute_graph.as_default()
sess = tf.Session(config=config)
with tf.gfile.GFile(model_path, 'rb') as fid:
graph_def = tf.GraphDef()
graph_def.ParseFromString(fid.read())
tf.import_graph_def(graph_def, name='')
return (compute_graph, sess)
model = init_pb(pb_path)
graph = model[0]
sess = model[1]
return graph, sess

View File

@@ -0,0 +1,154 @@
import cv2
import numpy as np
import tensorflow as tf
from .config import config as cfg
if tf.__version__ >= '2.0':
tf = tf.compat.v1
class FaceLandmark:
def __init__(self, dir):
self.model_path = dir + '/keypoints.pb'
self.min_face = 60
self.keypoint_num = cfg.KEYPOINTS.p_num * 2
self._graph = tf.Graph()
with self._graph.as_default():
self._graph, self._sess = self.init_model(self.model_path)
self.img_input = tf.get_default_graph().get_tensor_by_name(
'tower_0/images:0')
self.embeddings = tf.get_default_graph().get_tensor_by_name(
'tower_0/prediction:0')
self.training = tf.get_default_graph().get_tensor_by_name(
'training_flag:0')
self.landmark = self.embeddings[:, :self.keypoint_num]
self.headpose = self.embeddings[:, -7:-4] * 90.
self.state = tf.nn.sigmoid(self.embeddings[:, -4:])
def __call__(self, img, bboxes):
landmark_result = []
state_result = []
for i, bbox in enumerate(bboxes):
landmark, state = self._one_shot_run(img, bbox, i)
if landmark is not None:
landmark_result.append(landmark)
state_result.append(state)
return np.array(landmark_result), np.array(state_result)
def simple_run(self, cropped_img):
with self._graph.as_default():
cropped_img = np.expand_dims(cropped_img, axis=0)
landmark, p, states = self._sess.run(
[self.landmark, self.headpose, self.state],
feed_dict={
self.img_input: cropped_img,
self.training: False
})
return landmark, states
def _one_shot_run(self, image, bbox, i):
bbox_width = bbox[2] - bbox[0]
bbox_height = bbox[3] - bbox[1]
if (bbox_width <= self.min_face and bbox_height <= self.min_face):
return None, None
add = int(max(bbox_width, bbox_height))
bimg = cv2.copyMakeBorder(
image,
add,
add,
add,
add,
borderType=cv2.BORDER_CONSTANT,
value=cfg.DATA.pixel_means)
bbox += add
one_edge = (1 + 2 * cfg.KEYPOINTS.base_extend_range[0]) * bbox_width
center = [(bbox[0] + bbox[2]) // 2, (bbox[1] + bbox[3]) // 2]
bbox[0] = center[0] - one_edge // 2
bbox[1] = center[1] - one_edge // 2
bbox[2] = center[0] + one_edge // 2
bbox[3] = center[1] + one_edge // 2
bbox = bbox.astype(np.int)
crop_image = bimg[bbox[1]:bbox[3], bbox[0]:bbox[2], :]
h, w, _ = crop_image.shape
crop_image = cv2.resize(
crop_image,
(cfg.KEYPOINTS.input_shape[1], cfg.KEYPOINTS.input_shape[0]))
crop_image = crop_image.astype(np.float32)
keypoints, state = self.simple_run(crop_image)
res = keypoints[0][:self.keypoint_num].reshape((-1, 2))
res[:, 0] = res[:, 0] * w / cfg.KEYPOINTS.input_shape[1]
res[:, 1] = res[:, 1] * h / cfg.KEYPOINTS.input_shape[0]
landmark = []
for _index in range(res.shape[0]):
x_y = res[_index]
landmark.append([
int(x_y[0] * cfg.KEYPOINTS.input_shape[0] + bbox[0] - add),
int(x_y[1] * cfg.KEYPOINTS.input_shape[1] + bbox[1] - add)
])
landmark = np.array(landmark, np.float32)
return landmark, state
def init_model(self, *args):
if len(args) == 1:
use_pb = True
pb_path = args[0]
else:
use_pb = False
meta_path = args[0]
restore_model_path = args[1]
def ini_ckpt():
graph = tf.Graph()
graph.as_default()
configProto = tf.ConfigProto()
configProto.gpu_options.allow_growth = True
sess = tf.Session(config=configProto)
# load_model(model_path, sess)
saver = tf.train.import_meta_graph(meta_path)
saver.restore(sess, restore_model_path)
print('Model restred!')
return (graph, sess)
def init_pb(model_path):
config = tf.ConfigProto()
config.gpu_options.per_process_gpu_memory_fraction = 0.2
compute_graph = tf.Graph()
compute_graph.as_default()
sess = tf.Session(config=config)
with tf.gfile.GFile(model_path, 'rb') as fid:
graph_def = tf.GraphDef()
graph_def.ParseFromString(fid.read())
tf.import_graph_def(graph_def, name='')
# saver = tf.train.Saver(tf.global_variables())
# saver.save(sess, save_path='./tmp.ckpt')
return (compute_graph, sess)
if use_pb:
model = init_pb(pb_path)
else:
model = ini_ckpt()
graph = model[0]
sess = model[1]
return graph, sess

View File

@@ -0,0 +1,150 @@
import time
import cv2
import numpy as np
from .config import config as cfg
from .face_detector import FaceDetector
from .face_landmark import FaceLandmark
from .LK.lk import GroupTrack
class FaceAna():
'''
by default the top3 facea sorted by area will be calculated for time reason
'''
def __init__(self, model_dir):
self.face_detector = FaceDetector(model_dir)
self.face_landmark = FaceLandmark(model_dir)
self.trace = GroupTrack()
self.track_box = None
self.previous_image = None
self.previous_box = None
self.diff_thres = 5
self.top_k = cfg.DETECT.topk
self.iou_thres = cfg.TRACE.iou_thres
self.alpha = cfg.TRACE.smooth_box
def run(self, image):
boxes = self.face_detector(image)
if boxes.shape[0] > self.top_k:
boxes = self.sort(boxes)
boxes_return = np.array(boxes)
landmarks, states = self.face_landmark(image, boxes)
if 1:
track = []
for i in range(landmarks.shape[0]):
track.append([
np.min(landmarks[i][:, 0]),
np.min(landmarks[i][:, 1]),
np.max(landmarks[i][:, 0]),
np.max(landmarks[i][:, 1])
])
tmp_box = np.array(track)
self.track_box = self.judge_boxs(boxes_return, tmp_box)
self.track_box, landmarks = self.sort_res(self.track_box, landmarks)
return self.track_box, landmarks, states
def sort_res(self, bboxes, points):
area = []
for bbox in bboxes:
bbox_width = bbox[2] - bbox[0]
bbox_height = bbox[3] - bbox[1]
area.append(bbox_height * bbox_width)
area = np.array(area)
picked = area.argsort()[::-1]
sorted_bboxes = [bboxes[x] for x in picked]
sorted_points = [points[x] for x in picked]
return np.array(sorted_bboxes), np.array(sorted_points)
def diff_frames(self, previous_frame, image):
if previous_frame is None:
return True
else:
_diff = cv2.absdiff(previous_frame, image)
diff = np.sum(
_diff) / previous_frame.shape[0] / previous_frame.shape[1] / 3.
return diff > self.diff_thres
def sort(self, bboxes):
if self.top_k > 100:
return bboxes
area = []
for bbox in bboxes:
bbox_width = bbox[2] - bbox[0]
bbox_height = bbox[3] - bbox[1]
area.append(bbox_height * bbox_width)
area = np.array(area)
picked = area.argsort()[-self.top_k:][::-1]
sorted_bboxes = [bboxes[x] for x in picked]
return np.array(sorted_bboxes)
def judge_boxs(self, previuous_bboxs, now_bboxs):
def iou(rec1, rec2):
# computing area of each rectangles
S_rec1 = (rec1[2] - rec1[0]) * (rec1[3] - rec1[1])
S_rec2 = (rec2[2] - rec2[0]) * (rec2[3] - rec2[1])
# computing the sum_area
sum_area = S_rec1 + S_rec2
# find the each edge of intersect rectangle
x1 = max(rec1[0], rec2[0])
y1 = max(rec1[1], rec2[1])
x2 = min(rec1[2], rec2[2])
y2 = min(rec1[3], rec2[3])
# judge if there is an intersect
intersect = max(0, x2 - x1) * max(0, y2 - y1)
return intersect / (sum_area - intersect)
if previuous_bboxs is None:
return now_bboxs
result = []
for i in range(now_bboxs.shape[0]):
contain = False
for j in range(previuous_bboxs.shape[0]):
if iou(now_bboxs[i], previuous_bboxs[j]) > self.iou_thres:
result.append(
self.smooth(now_bboxs[i], previuous_bboxs[j]))
contain = True
break
if not contain:
result.append(now_bboxs[i])
return np.array(result)
def smooth(self, now_box, previous_box):
return self.do_moving_average(now_box[:4], previous_box[:4])
def do_moving_average(self, p_now, p_previous):
p = self.alpha * p_now + (1 - self.alpha) * p_previous
return p
def reset(self):
'''
reset the previous info used foe tracking,
:return:
'''
self.track_box = None
self.previous_image = None
self.previous_box = None

View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Dan Antoshchenko
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,26 @@
# MTCNN
`pytorch` implementation of **inference stage** of face detection algorithm described in
[Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Networks](https://arxiv.org/abs/1604.02878).
## Example
![example of a face detection](images/example.png)
## How to use it
Just download the repository and then do this
```python
from src import detect_faces
from PIL import Image
image = Image.open('image.jpg')
bounding_boxes, landmarks = detect_faces(image)
```
For examples see `test_on_images.ipynb`.
## Requirements
* pytorch 0.2
* Pillow, numpy
## Credit
This implementation is heavily inspired by:
* [pangyupo/mxnet_mtcnn_face_detection](https://github.com/pangyupo/mxnet_mtcnn_face_detection)

View File

@@ -0,0 +1,187 @@
"""
Created on Mon Apr 24 15:43:29 2017
@author: zhaoy
"""
import cv2
import numpy as np
from .matlab_cp2tform import get_similarity_transform_for_cv2
# reference facial points, a list of coordinates (x,y)
dx = 1
dy = 1
REFERENCE_FACIAL_POINTS = [
[30.29459953 + dx, 51.69630051 + dy], # left eye
[65.53179932 + dx, 51.50139999 + dy], # right eye
[48.02519989 + dx, 71.73660278 + dy], # nose
[33.54930115 + dx, 92.3655014 + dy], # left mouth
[62.72990036 + dx, 92.20410156 + dy] # right mouth
]
DEFAULT_CROP_SIZE = (96, 112)
global FACIAL_POINTS
class FaceWarpException(Exception):
def __str__(self):
return 'In File {}:{}'.format(__file__, super.__str__(self))
def get_reference_facial_points(output_size=None,
inner_padding_factor=0.0,
outer_padding=(0, 0),
default_square=False):
tmp_5pts = np.array(REFERENCE_FACIAL_POINTS)
tmp_crop_size = np.array(DEFAULT_CROP_SIZE)
# 0) make the inner region a square
if default_square:
size_diff = max(tmp_crop_size) - tmp_crop_size
tmp_5pts += size_diff / 2
tmp_crop_size += size_diff
h_crop = tmp_crop_size[0]
w_crop = tmp_crop_size[1]
if (output_size):
if (output_size[0] == h_crop and output_size[1] == w_crop):
return tmp_5pts
if (inner_padding_factor == 0 and outer_padding == (0, 0)):
if output_size is None:
return tmp_5pts
else:
raise FaceWarpException(
'No paddings to do, output_size must be None or {}'.format(
tmp_crop_size))
# check output size
if not (0 <= inner_padding_factor <= 1.0):
raise FaceWarpException('Not (0 <= inner_padding_factor <= 1.0)')
factor = inner_padding_factor > 0 or outer_padding[0] > 0
factor = factor or outer_padding[1] > 0
if (factor and output_size is None):
output_size = tmp_crop_size * \
(1 + inner_padding_factor * 2).astype(np.int32)
output_size += np.array(outer_padding)
cond1 = outer_padding[0] < output_size[0]
cond2 = outer_padding[1] < output_size[1]
if not (cond1 and cond2):
raise FaceWarpException('Not (outer_padding[0] < output_size[0]'
'and outer_padding[1] < output_size[1])')
# 1) pad the inner region according inner_padding_factor
if inner_padding_factor > 0:
size_diff = tmp_crop_size * inner_padding_factor * 2
tmp_5pts += size_diff / 2
tmp_crop_size += np.round(size_diff).astype(np.int32)
# 2) resize the padded inner region
size_bf_outer_pad = np.array(output_size) - np.array(outer_padding) * 2
if size_bf_outer_pad[0] * tmp_crop_size[1] != size_bf_outer_pad[
1] * tmp_crop_size[0]:
raise FaceWarpException(
'Must have (output_size - outer_padding)'
'= some_scale * (crop_size * (1.0 + inner_padding_factor)')
scale_factor = size_bf_outer_pad[0].astype(np.float32) / tmp_crop_size[0]
tmp_5pts = tmp_5pts * scale_factor
# 3) add outer_padding to make output_size
reference_5point = tmp_5pts + np.array(outer_padding)
return reference_5point
def get_affine_transform_matrix(src_pts, dst_pts):
tfm = np.float32([[1, 0, 0], [0, 1, 0]])
n_pts = src_pts.shape[0]
ones = np.ones((n_pts, 1), src_pts.dtype)
src_pts_ = np.hstack([src_pts, ones])
dst_pts_ = np.hstack([dst_pts, ones])
A, res, rank, s = np.linalg.lstsq(src_pts_, dst_pts_)
if rank == 3:
tfm = np.float32([[A[0, 0], A[1, 0], A[2, 0]],
[A[0, 1], A[1, 1], A[2, 1]]])
elif rank == 2:
tfm = np.float32([[A[0, 0], A[1, 0], 0], [A[0, 1], A[1, 1], 0]])
return tfm
def warp_and_crop_face(src_img,
facial_pts,
ratio=0.84,
reference_pts=None,
crop_size=(96, 112),
align_type='similarity'
'',
return_trans_inv=False):
if reference_pts is None:
if crop_size[0] == 96 and crop_size[1] == 112:
reference_pts = REFERENCE_FACIAL_POINTS
else:
default_square = False
inner_padding_factor = 0
outer_padding = (0, 0)
output_size = crop_size
reference_pts = get_reference_facial_points(
output_size, inner_padding_factor, outer_padding,
default_square)
ref_pts = np.float32(reference_pts)
factor = ratio
ref_pts = (ref_pts - 112 / 2) * factor + 112 / 2
ref_pts *= crop_size[0] / 112.
ref_pts_shp = ref_pts.shape
if max(ref_pts_shp) < 3 or min(ref_pts_shp) != 2:
raise FaceWarpException(
'reference_pts.shape must be (K,2) or (2,K) and K>2')
if ref_pts_shp[0] == 2:
ref_pts = ref_pts.T
src_pts = np.float32(facial_pts)
src_pts_shp = src_pts.shape
if max(src_pts_shp) < 3 or min(src_pts_shp) != 2:
raise FaceWarpException(
'facial_pts.shape must be (K,2) or (2,K) and K>2')
if src_pts_shp[0] == 2:
src_pts = src_pts.T
if src_pts.shape != ref_pts.shape:
raise FaceWarpException(
'facial_pts and reference_pts must have the same shape')
if align_type == 'cv2_affine':
tfm = cv2.getAffineTransform(src_pts, ref_pts)
tfm_inv = cv2.getAffineTransform(ref_pts, src_pts)
elif align_type == 'affine':
tfm = get_affine_transform_matrix(src_pts, ref_pts)
tfm_inv = get_affine_transform_matrix(ref_pts, src_pts)
else:
tfm, tfm_inv = get_similarity_transform_for_cv2(src_pts, ref_pts)
face_img = cv2.warpAffine(
src_img,
tfm, (crop_size[0], crop_size[1]),
borderValue=(255, 255, 255))
if return_trans_inv:
return face_img, tfm_inv
else:
return face_img

View File

@@ -0,0 +1,339 @@
"""
Created on Tue Jul 11 06:54:28 2017
@author: zhaoyafei
"""
import numpy as np
from numpy.linalg import inv, lstsq
from numpy.linalg import matrix_rank as rank
from numpy.linalg import norm
class MatlabCp2tormException(Exception):
def __str__(self):
return 'In File {}:{}'.format(__file__, super.__str__(self))
def tformfwd(trans, uv):
"""
Function:
----------
apply affine transform 'trans' to uv
Parameters:
----------
@trans: 3x3 np.array
transform matrix
@uv: Kx2 np.array
each row is a pair of coordinates (x, y)
Returns:
----------
@xy: Kx2 np.array
each row is a pair of transformed coordinates (x, y)
"""
uv = np.hstack((uv, np.ones((uv.shape[0], 1))))
xy = np.dot(uv, trans)
xy = xy[:, 0:-1]
return xy
def tforminv(trans, uv):
"""
Function:
----------
apply the inverse of affine transform 'trans' to uv
Parameters:
----------
@trans: 3x3 np.array
transform matrix
@uv: Kx2 np.array
each row is a pair of coordinates (x, y)
Returns:
----------
@xy: Kx2 np.array
each row is a pair of inverse-transformed coordinates (x, y)
"""
Tinv = inv(trans)
xy = tformfwd(Tinv, uv)
return xy
def findNonreflectiveSimilarity(uv, xy, options=None):
options = {'K': 2}
K = options['K']
M = xy.shape[0]
x = xy[:, 0].reshape((-1, 1)) # use reshape to keep a column vector
y = xy[:, 1].reshape((-1, 1)) # use reshape to keep a column vector
# print('--->x, y:\n', x, y
tmp1 = np.hstack((x, y, np.ones((M, 1)), np.zeros((M, 1))))
tmp2 = np.hstack((y, -x, np.zeros((M, 1)), np.ones((M, 1))))
X = np.vstack((tmp1, tmp2))
# print('--->X.shape: ', X.shape
# print('X:\n', X
u = uv[:, 0].reshape((-1, 1)) # use reshape to keep a column vector
v = uv[:, 1].reshape((-1, 1)) # use reshape to keep a column vector
U = np.vstack((u, v))
# print('--->U.shape: ', U.shape
# print('U:\n', U
# We know that X * r = U
if rank(X) >= 2 * K:
r, _, _, _ = lstsq(X, U)
r = np.squeeze(r)
else:
raise Exception('cp2tform:twoUniquePointsReq')
# print('--->r:\n', r
sc = r[0]
ss = r[1]
tx = r[2]
ty = r[3]
Tinv = np.array([[sc, -ss, 0], [ss, sc, 0], [tx, ty, 1]])
# print('--->Tinv:\n', Tinv
T = inv(Tinv)
# print('--->T:\n', T
T[:, 2] = np.array([0, 0, 1])
return T, Tinv
def findSimilarity(uv, xy, options=None):
options = {'K': 2}
# uv = np.array(uv)
# xy = np.array(xy)
# Solve for trans1
trans1, trans1_inv = findNonreflectiveSimilarity(uv, xy, options)
# Solve for trans2
# manually reflect the xy data across the Y-axis
xyR = xy
xyR[:, 0] = -1 * xyR[:, 0]
trans2r, trans2r_inv = findNonreflectiveSimilarity(uv, xyR, options)
# manually reflect the tform to undo the reflection done on xyR
TreflectY = np.array([[-1, 0, 0], [0, 1, 0], [0, 0, 1]])
trans2 = np.dot(trans2r, TreflectY)
# Figure out if trans1 or trans2 is better
xy1 = tformfwd(trans1, uv)
norm1 = norm(xy1 - xy)
xy2 = tformfwd(trans2, uv)
norm2 = norm(xy2 - xy)
if norm1 <= norm2:
return trans1, trans1_inv
else:
trans2_inv = inv(trans2)
return trans2, trans2_inv
def get_similarity_transform(src_pts, dst_pts, reflective=True):
"""
Function:
----------
Find Similarity Transform Matrix 'trans':
u = src_pts[:, 0]
v = src_pts[:, 1]
x = dst_pts[:, 0]
y = dst_pts[:, 1]
[x, y, 1] = [u, v, 1] * trans
Parameters:
----------
@src_pts: Kx2 np.array
source points, each row is a pair of coordinates (x, y)
@dst_pts: Kx2 np.array
destination points, each row is a pair of transformed
coordinates (x, y)
@reflective: True or False
if True:
use reflective similarity transform
else:
use non-reflective similarity transform
Returns:
----------
@trans: 3x3 np.array
transform matrix from uv to xy
trans_inv: 3x3 np.array
inverse of trans, transform matrix from xy to uv
"""
if reflective:
trans, trans_inv = findSimilarity(src_pts, dst_pts)
else:
trans, trans_inv = findNonreflectiveSimilarity(src_pts, dst_pts)
return trans, trans_inv
def cvt_tform_mat_for_cv2(trans):
"""
Function:
----------
Convert Transform Matrix 'trans' into 'cv2_trans' which could be
directly used by cv2.warpAffine():
u = src_pts[:, 0]
v = src_pts[:, 1]
x = dst_pts[:, 0]
y = dst_pts[:, 1]
[x, y].T = cv_trans * [u, v, 1].T
Parameters:
----------
@trans: 3x3 np.array
transform matrix from uv to xy
Returns:
----------
@cv2_trans: 2x3 np.array
transform matrix from src_pts to dst_pts, could be directly used
for cv2.warpAffine()
"""
cv2_trans = trans[:, 0:2].T
return cv2_trans
def get_similarity_transform_for_cv2(src_pts, dst_pts, reflective=True):
"""
Function:
----------
Find Similarity Transform Matrix 'cv2_trans' which could be
directly used by cv2.warpAffine():
u = src_pts[:, 0]
v = src_pts[:, 1]
x = dst_pts[:, 0]
y = dst_pts[:, 1]
[x, y].T = cv_trans * [u, v, 1].T
Parameters:
----------
@src_pts: Kx2 np.array
source points, each row is a pair of coordinates (x, y)
@dst_pts: Kx2 np.array
destination points, each row is a pair of transformed
coordinates (x, y)
reflective: True or False
if True:
use reflective similarity transform
else:
use non-reflective similarity transform
Returns:
----------
@cv2_trans: 2x3 np.array
transform matrix from src_pts to dst_pts, could be directly used
for cv2.warpAffine()
"""
trans, trans_inv = get_similarity_transform(src_pts, dst_pts, reflective)
cv2_trans = cvt_tform_mat_for_cv2(trans)
cv2_trans_inv = cvt_tform_mat_for_cv2(trans_inv)
return cv2_trans, cv2_trans_inv
if __name__ == '__main__':
"""
u = [0, 6, -2]
v = [0, 3, 5]
x = [-1, 0, 4]
y = [-1, -10, 4]
# In Matlab, run:
#
# uv = [u'; v'];
# xy = [x'; y'];
# tform_sim=cp2tform(uv,xy,'similarity');
#
# trans = tform_sim.tdata.T
# ans =
# -0.0764 -1.6190 0
# 1.6190 -0.0764 0
# -3.2156 0.0290 1.0000
# trans_inv = tform_sim.tdata.Tinv
# ans =
#
# -0.0291 0.6163 0
# -0.6163 -0.0291 0
# -0.0756 1.9826 1.0000
# xy_m=tformfwd(tform_sim, u,v)
#
# xy_m =
#
# -3.2156 0.0290
# 1.1833 -9.9143
# 5.0323 2.8853
# uv_m=tforminv(tform_sim, x,y)
#
# uv_m =
#
# 0.5698 1.3953
# 6.0872 2.2733
# -2.6570 4.3314
"""
u = [0, 6, -2]
v = [0, 3, 5]
x = [-1, 0, 4]
y = [-1, -10, 4]
uv = np.array((u, v)).T
xy = np.array((x, y)).T
print('\n--->uv:')
print(uv)
print('\n--->xy:')
print(xy)
trans, trans_inv = get_similarity_transform(uv, xy)
print('\n--->trans matrix:')
print(trans)
print('\n--->trans_inv matrix:')
print(trans_inv)
print('\n---> apply transform to uv')
print('\nxy_m = uv_augmented * trans')
uv_aug = np.hstack((uv, np.ones((uv.shape[0], 1))))
xy_m = np.dot(uv_aug, trans)
print(xy_m)
print('\nxy_m = tformfwd(trans, uv)')
xy_m = tformfwd(trans, uv)
print(xy_m)
print('\n---> apply inverse transform to xy')
print('\nuv_m = xy_augmented * trans_inv')
xy_aug = np.hstack((xy, np.ones((xy.shape[0], 1))))
uv_m = np.dot(xy_aug, trans_inv)
print(uv_m)
print('\nuv_m = tformfwd(trans_inv, xy)')
uv_m = tformfwd(trans_inv, xy)
print(uv_m)
uv_m = tforminv(trans, xy)
print('\nuv_m = tforminv(trans, xy)')
print(uv_m)

View File

@@ -0,0 +1,91 @@
import os
import cv2
import numpy as np
def resize_size(image, size=720):
h, w, c = np.shape(image)
if min(h, w) > size:
if h > w:
h, w = int(size * h / w), size
else:
h, w = size, int(size * w / h)
image = cv2.resize(image, (w, h), interpolation=cv2.INTER_AREA)
return image
def padTo16x(image):
h, w, c = np.shape(image)
if h % 16 == 0 and w % 16 == 0:
return image, h, w
nh, nw = (h // 16 + 1) * 16, (w // 16 + 1) * 16
img_new = np.ones((nh, nw, 3), np.uint8) * 255
img_new[:h, :w, :] = image
return img_new, h, w
def get_f5p(landmarks, np_img):
eye_left = find_pupil(landmarks[36:41], np_img)
eye_right = find_pupil(landmarks[42:47], np_img)
if eye_left is None or eye_right is None:
print('cannot find 5 points with find_puil, used mean instead.!')
eye_left = landmarks[36:41].mean(axis=0)
eye_right = landmarks[42:47].mean(axis=0)
nose = landmarks[30]
mouth_left = landmarks[48]
mouth_right = landmarks[54]
f5p = [[eye_left[0], eye_left[1]], [eye_right[0], eye_right[1]],
[nose[0], nose[1]], [mouth_left[0], mouth_left[1]],
[mouth_right[0], mouth_right[1]]]
return f5p
def find_pupil(landmarks, np_img):
h, w, _ = np_img.shape
xmax = int(landmarks[:, 0].max())
xmin = int(landmarks[:, 0].min())
ymax = int(landmarks[:, 1].max())
ymin = int(landmarks[:, 1].min())
if ymin >= ymax or xmin >= xmax or ymin < 0 or xmin < 0 or ymax > h or xmax > w:
return None
eye_img_bgr = np_img[ymin:ymax, xmin:xmax, :]
eye_img = cv2.cvtColor(eye_img_bgr, cv2.COLOR_BGR2GRAY)
eye_img = cv2.equalizeHist(eye_img)
n_marks = landmarks - np.array([xmin, ymin]).reshape([1, 2])
eye_mask = cv2.fillConvexPoly(
np.zeros_like(eye_img), n_marks.astype(np.int32), 1)
ret, thresh = cv2.threshold(eye_img, 100, 255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)
thresh = (1 - thresh / 255.) * eye_mask
cnt = 0
xm = []
ym = []
for i in range(thresh.shape[0]):
for j in range(thresh.shape[1]):
if thresh[i, j] > 0.5:
xm.append(j)
ym.append(i)
cnt += 1
if cnt != 0:
xm.sort()
ym.sort()
xm = xm[cnt // 2]
ym = ym[cnt // 2]
else:
xm = thresh.shape[1] / 2
ym = thresh.shape[0] / 2
return xm + xmin, ym + ymin
def all_file(file_dir):
L = []
for root, dirs, files in os.walk(file_dir):
for file in files:
extend = os.path.splitext(file)[1]
if extend == '.png' or extend == '.jpg' or extend == '.jpeg':
L.append(os.path.join(root, file))
return L

View File

@@ -1,3 +1,4 @@
from .sequence_classification_model import * # noqa F403
from .space.dialog_generation_model import * # noqa F403
from .space.dialog_intent_model import *
from .space.dialog_intent_model import * # noqa F403
from .text_generation_model import * # noqa F403

View File

@@ -1,17 +1,17 @@
from typing import Any, Dict, Optional, Union
from typing import Any, Dict
import numpy as np
from maas_lib.utils.constant import Tasks
from modelscope.utils.constant import Tasks
from ..base import Model
from ..builder import MODELS
__all__ = ['SequenceClassificationModel']
__all__ = ['BertForSequenceClassification']
@MODELS.register_module(
Tasks.text_classification, module_name=r'bert-sentiment-analysis')
class SequenceClassificationModel(Model):
class BertForSequenceClassification(Model):
def __init__(self, model_dir: str, *args, **kwargs):
# Model.__init__(self, model_dir, model_cls, first_sequence, *args, **kwargs)

View File

@@ -1,7 +1,7 @@
from typing import Any, Dict, Optional
from maas_lib.trainers.nlp.space.trainers.gen_trainer import MultiWOZTrainer
from maas_lib.utils.constant import Tasks
from modelscope.trainers.nlp.space.trainers.gen_trainer import MultiWOZTrainer
from modelscope.utils.constant import Tasks
from ...base import Model, Tensor
from ...builder import MODELS
from .model.generator import Generator
@@ -68,13 +68,13 @@ class DialogGenerationModel(Model):
from numpy import array, float32
import torch
turn_1 = {
'user': [
13, 1045, 2052, 2066, 1037, 10095, 2013, 3002, 2198, 1005,
1055, 2267, 2000, 10733, 12570, 21713, 4487, 15474, 1012, 7
]
}
old_pv_turn_1 = {}
# turn_1 = {
# 'user': [
# 13, 1045, 2052, 2066, 1037, 10095, 2013, 3002, 2198, 1005,
# 1055, 2267, 2000, 10733, 12570, 21713, 4487, 15474, 1012, 7
# ]
# }
# old_pv_turn_1 = {}
turn_2 = {
'user':

View File

@@ -1,7 +1,7 @@
from typing import Any, Dict, Optional
from maas_lib.trainers.nlp.space.trainers.intent_trainer import IntentTrainer
from maas_lib.utils.constant import Tasks
from modelscope.trainers.nlp.space.trainers.intent_trainer import IntentTrainer
from modelscope.utils.constant import Tasks
from ...base import Model, Tensor
from ...builder import MODELS
from .model.generator import Generator

View File

@@ -3,7 +3,7 @@ IntentUnifiedTransformer
"""
import torch
from maas_lib.models.nlp.space.model.unified_transformer import \
from modelscope.models.nlp.space.model.unified_transformer import \
UnifiedTransformer

View File

@@ -5,7 +5,7 @@ import torch
import torch.nn as nn
import torch.nn.functional as F
from maas_lib.utils.nlp.space.criterions import compute_kl_loss
from modelscope.utils.nlp.space.criterions import compute_kl_loss
from .unified_transformer import UnifiedTransformer

View File

@@ -7,9 +7,9 @@ import torch
import torch.nn as nn
import torch.nn.functional as F
from maas_lib.models.nlp.space.model.model_base import ModelBase
from maas_lib.models.nlp.space.modules.embedder import Embedder
from maas_lib.models.nlp.space.modules.transformer_block import \
from modelscope.models.nlp.space.model.model_base import ModelBase
from modelscope.models.nlp.space.modules.embedder import Embedder
from modelscope.models.nlp.space.modules.transformer_block import \
TransformerBlock
@@ -171,7 +171,7 @@ class UnifiedTransformer(ModelBase):
batch_size = mask1.shape[0]
seq_len1 = mask1.shape[1]
seq_len2 = mask2.shape[1]
seq_len = seq_len1 + seq_len2
# seq_len = seq_len1 + seq_len2
mask_lu = mask1
mask_ru = torch.ones(batch_size, seq_len1, seq_len2)

View File

@@ -5,8 +5,8 @@ TransformerBlock class.
import torch
import torch.nn as nn
from maas_lib.models.nlp.space.modules.feedforward import FeedForward
from maas_lib.models.nlp.space.modules.multihead_attention import \
from modelscope.models.nlp.space.modules.feedforward import FeedForward
from modelscope.models.nlp.space.modules.multihead_attention import \
MultiheadAttention

View File

@@ -0,0 +1,52 @@
from typing import Any, Dict
from modelscope.utils.constant import Tasks
from ..base import Model, Tensor
from ..builder import MODELS
__all__ = ['PalmForTextGenerationModel']
@MODELS.register_module(Tasks.text_generation, module_name=r'palm')
class PalmForTextGenerationModel(Model):
def __init__(self, model_dir: str, *args, **kwargs):
"""initialize the text generation model from the `model_dir` path.
Args:
model_dir (str): the model path.
model_cls (Optional[Any], optional): model loader, if None, use the
default loader to load model weights, by default None.
"""
from sofa import PalmTokenizer
super().__init__(model_dir, *args, **kwargs)
self.model_dir = model_dir
from sofa.models.palm import PalmForConditionalGeneration, TextGenerator
tokenizer = kwargs.pop('tokenizer',
PalmTokenizer.from_pretrained(model_dir))
model = PalmForConditionalGeneration.from_pretrained(model_dir)
self.generator = TextGenerator(model, tokenizer)
def forward(self, input: Dict[str, Tensor]) -> Dict[str, Tensor]:
"""return the result by the model
Args:
input (Dict[str, Any]): the preprocessed data
Returns:
Dict[str, np.ndarray]: results
Example:
{
'predictions': array([1]), # lable 0-negative 1-positive
'probabilities': array([[0.11491239, 0.8850876 ]], dtype=float32),
'logits': array([[-0.53860897, 1.5029076 ]], dtype=float32) # true value
}
"""
encoder_inputs = [
input['input_ids'], input['token_type_ids'],
input['attention_mask']
]
return self.generator(encoder_inputs)

View File

@@ -2,67 +2,86 @@
import os.path as osp
from abc import ABC, abstractmethod
from multiprocessing.sharedctypes import Value
from typing import Any, Dict, Generator, List, Tuple, Union
from typing import Any, Dict, Generator, List, Union
from ali_maas_datasets import PyDataset
from maas_hub.snapshot_download import snapshot_download
from maas_lib.models import Model
from maas_lib.preprocessors import Preprocessor
from maas_lib.utils.config import Config
from maas_lib.utils.constant import CONFIGFILE
from modelscope.models.base import Model
from modelscope.preprocessors import Preprocessor
from modelscope.pydatasets import PyDataset
from modelscope.utils.config import Config
from modelscope.utils.hub import get_model_cache_dir
from modelscope.utils.logger import get_logger
from .util import is_model_name
Tensor = Union['torch.Tensor', 'tf.Tensor']
Input = Union[str, PyDataset, 'PIL.Image.Image', 'numpy.ndarray']
InputModel = Union[str, Model]
output_keys = [
] # 对于不同task的pipeline规定标准化的输出key用以对接postprocess,同时也用来标准化postprocess后输出的key
logger = get_logger()
class Pipeline(ABC):
def initiate_single_model(self, model):
logger.info(f'initiate model from {model}')
# TODO @wenmeng.zwm replace model.startswith('damo/') with get_model
if isinstance(model, str) and model.startswith('damo/'):
if not osp.exists(model):
cache_path = get_model_cache_dir(model)
model = cache_path if osp.exists(
cache_path) else snapshot_download(model)
return Model.from_pretrained(model) if is_model_name(
model) else model
elif isinstance(model, Model):
return model
else:
if model and not isinstance(model, str):
raise ValueError(
f'model type for single model is either str or Model, but got type {type(model)}'
)
return model
def initiate_multiple_models(self, input_models: List[InputModel]):
models = []
for model in input_models:
models.append(self.initiate_single_model(model))
return models
def __init__(self,
config_file: str = None,
model: Union[Model, str] = None,
preprocessor: Preprocessor = None,
model: Union[InputModel, List[InputModel]] = None,
preprocessor: Union[Preprocessor, List[Preprocessor]] = None,
**kwargs):
""" Base class for pipeline.
If config_file is provided, model and preprocessor will be
instantiated from corresponding config. Otherwise model
instantiated from corresponding config. Otherwise, model
and preprocessor will be constructed separately.
Args:
config_file(str, optional): Filepath to configuration file.
model: Model name or model object
preprocessor: Preprocessor object
model: (list of) Model name or model object
preprocessor: (list of) Preprocessor object
"""
if config_file is not None:
self.cfg = Config.from_file(config_file)
if isinstance(model, str):
if not osp.exists(model):
model = snapshot_download(model)
if is_model_name(model):
self.model = Model.from_pretrained(model)
else:
self.model = model
elif isinstance(model, Model):
self.model = model
if not isinstance(model, List):
self.model = self.initiate_single_model(model)
self.models = [self.model]
else:
if model:
raise ValueError(
f'model type is either str or Model, but got type {type(model)}'
)
self.models = self.initiate_multiple_models(model)
self.has_multiple_models = len(self.models) > 1
self.preprocessor = preprocessor
def __call__(self, input: Union[Input, List[Input]], *args,
**post_kwargs) -> Union[Dict[str, Any], Generator]:
# moodel provider should leave it as it is
# maas library developer will handle this function
# model provider should leave it as it is
# modelscope library developer will handle this function
# simple showcase, need to support iterator type for both tensorflow and pytorch
# input_dict = self._handle_input(input)
@@ -91,15 +110,17 @@ class Pipeline(ABC):
def preprocess(self, inputs: Input) -> Dict[str, Any]:
""" Provide default implementation based on preprocess_cfg and user can reimplement it
"""
assert self.preprocessor is not None, 'preprocess method should be implemented'
assert not isinstance(self.preprocessor, List),\
'default implementation does not support using multiple preprocessors.'
return self.preprocessor(inputs)
def forward(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
""" Provide default implementation using self.model and user can reimplement it
"""
assert self.model is not None, 'forward method should be implemented'
assert not self.has_multiple_models, 'default implementation does not support multiple models in a pipeline.'
return self.model(inputs)
@abstractmethod

View File

@@ -0,0 +1,171 @@
# Copyright (c) Alibaba, Inc. and its affiliates.
import os.path as osp
from typing import List, Union
import json
from maas_hub.file_download import model_file_download
from modelscope.models.base import Model
from modelscope.utils.config import Config, ConfigDict
from modelscope.utils.constant import CONFIGFILE, Tasks
from modelscope.utils.registry import Registry, build_from_cfg
from .base import Pipeline
from .util import is_model_name
PIPELINES = Registry('pipelines')
DEFAULT_MODEL_FOR_PIPELINE = {
# TaskName: (pipeline_module_name, model_repo)
Tasks.image_matting: ('image-matting', 'damo/image-matting-person'),
Tasks.text_classification:
('bert-sentiment-analysis', 'damo/bert-base-sst2'),
Tasks.text_generation: ('palm', 'damo/nlp_palm_text-generation_chinese'),
Tasks.image_captioning: ('ofa', None),
Tasks.image_generation:
('person-image-cartoon',
'damo/cv_unet_person-image-cartoon_compound-models'),
}
def build_pipeline(cfg: ConfigDict,
task_name: str = None,
default_args: dict = None):
""" build pipeline given model config dict.
Args:
cfg (:obj:`ConfigDict`): config dict for model object.
task_name (str, optional): task name, refer to
:obj:`Tasks` for more details.
default_args (dict, optional): Default initialization arguments.
"""
return build_from_cfg(
cfg, PIPELINES, group_key=task_name, default_args=default_args)
def pipeline(task: str = None,
model: Union[str, List[str], Model, List[Model]] = None,
preprocessor=None,
config_file: str = None,
pipeline_name: str = None,
framework: str = None,
device: int = -1,
**kwargs) -> Pipeline:
""" Factory method to build a obj:`Pipeline`.
Args:
task (str): Task name defining which pipeline will be returned.
model (str or List[str] or obj:`Model` or obj:list[`Model`]): (list of) model name or model object.
preprocessor: preprocessor object.
config_file (str, optional): path to config file.
pipeline_name (str, optional): pipeline class name or alias name.
framework (str, optional): framework type.
device (int, optional): which device is used to do inference.
Return:
pipeline (obj:`Pipeline`): pipeline object for certain task.
Examples:
```python
>>> # Using default model for a task
>>> p = pipeline('image-classification')
>>> # Using pipeline with a model name
>>> p = pipeline('text-classification', model='damo/distilbert-base-uncased')
>>> # Using pipeline with a model object
>>> resnet = Model.from_pretrained('Resnet')
>>> p = pipeline('image-classification', model=resnet)
>>> # Using pipeline with a list of model names
>>> p = pipeline('audio-kws', model=['damo/audio-tts', 'damo/auto-tts2'])
"""
if task is None and pipeline_name is None:
raise ValueError('task or pipeline_name is required')
if pipeline_name is None:
# get default pipeline for this task
if isinstance(model, str) \
or (isinstance(model, list) and isinstance(model[0], str)):
# if is_model_name(model):
if (isinstance(model, str) and model.startswith('damo/')) \
or (isinstance(model, list) and model[0].startswith('damo/')) \
or (isinstance(model, str) and osp.exists(model)):
# TODO @wenmeng.zwm add support when model is a str of modelhub address
# read pipeline info from modelhub configuration file.
pipeline_name, default_model_repo = get_default_pipeline_info(
task)
else:
pipeline_name = get_pipeline_by_model_name(task, model)
else:
pipeline_name, default_model_repo = get_default_pipeline_info(task)
if model is None:
model = default_model_repo
assert isinstance(model, (type(None), str, Model, list)), \
f'model should be either None, str, List[str], Model, or List[Model], but got {type(model)}'
cfg = ConfigDict(type=pipeline_name, model=model)
if kwargs:
cfg.update(kwargs)
if preprocessor is not None:
cfg.preprocessor = preprocessor
return build_pipeline(cfg, task_name=task)
def add_default_pipeline_info(task: str,
model_name: str,
modelhub_name: str = None,
overwrite: bool = False):
""" Add default model for a task.
Args:
task (str): task name.
model_name (str): model_name.
modelhub_name (str): name for default modelhub.
overwrite (bool): overwrite default info.
"""
if not overwrite:
assert task not in DEFAULT_MODEL_FOR_PIPELINE, \
f'task {task} already has default model.'
DEFAULT_MODEL_FOR_PIPELINE[task] = (model_name, modelhub_name)
def get_default_pipeline_info(task):
""" Get default info for certain task.
Args:
task (str): task name.
Return:
A tuple: first element is pipeline name(model_name), second element
is modelhub name.
"""
if task not in DEFAULT_MODEL_FOR_PIPELINE:
# support pipeline which does not register default model
pipeline_name = list(PIPELINES.modules[task].keys())[0]
default_model = None
else:
pipeline_name, default_model = DEFAULT_MODEL_FOR_PIPELINE[task]
return pipeline_name, default_model
def get_pipeline_by_model_name(task: str, model: Union[str, List[str]]):
""" Get pipeline name by task name and model name
Args:
task (str): task name.
model (str| list[str]): model names
"""
if isinstance(model, str):
model_key = model
else:
model_key = '_'.join(model)
assert model_key in PIPELINES.modules[task], \
f'pipeline for task {task} model {model_key} not found.'
return model_key

View File

@@ -0,0 +1,2 @@
from .image_cartoon_pipeline import ImageCartoonPipeline
from .image_matting_pipeline import ImageMattingPipeline

View File

@@ -0,0 +1,148 @@
import os
from typing import Any, Dict
import cv2
import numpy as np
import PIL
import tensorflow as tf
from modelscope.models.cv.cartoon.facelib.facer import FaceAna
from modelscope.models.cv.cartoon.mtcnn_pytorch.src.align_trans import (
get_reference_facial_points, warp_and_crop_face)
from modelscope.models.cv.cartoon.utils import get_f5p, padTo16x, resize_size
from modelscope.pipelines.base import Input
from modelscope.preprocessors import load_image
from modelscope.utils.constant import Tasks
from modelscope.utils.logger import get_logger
from ..base import Pipeline
from ..builder import PIPELINES
if tf.__version__ >= '2.0':
tf = tf.compat.v1
tf.disable_eager_execution()
logger = get_logger()
@PIPELINES.register_module(
Tasks.image_generation, module_name='person-image-cartoon')
class ImageCartoonPipeline(Pipeline):
def __init__(self, model: str):
super().__init__(model=model)
self.facer = FaceAna(self.model)
self.sess_anime_head = self.load_sess(
os.path.join(self.model, 'cartoon_anime_h.pb'), 'model_anime_head')
self.sess_anime_bg = self.load_sess(
os.path.join(self.model, 'cartoon_anime_bg.pb'), 'model_anime_bg')
self.box_width = 288
global_mask = cv2.imread(os.path.join(self.model, 'alpha.jpg'))
global_mask = cv2.resize(
global_mask, (self.box_width, self.box_width),
interpolation=cv2.INTER_AREA)
self.global_mask = cv2.cvtColor(
global_mask, cv2.COLOR_BGR2GRAY).astype(np.float32) / 255.0
def load_sess(self, model_path, name):
config = tf.ConfigProto(allow_soft_placement=True)
config.gpu_options.allow_growth = True
sess = tf.Session(config=config)
logger.info(f'loading model from {model_path}')
with tf.gfile.FastGFile(model_path, 'rb') as f:
graph_def = tf.GraphDef()
graph_def.ParseFromString(f.read())
sess.graph.as_default()
tf.import_graph_def(graph_def, name=name)
sess.run(tf.global_variables_initializer())
logger.info(f'load model {model_path} done.')
return sess
def preprocess(self, input: Input) -> Dict[str, Any]:
if isinstance(input, str):
img = np.array(load_image(input))
elif isinstance(input, PIL.Image.Image):
img = np.array(input.convert('RGB'))
elif isinstance(input, np.ndarray):
if len(input.shape) == 2:
input = cv2.cvtColor(input, cv2.COLOR_GRAY2BGR)
img = input[:, :, ::-1]
else:
raise TypeError(f'input should be either str, PIL.Image,'
f' np.array, but got {type(input)}')
img = img.astype(np.float)
result = {'img': img}
return result
def detect_face(self, img):
src_h, src_w, _ = img.shape
boxes, landmarks, _ = self.facer.run(img)
if boxes.shape[0] == 0:
return None
else:
return landmarks
def forward(self, input: Dict[str, Any]) -> Dict[str, Any]:
img = input['img'].astype(np.uint8)
ori_h, ori_w, _ = img.shape
img = resize_size(img, size=720)
img_brg = img[:, :, ::-1]
landmarks = self.detect_face(img)
if landmarks is None:
print('No face detected!')
return {'output_png': None}
# background process
pad_bg, pad_h, pad_w = padTo16x(img_brg)
bg_res = self.sess_anime_bg.run(
self.sess_anime_bg.graph.get_tensor_by_name(
'model_anime_bg/output_image:0'),
feed_dict={'model_anime_bg/input_image:0': pad_bg})
res = bg_res[:pad_h, :pad_w, :]
for landmark in landmarks:
# get facial 5 points
f5p = get_f5p(landmark, img_brg)
# face alignment
head_img, trans_inv = warp_and_crop_face(
img,
f5p,
ratio=0.75,
reference_pts=get_reference_facial_points(default_square=True),
crop_size=(self.box_width, self.box_width),
return_trans_inv=True)
# head process
head_res = self.sess_anime_head.run(
self.sess_anime_head.graph.get_tensor_by_name(
'model_anime_head/output_image:0'),
feed_dict={
'model_anime_head/input_image:0': head_img[:, :, ::-1]
})
# merge head and background
head_trans_inv = cv2.warpAffine(
head_res,
trans_inv, (np.size(img, 1), np.size(img, 0)),
borderValue=(0, 0, 0))
mask = self.global_mask
mask_trans_inv = cv2.warpAffine(
mask,
trans_inv, (np.size(img, 1), np.size(img, 0)),
borderValue=(0, 0, 0))
mask_trans_inv = np.expand_dims(mask_trans_inv, 2)
res = mask_trans_inv * head_trans_inv + (1 - mask_trans_inv) * res
res = cv2.resize(res, (ori_w, ori_h), interpolation=cv2.INTER_AREA)
return {'output_png': res}
def postprocess(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
return inputs

Some files were not shown because too many files have changed in this diff Show More