Merge branch 'dev' into main
This commit is contained in:
		
							
								
								
									
										15
									
								
								.codacy.yml
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								.codacy.yml
									
									
									
									
									
								
							@@ -1,15 +0,0 @@
 | 
				
			|||||||
# To validate the contents of your configuration file
 | 
					 | 
				
			||||||
# run the following command in the folder where the configuration file is located:
 | 
					 | 
				
			||||||
# codacy-analysis-cli validate-configuration --directory `pwd`
 | 
					 | 
				
			||||||
# To analyse, run:
 | 
					 | 
				
			||||||
# codacy-analysis-cli analyse --tool remark-lint --directory `pwd`
 | 
					 | 
				
			||||||
---
 | 
					 | 
				
			||||||
engines:
 | 
					 | 
				
			||||||
  pylintpython3:
 | 
					 | 
				
			||||||
    exclude_paths:
 | 
					 | 
				
			||||||
      - config/engines.yml
 | 
					 | 
				
			||||||
  remark-lint:
 | 
					 | 
				
			||||||
    exclude_paths:
 | 
					 | 
				
			||||||
      - config/engines.yml
 | 
					 | 
				
			||||||
exclude_paths:
 | 
					 | 
				
			||||||
  - 'tests/**'
 | 
					 | 
				
			||||||
@@ -1,2 +0,0 @@
 | 
				
			|||||||
