allegroai / clearml

ClearML - Auto-Magical CI/CD to streamline your AI workload. Experiment Management, Data Management, Pipeline, Orchestration, Scheduling & Serving in one MLOps/LLMOps solution
https://clear.ml/docs
Apache License 2.0
5.69k stars 655 forks source link

Tensorboard images are not saved and rendered correctly #1142

Closed Inquisitive-ME closed 1 year ago

Inquisitive-ME commented 1 year ago

Describe the bug

Small images are incorrectly saved and rendered when saved through tensorboard

To reproduce

Run the python script below

from clearml import Task

import numpy as np
import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.callbacks import TensorBoard
import datetime

task = Task.init(project_name="temp",
                 task_name="debug viewing images",
                 continue_last_task=False)

# Define a simple model
model = models.Sequential([
    layers.Dense(10, activation='relu', input_shape=(32*32*3,)),
    layers.Dense(32*32*3, activation='sigmoid')
])

model.compile(optimizer='adam', loss='mse')

# Generate random data
x_train = np.random.random((1000, 32*32*3))
y_train = np.random.random((1000, 32*32*3))

# Specify the two colors you want (in RGB format)
color1 = [1, 0, 0]  # Red for the two 8x8 squares
color2 = [0, 0, 1]  # Blue for the 4x4 square
color3 = [0, 1, 0]  # Blue for the 4x4 square

# Define a custom callback to save images to TensorBoard
class ImageLoggingCallback(tf.keras.callbacks.Callback):
    def __init__(self, log_dir):
        self.log_dir = log_dir
    def on_epoch_end(self, epoch, logs=None):
        random_image = np.random.random((1, 32, 32, 3))
        # Create two 8x8 squares with color1
        square1 = np.array(color1).reshape(1, 1, 3)
        square1 = np.repeat(square1, 8, axis=0)
        square1 = np.repeat(square1, 8, axis=1)

        square2 = np.array(color2).reshape(1, 1, 3)
        square2 = np.repeat(square2, 8, axis=0)
        square2 = np.repeat(square2, 8, axis=1)

        # Create a 4x4 square with color2
        small_square = np.array(color3).reshape(1, 1, 3)
        small_square = np.repeat(small_square, 4, axis=0)
        small_square = np.repeat(small_square, 4, axis=1)

        # Place them on a blank 32x32 canvas
        canvas = np.ones((32, 32, 3))
        canvas[:8, :8] = square1
        canvas[:8, 8:16] = square2
        canvas[28:32, 28:32] = small_square

        canvas = np.expand_dims(canvas, axis=0)
        writer = tf.summary.create_file_writer(self.log_dir)
        with writer.as_default():
            tf.summary.image("Random Image", canvas, step=epoch)

log_dir = "logs/" + datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
tensorboard_callback = TensorBoard(log_dir=log_dir, histogram_freq=0)
image_logging_callback = ImageLoggingCallback(log_dir)

model.fit(x_train, y_train, epochs=5, callbacks=[tensorboard_callback, image_logging_callback])
task.close()

print("Training complete! You can now view the logs in TensorBoard.")

Expected behaviour

The image downloaded via clearML is below, which has artifacts that do not exist in the actual image ClearML Image

This is the actual image that was downloaded from tensoboard tensorboard_image

Github does not show them well so here is a closeup side by side of each image. The correct TensorBoard image is on the left

image

Environment

ainoam commented 1 year ago

@Inquisitive-ME ClearML converts Tensorboard images to image files, and its default settings might indeed produce distorted results for small images. You can configure the conversion settings through clearml.conf (e.g. in this case, opting for a "PNG" format would yield better results).

Inquisitive-ME commented 1 year ago

Thank you that fixed the issue.