Skip to content

Commit 852873d

Browse files
committed
tweak
1 parent a338a2d commit 852873d

File tree

1 file changed

+15
-103
lines changed

1 file changed

+15
-103
lines changed

README.md

Lines changed: 15 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,118 +1,38 @@
11
# Tensor Sensor
22

3-
The goal of this library is to generate more helpful exception
4-
messages for numpy/pytorch/tensorflow matrix algebra expressions. Because the
5-
matrix algebra in these libraries is all done in C/C++, they do not
6-
have access to the Python execution environment so they are literally
7-
unable to give information about which Python variables and subexpression caused the problem. Only by catching the exception and then analyzing/re-executing the Python code can we get this kind of an error message.
3+
<img src="https://explained.ai/tensor-sensor/images/teaser.png" width="40%" align="right">One of the biggest challenges when writing code to implement deep learning networks, particularly for us newbies, is getting all of the tensor (matrix and vector) dimensions to line up properly. It's really easy to lose track of tensor dimensionality in complicated expressions involving multiple tensors and tensor operations. Even when just feeding data into predefined [Tensorflow](https://www.tensorflow.org/) network layers, we still need to get the dimensions right. When you ask for improper computations, you're going to run into some less than helpful exception messages. To help myself and other programmers debug tensor code, I built this library. TensorSensor clarifies exceptions by augmenting messages and visualizing Python code to indicate the shape of tensor variables (see figure to the right for a teaser). It works with [Tensorflow](https://www.tensorflow.org/), [PyTorch](https://pytorch.org/), and [Numpy](https://numpy.org/), as well as higher-level libraries like [Keras](https://keras.io/) and [fastai](https://www.fast.ai/).
84

9-
The Python `with` statement allows me to trap exceptions that occur
10-
and then I literally parse the Python code of the offending line, build an
11-
expression tree, and then incrementally evaluate the operands
12-
bottom-up until I run into an exception. That tells me which of the
13-
subexpressions caused the problem and then I can pull it apart and
14-
ask if any of those operands are matrices.
15-
16-
Imagine you have a complicated little matrix expression like:
17-
18-
```
19-
W @ torch.dot(b,b)+ torch.eye(2,2)@x + z
20-
```
21-
22-
And you get this unhelpful error message from pytorch:
23-
24-
```
25-
RuntimeError: 1D tensors expected, got 2D, 2D tensors at [...]/THTensorEvenMoreMath.cpp:83
26-
```
27-
28-
There are two problems: it does not tell you which of the sub
29-
expressions threw the exception and it does not tell you what the
30-
shape of relevant operands are. This library that lets you
31-
do this:
32-
33-
```
34-
import tsensor
35-
with tsensor.clarify():
36-
W @ torch.dot(b,b)+ torch.eye(2,2)@x + z
37-
```
38-
39-
which then augments the exception message with the following clarification:
40-
41-
```
42-
Cause: torch.dot(b,b) tensor arg b w/shape [2, 1], arg b w/shape [2, 1]
43-
```
44-
45-
Here’s another default error message that is almost helpful for expression `W @ z`:
46-
47-
```
48-
RuntimeError: size mismatch, get 2, 2x2,3
49-
```
50-
51-
But tensor-sensor gives:
52-
53-
```
54-
Cause: @ on tensor operand W w/shape [2, 2] and operand z w/shape [3]
55-
```
56-
57-
Non-tensor args/values are ignored.
58-
59-
```
60-
with tsensor.clarify():
61-
torch.dot(b, 3)
62-
```
63-
64-
gives:
65-
66-
```
67-
TypeError: dot(): argument 'tensor' (position 2) must be Tensor, not int
68-
Cause: torch.dot(b,3) tensor arg b w/shape [2, 1]
69-
```
70-
71-
If there are no tensor args, it just shows the cause:
72-
73-
```
74-
with tsensor.clarify():
75-
z.reshape(1,2,2)
76-
```
77-
78-
gives:
79-
80-
```
81-
RuntimeError: shape '[1, 2, 2]' is invalid for input of size 3
82-
Cause: z.reshape(1,2,2)
83-
```
5+
*TensorSensor is currently at 0.1b1 so I'm happy to receive issues created at this repo or direct email*.
846

857
## Visualizations
868

879
For more, see [examples.ipynb](testing/examples.ipynb).
8810

8911
```python
90-
import tsensor
91-
import graphviz
9212
import torch
93-
import sys
13+
W = torch.rand(d,n_neurons)
14+
b = torch.rand(n_neurons,1)
15+
X = torch.rand(n,d)
16+
with tsensor.clarify():
17+
Y = W @ X.T + b
18+
```
9419

95-
W = torch.tensor([[1, 2], [3, 4]])
96-
b = torch.tensor([9, 10]).reshape(2, 1)
97-
x = torch.tensor([4, 5]).reshape(2, 1)
98-
h = torch.tensor([1,2])
20+
Displays this in a jupyter notebook or separate window:
9921

100-
with tsensor.explain():
101-
a = torch.relu(x)
102-
b = W @ b + h.dot(h)
103-
```
22+
<img src="https://explained.ai/tensor-sensor/images/mm.svg">
23+
24+
Instead of the following default exception message:
10425

105-
Displays this in a notebook:
26+
<font bgcolor="#FEE4E5">RuntimeError: size mismatch, m1: [764 x 100], m2: [764 x 200] at /tmp/pip-req-build-as628lz5/aten/src/TH/generic/THTensorMath.cpp:41</font>
10627

107-
<img src="images/sample-1.svg">
28+
TensorSensor augmented with:
10829

109-
<img src="images/sample-2.svg">
30+
<font bgcolor="#FEE4E5">Cause: @ on tensor operand W w/shape [764, 100] and operand X.T w/shape [764, 200]</font>
11031

11132

11233
## Install
11334

11435
```
115-
pip install -U graphviz # make sure you have latest
11636
pip install tensor-sensor
11737
```
11838

@@ -164,14 +84,6 @@ $ cd ~/github/tensor-sensor
16484
$ pip install .
16585
```
16686

167-
## Notes
168-
169-
The behavior of clarify. Clarify has no burden on the run time unless an exception occurs. At this time, it reevaluates the offending line looking for the self-expression that caused the problem. It not only updates the error message in the exception object, but it visualizes the error.
170-
171-
The behavior of explain. Explain is a big burden on runtime execution. Before every line is executed, explain will evaluate all sub expressions and produce a visualization. Then, the line executes normally. If there is an exception in that line, we detected during visualization and display an altered view of that statement that highlights the offending sub expression. We also need to behave like clarify for the error message in the exception triggered when the Python VM executes that statement normally (after are visualization).
172-
173-
So, in both cases, we trap exceptions using the `with` construct and augment exception messages. Explain differs from clarify in that we use `settrace()` to process each line of code before the VM executes it normally. Clarify never needs to deal with tracing.
174-
17587
### TODO
17688

17789
* can i call pyviz in debugger?

0 commit comments

Comments
 (0)