Displaying tf.summary.text with underscores correctly in Tensorboard
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
tf.summary.text is handy when you want TensorBoard to show labels, generated text, sample predictions, or debug strings. The confusing part is that TensorBoard's text plugin renders markdown, so underscores are not always treated as literal characters. If your string contains names such as user_id or model_v2_checkpoint, you need to format the text so markdown does not interpret those underscores as emphasis markers.
Why Underscores Behave Strangely
TensorBoard's text summary is rendered as markdown, not plain text. In markdown, underscores can trigger italic formatting. That means a string that should appear literally may be rendered differently or look partially formatted.
A basic text summary looks like this:
If the viewer interprets the underscores as markdown syntax, the displayed text may not look the way you expect.
Escape The Underscores
The simplest fix is to escape each underscore before writing the summary.
This works well when you want normal prose plus a few literal identifiers.
Use Code Formatting For Identifiers And Logs
If the text is really code-like content, markdown code formatting is often better than escaping individual characters. Wrapping the content in backticks or a fenced code block tells TensorBoard to render it literally.
For multi-line logs or structured output, use a fenced block:
This is usually the most reliable option when the text contains many markdown-sensitive characters.
Choosing Between Escaping And Code Blocks
Escaping is best when the text is mostly normal explanation and only a few identifiers need protection. It keeps the summary readable as prose and requires only light preprocessing.
Code formatting is better when the whole payload is machine-like, such as logs, SQL snippets, feature names, checkpoints, or JSON-shaped debug output. In those cases, a code block is easier to read and usually more robust than escaping one special character after another.
A good rule is simple: if the content should look like documentation, escape selectively. If it should look like raw output, render it as code.
Logging Dynamic Text Safely
If the content is generated dynamically, normalize it before passing it to TensorBoard. That keeps the training loop clean and avoids rendering surprises.
If your output is always machine-like data, prefer the fenced-code approach instead of doing piecemeal escaping for every special markdown character.
Common Pitfalls
The biggest mistake is assuming tf.summary.text renders plain text. It does not. Once you remember that markdown is involved, the underscore behavior makes sense.
Another issue is escaping only some strings and not others. If text comes from several places in your pipeline, centralize the formatting step so you get consistent rendering.
Be careful with Python string escaping too. To produce a literal backslash before the underscore, the Python string usually needs "\\_", not just "\_" in arbitrary contexts.
Finally, if the text is meant to look like code, do not fight markdown character by character. Wrap the content in inline code or a fenced block and let the renderer do the right thing.
Summary
- '
tf.summary.textcontent is rendered as markdown in TensorBoard.' - Underscores can be interpreted as formatting markers instead of literal characters.
- Escape underscores when you want plain text with literal identifiers.
- Use backticks or fenced code blocks for code-like or multi-line text.
- Centralize formatting for dynamic strings to avoid inconsistent rendering.

