Repository: truera/trulens
Issue: Dependency of visualizers on backend leads to confusing error
Root cause: Validation Gap

Many visualizers, including the `Tiler` class should be able to be used without necessarily using other TruLens features. However, typically, the backend will be set when the user calls `get_model_wrapper`, unless they have explicitly set the backend environment variable (which is probably not the norm). This creates a problem when using the `Tiler` as it uses the backend to get the channel dimension. When the backend has not been set either in the environment variable or by calling `get_model_wrapper`, the backend comes back as `None`, leading to an error, that will perhaps be confusing to a user trying to use just the visualization library of TruLens.

I suggest that we try to handle the case where the backend is not set when the tiler is called (and other places the channel dimension comes up in the visualizers). Most of the time, the channel dimension should be able to be inferred, because it is used for the purpose of displaying RGB or grayscale images, which can only have a 3 or a 1 as the size of the channel dimension. Thus, the only ambiguous case is when the image itself has a height/width of 3 or 1. In those cases, perhaps we can adopt a default, e.g., the convention used by `matplotlib` (which I believe is channels last).

The new process when trying to obtain the channel dimension would be:
* check if the backend is set. If so, use the backend channel dimension;
* otherwise, check if there is a single dimension with size 1 or 3. If so, use that as the channel dimension;
* otherwise, assume the user has provided images in the format that the visualization library (`matplotlib`) expects.

This way the `visualizations` module never throws errors simply because the user never specified the backend.

Makes sense, if anything, I would move the matplotlib assumption above the choosing any single dimension, since that one is more arbitrary and kind of a last ditch naive approach.

> I would move the matplotlib assumption above the choosing any single dimension, since that one is more arbitrary and kind of a last ditch naive approach.

My thinking was that this ordering would lead to the greatest convenience. Basically, I like to use the `Tiler` class as a convenient for visualizing training data, even if I'm not using other TruLens features.

If we use the matplotlib assumption, then we will always pick (I think) the last dimension as the channel dimension (so we'll never reach any other cases in our "switch statement" suggested above). This is standard in tensorflow, but not pytorch. So if the user is using pytorch, or keras with `'channels_first'`, they may have some data that they would like to visualize that is naturally in NCHW format. In that case, they would have to transpose the dimensions before sending it to the tiler. On the other hand, this data would probably have a shape of something like (n, 3, x, y), in which case we could infer that dimension 1 is the channel dimension, as long as y doesn't happen to be 3. This would make it so that NCHW users could use the tiler with their preferred format without having to "know" that matplotlib wants NHWC format, and also without having to specify the backend to TruLens.

If it happens to be ambiguous for some reason we could warn them that we're using the default of NHWC.