This repository was archived by the owner on Apr 23, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 149
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This change is a first attempt at leveraging structural generic programming to implement some sugar for a higher-level API.
This change explores using structural generic programming to build (at compile time) a type-safe "hyper-parameter" object that can subsequently be manipulated and subsequently used to initialize a NN with the minimum of fuss. See HParamInitExample.swift for an example usage (partially replicated here): ```swift public struct MyInitModel { var conv: Conv2D<Float> var flatten: Flatten<Float> var dense: Dense<Float> } // Thanks to `DifferentiableStructural` conformances, we can derive these protocols automagically! extension MyInitModel: HParamInitLayer, Layer, SequentialLayer { // Must specify typealiases because they are not inferred automatically. :-( public typealias Input = Tensor<Float> public typealias Output = Tensor<Float> public typealias SequentialInput = Input public typealias SequentialOutput = Output public typealias HParam = StaticStructuralRepresentation.HParam } // Usage: func makeExplicitModel() -> MyInitModel { var hparams = MyInitModel.HParam() hparams.conv = .init(height: 3, width: 3, channels: 10) // Fully typesafe! hparams.dense = .init(size: 10) return hparams.build(for: Tensor<Float>(zeros: [5, 28, 28, 1])) } ``` Note: in order to build the full API, I needed to make some modifications to the proposed Structural APIs. (Note: this is a quick-hack, and deserves much more refinement!) Related PR: #613
saeta
added a commit
to google/swift-structural
that referenced
this pull request
Jul 31, 2020
Based on explorations of structural generic programming in tensorflow/swift-models#650 we would like to support smooth interactions between KeyPaths and structural generic programming. Based on discussions with @shabalind, I have put together a quick proof-of-concept demonstrating how to unify a "static structural" implementation with the "instance"-level structural generic programming we have been exploring so far. This is definitely an incomplete implementation, but this would allow us to easily implement KeyPathIterable and its ilk on top of structural generic programming (something not possible previously), in addition to unifying with the existing KeyPath world. There are a couple further extensions: 1. **Solution for `HNil`** To use a proper cons-list construction, this will require a bottom type (`Never`) that conforms to every protocol, and multiple conformances. Alternatively, an encoding that appears to work is a cons-list construction that doesn't use a special end type. 2. **Typealias inference**: Swift does not currently infer typealiases for these kinds of derived conformances. 3. **Enum support** This current implementation doesn't include enum support although this is straight forward to add. 4. **Simplier structural representations**: When the single static structural derived conformance, we can easily implement multiple simpler "structural" encodings (e.g. a simple Cons-list of values in addition to the current structural representation). 5. Extensions to KeyPaths could enable StaticStructural to simply be the key paths themselves. (i.e. if you could retrieve the field name corresponding to the key path.)
Closing until structural GP is available in the upstream compiler. |
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Use structural generic programming to build an HParam object.
This change explores using structural generic programming to build (at compile time)
a type-safe "hyper-parameter" object that can subsequently be manipulated and
subsequently used to initialize a NN with the minimum of fuss.
See HParamInitExample.swift for an example usage (partially replicated, and simultaneously idealized here -- there are a few bugs / issues that must be resolved first before we can achieve this):
For comparisons, writing this out using the existing APIs would look something like the following and require (1) explicit shape calculations, (2) custom definition of hyperparameters, (3) redundant specification of the forward pass + initialization logic:
Further ideas to explore include:
with example usage:
Using structural generic programming on the HParam types themselves (e.g. for easy serialization / deserialization, checkpointing, flag parsing, etc).
Take an explicit random number generator when building the model from the
HParam
type to allow random number generation to be made deterministic.Related PR: #613