Uh oh!
There was an error while loading. Please reload this page.
Added Tensor.dataToString() - #272
Conversation
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed (or fixed any issues), please reply here with What to do if you already signed the CLAIndividual signers
Corporate signers
ℹ️ Googlers: Go here for more info. |
cowwoc
commented
Apr 3, 2021
@googlebot I signed it! |
cowwoc
commented
Apr 3, 2021
@rnett Please review. Apologies in advance. The implementation got hairy once I added |
cowwoc
commented
Apr 3, 2021
The build failure doesn't seem to be related to my changes. Please confirm. |
Craigacp
commented
Apr 3, 2021
The quick build failing in javadoc generation is a known issue we're working on in other PRs. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
cowwoc
commented
Apr 4, 2021
Yes, I could do that. Are you saying that you would leave the main implementation on |
* Added support for Tensors.toString(RawTensor). * Test multidimensional tensor, RawTensor.
cowwoc
commented
Apr 4, 2021
FYI, I decided to remove trailing commas after closing brackets. I think it looks better this way and I think that Will now show up as: |
Yeah, that's exactly what I meant. |
Signed-off-by: Ryan Nett <JNett96@gmail.com>
There was a problem hiding this comment.
Other than the small comments, I made a PR (cowwoc#1) against your branch with additional data type tests, and (because of said tests) wrapping string elements in quotes. Use the PR if you want, but regardless, both of those would be good to have.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Data type tests, wrap strings in quotes
All (the pull request submitter and all commit authors) CLAs are signed, but one or more commits were authored or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that by leaving a comment that contains only Note to project maintainer: There may be cases where the author cannot leave a comment, or the comment is not properly detected as consent. In those cases, you can manually confirm consent of the commit author(s), and set the ℹ️ Googlers: Go here for more info. |
cowwoc
commented
Apr 6, 2021
Merged. Thank you. Let me know if there is anything else. Otherwise, how do we fix the quick-build so I can merge this PR? |
Craigacp
commented
Apr 6, 2021
rnett
commented
Apr 6, 2021
@googlebot I consent. |
karllessard
left a comment
There was a problem hiding this comment.
Thanks a lot @cowwoc , I'm not done with the review but I'll wait to see you have to say about my comments so far.
| * is only a reference to a native tensor allowing basic operations and flat data access.</p> | ||
| * {@link RawTensor raw tensors}. The former maps the tensor native memory to an n-dimensional typed | ||
| * data space, allowing direct I/O operations from the JVM, while the latter is only a reference to | ||
| * a native tensor allowing basic operations and flat data access.</p> |
There was a problem hiding this comment.
There is a lot of (undesirable?) format change in this PR, can you please revert those and only preserve changes related to the dataToString feature?
| * @param maxWidth the maximum width of the output in characters ({@code null} if unlimited). This | ||
| * limit may surpassed if the first or last element are too long. | ||
| */ | ||
| static ToStringOptions maxWidth(Integer maxWidth) { |
There was a problem hiding this comment.
I'm not sure this method is in the right place. Maybe move it in ToStringOptions? Also you need to describe the returned value in the javadoc or the checks might complain.
There was a problem hiding this comment.
I do it similar to this:Layers.Options.create().inputShape(Shape.of(2,2))
without the ellipsis in the CTORs.
| * @return the String representation of the tensor elements | ||
| * @throws IllegalStateException if this is an operand of a graph | ||
| */ | ||
| default String dataToString(ToStringOptions... options) { |
There was a problem hiding this comment.
I don't think the use of a vararg to handle the optional presence of options is a good idea. Having a second method accepting no parameter would be better.
We use vararg options in the op wrappers because we want to limit the number of methods that ending up in the *Ops classes, which is already more than a thousand. But here it's fine "duplicating" it.
| * limit may surpassed if the first or last element are too long. | ||
| * @return the String representation of the tensor | ||
| */ | ||
| public static String toString(Tensor tensor, Integer maxWidth) { |
There was a problem hiding this comment.
I'm not sure about having that many ways to print a tensors (if we can call tensor.toString, why having Tensors.toString(tensor)?) It's a bit confusing and I find that that feature maybe spreads out a bit in multiple parts of the code.
I have a new design to propose, let me know what you think. But what about having this toString logic in another called, let say, TensorPrinter, which can be returned or directly invoked in the Tensor class? i.e.
classTensorPrinter {
TensorPrinter(Tensortensor, intmaxWidth) { ... }
TensorPrinterwithMaxWidth(intmaxWidth) {
returnnewTensorPrinter(this.tensor, maxWidth);
}
Stringprint() {
return .... (thislogichere)
}
}
interfaceTensor {
Stringprint() {
returnnewTensorPrinter(this, null).print();
}
TensorPrinterprinter() {
returnnewTensorPrinter(this, null);
}
}
Tensort = TFloat32.scalarOf(10.0f);
t.print();
t.printer().maxWidth(10).anotherOption(234).print();There was a problem hiding this comment.
I prefer your proposal. It is exactly what I was hoping to implement in the long term but I ended up pushing what you see above as a stepping stone in the right direction.
Also, consider the relationship (if any) between Ops.print() and this functionality. I may be wrong, but I believe the C++ implementation of tf.print() returns roughly what we're trying to implement in this PR. Does it make sense to have Ops.print() invoke this new code?
There was a problem hiding this comment.
Do we want to call it print() and not toString()?
There was a problem hiding this comment.
If we do that, then I would then expect it to work the same as Ops.print() since the two share the same name. Are we planning to merge the two?
There was a problem hiding this comment.
I think Ops.print() simply writes a given string to an output stream, like the console, when the graph is being executed.
I picked the "print" expression in this example just to show the logic but it can for sure be named otherwise to avoid the confusion. Maybe TensorStringifier, tensor.stringify() and tensor.stringifier()? Or the methods could remain dataToString() as well.
| "actual : " + tensor + "\n" + | ||
| "dataType: " + tensor.dataType() + "\n" + | ||
| "class : " + tensor.getClass()); | ||
| } |
There was a problem hiding this comment.
Since you only accept typed tensors for this method, the endpoint should probably be added to TType instead of Tensor.
There was a problem hiding this comment.
@karllessard Is there a way for me to handle all tensors (not just TType)? It's okay if not. I'm just asking.
There was a problem hiding this comment.
@karllessard How do you create a RawTensor that doesn't inherit from NdArray? Or more precisely how do you create a plain Tensor object that doesn't inherit from NdArray without using one of the org.tensorflow.types classes?
RawTensor rawTensor = RawTensor.allocate(TFloat32.class, Shape.of(2, 2), -1);
Still inherits from NdArray.
There was a problem hiding this comment.
You can't user-side, but all of the Tensor.fromHandle methods don't inherit, afaik. And in places where that's used (Session, somewhere in Operand.asTensor()) if a asTypedTensor() is missed somewhere it's nice to not crash when printing. However, afaik, that's covered by the tensor = ((RawTensor) tensor).asTypedTensor(); line, so the method should support all Tensors not just TType.
JimClarke5
left a comment
There was a problem hiding this comment.
I have quite a bit of Tensor print helper classes that I use in test/java/org.tensorflow.framework.utils.TestSession, EagerTestSession, and GraphTestSession.
I would like to use this PR in those classes to make sure nothing is missed.
I'll test that and let you know how it goes.
cowwoc
commented
Apr 13, 2021
@JimClarke5 Any chance you could pick up the torch (apply the changes that Karl asked for) on my behalf? I won't have time to pick this up for another week or two. |
JimClarke5
commented
Apr 13, 2021
@cowwoc OK, one problem I have is I need to work with my latest version of the xxxSession classes that I am using for Models and Layers, I assume you could cherry pick the Tensor related changes. |
@JimClarke5 You should be able to fork my PR, merge in your changes and push a new PR. I will approve it which should merge the changes back into this initial PR. |
JimClarke5
commented
Apr 13, 2021
I understand that, but I need to test with my latest code first. |
JimClarke5
commented
Apr 13, 2021
Will |
JimClarke5
commented
Apr 13, 2021
Would we want the printed values enclosed in braces |
JimClarke5
commented
Apr 13, 2021
I think we should pattern the output after |
cowwoc
commented
Apr 13, 2021
Per #268 (comment) I was asked to only support eager mode. I suggest discussing this part with @rnett.
My 2 cents: Make the default output human-friendly (i.e. square brackets as |
rnett
commented
Apr 13, 2021
That's for Operands,
I'd agree with this: default to |
JimClarke5
commented
Apr 13, 2021
rnett
commented
Apr 13, 2021
JimClarke5
commented
Apr 14, 2021
@cowwoc Your branch is behind master and that is causing me build issues. |
cowwoc
commented
Apr 14, 2021
@JimClarke5 One sec, I'll merge master into it. |
cowwoc
commented
Apr 14, 2021
@JimClarke5 Try now. |
JimClarke5
commented
Apr 16, 2021
Actually the print code is keying on inheriting from NDArray. It has nothing to do specifically with TType. That is why @karllessard ’s comment is throwing me off. |
karllessard
commented
Apr 16, 2021
@JimClarke5 yeah maybe my comment wasn't clear. I was just pointing out that the But I'm also fine leaving it there, in |
ajs1998
commented
Oct 16, 2022
Any updates on this? I am very new to Tensorflow and I have no idea how to visualize simple output. This seems perfect but it's been a year an a half since the last comment. |
karllessard
commented
Oct 16, 2022
@ajs1998 you can print the value of any operand ( But if you want to print the values of a |
ajs1998
commented
Oct 16, 2022
@karllessard Excellent! Didn't know I could print an operand like that, thank you. |
Fixes#268