comment:
 | 
					 | 
				
			||||||
  require_changes: yes
 | 
					 | 
				
			||||||
							
								
								
									
										25
									
								
								.github/workflows/examples.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								.github/workflows/examples.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					# Thi workflow will install Python dependencies, run tests and lint with a single version of Python
 | 
				
			||||||
 | 
					# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					name: examples
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on:
 | 
				
			||||||
 | 
					  push:
 | 
				
			||||||
 | 
					    paths:
 | 
				
			||||||
 | 
					      - 'examples/**.py'
 | 
				
			||||||
 | 
					jobs:
 | 
				
			||||||
 | 
					  cpu:
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					    - uses: actions/checkout@v2
 | 
				
			||||||
 | 
					    - name: Set up Python 3.9
 | 
				
			||||||
 | 
					      uses: actions/setup-python@v2
 | 
				
			||||||
 | 
					      with:
 | 
				
			||||||
 | 
					        python-version: 3.9
 | 
				
			||||||
 | 
					    - name: Install dependencies
 | 
				
			||||||
 | 
					      run: |
 | 
				
			||||||
 | 
					        python -m pip install --upgrade pip
 | 
				
			||||||
 | 
					        pip install .[all]
 | 
				
			||||||
 | 
					    - name: Run examples
 | 
				
			||||||
 | 
					      run: |
 | 
				
			||||||
 | 
					        ./tests/test_examples.sh examples/
 | 
				
			||||||
							
								
								
									
										73
									
								
								.github/workflows/pythonapp.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								.github/workflows/pythonapp.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
				
			|||||||
 | 
					# This workflow will install Python dependencies, run tests and lint with a single version of Python
 | 
				
			||||||
 | 
					# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					name: tests
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					on:
 | 
				
			||||||
 | 
					  push:
 | 
				
			||||||
 | 
					  pull_request:
 | 
				
			||||||
 | 
					    branches: [ master ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					jobs:
 | 
				
			||||||
 | 
					  style:
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					    - uses: actions/checkout@v2
 | 
				
			||||||
 | 
					    - name: Set up Python 3.9
 | 
				
			||||||
 | 
					      uses: actions/setup-python@v2
 | 
				
			||||||
 | 
					      with:
 | 
				
			||||||
 | 
					        python-version: 3.9
 | 
				
			||||||
 | 
					    - name: Install dependencies
 | 
				
			||||||
 | 
					      run: |
 | 
				
			||||||
 | 
					        python -m pip install --upgrade pip
 | 
				
			||||||
 | 
					        pip install .[all]
 | 
				
			||||||
 | 
					    - uses: pre-commit/action@v2.0.3
 | 
				
			||||||
 | 
					  compatibility:
 | 
				
			||||||
 | 
					    needs: style
 | 
				
			||||||
 | 
					    strategy:
 | 
				
			||||||
 | 
					      fail-fast: false
 | 
				
			||||||
 | 
					      matrix:
 | 
				
			||||||
 | 
					        python-version: ["3.7", "3.8", "3.9"]
 | 
				
			||||||
 | 
					        os: [ubuntu-latest, windows-latest]
 | 
				
			||||||
 | 
					        exclude:
 | 
				
			||||||
 | 
					        - os: windows-latest
 | 
				
			||||||
 | 
					          python-version: "3.7"
 | 
				
			||||||
 | 
					        - os: windows-latest
 | 
				
			||||||
 | 
					          python-version: "3.8"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    runs-on: ${{ matrix.os }}
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					    - uses: actions/checkout@v2
 | 
				
			||||||
 | 
					    - name: Set up Python ${{ matrix.python-version }}
 | 
				
			||||||
 | 
					      uses: actions/setup-python@v2
 | 
				
			||||||
 | 
					      with:
 | 
				
			||||||
 | 
					        python-version: ${{ matrix.python-version }}
 | 
				
			||||||
 | 
					    - name: Install dependencies
 | 
				
			||||||
 | 
					      run: |
 | 
				
			||||||
 | 
					        python -m pip install --upgrade pip
 | 
				
			||||||
 | 
					        pip install .[all]
 | 
				
			||||||
 | 
					    - name: Test with pytest
 | 
				
			||||||
 | 
					      run: |
 | 
				
			||||||
 | 
					        pytest
 | 
				
			||||||
 | 
					  publish_pypi:
 | 
				
			||||||
 | 
					    if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
 | 
				
			||||||
 | 
					    needs: compatibility
 | 
				
			||||||
 | 
					    runs-on: ubuntu-latest
 | 
				
			||||||
 | 
					    steps:
 | 
				
			||||||
 | 
					    - uses: actions/checkout@v2
 | 
				
			||||||
 | 
					    - name: Set up Python 3.9
 | 
				
			||||||
 | 
					      uses: actions/setup-python@v2
 | 
				
			||||||
 | 
					      with:
 | 
				
			||||||
 | 
					        python-version: "3.9"
 | 
				
			||||||
 | 
					    - name: Install dependencies
 | 
				
			||||||
 | 
					      run: |
 | 
				
			||||||
 | 
					        python -m pip install --upgrade pip
 | 
				
			||||||
 | 
					        pip install .[all]
 | 
				
			||||||
 | 
					        pip install wheel
 | 
				
			||||||
 | 
					    - name: Build package
 | 
				
			||||||
 | 
					      run: python setup.py sdist bdist_wheel
 | 
				
			||||||
 | 
					    - name: Publish a Python distribution to PyPI
 | 
				
			||||||
 | 
					      uses: pypa/gh-action-pypi-publish@release/v1
 | 
				
			||||||
 | 
					      with:
 | 
				
			||||||
 | 
					        user: __token__
 | 
				
			||||||
 | 
					        password: ${{ secrets.PYPI_API_TOKEN }}
 | 
				
			||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
repos:
 | 
					repos:
 | 
				
			||||||
- repo: https://github.com/pre-commit/pre-commit-hooks
 | 
					- repo: https://github.com/pre-commit/pre-commit-hooks
 | 
				
			||||||
  rev: v4.0.1
 | 
					  rev: v4.1.0
 | 
				
			||||||
  hooks:
 | 
					  hooks:
 | 
				
			||||||
  - id: trailing-whitespace
 | 
					  - id: trailing-whitespace
 | 
				
			||||||
  - id: end-of-file-fixer
 | 
					  - id: end-of-file-fixer
 | 
				
			||||||
@@ -18,19 +18,19 @@ repos:
 | 
				
			|||||||
  - id: autoflake
 | 
					  - id: autoflake
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- repo: http://github.com/PyCQA/isort
 | 
					- repo: http://github.com/PyCQA/isort
 | 
				
			||||||
  rev: 5.8.0
 | 
					  rev: 5.10.1
 | 
				
			||||||
  hooks:
 | 
					  hooks:
 | 
				
			||||||
  - id: isort
 | 
					  - id: isort
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- repo: https://github.com/pre-commit/mirrors-mypy
 | 
					- repo: https://github.com/pre-commit/mirrors-mypy
 | 
				
			||||||
  rev: v0.902
 | 
					  rev: v0.931
 | 
				
			||||||
  hooks:
 | 
					  hooks:
 | 
				
			||||||
  - id: mypy
 | 
					  - id: mypy
 | 
				
			||||||
    files: prototorch
 | 
					    files: prototorch
 | 
				
			||||||
    additional_dependencies: [types-pkg_resources]
 | 
					    additional_dependencies: [types-pkg_resources]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- repo: https://github.com/pre-commit/mirrors-yapf
 | 
					- repo: https://github.com/pre-commit/mirrors-yapf
 | 
				
			||||||
  rev: v0.31.0
 | 
					  rev: v0.32.0
 | 
				
			||||||
  hooks:
 | 
					  hooks:
 | 
				
			||||||
  - id: yapf
 | 
					  - id: yapf
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -42,7 +42,7 @@ repos:
 | 
				
			|||||||
  - id: python-check-blanket-noqa
 | 
					  - id: python-check-blanket-noqa
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- repo: https://github.com/asottile/pyupgrade
 | 
					- repo: https://github.com/asottile/pyupgrade
 | 
				
			||||||
  rev: v2.19.4
 | 
					  rev: v2.31.0
 | 
				
			||||||
  hooks:
 | 
					  hooks:
 | 
				
			||||||
  - id: pyupgrade
 | 
					  - id: pyupgrade
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										44
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								.travis.yml
									
									
									
									
									
								
							@@ -1,44 +0,0 @@
 | 
				
			|||||||
dist: bionic
 | 
					 | 
				
			||||||
sudo: false
 | 
					 | 
				
			||||||
language: python
 | 
					 | 
				
			||||||
python:
 | 
					 | 
				
			||||||
  - 3.9
 | 
					 | 
				
			||||||
  - 3.8
 | 
					 | 
				
			||||||
  - 3.7
 | 
					 | 
				
			||||||
  - 3.6
 | 
					 | 
				
			||||||
cache:
 | 
					 | 
				
			||||||
  directories:
 | 
					 | 
				
			||||||
  - "$HOME/.cache/pip"
 | 
					 | 
				
			||||||
  - "./tests/artifacts"
 | 
					 | 
				
			||||||
  - "$HOME/datasets"
 | 
					 | 
				
			||||||
install:
 | 
					 | 
				
			||||||
- pip install git+git://github.com/si-cim/prototorch@dev --progress-bar off
 | 
					 | 
				
			||||||
- pip install .[all] --progress-bar off
 | 
					 | 
				
			||||||
script:
 | 
					 | 
				
			||||||
- coverage run -m pytest
 | 
					 | 
				
			||||||
- ./tests/test_examples.sh examples/
 | 
					 | 
				
			||||||
after_success:
 | 
					 | 
				
			||||||
- bash <(curl -s https://codecov.io/bash)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Publish on PyPI
 | 
					 | 
				
			||||||
jobs:
 | 
					 | 
				
			||||||
  include:
 | 
					 | 
				
			||||||
    - stage: build
 | 
					 | 
				
			||||||
      python: 3.9
 | 
					 | 
				
			||||||
      script: echo "Starting Pypi build"
 | 
					 | 
				
			||||||
      deploy:
 | 
					 | 
				
			||||||
        provider: pypi
 | 
					 | 
				
			||||||
        username: __token__
 | 
					 | 
				
			||||||
        distributions: "sdist bdist_wheel"
 | 
					 | 
				
			||||||
        password:
 | 
					 | 
				
			||||||
          secure: PDoASdYdVlt1aIROYilAsCW6XpBs/TDel0CSptDzX0CI7i4+ksEW6Jk0JyL58bQt7V4F8PeGty4A8SODzAUIk2d8sty5RI4VJjvXZFCXlUsW+JGUN3EvWNqJLnwN8TDxgu2ENao37GUh0dC6pL8b6bVDGeOLaY1E/YR1jimmTJuxxjKjBIU8ByqTNBnC3rzybMTPU3nRoOM/WMQUyReHrPoUJj685sLqrLruhAqhiYsPbotP8xY6i8+KBbhp5vgiARV2+LkbeGcYZwozCzrEqPKY7YIfVPh895cw0v4NRyFwK1P2jyyIt22Z9Ni0Uy1J5/Qp9Sv6mBPeGjm3pnpDCQyS+2bNIDaj08KUYTIo1mC/Jcu4jQgppZEF+oey9q1tgGo+/JhsTeERKV9BoPF5HDiRArU1s5aWJjFnCsHfu+W1XqX8bwN3aTYsEIaApT3/irc6XyFJIfMN82+z+lUcZ4Y1yAHT3nH1Vif+pZYZB0UOSGrHwuI/UayjKzbCzHMuHWylWB/9ehd4o4YVp6iubVHc7Sj0KQkwBgwgl6TvwNcUuFsplFabCxmX0mVcavXsWiOBc+ivPmU6574zGj0JcEk5ghVgnKH+QS96aVrKOzegwbl4O13jY8dJp+/zgXl0gJOvRKr4BhuBJKcBaMQHdSKUChVsJJtqDyt59GvWcbg=
 | 
					 | 
				
			||||||
        on:
 | 
					 | 
				
			||||||
          tags: true
 | 
					 | 
				
			||||||
          skip_existing: true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# The password is encrypted with:
 | 
					 | 
				
			||||||
# `cd prototorch && travis encrypt your-pypi-api-token --add deploy.password`
 | 
					 | 
				
			||||||
# See https://docs.travis-ci.com/user/deployment/pypi and
 | 
					 | 
				
			||||||
# https://github.com/travis-ci/travis.rb#installation
 | 
					 | 
				
			||||||
# for more details
 | 
					 | 
				
			||||||
# Note: The encrypt command does not work well in ZSH.
 | 
					 | 
				
			||||||
@@ -1,6 +1,5 @@
 | 
				
			|||||||
# ProtoTorch Models
 | 
					# ProtoTorch Models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[](https://travis-ci.com/github/si-cim/prototorch_models)
 | 
					 | 
				
			||||||
[](https://github.com/si-cim/prototorch_models/releases)
 | 
					[](https://github.com/si-cim/prototorch_models/releases)
 | 
				
			||||||
[](https://pypi.org/project/prototorch_models/)
 | 
					[](https://pypi.org/project/prototorch_models/)
 | 
				
			||||||
[](https://github.com/si-cim/prototorch_models/blob/master/LICENSE)
 | 
					[](https://github.com/si-cim/prototorch_models/blob/master/LICENSE)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,4 +1,4 @@
 | 
				
			|||||||
"""GLVQ example using the spiral dataset."""
 | 
					"""GMLVQ example using the spiral dataset."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import argparse
 | 
					import argparse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										104
									
								
								examples/gtlvq_mnist.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								examples/gtlvq_mnist.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,104 @@
 | 
				
			|||||||
 | 
					"""GTLVQ example using the MNIST dataset."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import argparse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import prototorch as pt
 | 
				
			||||||
 | 
					import pytorch_lightning as pl
 | 
				
			||||||
 | 
					import torch
 | 
				
			||||||
 | 
					from torchvision import transforms
 | 
				
			||||||
 | 
					from torchvision.datasets import MNIST
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    # Command-line arguments
 | 
				
			||||||
 | 
					    parser = argparse.ArgumentParser()
 | 
				
			||||||
 | 
					    parser = pl.Trainer.add_argparse_args(parser)
 | 
				
			||||||
 | 
					    args = parser.parse_args()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Dataset
 | 
				
			||||||
 | 
					    train_ds = MNIST(
 | 
				
			||||||
 | 
					        "~/datasets",
 | 
				
			||||||
 | 
					        train=True,
 | 
				
			||||||
 | 
					        download=True,
 | 
				
			||||||
 | 
					        transform=transforms.Compose([
 | 
				
			||||||
 | 
					            transforms.ToTensor(),
 | 
				
			||||||
 | 
					        ]),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    test_ds = MNIST(
 | 
				
			||||||
 | 
					        "~/datasets",
 | 
				
			||||||
 | 
					        train=False,
 | 
				
			||||||
 | 
					        download=True,
 | 
				
			||||||
 | 
					        transform=transforms.Compose([
 | 
				
			||||||
 | 
					            transforms.ToTensor(),
 | 
				
			||||||
 | 
					        ]),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Dataloaders
 | 
				
			||||||
 | 
					    train_loader = torch.utils.data.DataLoader(train_ds,
 | 
				
			||||||
 | 
					                                               num_workers=0,
 | 
				
			||||||
 | 
					                                               batch_size=256)
 | 
				
			||||||
 | 
					    test_loader = torch.utils.data.DataLoader(test_ds,
 | 
				
			||||||
 | 
					                                              num_workers=0,
 | 
				
			||||||
 | 
					                                              batch_size=256)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Hyperparameters
 | 
				
			||||||
 | 
					    num_classes = 10
 | 
				
			||||||
 | 
					    prototypes_per_class = 1
 | 
				
			||||||
 | 
					    hparams = dict(
 | 
				
			||||||
 | 
					        input_dim=28 * 28,
 | 
				
			||||||
 | 
					        latent_dim=28,
 | 
				
			||||||
 | 
					        distribution=(num_classes, prototypes_per_class),
 | 
				
			||||||
 | 
					        proto_lr=0.01,
 | 
				
			||||||
 | 
					        bb_lr=0.01,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Initialize the model
 | 
				
			||||||
 | 
					    model = pt.models.ImageGTLVQ(
 | 
				
			||||||
 | 
					        hparams,
 | 
				
			||||||
 | 
					        optimizer=torch.optim.Adam,
 | 
				
			||||||
 | 
					        prototypes_initializer=pt.initializers.SMCI(train_ds),
 | 
				
			||||||
 | 
					        #Use one batch of data for subspace initiator.
 | 
				
			||||||
 | 
					        omega_initializer=pt.initializers.PCALinearTransformInitializer(
 | 
				
			||||||
 | 
					            next(iter(train_loader))[0].reshape(256, 28 * 28)))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Callbacks
 | 
				
			||||||
 | 
					    vis = pt.models.VisImgComp(
 | 
				
			||||||
 | 
					        data=train_ds,
 | 
				
			||||||
 | 
					        num_columns=10,
 | 
				
			||||||
 | 
					        show=False,
 | 
				
			||||||
 | 
					        tensorboard=True,
 | 
				
			||||||
 | 
					        random_data=100,
 | 
				
			||||||
 | 
					        add_embedding=True,
 | 
				
			||||||
 | 
					        embedding_data=200,
 | 
				
			||||||
 | 
					        flatten_data=False,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    pruning = pt.models.PruneLoserPrototypes(
 | 
				
			||||||
 | 
					        threshold=0.01,
 | 
				
			||||||
 | 
					        idle_epochs=1,
 | 
				
			||||||
 | 
					        prune_quota_per_epoch=10,
 | 
				
			||||||
 | 
					        frequency=1,
 | 
				
			||||||
 | 
					        verbose=True,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    es = pl.callbacks.EarlyStopping(
 | 
				
			||||||
 | 
					        monitor="train_loss",
 | 
				
			||||||
 | 
					        min_delta=0.001,
 | 
				
			||||||
 | 
					        patience=15,
 | 
				
			||||||
 | 
					        mode="min",
 | 
				
			||||||
 | 
					        check_on_train_epoch_end=True,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Setup trainer
 | 
				
			||||||
 | 
					    # using GPUs here is strongly recommended!
 | 
				
			||||||
 | 
					    trainer = pl.Trainer.from_argparse_args(
 | 
				
			||||||
 | 
					        args,
 | 
				
			||||||
 | 
					        callbacks=[
 | 
				
			||||||
 | 
					            vis,
 | 
				
			||||||
 | 
					            pruning,
 | 
				
			||||||
 | 
					            # es,
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        terminate_on_nan=True,
 | 
				
			||||||
 | 
					        weights_summary=None,
 | 
				
			||||||
 | 
					        accelerator="ddp",
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Training loop
 | 
				
			||||||
 | 
					    trainer.fit(model, train_loader)
 | 
				
			||||||
							
								
								
									
										63
									
								
								examples/gtlvq_moons.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								examples/gtlvq_moons.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,63 @@
 | 
				
			|||||||
 | 
					"""Localized-GTLVQ example using the Moons dataset."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import argparse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import prototorch as pt
 | 
				
			||||||
 | 
					import pytorch_lightning as pl
 | 
				
			||||||
 | 
					import torch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    # Command-line arguments
 | 
				
			||||||
 | 
					    parser = argparse.ArgumentParser()
 | 
				
			||||||
 | 
					    parser = pl.Trainer.add_argparse_args(parser)
 | 
				
			||||||
 | 
					    args = parser.parse_args()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Reproducibility
 | 
				
			||||||
 | 
					    pl.utilities.seed.seed_everything(seed=2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Dataset
 | 
				
			||||||
 | 
					    train_ds = pt.datasets.Moons(num_samples=300, noise=0.2, seed=42)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Dataloaders
 | 
				
			||||||
 | 
					    train_loader = torch.utils.data.DataLoader(train_ds,
 | 
				
			||||||
 | 
					                                               batch_size=256,
 | 
				
			||||||
 | 
					                                               shuffle=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Hyperparameters
 | 
				
			||||||
 | 
					    # Latent_dim should be lower than input dim.
 | 
				
			||||||
 | 
					    hparams = dict(distribution=[1, 3], input_dim=2, latent_dim=1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Initialize the model
 | 
				
			||||||
 | 
					    model = pt.models.GTLVQ(
 | 
				
			||||||
 | 
					        hparams, prototypes_initializer=pt.initializers.SMCI(train_ds))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Compute intermediate input and output sizes
 | 
				
			||||||
 | 
					    model.example_input_array = torch.zeros(4, 2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Summary
 | 
				
			||||||
 | 
					    print(model)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Callbacks
 | 
				
			||||||
 | 
					    vis = pt.models.VisGLVQ2D(data=train_ds)
 | 
				
			||||||
 | 
					    es = pl.callbacks.EarlyStopping(
 | 
				
			||||||
 | 
					        monitor="train_acc",
 | 
				
			||||||
 | 
					        min_delta=0.001,
 | 
				
			||||||
 | 
					        patience=20,
 | 
				
			||||||
 | 
					        mode="max",
 | 
				
			||||||
 | 
					        verbose=False,
 | 
				
			||||||
 | 
					        check_on_train_epoch_end=True,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Setup trainer
 | 
				
			||||||
 | 
					    trainer = pl.Trainer.from_argparse_args(
 | 
				
			||||||
 | 
					        args,
 | 
				
			||||||
 | 
					        callbacks=[
 | 
				
			||||||
 | 
					            vis,
 | 
				
			||||||
 | 
					            es,
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        weights_summary="full",
 | 
				
			||||||
 | 
					        accelerator="ddp",
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Training loop
 | 
				
			||||||
 | 
					    trainer.fit(model, train_loader)
 | 
				
			||||||
@@ -10,6 +10,7 @@ from prototorch.utils.colors import hex_to_rgb
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Vis2DColorSOM(pl.Callback):
 | 
					class Vis2DColorSOM(pl.Callback):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, data, title="ColorSOMe", pause_time=0.1):
 | 
					    def __init__(self, data, title="ColorSOMe", pause_time=0.1):
 | 
				
			||||||
        super().__init__()
 | 
					        super().__init__()
 | 
				
			||||||
        self.title = title
 | 
					        self.title = title
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,7 @@ import torch
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Backbone(torch.nn.Module):
 | 
					class Backbone(torch.nn.Module):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, input_size=4, hidden_size=10, latent_size=2):
 | 
					    def __init__(self, input_size=4, hidden_size=10, latent_size=2):
 | 
				
			||||||
        super().__init__()
 | 
					        super().__init__()
 | 
				
			||||||
        self.input_size = input_size
 | 
					        self.input_size = input_size
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,6 +8,7 @@ import torch
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Backbone(torch.nn.Module):
 | 
					class Backbone(torch.nn.Module):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, input_size=4, hidden_size=10, latent_size=2):
 | 
					    def __init__(self, input_size=4, hidden_size=10, latent_size=2):
 | 
				
			||||||
        super().__init__()
 | 
					        super().__init__()
 | 
				
			||||||
        self.input_size = input_size
 | 
					        self.input_size = input_size
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										73
									
								
								examples/siamese_gtlvq_iris.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								examples/siamese_gtlvq_iris.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
				
			|||||||
 | 
					"""Siamese GTLVQ example using all four dimensions of the Iris dataset."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import argparse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import prototorch as pt
 | 
				
			||||||
 | 
					import pytorch_lightning as pl
 | 
				
			||||||
 | 
					import torch
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Backbone(torch.nn.Module):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, input_size=4, hidden_size=10, latent_size=2):
 | 
				
			||||||
 | 
					        super().__init__()
 | 
				
			||||||
 | 
					        self.input_size = input_size
 | 
				
			||||||
 | 
					        self.hidden_size = hidden_size
 | 
				
			||||||
 | 
					        self.latent_size = latent_size
 | 
				
			||||||
 | 
					        self.dense1 = torch.nn.Linear(self.input_size, self.hidden_size)
 | 
				
			||||||
 | 
					        self.dense2 = torch.nn.Linear(self.hidden_size, self.latent_size)
 | 
				
			||||||
 | 
					        self.activation = torch.nn.Sigmoid()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def forward(self, x):
 | 
				
			||||||
 | 
					        x = self.activation(self.dense1(x))
 | 
				
			||||||
 | 
					        out = self.activation(self.dense2(x))
 | 
				
			||||||
 | 
					        return out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    # Command-line arguments
 | 
				
			||||||
 | 
					    parser = argparse.ArgumentParser()
 | 
				
			||||||
 | 
					    parser = pl.Trainer.add_argparse_args(parser)
 | 
				
			||||||
 | 
					    args = parser.parse_args()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Dataset
 | 
				
			||||||
 | 
					    train_ds = pt.datasets.Iris()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Reproducibility
 | 
				
			||||||
 | 
					    pl.utilities.seed.seed_everything(seed=2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Dataloaders
 | 
				
			||||||
 | 
					    train_loader = torch.utils.data.DataLoader(train_ds, batch_size=150)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Hyperparameters
 | 
				
			||||||
 | 
					    hparams = dict(distribution=[1, 2, 3],
 | 
				
			||||||
 | 
					                   proto_lr=0.01,
 | 
				
			||||||
 | 
					                   bb_lr=0.01,
 | 
				
			||||||
 | 
					                   input_dim=2,
 | 
				
			||||||
 | 
					                   latent_dim=1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Initialize the backbone
 | 
				
			||||||
 | 
					    backbone = Backbone(latent_size=hparams["input_dim"])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Initialize the model
 | 
				
			||||||
 | 
					    model = pt.models.SiameseGTLVQ(
 | 
				
			||||||
 | 
					        hparams,
 | 
				
			||||||
 | 
					        prototypes_initializer=pt.initializers.SMCI(train_ds),
 | 
				
			||||||
 | 
					        backbone=backbone,
 | 
				
			||||||
 | 
					        both_path_gradients=False,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Model summary
 | 
				
			||||||
 | 
					    print(model)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Callbacks
 | 
				
			||||||
 | 
					    vis = pt.models.VisSiameseGLVQ2D(data=train_ds, border=0.1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Setup trainer
 | 
				
			||||||
 | 
					    trainer = pl.Trainer.from_argparse_args(
 | 
				
			||||||
 | 
					        args,
 | 
				
			||||||
 | 
					        callbacks=[vis],
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Training loop
 | 
				
			||||||
 | 
					    trainer.fit(model, train_loader)
 | 
				
			||||||
@@ -8,17 +8,34 @@ from .glvq import (
 | 
				
			|||||||
    GLVQ21,
 | 
					    GLVQ21,
 | 
				
			||||||
    GMLVQ,
 | 
					    GMLVQ,
 | 
				
			||||||
    GRLVQ,
 | 
					    GRLVQ,
 | 
				
			||||||
 | 
					    GTLVQ,
 | 
				
			||||||
    LGMLVQ,
 | 
					    LGMLVQ,
 | 
				
			||||||
    LVQMLN,
 | 
					    LVQMLN,
 | 
				
			||||||
    ImageGLVQ,
 | 
					    ImageGLVQ,
 | 
				
			||||||
    ImageGMLVQ,
 | 
					    ImageGMLVQ,
 | 
				
			||||||
 | 
					    ImageGTLVQ,
 | 
				
			||||||
    SiameseGLVQ,
 | 
					    SiameseGLVQ,
 | 
				
			||||||
    SiameseGMLVQ,
 | 
					    SiameseGMLVQ,
 | 
				
			||||||
 | 
					    SiameseGTLVQ,
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
from .knn import KNN
 | 
					from .knn import KNN
 | 
				
			||||||
from .lvq import LVQ1, LVQ21, MedianLVQ
 | 
					from .lvq import (
 | 
				
			||||||
from .probabilistic import CELVQ, PLVQ, RSLVQ, SLVQ
 | 
					    LVQ1,
 | 
				
			||||||
from .unsupervised import GrowingNeuralGas, HeskesSOM, KohonenSOM, NeuralGas
 | 
					    LVQ21,
 | 
				
			||||||
 | 
					    MedianLVQ,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					from .probabilistic import (
 | 
				
			||||||
 | 
					    CELVQ,
 | 
				
			||||||
 | 
					    PLVQ,
 | 
				
			||||||
 | 
					    RSLVQ,
 | 
				
			||||||
 | 
					    SLVQ,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					from .unsupervised import (
 | 
				
			||||||
 | 
					    GrowingNeuralGas,
 | 
				
			||||||
 | 
					    HeskesSOM,
 | 
				
			||||||
 | 
					    KohonenSOM,
 | 
				
			||||||
 | 
					    NeuralGas,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
from .vis import *
 | 
					from .vis import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__version__ = "0.4.0"
 | 
					__version__ = "0.4.0"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@ from ..nn.wrappers import LambdaLayer
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class ProtoTorchBolt(pl.LightningModule):
 | 
					class ProtoTorchBolt(pl.LightningModule):
 | 
				
			||||||
    """All ProtoTorch models are ProtoTorch Bolts."""
 | 
					    """All ProtoTorch models are ProtoTorch Bolts."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        super().__init__()
 | 
					        super().__init__()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -52,6 +53,7 @@ class ProtoTorchBolt(pl.LightningModule):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PrototypeModel(ProtoTorchBolt):
 | 
					class PrototypeModel(ProtoTorchBolt):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        super().__init__(hparams, **kwargs)
 | 
					        super().__init__(hparams, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -81,6 +83,7 @@ class PrototypeModel(ProtoTorchBolt):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class UnsupervisedPrototypeModel(PrototypeModel):
 | 
					class UnsupervisedPrototypeModel(PrototypeModel):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        super().__init__(hparams, **kwargs)
 | 
					        super().__init__(hparams, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -103,6 +106,7 @@ class UnsupervisedPrototypeModel(PrototypeModel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SupervisedPrototypeModel(PrototypeModel):
 | 
					class SupervisedPrototypeModel(PrototypeModel):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        super().__init__(hparams, **kwargs)
 | 
					        super().__init__(hparams, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -135,7 +139,7 @@ class SupervisedPrototypeModel(PrototypeModel):
 | 
				
			|||||||
        distances = self.compute_distances(x)
 | 
					        distances = self.compute_distances(x)
 | 
				
			||||||
        _, plabels = self.proto_layer()
 | 
					        _, plabels = self.proto_layer()
 | 
				
			||||||
        winning = stratified_min_pooling(distances, plabels)
 | 
					        winning = stratified_min_pooling(distances, plabels)
 | 
				
			||||||
        y_pred = torch.nn.functional.softmin(winning)
 | 
					        y_pred = torch.nn.functional.softmin(winning, dim=1)
 | 
				
			||||||
        return y_pred
 | 
					        return y_pred
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def predict_from_distances(self, distances):
 | 
					    def predict_from_distances(self, distances):
 | 
				
			||||||
@@ -178,6 +182,7 @@ class ProtoTorchMixin(object):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class NonGradientMixin(ProtoTorchMixin):
 | 
					class NonGradientMixin(ProtoTorchMixin):
 | 
				
			||||||
    """Mixin for custom non-gradient optimization."""
 | 
					    """Mixin for custom non-gradient optimization."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, *args, **kwargs):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        super().__init__(*args, **kwargs)
 | 
					        super().__init__(*args, **kwargs)
 | 
				
			||||||
        self.automatic_optimization = False
 | 
					        self.automatic_optimization = False
 | 
				
			||||||
@@ -188,6 +193,7 @@ class NonGradientMixin(ProtoTorchMixin):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class ImagePrototypesMixin(ProtoTorchMixin):
 | 
					class ImagePrototypesMixin(ProtoTorchMixin):
 | 
				
			||||||
    """Mixin for models with image prototypes."""
 | 
					    """Mixin for models with image prototypes."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def on_train_batch_end(self, outputs, batch, batch_idx, dataloader_idx):
 | 
					    def on_train_batch_end(self, outputs, batch, batch_idx, dataloader_idx):
 | 
				
			||||||
        """Constrain the components to the range [0, 1] by clamping after updates."""
 | 
					        """Constrain the components to the range [0, 1] by clamping after updates."""
 | 
				
			||||||
        self.proto_layer.components.data.clamp_(0.0, 1.0)
 | 
					        self.proto_layer.components.data.clamp_(0.0, 1.0)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,7 @@ from .extras import ConnectionTopology
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PruneLoserPrototypes(pl.Callback):
 | 
					class PruneLoserPrototypes(pl.Callback):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self,
 | 
					    def __init__(self,
 | 
				
			||||||
                 threshold=0.01,
 | 
					                 threshold=0.01,
 | 
				
			||||||
                 idle_epochs=10,
 | 
					                 idle_epochs=10,
 | 
				
			||||||
@@ -67,6 +68,7 @@ class PruneLoserPrototypes(pl.Callback):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PrototypeConvergence(pl.Callback):
 | 
					class PrototypeConvergence(pl.Callback):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, min_delta=0.01, idle_epochs=10, verbose=False):
 | 
					    def __init__(self, min_delta=0.01, idle_epochs=10, verbose=False):
 | 
				
			||||||
        self.min_delta = min_delta
 | 
					        self.min_delta = min_delta
 | 
				
			||||||
        self.idle_epochs = idle_epochs  # epochs to wait
 | 
					        self.idle_epochs = idle_epochs  # epochs to wait
 | 
				
			||||||
@@ -89,6 +91,7 @@ class GNGCallback(pl.Callback):
 | 
				
			|||||||
    Based on "A Growing Neural Gas Network Learns Topologies" by Bernd Fritzke.
 | 
					    Based on "A Growing Neural Gas Network Learns Topologies" by Bernd Fritzke.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, reduction=0.1, freq=10):
 | 
					    def __init__(self, reduction=0.1, freq=10):
 | 
				
			||||||
        self.reduction = reduction
 | 
					        self.reduction = reduction
 | 
				
			||||||
        self.freq = freq
 | 
					        self.freq = freq
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,6 +13,7 @@ from .glvq import SiameseGLVQ
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class CBC(SiameseGLVQ):
 | 
					class CBC(SiameseGLVQ):
 | 
				
			||||||
    """Classification-By-Components."""
 | 
					    """Classification-By-Components."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        super().__init__(hparams, **kwargs)
 | 
					        super().__init__(hparams, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,7 +15,46 @@ def rank_scaled_gaussian(distances, lambd):
 | 
				
			|||||||
    return torch.exp(-torch.exp(-ranks / lambd) * distances)
 | 
					    return torch.exp(-torch.exp(-ranks / lambd) * distances)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def orthogonalization(tensors):
 | 
				
			||||||
 | 
					    """Orthogonalization via polar decomposition """
 | 
				
			||||||
 | 
					    u, _, v = torch.svd(tensors, compute_uv=True)
 | 
				
			||||||
 | 
					    u_shape = tuple(list(u.shape))
 | 
				
			||||||
 | 
					    v_shape = tuple(list(v.shape))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # reshape to (num x N x M)
 | 
				
			||||||
 | 
					    u = torch.reshape(u, (-1, u_shape[-2], u_shape[-1]))
 | 
				
			||||||
 | 
					    v = torch.reshape(v, (-1, v_shape[-2], v_shape[-1]))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    out = u @ v.permute([0, 2, 1])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    out = torch.reshape(out, u_shape[:-1] + (v_shape[-2], ))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return out
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def ltangent_distance(x, y, omegas):
 | 
				
			||||||
 | 
					    r"""Localized Tangent distance.
 | 
				
			||||||
 | 
					    Compute Orthogonal Complement: math:`\bm P_k = \bm I - \Omega_k \Omega_k^T`
 | 
				
			||||||
 | 
					    Compute Tangent Distance: math:`{\| \bm P \bm x - \bm P_k \bm y_k \|}_2`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    :param `torch.tensor` omegas: Three dimensional matrix
 | 
				
			||||||
 | 
					    :rtype: `torch.tensor`
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    x, y = [arr.view(arr.size(0), -1) for arr in (x, y)]
 | 
				
			||||||
 | 
					    p = torch.eye(omegas.shape[-2], device=omegas.device) - torch.bmm(
 | 
				
			||||||
 | 
					        omegas, omegas.permute([0, 2, 1]))
 | 
				
			||||||
 | 
					    projected_x = x @ p
 | 
				
			||||||
 | 
					    projected_y = torch.diagonal(y @ p).T
 | 
				
			||||||
 | 
					    expanded_y = torch.unsqueeze(projected_y, dim=1)
 | 
				
			||||||
 | 
					    batchwise_difference = expanded_y - projected_x
 | 
				
			||||||
 | 
					    differences_squared = batchwise_difference**2
 | 
				
			||||||
 | 
					    distances = torch.sqrt(torch.sum(differences_squared, dim=2))
 | 
				
			||||||
 | 
					    distances = distances.permute(1, 0)
 | 
				
			||||||
 | 
					    return distances
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GaussianPrior(torch.nn.Module):
 | 
					class GaussianPrior(torch.nn.Module):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, variance):
 | 
					    def __init__(self, variance):
 | 
				
			||||||
        super().__init__()
 | 
					        super().__init__()
 | 
				
			||||||
        self.variance = variance
 | 
					        self.variance = variance
 | 
				
			||||||
@@ -25,6 +64,7 @@ class GaussianPrior(torch.nn.Module):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RankScaledGaussianPrior(torch.nn.Module):
 | 
					class RankScaledGaussianPrior(torch.nn.Module):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, lambd):
 | 
					    def __init__(self, lambd):
 | 
				
			||||||
        super().__init__()
 | 
					        super().__init__()
 | 
				
			||||||
        self.lambd = lambd
 | 
					        self.lambd = lambd
 | 
				
			||||||
@@ -34,6 +74,7 @@ class RankScaledGaussianPrior(torch.nn.Module):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ConnectionTopology(torch.nn.Module):
 | 
					class ConnectionTopology(torch.nn.Module):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, agelimit, num_prototypes):
 | 
					    def __init__(self, agelimit, num_prototypes):
 | 
				
			||||||
        super().__init__()
 | 
					        super().__init__()
 | 
				
			||||||
        self.agelimit = agelimit
 | 
					        self.agelimit = agelimit
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,16 +4,26 @@ import torch
 | 
				
			|||||||
from torch.nn.parameter import Parameter
 | 
					from torch.nn.parameter import Parameter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ..core.competitions import wtac
 | 
					from ..core.competitions import wtac
 | 
				
			||||||
from ..core.distances import lomega_distance, omega_distance, squared_euclidean_distance
 | 
					from ..core.distances import (
 | 
				
			||||||
 | 
					    lomega_distance,
 | 
				
			||||||
 | 
					    omega_distance,
 | 
				
			||||||
 | 
					    squared_euclidean_distance,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
from ..core.initializers import EyeTransformInitializer
 | 
					from ..core.initializers import EyeTransformInitializer
 | 
				
			||||||
from ..core.losses import GLVQLoss, lvq1_loss, lvq21_loss
 | 
					from ..core.losses import (
 | 
				
			||||||
 | 
					    GLVQLoss,
 | 
				
			||||||
 | 
					    lvq1_loss,
 | 
				
			||||||
 | 
					    lvq21_loss,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
from ..core.transforms import LinearTransform
 | 
					from ..core.transforms import LinearTransform
 | 
				
			||||||
from ..nn.wrappers import LambdaLayer, LossLayer
 | 
					from ..nn.wrappers import LambdaLayer, LossLayer
 | 
				
			||||||
from .abstract import ImagePrototypesMixin, SupervisedPrototypeModel
 | 
					from .abstract import ImagePrototypesMixin, SupervisedPrototypeModel
 | 
				
			||||||
 | 
					from .extras import ltangent_distance, orthogonalization
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GLVQ(SupervisedPrototypeModel):
 | 
					class GLVQ(SupervisedPrototypeModel):
 | 
				
			||||||
    """Generalized Learning Vector Quantization."""
 | 
					    """Generalized Learning Vector Quantization."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        super().__init__(hparams, **kwargs)
 | 
					        super().__init__(hparams, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -98,6 +108,7 @@ class SiameseGLVQ(GLVQ):
 | 
				
			|||||||
    transformation pipeline are only learned from the inputs.
 | 
					    transformation pipeline are only learned from the inputs.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self,
 | 
					    def __init__(self,
 | 
				
			||||||
                 hparams,
 | 
					                 hparams,
 | 
				
			||||||
                 backbone=torch.nn.Identity(),
 | 
					                 backbone=torch.nn.Identity(),
 | 
				
			||||||
@@ -164,6 +175,7 @@ class LVQMLN(SiameseGLVQ):
 | 
				
			|||||||
    rather in the embedding space.
 | 
					    rather in the embedding space.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def compute_distances(self, x):
 | 
					    def compute_distances(self, x):
 | 
				
			||||||
        latent_protos, _ = self.proto_layer()
 | 
					        latent_protos, _ = self.proto_layer()
 | 
				
			||||||
        latent_x = self.backbone(x)
 | 
					        latent_x = self.backbone(x)
 | 
				
			||||||
@@ -179,6 +191,7 @@ class GRLVQ(SiameseGLVQ):
 | 
				
			|||||||
    TODO Make a RelevanceLayer. `bb_lr` is ignored otherwise.
 | 
					    TODO Make a RelevanceLayer. `bb_lr` is ignored otherwise.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        super().__init__(hparams, **kwargs)
 | 
					        super().__init__(hparams, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -204,6 +217,7 @@ class SiameseGMLVQ(SiameseGLVQ):
 | 
				
			|||||||
    Implemented as a Siamese network with a linear transformation backbone.
 | 
					    Implemented as a Siamese network with a linear transformation backbone.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        super().__init__(hparams, **kwargs)
 | 
					        super().__init__(hparams, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -234,6 +248,7 @@ class GMLVQ(GLVQ):
 | 
				
			|||||||
    function. This makes it easier to implement a localized variant.
 | 
					    function. This makes it easier to implement a localized variant.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        distance_fn = kwargs.pop("distance_fn", omega_distance)
 | 
					        distance_fn = kwargs.pop("distance_fn", omega_distance)
 | 
				
			||||||
        super().__init__(hparams, distance_fn=distance_fn, **kwargs)
 | 
					        super().__init__(hparams, distance_fn=distance_fn, **kwargs)
 | 
				
			||||||
@@ -268,6 +283,7 @@ class GMLVQ(GLVQ):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class LGMLVQ(GMLVQ):
 | 
					class LGMLVQ(GMLVQ):
 | 
				
			||||||
    """Localized and Generalized Matrix Learning Vector Quantization."""
 | 
					    """Localized and Generalized Matrix Learning Vector Quantization."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        distance_fn = kwargs.pop("distance_fn", lomega_distance)
 | 
					        distance_fn = kwargs.pop("distance_fn", lomega_distance)
 | 
				
			||||||
        super().__init__(hparams, distance_fn=distance_fn, **kwargs)
 | 
					        super().__init__(hparams, distance_fn=distance_fn, **kwargs)
 | 
				
			||||||
@@ -282,8 +298,48 @@ class LGMLVQ(GMLVQ):
 | 
				
			|||||||
        self.register_parameter("_omega", Parameter(omega))
 | 
					        self.register_parameter("_omega", Parameter(omega))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GTLVQ(LGMLVQ):
 | 
				
			||||||
 | 
					    """Localized and Generalized Tangent Learning Vector Quantization."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
 | 
					        distance_fn = kwargs.pop("distance_fn", ltangent_distance)
 | 
				
			||||||
 | 
					        super().__init__(hparams, distance_fn=distance_fn, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        omega_initializer = kwargs.get("omega_initializer")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if omega_initializer is not None:
 | 
				
			||||||
 | 
					            subspace = omega_initializer.generate(self.hparams.input_dim,
 | 
				
			||||||
 | 
					                                                  self.hparams.latent_dim)
 | 
				
			||||||
 | 
					            omega = torch.repeat_interleave(subspace.unsqueeze(0),
 | 
				
			||||||
 | 
					                                            self.num_prototypes,
 | 
				
			||||||
 | 
					                                            dim=0)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            omega = torch.rand(
 | 
				
			||||||
 | 
					                self.num_prototypes,
 | 
				
			||||||
 | 
					                self.hparams.input_dim,
 | 
				
			||||||
 | 
					                self.hparams.latent_dim,
 | 
				
			||||||
 | 
					                device=self.device,
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Re-register `_omega` to override the one from the super class.
 | 
				
			||||||
 | 
					        self.register_parameter("_omega", Parameter(omega))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def on_train_batch_end(self, outputs, batch, batch_idx, dataloader_idx):
 | 
				
			||||||
 | 
					        with torch.no_grad():
 | 
				
			||||||
 | 
					            self._omega.copy_(orthogonalization(self._omega))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SiameseGTLVQ(SiameseGLVQ, GTLVQ):
 | 
				
			||||||
 | 
					    """Generalized Tangent Learning Vector Quantization.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Implemented as a Siamese network with a linear transformation backbone.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GLVQ1(GLVQ):
 | 
					class GLVQ1(GLVQ):
 | 
				
			||||||
    """Generalized Learning Vector Quantization 1."""
 | 
					    """Generalized Learning Vector Quantization 1."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        super().__init__(hparams, **kwargs)
 | 
					        super().__init__(hparams, **kwargs)
 | 
				
			||||||
        self.loss = LossLayer(lvq1_loss)
 | 
					        self.loss = LossLayer(lvq1_loss)
 | 
				
			||||||
@@ -292,6 +348,7 @@ class GLVQ1(GLVQ):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class GLVQ21(GLVQ):
 | 
					class GLVQ21(GLVQ):
 | 
				
			||||||
    """Generalized Learning Vector Quantization 2.1."""
 | 
					    """Generalized Learning Vector Quantization 2.1."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        super().__init__(hparams, **kwargs)
 | 
					        super().__init__(hparams, **kwargs)
 | 
				
			||||||
        self.loss = LossLayer(lvq21_loss)
 | 
					        self.loss = LossLayer(lvq21_loss)
 | 
				
			||||||
@@ -314,3 +371,18 @@ class ImageGMLVQ(ImagePrototypesMixin, GMLVQ):
 | 
				
			|||||||
    after updates.
 | 
					    after updates.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ImageGTLVQ(ImagePrototypesMixin, GTLVQ):
 | 
				
			||||||
 | 
					    """GTLVQ for training on image data.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    GTLVQ model that constrains the prototypes to the range [0, 1] by clamping
 | 
				
			||||||
 | 
					    after updates.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def on_train_batch_end(self, outputs, batch, batch_idx, dataloader_idx):
 | 
				
			||||||
 | 
					        """Constrain the components to the range [0, 1] by clamping after updates."""
 | 
				
			||||||
 | 
					        self.proto_layer.components.data.clamp_(0.0, 1.0)
 | 
				
			||||||
 | 
					        with torch.no_grad():
 | 
				
			||||||
 | 
					            self._omega.copy_(orthogonalization(self._omega))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,13 +4,17 @@ import warnings
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
from ..core.competitions import KNNC
 | 
					from ..core.competitions import KNNC
 | 
				
			||||||
from ..core.components import LabeledComponents
 | 
					from ..core.components import LabeledComponents
 | 
				
			||||||
from ..core.initializers import LiteralCompInitializer, LiteralLabelsInitializer
 | 
					from ..core.initializers import (
 | 
				
			||||||
 | 
					    LiteralCompInitializer,
 | 
				
			||||||
 | 
					    LiteralLabelsInitializer,
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
from ..utils.utils import parse_data_arg
 | 
					from ..utils.utils import parse_data_arg
 | 
				
			||||||
from .abstract import SupervisedPrototypeModel
 | 
					from .abstract import SupervisedPrototypeModel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class KNN(SupervisedPrototypeModel):
 | 
					class KNN(SupervisedPrototypeModel):
 | 
				
			||||||
    """K-Nearest-Neighbors classification algorithm."""
 | 
					    """K-Nearest-Neighbors classification algorithm."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        super().__init__(hparams, **kwargs)
 | 
					        super().__init__(hparams, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,7 @@ from .glvq import GLVQ
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class LVQ1(NonGradientMixin, GLVQ):
 | 
					class LVQ1(NonGradientMixin, GLVQ):
 | 
				
			||||||
    """Learning Vector Quantization 1."""
 | 
					    """Learning Vector Quantization 1."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def training_step(self, train_batch, batch_idx, optimizer_idx=None):
 | 
					    def training_step(self, train_batch, batch_idx, optimizer_idx=None):
 | 
				
			||||||
        protos, plables = self.proto_layer()
 | 
					        protos, plables = self.proto_layer()
 | 
				
			||||||
        x, y = train_batch
 | 
					        x, y = train_batch
 | 
				
			||||||
@@ -38,6 +39,7 @@ class LVQ1(NonGradientMixin, GLVQ):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class LVQ21(NonGradientMixin, GLVQ):
 | 
					class LVQ21(NonGradientMixin, GLVQ):
 | 
				
			||||||
    """Learning Vector Quantization 2.1."""
 | 
					    """Learning Vector Quantization 2.1."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def training_step(self, train_batch, batch_idx, optimizer_idx=None):
 | 
					    def training_step(self, train_batch, batch_idx, optimizer_idx=None):
 | 
				
			||||||
        protos, plabels = self.proto_layer()
 | 
					        protos, plabels = self.proto_layer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -70,6 +72,7 @@ class MedianLVQ(NonGradientMixin, GLVQ):
 | 
				
			|||||||
    # TODO Avoid computing distances over and over
 | 
					    # TODO Avoid computing distances over and over
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, verbose=True, **kwargs):
 | 
					    def __init__(self, hparams, verbose=True, **kwargs):
 | 
				
			||||||
        self.verbose = verbose
 | 
					        self.verbose = verbose
 | 
				
			||||||
        super().__init__(hparams, **kwargs)
 | 
					        super().__init__(hparams, **kwargs)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,7 @@ from .glvq import GLVQ, SiameseGMLVQ
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class CELVQ(GLVQ):
 | 
					class CELVQ(GLVQ):
 | 
				
			||||||
    """Cross-Entropy Learning Vector Quantization."""
 | 
					    """Cross-Entropy Learning Vector Quantization."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        super().__init__(hparams, **kwargs)
 | 
					        super().__init__(hparams, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -29,6 +30,7 @@ class CELVQ(GLVQ):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ProbabilisticLVQ(GLVQ):
 | 
					class ProbabilisticLVQ(GLVQ):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, rejection_confidence=0.0, **kwargs):
 | 
					    def __init__(self, hparams, rejection_confidence=0.0, **kwargs):
 | 
				
			||||||
        super().__init__(hparams, **kwargs)
 | 
					        super().__init__(hparams, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -62,6 +64,7 @@ class ProbabilisticLVQ(GLVQ):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class SLVQ(ProbabilisticLVQ):
 | 
					class SLVQ(ProbabilisticLVQ):
 | 
				
			||||||
    """Soft Learning Vector Quantization."""
 | 
					    """Soft Learning Vector Quantization."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, *args, **kwargs):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        super().__init__(*args, **kwargs)
 | 
					        super().__init__(*args, **kwargs)
 | 
				
			||||||
        self.loss = LossLayer(nllr_loss)
 | 
					        self.loss = LossLayer(nllr_loss)
 | 
				
			||||||
@@ -70,6 +73,7 @@ class SLVQ(ProbabilisticLVQ):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class RSLVQ(ProbabilisticLVQ):
 | 
					class RSLVQ(ProbabilisticLVQ):
 | 
				
			||||||
    """Robust Soft Learning Vector Quantization."""
 | 
					    """Robust Soft Learning Vector Quantization."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, *args, **kwargs):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        super().__init__(*args, **kwargs)
 | 
					        super().__init__(*args, **kwargs)
 | 
				
			||||||
        self.loss = LossLayer(rslvq_loss)
 | 
					        self.loss = LossLayer(rslvq_loss)
 | 
				
			||||||
@@ -81,6 +85,7 @@ class PLVQ(ProbabilisticLVQ, SiameseGMLVQ):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    TODO: Use Backbone LVQ instead
 | 
					    TODO: Use Backbone LVQ instead
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, *args, **kwargs):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        super().__init__(*args, **kwargs)
 | 
					        super().__init__(*args, **kwargs)
 | 
				
			||||||
        self.conditional_distribution = RankScaledGaussianPrior(
 | 
					        self.conditional_distribution = RankScaledGaussianPrior(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,6 +18,7 @@ class KohonenSOM(NonGradientMixin, UnsupervisedPrototypeModel):
 | 
				
			|||||||
    TODO Allow non-2D grids
 | 
					    TODO Allow non-2D grids
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        h, w = hparams.get("shape")
 | 
					        h, w = hparams.get("shape")
 | 
				
			||||||
        # Ignore `num_prototypes`
 | 
					        # Ignore `num_prototypes`
 | 
				
			||||||
@@ -69,6 +70,7 @@ class KohonenSOM(NonGradientMixin, UnsupervisedPrototypeModel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HeskesSOM(UnsupervisedPrototypeModel):
 | 
					class HeskesSOM(UnsupervisedPrototypeModel):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        super().__init__(hparams, **kwargs)
 | 
					        super().__init__(hparams, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -78,6 +80,7 @@ class HeskesSOM(UnsupervisedPrototypeModel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class NeuralGas(UnsupervisedPrototypeModel):
 | 
					class NeuralGas(UnsupervisedPrototypeModel):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        super().__init__(hparams, **kwargs)
 | 
					        super().__init__(hparams, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -110,6 +113,7 @@ class NeuralGas(UnsupervisedPrototypeModel):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GrowingNeuralGas(NeuralGas):
 | 
					class GrowingNeuralGas(NeuralGas):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, hparams, **kwargs):
 | 
					    def __init__(self, hparams, **kwargs):
 | 
				
			||||||
        super().__init__(hparams, **kwargs)
 | 
					        super().__init__(hparams, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,7 @@ from ..utils.utils import mesh2d
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Vis2DAbstract(pl.Callback):
 | 
					class Vis2DAbstract(pl.Callback):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self,
 | 
					    def __init__(self,
 | 
				
			||||||
                 data,
 | 
					                 data,
 | 
				
			||||||
                 title="Prototype Visualization",
 | 
					                 title="Prototype Visualization",
 | 
				
			||||||
@@ -118,6 +119,7 @@ class Vis2DAbstract(pl.Callback):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VisGLVQ2D(Vis2DAbstract):
 | 
					class VisGLVQ2D(Vis2DAbstract):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def on_epoch_end(self, trainer, pl_module):
 | 
					    def on_epoch_end(self, trainer, pl_module):
 | 
				
			||||||
        if not self.precheck(trainer):
 | 
					        if not self.precheck(trainer):
 | 
				
			||||||
            return True
 | 
					            return True
 | 
				
			||||||
@@ -141,6 +143,7 @@ class VisGLVQ2D(Vis2DAbstract):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VisSiameseGLVQ2D(Vis2DAbstract):
 | 
					class VisSiameseGLVQ2D(Vis2DAbstract):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, *args, map_protos=True, **kwargs):
 | 
					    def __init__(self, *args, map_protos=True, **kwargs):
 | 
				
			||||||
        super().__init__(*args, **kwargs)
 | 
					        super().__init__(*args, **kwargs)
 | 
				
			||||||
        self.map_protos = map_protos
 | 
					        self.map_protos = map_protos
 | 
				
			||||||
@@ -179,6 +182,7 @@ class VisSiameseGLVQ2D(Vis2DAbstract):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VisGMLVQ2D(Vis2DAbstract):
 | 
					class VisGMLVQ2D(Vis2DAbstract):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self, *args, ev_proj=True, **kwargs):
 | 
					    def __init__(self, *args, ev_proj=True, **kwargs):
 | 
				
			||||||
        super().__init__(*args, **kwargs)
 | 
					        super().__init__(*args, **kwargs)
 | 
				
			||||||
        self.ev_proj = ev_proj
 | 
					        self.ev_proj = ev_proj
 | 
				
			||||||
@@ -212,6 +216,7 @@ class VisGMLVQ2D(Vis2DAbstract):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VisCBC2D(Vis2DAbstract):
 | 
					class VisCBC2D(Vis2DAbstract):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def on_epoch_end(self, trainer, pl_module):
 | 
					    def on_epoch_end(self, trainer, pl_module):
 | 
				
			||||||
        if not self.precheck(trainer):
 | 
					        if not self.precheck(trainer):
 | 
				
			||||||
            return True
 | 
					            return True
 | 
				
			||||||
@@ -235,6 +240,7 @@ class VisCBC2D(Vis2DAbstract):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VisNG2D(Vis2DAbstract):
 | 
					class VisNG2D(Vis2DAbstract):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def on_epoch_end(self, trainer, pl_module):
 | 
					    def on_epoch_end(self, trainer, pl_module):
 | 
				
			||||||
        if not self.precheck(trainer):
 | 
					        if not self.precheck(trainer):
 | 
				
			||||||
            return True
 | 
					            return True
 | 
				
			||||||
@@ -262,6 +268,7 @@ class VisNG2D(Vis2DAbstract):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class VisImgComp(Vis2DAbstract):
 | 
					class VisImgComp(Vis2DAbstract):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self,
 | 
					    def __init__(self,
 | 
				
			||||||
                 *args,
 | 
					                 *args,
 | 
				
			||||||
                 random_data=0,
 | 
					                 random_data=0,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										23
									
								
								setup.cfg
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								setup.cfg
									
									
									
									
									
								
							@@ -1,8 +1,23 @@
 | 
				
			|||||||
[isort]
 | 
					 | 
				
			||||||
profile = hug
 | 
					 | 
				
			||||||
src_paths = isort, test
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[yapf]
 | 
					[yapf]
 | 
				
			||||||
based_on_style = pep8
 | 
					based_on_style = pep8
 | 
				
			||||||
spaces_before_comment = 2
 | 
					spaces_before_comment = 2
 | 
				
			||||||
split_before_logical_operator = true
 | 
					split_before_logical_operator = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[pylint]
 | 
				
			||||||
 | 
					disable =
 | 
				
			||||||
 | 
						too-many-arguments,
 | 
				
			||||||
 | 
						too-few-public-methods,
 | 
				
			||||||
 | 
						fixme,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[pycodestyle]
 | 
				
			||||||
 | 
					max-line-length = 79
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[isort]
 | 
				
			||||||
 | 
					profile = hug
 | 
				
			||||||
 | 
					src_paths = isort, test
 | 
				
			||||||
 | 
					multi_line_output = 3
 | 
				
			||||||
 | 
					include_trailing_comma = True
 | 
				
			||||||
 | 
					force_grid_wrap = 3
 | 
				
			||||||
 | 
					use_parentheses = True
 | 
				
			||||||
 | 
					line_length = 79
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,6 +4,7 @@ import unittest
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestDummy(unittest.TestCase):
 | 
					class TestDummy(unittest.TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
        pass
 | 
					        pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user