Comments (11)
In Objax, contrary to other JAX frameworks, you don't need to pass model variables around. They are stored in modules, and for functions they're only needed when you JIT them.
In your particular example, you don't need to pass model_vars
to train_op
, you already do it in the Jit
call.
def train_op(x, y, lr):
g, v = gv(x, y)
for grad, p in zip(g, model_vars.subset(objax.TrainVar)):
p.value -= lr * grad
return v
Check the SGD source code, it's 3 lines of code, basically you can copy it and make your own optimizer:
https://objax.readthedocs.io/en/latest/_modules/objax/optimizer/sgd.html#SGD
from objax.
Thanks for the fast reply. When I ran this code I received:
ValueError: Direct assignment not allowed, use TrainRef to update a TrainVar.
I got the same error by replacing model_vars with model.vars() which I think are equivalent.
from objax.
I got it working by replacing
model_vars.subset(objax.TrainVar)
with
ModuleList(TrainRef(x) for x in model.vars().subset(TrainVar))
and importing the associated modules
from objax.module import Module, ModuleList
from objax.variable import TrainRef, TrainVar, VarCollection
However, I have two issues which is,
- this code is very slow because I'm not using Objax.Jit on the optimizer routine (took roughly 16 seconds for 1 epoch).
- it is not very minimalistic. (is there a way to hide ModuleList for instance?)
Do you have any suggestions?
from objax.
Oh right, yes =
is disallow on TrainVar
to avoid users accidentally writing a trainable variable.
For minimalism, you could use assign
instead of =
:
def train_op(x, y, lr):
g, v = gv(x, y)
for grad, p in zip(g, model_vars.subset(objax.TrainVar)):
p.assign(p.value - lr * grad)
return v
For performance, you simply need to JIT train_op
, everything inside gets jitted but it won't allow you to write TrainVar
objects. So the solution would be:
gv = objax.GradValues(loss, model.vars())
refs = objax.ModuleList(objax.TrainRef(x) for x in model.vars().subset(objax.TrainVar))
def train_op(x, y, lr):
g, v = gv(x, y)
for grad, p in zip(g, refs.vars()):
p.value -= lr * grad
return v
train_op = objax.Jit(train_op, gv.vars() + refs.vars())
from objax.
Thanks for your reply! I am still having some trouble however. After using,
def train_op(x, y, lr):
g, v = gv(x, y)
for grad, p in zip(g, model_vars.subset(objax.TrainVar)):
p.assign(p.value - lr * grad)
return v
exactly as it appears, I received: UnexpectedTracerError: Encountered an unexpected tracer. Perhaps this tracer escaped through global state from a previously traced function. The functions being transformed should not save traced values to global state.
After fixing this problem I will try out jit(train_op(...)). However, is there a way to directly modify
train_op = objax.Jit(train_op, gv.vars())
to account for the optimizer?
from objax.
I updated my comment, check if it works.
from objax.
I've changed my code per your suggestion. Unfortunately now I have this error:
TypeError: cannot convert dictionary update sequence element #0 to a sequence
from objax.
Updated again.
from objax.
Thanks. This completely solves my question.
Just as a suggestion (feel free to disagree here) it seems that this line
objax.ModuleList(objax.TrainRef(x) for x in model.vars().subset(objax.TrainVar))
could be made more minimalistic somewhere down the line, or at least a bit more intuitive.
All the user wants to do is to update the trainable variables in the model.
Perhaps there should be a way to directly access them with minimal code and then just update them as usual
e.g., trainable_vars = trainable_vars + lr * gradient
from objax.
Well consider that Objax is object-oriented and an optimizer is meant to be an objax.Module
. If you look at SGD it's just 3 lines of code:
https://objax.readthedocs.io/en/latest/_modules/objax/optimizer/sgd.html#SGD
On the other hand, if you're looking for a functional design, maybe pure JAX is what will suit you best or one of the functional frameworks out there (I mean they're pretty much all functional).
from objax.
Reopening since I'm experimenting with design changes to allow for the original code, e.g.:
def train_op(x, y, lr):
g, v = gv(x, y)
for grad, p in zip(g, model_vars.subset(objax.TrainVar)):
p.assign(p.value - lr * grad)
return v
from objax.
Related Issues (20)
- Improve automatic variable tracing
- If user won't add random generator to VarCollection of jitted code then same number always return by random generator
- Model compiling twice when using jax==0.2.10 or later HOT 6
- Update Objax Basics tutorial to reflect .value change
- Accessing variable of a vectorized module HOT 2
- objax.Jit reports error when StateVar is added to the vc argument HOT 3
- Regression of JAX duck typing. HOT 2
- RecursionError when attempting to unpickle objax objects HOT 2
- How to compute Jacobian of outputs w.r.t. inputs HOT 3
- Activation functions like Swish and Mish are absent. HOT 1
- Error due to the deprecation of jax.api
- objax.Jacobian and objax.Hessian similar to objax.Grad HOT 4
- replacing jax.vmap with objax.Vectorize HOT 3
- Closure scoping for nested objax.Functions HOT 2
- ResNetV2 from model.zoo does not specify train arg for ResNetV2Block HOT 2
- pmean inside objax.parallel causes multithreading deadlock for more than 2 gpus HOT 3
- `objax.variable.VarCollection.update` fails when passing `Dict[str, Any]` HOT 1
- `objax.variable.VarCollection.update` not compliant with key-value assignment HOT 1
- TypeError during gradient computation: type <class 'objax.variable.TrainVar'> is not a valid JAX type
- Missing release 1.7.0 on GitHub HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from objax.