Skip to content
This repository has been archived by the owner on Nov 17, 2023. It is now read-only.

Tensor Inspector Tutorial #15517

Merged
merged 15 commits into from
Jul 20, 2019
Merged

Tensor Inspector Tutorial #15517

merged 15 commits into from
Jul 20, 2019

Conversation

Zha0q1
Copy link
Contributor

@Zha0q1 Zha0q1 commented Jul 12, 2019

Description

Tutorial for this PR: #15490

Need images uploaded here: dmlc/web-data#194

Checklist

Essentials

Please feel free to remove inapplicable items for your PR.

  • The PR title starts with [MXNET-$JIRA_ID], where $JIRA_ID refers to the relevant JIRA issue created (except PRs with tiny changes)
  • Changes are complete (i.e. I finished coding on this PR)
  • All changes have test coverage:
  • Unit tests are added for small changes to verify correctness (e.g. adding a new operator)
  • Nightly tests are added for complicated/long-running ones (e.g. changing distributed kvstore)
  • Build tests will be added for build configuration changes (e.g. adding a new build option with NCCL)
  • Code is well-documented:
  • For user-facing API changes, API doc string has been updated.
  • For new C++ functions in header files, their functionalities and arguments are documented.
  • For new examples, README.md is added to explain the what the example does, the source of the dataset, expected performance on test set and reference to the original paper if applicable
  • Check the API doc at http://mxnet-ci-doc.s3-accelerate.dualstack.amazonaws.com/PR-$PR_ID/$BUILD_ID/index.html
  • To the my best knowledge, examples are either not affected by this change, or have been fixed to be compatible with this change

Changes

  • Feature1, tests, (and when applicable, API doc)
  • Feature2, tests, (and when applicable, API doc)

Comments

  • If this change is a backward incompatible change, why must this change be made.
  • Interesting edge cases to note here

@Zha0q1 Zha0q1 requested a review from szha as a code owner July 12, 2019 00:43
@Zha0q1 Zha0q1 changed the title Tensor Inspector Tutorial [WIP]Tensor Inspector Tutorial Jul 12, 2019
docs/faq/tensor_inspector_tutorial.md Outdated Show resolved Hide resolved
docs/faq/tensor_inspector_tutorial.md Outdated Show resolved Hide resolved
docs/faq/tensor_inspector_tutorial.md Outdated Show resolved Hide resolved
docs/faq/tensor_inspector_tutorial.md Outdated Show resolved Hide resolved
docs/faq/tensor_inspector_tutorial.md Outdated Show resolved Hide resolved
docs/faq/tensor_inspector_tutorial.md Outdated Show resolved Hide resolved
docs/faq/tensor_inspector_tutorial.md Outdated Show resolved Hide resolved
@Zha0q1
Copy link
Contributor Author

Zha0q1 commented Jul 13, 2019

@ChaiBapchya Thanks for the thoughtful review!

@karan6181
Copy link
Contributor

@mxnet-label-bot add [Operator, NDArray, Visualization, pr-work-in-progress]

@Zha0q1
Copy link
Contributor Author

Zha0q1 commented Jul 16, 2019

@access2rohit @sandeep-krishnamurthy The tutorial is ready for review. After applying your suggestions I will replace the image url to the ones I uploaded to dmlc/web-data so don't worry about image names or urls for now

@Zha0q1 Zha0q1 changed the title [WIP]Tensor Inspector Tutorial Tensor Inspector Tutorial Jul 16, 2019
@sandeep-krishnamurthy
Copy link
Contributor

@aaronmarkham - Can you please help review? Thanks!

@Zha0q1 Zha0q1 closed this Jul 18, 2019
@Zha0q1 Zha0q1 reopened this Jul 18, 2019

You can create a `TensorInspector` object by passing in two things: 1) an object of type `Tensor`, `Tbob`, or `NDArray`, and 2) an `RunContext` object.

Essentially, `TensorInspector` can be understood as a wrapper class around `TBlob`. Internally, the `Tensor`, `Tbob`, or `NDArray` object that you passed in will be converted to a `TBlob` object. The `RunContext` object is used when the the tensor is a GPU tensor; in such a case, we need to use the context information to copy the data from GPU memory to CPU/main memory.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

