* Tensorflow 2.3.0 building and passing tests.
* Added einsum and test.
* Added ByteString as a possible argument to a function.
* Support more data types for Adam.
* Move to later version of LTS on stackage.
* Added a wrapper module for convolution functions.
* Update ci build to use a later version of stack.
* Removed a deprecated import in GradientTest.
Required by #187.
The version we were using is old enough that it doesn't work with the
latest stackage LTS. haskellstack.org says
There is also a Ubuntu package for Ubuntu 16.10 and up, but the
distribution's Stack version lags behind, ...
So, instead of asking them to update it, it's probably better to
download the tar of the version we want.
Somehow updating stack surfaced a new pedantic warning in GradientTest,
so I've fixed that as well.
- Merge tensorflow-nn and tensorflow-queue into tensorflow-ops.
They don't add extra dependencies and each contain a single module, so I
don't think it's worth separating them at the package level.
- Remove google-shim in favor of direct use of test-framework.
Distinguish between "rendered" and "unrendered" Tensors.
There are now three types of `Tensor`:
- `Tensor Value a`: rendered value
- `Tensor Ref a`: rendered reference
- `Tensor Build a` : unrendered value
The extra bookkeeping makes it easier to track (and enforce) which tensors are
rendered or not. For examples where this has been confusing in the past, see
With this change, pure ops look similar to before, returning `Tensor Build`
instead of `Tensor Value`. "Stateful" (monadic) ops are unchanged. For
example:
add :: OneOf [..] t => Tensor v'1 t -> Tensor v'2 t -> Tensor Build t
assign :: (MonadBuild m, TensorType t)
=> Tensor Ref t -> Tensor v'2 t -> m (Tensor Ref t)
The `gradients` function now requires that the variables over which it's
differentiating are pre-rendered:
gradients :: (..., Rendered v2) => Tensor v1 a -> [Tensor v2 a]
-> m [Tensor Value a]
(`Rendered v2` means that `v2` is either a `Ref` or a `Value`.)
Additionally, the implementation of `gradients` now takes care to render every
intermediate value when performing the reverse accumulation. I suspect this
fixes an exponential blowup for complicated expressions.
This change adds a class that both `Build` and `Session` are instances of:
class MonadBuild m where
build :: Build a -> m a
All stateful ops (generated and manually written) now have a signature that returns
an instance of `MonadBuild` (rather than just `Build`). For example:
assign_ :: (MonadBuild m, TensorType t)
=> Tensor Ref t -> Tensor v t -> m (Tensor Ref t)
This lets us remove a bunch of spurious calls to `build` in user code. It also
lets us replace the pattern `buildAnd run foo` with the simpler pattern `foo >>= run`
(or `run =<< foo`, which is sometimes nicer when foo is a complicated expression).
I went ahead and deleted `buildAnd` altogether since it seems to lead to
confusion; in particular a few tests had `buildAnd run . pure` which is
actually equivalent to just `run`.