Closed alexanderkoller closed 6 years ago
We used to have LSTM support but the ONNX spec regarding LSTM kept changing and it eventually went outdated so I deleted them. I hope you understand that It's not a minor effort keeping updated with the spec. Hopefully the spec is more stabilized now.
You can take a look at an older version of backend.py
here which has support for the older spec and improve from there.
Please let me know if you have any further questions and any contribution is very welcome.
Thank you for your answer! Yes, I do appreciate that it is tricky to keep up with a changing spec. Let me see what I can do with the current version.
Turns out that backend.py doesn't even get to _onnx_node_to_tensorflow_op
, which as far as I can tell is where handle_optimized_r_n_n
would be called.
Am I interpreting the exception correctly that the ValidationError is thrown in onnx.checker.check_model
, and that what we're seeing here is actually a mismatch between the ONNX that Pytorch generates (current source version from Github) and what ONNX (1.0.1) expects - and not actually a problem with onnx-tensorflow yet?
@alexanderkoller I can’t reproduce your error locally. But I built them from source both. So try using onnx built from source first.
@fumihwh I built Pytorch and onnx-tensorflow from source, but used ONNX 1.0.1, which came from conda install -c conda-forge onnx
. I will try to build ONNX from source (had some trouble with that last night) and report back.
In the meantime, here is the ONNX file that Pytorch exported: lstm.onnx, in case that helps. The error message is generated when running the following onnx-tensorflow program:
import onnx
from onnx_tf.backend import prepare
model = onnx.load("lstm.onnx")
tf_rep = prepare(model)
@alexanderkoller
I used your lstm.onnx
and got NotImplementedError: LSTM op is not implemented.
.
So, it means I have already passed onnx.checker.check_model
step.
This error makes more sense.
@tjingrant Yes. LSTM is one of ONNX op not implemented here currently.
@fumihwh But you get the "LSTM op is not implemented" error with the development version of ONNX, right? Still working on building it; now that I've fixed the protobuf version mismatch, I'm stuck at the missing pybind11.h. I will keep trying, and report back.
@alexanderkoller you may be missing the --recursive
flag when cloning.
Okay, I have managed to compile ONNX from source and am now getting the same error as you guys.
I have also implemented a handle_l_s_t_m
method in TensorflowBackend
, which creates the LSTM in Tensorflow (so at least it can be run in a TF session without crashing), and figured out how to access both the weights in the ONNX LSTM operator and the variables inside the Tensorflow LSTMCell.
Now I'm facing the challenge of injecting the weights from ONNX into the weight variables in the Tensorflow LSTMCell. Do you have any advice on how to do this? The old code that @tjingrant linked to doesn't seem to do it. To the extent that I understand Tensorflow, the clean way would be to initialize the variable with tf.assign
. Do you have a mechanism for doing this that I can use?
I created a pr to add lstm handler. It works but without some features. Any advice is welcome.
@alexanderkoller You can try above one.
@fumihwh Great, thanks! This is roughly as far as I got too.
How does your code set the weight tensors of the LSTM to be as in the ONNX? I can't see how it does it, but maybe I'm missing something?
@alexanderkoller
onnx_graph_to_tensorflow_net
in backend.py
https://github.com/onnx/onnx-tensorflow/blob/master/onnx_tf/backend.py#L343-L353
Initialize tensors here.
@fumihwh Thanks!
So if I understand your code correctly, the input_dict_items
contain a mapping from placeholders or variables to tensors. When run
in TensorflowRep
is called, these will be fed into the computation graph through the feed_dict
.
What I don't understand yet is what your preferred strategy is for adding entries to the input_dict_items
. If I simply try to update the input_dict
in handle_l_s_t_m
, that value gets lost because onnx_graph_to_tensorflow_net
returns the original_input_dict
, before the handle* methods had a chance to add their own entries. On the other hand, I can't initialize the LSTM variables in lines 343-353 (to which you pointed me), because the Tensorflow LSTM node is only generated in handle_l_s_t_m
, and so its variables don't exist yet at this point in the program.
Could you clarify?
@alexanderkoller
First, original_input_dict
from onnx_graph_to_tensorflow_net
contains initialized inputs.
So, LSTM variables are initialized and passed to handle_l_s_t_m
. Please check logic again.
The problem should be how pass initialized params(W,R,B) to tf.contrib.rnn.LSTMCell
. Because there are no attrs for them in tf.
Maybe you can try assign them after make cell.
https://github.com/tensorflow/tensorflow/issues/3115
https://stackoverflow.com/questions/40318812/tensorflow-rnn-weight-matrices-initialization
Hi,
I've picked up where @alexanderkoller left off, and I have found a way to transfer the weights from the ONNX model into TensorFlow. The way I'm doing it is by reading the weights by using a dummy tf.Session
, and then creating a custom LSTM cell by using constant initializers.
I have submitted a Pull Reqeuest for your consideration. Right now, it can only handle vanilla unidirectional LSTMs, but I think it should be very easy to extend this method to bidirectional and peephole LSTMs. Please let me know what you think!
@stgrue Can you please explain it a bit more or share code if you can. I am currently trying to do : - f = [np.random.normal(size = [15, 40]), np.random.normal(size = [40,])] init = tf.constant_initializer(f, verify_shape = True, dtype = tf.float32)
cell = tf.contrib.rnn.LSTMCell(lstm_units, initializer = init) unused_encoder_outputs, encoder_state =tf.nn.dynamic_rnn(cell ,source_seq_embedded,sequence_length=source_seq_len,dtype = tf.float32)
but it is giving the following error
TypeError Traceback (most recent call last)
Since the maintainers of this repository have already solved the LSTM conversion problem, I have not continued working on this issue, so I cannot help you with your problem. Sorry.
Hi,
I'm trying to convert a very simple LSTM from Pytorch to Tensorflow via ONNX, but I'm getting an error in the onnx-tensorflow
prepare
function.Are LSTMs supported by onnx-tensorflow? If no, why not, and how would I go about adding them?
Best, Alexander.
Error message:
Output produced by
torch.onnx.export(lstm, (inputs,hidden), "lstm.onnx", verbose=True)
:The LSTM itself is the first example from http://pytorch.org/tutorials/beginner/nlp/sequence_models_tutorial.html