2016-07-23 46 views
18

Sekcja Image Dashboard z Tensorboard pliku ReadMe mówi:Tensorflow: Jak wyświetlić obrazy niestandardowe w Tensorboard (np matplotlib wykresy)

Since the image dashboard supports arbitrary pngs, you can use this to embed custom visualizations (e.g. matplotlib scatterplots) into TensorBoard.

widzę jak obraz pyplot można zapisać do pliku, odczytać z powrotem w postaci tensor, a następnie użyte z tf.image_summary() do zapisania go na TensorBoard, ale to stwierdzenie z readme sugeruje, że istnieje bardziej bezpośredni sposób. Jest tu? Jeśli tak, to czy istnieje jakakolwiek dodatkowa dokumentacja i/lub przykłady, jak to zrobić skutecznie?

Odpowiedz

27

Jest to dość łatwe do zrobienia, jeśli obraz znajduje się w buforze pamięci. Poniżej przedstawiam przykład, w którym pyplot jest zapisywany w buforze, a następnie konwertowany na reprezentację obrazu TF, która jest następnie przesyłana do podsumowania obrazu.

import io 
import matplotlib.pyplot as plt 
import tensorflow as tf 


def gen_plot(): 
    """Create a pyplot plot and save to buffer.""" 
    plt.figure() 
    plt.plot([1, 2]) 
    plt.title("test") 
    buf = io.BytesIO() 
    plt.savefig(buf, format='png') 
    buf.seek(0) 
    return buf 


# Prepare the plot 
plot_buf = gen_plot() 

# Convert PNG buffer to TF image 
image = tf.image.decode_png(plot_buf.getvalue(), channels=4) 

# Add the batch dimension 
image = tf.expand_dims(image, 0) 

# Add image summary 
summary_op = tf.summary.image("plot", image) 

# Session 
with tf.Session() as sess: 
    # Run 
    summary = sess.run(summary_op) 
    # Write summary 
    writer = tf.train.SummaryWriter('./logs') 
    writer.add_summary(summary) 
    writer.close() 

To daje następujące TensorBoard wizualizację:

enter image description here

+0

dziękuję. Twój przykład rzeczywiście działa. Z jakiegoś powodu, chociaż integruję tę samą metodę w moim rzeczywistym skrypcie (który ma inne podsumowania itp.), Rozwiązanie nie wydaje się być stabilne. Napisze jeden lub dwa obrazy do pliku podsumowania, a następnie zakończy się niepowodzeniem z następującym komunikatem o błędzie: 'tensorflow.python.framework.errors.NotFoundError: FetchOutputs node ImageSummary_2: 0: not found'. Być może pewnego rodzaju kwestia czasu. Jakieś pomysły? – RobR

+0

Nie jestem pewien, dlaczego tak się stanie. Trudno powiedzieć, nie widząc kodu. –

+1

'tf.image_summary' jest teraz przestarzałe. Interfejs API się zmienił. Zamiast tego użyj 'tf.summary.image' (cf [podręcznik użytkownika] (https://www.tensorflow.org/api_docs/python/tf/contrib/deprecated/image_summary) –

3

Następny skrypt nie korzysta z pośredniej kodowanie RGB/PNG. Rozwiązuje również problem z dodatkową konstrukcją operacji podczas wykonywania, pojedyncze podsumowanie jest ponownie wykorzystywane. Oczekuje się

Wielkość rysunku pozostać taka sama podczas wykonywania

Rozwiązanie to działa:

import matplotlib.pyplot as plt 
import tensorflow as tf 
import numpy as np 

def get_figure(): 
    fig = plt.figure(num=0, figsize=(6, 4), dpi=300) 
    fig.clf() 
    return fig 


def fig2rgb_array(fig, expand=True): 
    fig.canvas.draw() 
    buf = fig.canvas.tostring_rgb() 
    ncols, nrows = fig.canvas.get_width_height() 
    shape = (nrows, ncols, 3) if not expand else (1, nrows, ncols, 3) 
    return np.fromstring(buf, dtype=np.uint8).reshape(shape) 


def figure_to_summary(fig): 
    image = fig2rgb_array(fig) 
    summary_writer.add_summary(
    vis_summary.eval(feed_dict={vis_placeholder: image})) 


if __name__ == '__main__': 
     # construct graph 
     x = tf.Variable(initial_value=tf.random_uniform((2, 10))) 
     inc = x.assign(x + 1) 

     # construct summary 
     fig = get_figure() 
     vis_placeholder = tf.placeholder(tf.uint8, fig2rgb_array(fig).shape) 
     vis_summary = tf.summary.image('custom', vis_placeholder) 

     with tf.Session() as sess: 
     tf.global_variables_initializer().run() 
     summary_writer = tf.summary.FileWriter('./tmp', sess.graph) 

     for i in range(100): 
      # execute step 
      _, values = sess.run([inc, x]) 
      # draw on the plot 
      fig = get_figure() 
      plt.subplot('111').scatter(values[0], values[1]) 
      # save the summary 
      figure_to_summary(fig) 
0

ten zamierza zakończyć odpowiedź Andrzeja Pronobis. Uważnie śledzi jego piękny post, skonfigurować ten przykład minimalny roboczą:

plt.figure() 
    plt.plot([1, 2]) 
    plt.title("test") 
    buf = io.BytesIO() 
    plt.savefig(buf, format='png') 
    buf.seek(0) 
    image = tf.image.decode_png(buf.getvalue(), channels=4) 
    image = tf.expand_dims(image, 0) 
    summary = tf.summary.image("test", image, max_outputs=1) 
    writer.add_summary(summary, step) 

Gdzie pisarz jest instancją tf.summary.FileWriter. To dało mi następujący błąd: AttributeError: Przedmiot „tensor” nie ma atrybutu „wartość” Dla których this github post mieli rozwiązanie: podsumowanie musi być oceniana (w przeliczeniu na sznurku) przed dodaniem do pisarza. Więc kod działa dla mnie pozostał w następujący sposób (wystarczy dodać .eval (połączenia) w ostatnim wierszu):

plt.figure() 
    plt.plot([1, 2]) 
    plt.title("test") 
    buf = io.BytesIO() 
    plt.savefig(buf, format='png') 
    buf.seek(0) 
    image = tf.image.decode_png(buf.getvalue(), channels=4) 
    image = tf.expand_dims(image, 0) 
    summary = tf.summary.image("test", image, max_outputs=1) 
    writer.add_summary(summary.eval(), step) 

To może być na tyle krótki, aby być komentarz na jego odpowiedź, ale można je łatwo przeoczyć (i mogę też robić coś innego), więc oto jest, mam nadzieję, że to pomoże!

Cheers,
Andres