This release focus on integration with TF 2.4, cleaning up redundancies in the PsiZ API, and laying the ground-work for a stable API.
Major Feature Changes
* TF 2.4 improves support for saving custom models.
* The internal sampling mechanics for stochastic models has changed. 1) Sampling is now handled at the input of the model by creating an additional "sample" axis. 2) The sampling axis is now located at `axis=1`. This is a departure from the previous implementation which followed tensorflow-probability, which prepends sample dimensions. Placing the sampling dimensions at axis=0 created many downstream problems where there are often strict assumptions that the first axis is the "batch" axis. Together, these two changes have yielded cleaner code that is easier to reason about. In particular, non-input layers can remain ignorant of the sampling strategy implemented at the input.
* Added sparse dispatching functionality (`GroupGate` and `GroupGateMulti`) to facilitate generic group-specific layers.
* New similarity kernel strategy. New strategy is more general, exhibits looser coupling, and does not rely on Embedding layers. New strategy uses a generic `DistanceBased` container layer along with the reworked `Minkowski` layer. The `Minkowski` layer uses a standard set of trainable weights rather than an Embedding layer. Combined with `GroupGateMulti` users can assemble group-specific layers (see `examples/rank/mle_3g.py`). The classes `Kernel`, `AttentionKernel`, `WeightedMinkowski`, `GroupAttention` and `GroupAttentionVariational` have been deprecated and will be removed in a future release. Instead use `DistanceBased`, `Minkowski`, `MinkowksiVariational`, and `GroupGateMulti`.
* Expanded tests. Added `slow` pytest marker for slow running tests.
* Added `trials.experimental` which introduces an alternative set of classes for tracking trial data. The primary differences are the use of compositionality and the coding of trials sequences.
Breaking Changes
* Calling `model.save` uses TF save method instead of PsiZ's custom save method. See Issue 17 and 19 for advice on converting old models.
* Removed `Proxy` class from API. All examples have been updated. (See Issue 20)
* Replaced `procrustes_2d` utility function with more general and robust `procrustes_rotation` which uses SVD instead of iteration-based optimization. All examples have been updated.
* Shape assumptions for `wpnorm` have changed to be more inclusive. This is only a breaking change for gradient computations.
Other Changes
* Moved `models` module into `keras`. A full import looks something like `psiz.keras.models.Rank`. Users can still import models the old way (e.g., `psiz.models.Rank`) although this may be deprecated in the future. This was primarily done to safeguard against future model additions that do not follow the Keras API. A side-effect is that this organization mimics TF.
* Moved `generators` module into trials.
* Removed `preprocessing` module.
* Replaced `visualization` module with `mplot` module. Some functionality is overlapping.
* Internal changes to source code file naming and directory organization.
Resolved Issues
* Issue 19: The problem was due to an if statement in the `Rank` call method. The `Rank` refactor creates tighter guarantees on Tensor shapes, eliminating the need for the if statement.