object -> objects

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's "the object", referring to the same object that the user has passed as described in line 36

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok


### Dump Tensor Value

Sometimes, you might want to dump the tensor to a file in binary mode. Then, you might want to use a python script to further analyze the tensor value. Or, you might do that simply because a binary dumps has better precision and is faster to load than if you copy-paste the output from `print_string()` and load it as a `JASON` string. Either way, you can use this API:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JASON -> JSON?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Haha you r right!


This API will set a "break point" in your code, so that you will enter a loop that will keep asking you for further command. In the API call, `tag` is an optional parameter to give the call a name, so that you can identify it when you have multiple `interactive_print()` calls in different parts of your code. A visit count will tell you for how many times have you stepped into this particular "break point", should this operator be called more than once. Note that all `interactive_print()` calls are properly locked, so you can use it in many different places without issues.

![Screen Shot 2019-07-10 at 5 29 07 PM](https://user-images.githubusercontent.com/16669457/61013632-5325e800-a338-11e9-90e6-607f17d81495.png)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proper host


Let's see the how it runs:

![Screen Shot 2019-07-10 at 5 17 29 PM](https://user-images.githubusercontent.com/16669457/61013259-cc244000-a336-11e9-8564-a018041634f6.png)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proper host

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I have them uploaded in another PR. Will update the url after taking in the comments


Notice: in `interactive_print()`, you could also do value dumping with command "d". You will be prompted to enter the `tag` value:

![Screen Shot 2019-07-11 at 4 57 41 PM](https://user-images.githubusercontent.com/16669457/61092906-0f48e680-a3fd-11e9-8251-c4371cdd00ad.png)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proper host

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I have them uploaded in another PR. Will update the url after taking in the comments

Copy link
Contributor

@larroy larroy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks for the documentation! Leading by example.

Copy link
Contributor

@IvyBazan IvyBazan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed and added suggested edits for clarity and flow


You can create a `TensorInspector` object by passing in two things: 1) an object of type `Tensor`, `Tbob`, or `NDArray`, and 2) an `RunContext` object.

Essentially, `TensorInspector` can be understood as a wrapper class around `TBlob`. Internally, the `Tensor`, `Tbob`, or `NDArray` object that you passed in will be converted to a `TBlob` object. The `RunContext` object is used when the the tensor is a GPU tensor; in such a case, we need to use the context information to copy the data from GPU memory to CPU/main memory.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate "the". Corrected sentence: "The RunContext object is used when the tensor is a GPU tensor"


Essentially, `TensorInspector` can be understood as a wrapper class around `TBlob`. Internally, the `Tensor`, `Tbob`, or `NDArray` object that you passed in will be converted to a `TBlob` object. The `RunContext` object is used when the the tensor is a GPU tensor; in such a case, we need to use the context information to copy the data from GPU memory to CPU/main memory.

Below are the three constructors:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Following are the three constructors:"

void print_string();
```

This API will print the entire tensor to `std::cout` and preserve the shape (it supports all dimensions from 1 and up). You can copy the output and interpret it with any `JSON` loader. Also, on the last line of the output you can find some useful information about the tensor. Refer to the case below, we are able to know that this is a float-typed tensor with shape 20x1x5x5.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested edit for clarity and flow: "You can find some useful information about the tensor on the last line of the output."


### Interactively Print Tensor Value (Dynamic)

When debugging, situations might occur that at compilation time, you do not know which part of a tensor to inspect. Also, sometimes, it would be nice to pause the operator control flow to “zoom into” a specific, erroneous part of a tensor multiple times until you are satisfied. In this regard, you can use this API to interactively inspect the tensor:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Edit for clarity: "When debugging, situations might occur at compilation time, so you do not know which part of a tensor to inspect. Sometimes, it may be nice to pause the operator control flow to “zoom into” a specific, erroneous part of a tensor multiple times until you are satisfied."

void interactive_print(std::string tag = "") {
```

This API will set a "break point" in your code, so that you will enter a loop that will keep asking you for further command. In the API call, `tag` is an optional parameter to give the call a name, so that you can identify it when you have multiple `interactive_print()` calls in different parts of your code. A visit count will tell you for how many times have you stepped into this particular "break point", should this operator be called more than once. Note that all `interactive_print()` calls are properly locked, so you can use it in many different places without issues.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"This API will set a "break point" in your code. When used, you will enter a loop that will keep asking you for further command input."

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"A visit count will tell you how many times you stepped into this particular "break point", should this operator be called more than once."


![Screen Shot 2019-07-10 at 5 29 07 PM](https://user-images.githubusercontent.com/16669457/61013632-5325e800-a338-11e9-90e6-607f17d81495.png)

Refer the screenshot above, there are many useful commands available: you can type "e" to print out the entire tensor, "d" to dump the tensor to file (see below), "b" to break from this command loop, and "s" to skip all future `interactive_print()`. Most importantly, in this screen, you can specify a part of the tensor that you are particularly interested in and want to print out. For example, for this 20x1x5x5 tensor, you can type in "0, 0" and presss enter to check the sub-tensor with shape 5x5 at coordinate (0, 0).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"There are many useful commands available, as described in the previous screenshot"


### Dump Tensor Value

Sometimes, you might want to dump the tensor to a file in binary mode. Then, you might want to use a python script to further analyze the tensor value. Or, you might do that simply because a binary dumps has better precision and is faster to load than if you copy-paste the output from `print_string()` and load it as a `JASON` string. Either way, you can use this API:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Or, you might do that simply because a binary dump has better precision and is faster to load than output copy-pasted from print_string() and loaded as a JASON string."

print(a)
```

Let's see the how it runs:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Let's see how it runs:"

Copy link
Contributor

@ChaiBapchya ChaiBapchya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor nitpicks. And retriever the CI.
@Zha0q1 Super helpful! Thanks for your contribution!

print(a)
```

Let's see the how it runs:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick:

Suggested change
Let's see the how it runs:
Let's see how it runs:


## Usage

This utility is located in `src/common/tensor_inspector.h`. To use it in any operator code, just include `tensor_inspector`, construct an `TensorInspector` object, and call the APIs on that object. You can run any script that uses the operator you just modified then.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any command for the same? How to include it?


### Print Tensor Value (Static)

To print out the tensor value in a nicely structured way, you can use this API:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick:

Suggested change
To print out the tensor value in a nicely structured way, you can use this API:
To print out the tensor value in a nicely structured way, you can use this API:


```c++
enum CheckerType {
NegativeChecker, // check if is negative
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
NegativeChecker, // check if is negative
NegativeChecker, // check if negative

or

Suggested change
NegativeChecker, // check if is negative
NegativeChecker, // check if it is negative

```c++
enum CheckerType {
NegativeChecker, // check if is negative
PositiveChecker, // check if is positive
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
PositiveChecker, // check if is positive
PositiveChecker, // check if positive

or

Suggested change
PositiveChecker, // check if is positive
PositiveChecker, // check if it is positive

So on and so forth for the rest

@Zha0q1
Copy link
Contributor Author

Zha0q1 commented Jul 19, 2019

@ChaiBapchya @IvyBazan Thanks for the very detailed revision suggestions! I've made the changes locally, and after my images are ready, I will change the image url's in the doc as well. Very looking forward to having it posted so that developers can start using!

Copy link
Contributor

@apeforest apeforest left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LATM (Looks Awesome To Me)
Thanks for your contribution

Copy link
Contributor

@IvyBazan IvyBazan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Contributor

@ChaiBapchya ChaiBapchya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LSTM! Looks SUPER to me! 👍 😛

@Zha0q1
Copy link
Contributor Author

Zha0q1 commented Jul 20, 2019

Haha you guys are BREATHTAKING

@sandeep-krishnamurthy sandeep-krishnamurthy merged commit cc861f0 into apache:master Jul 20, 2019
@sandeep-krishnamurthy
Copy link
Contributor

anirudhacharya pushed a commit to anirudhacharya/mxnet that referenced this pull request Aug 20, 2019
* add tensor inspector tutorial

* link docs

* link docs

* add license

* Revert "add license"

This reverts commit 32881e5.

* Revert "link docs"

This reverts commit f93ae21.

* Revert "link docs"

This reverts commit 160b891.

* Revert "add tensor inspector tutorial"

This reverts commit 3b53981.

* add tensor inspector doc

* fix api name

* add new test and limitations section

* fix

* update urls and other fixes

* fix urls

* fix
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants