Spaces:
Sleeping
Sleeping
""" | |
Attack Logs to Visdom | |
======================== | |
""" | |
import socket | |
from textattack.shared.utils import LazyLoader, html_table_from_rows | |
from .logger import Logger | |
visdom = LazyLoader("visdom", globals(), "visdom") | |
def port_is_open(port_num, hostname="127.0.0.1"): | |
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |
result = sock.connect_ex((hostname, port_num)) | |
sock.close() | |
if result == 0: | |
return True | |
return False | |
class VisdomLogger(Logger): | |
"""Logs attack results to Visdom.""" | |
def __init__(self, env="main", port=8097, hostname="localhost"): | |
if not port_is_open(port, hostname=hostname): | |
raise socket.error(f"Visdom not running on {hostname}:{port}") | |
self.vis = visdom.Visdom(port=port, server=hostname, env=env) | |
self.env = env | |
self.port = port | |
self.hostname = hostname | |
self.windows = {} | |
self.sample_rows = [] | |
def __getstate__(self): | |
state = {i: self.__dict__[i] for i in self.__dict__ if i != "vis"} | |
return state | |
def __setstate__(self, state): | |
self.__dict__ = state | |
self.vis = visdom.Visdom(port=self.port, server=self.hostname, env=self.env) | |
def log_attack_result(self, result): | |
text_a, text_b = result.diff_color(color_method="html") | |
result_str = result.goal_function_result_str(color_method="html") | |
self.sample_rows.append([result_str, text_a, text_b]) | |
def log_summary_rows(self, rows, title, window_id): | |
self.table(rows, title=title, window_id=window_id) | |
def flush(self): | |
self.table( | |
self.sample_rows, | |
title="Sample-Level Results", | |
window_id="sample_level_results", | |
) | |
def log_hist(self, arr, numbins, title, window_id): | |
self.bar(arr, numbins=numbins, title=title, window_id=window_id) | |
def text(self, text_data, title=None, window_id="default"): | |
if window_id and window_id in self.windows: | |
window = self.windows[window_id] | |
self.vis.text(text_data, win=window) | |
else: | |
new_window = self.vis.text(text_data, opts=dict(title=title)) | |
self.windows[window_id] = new_window | |
def table(self, rows, window_id=None, title=None, header=None, style=None): | |
"""Generates an HTML table.""" | |
if not window_id: | |
window_id = title # Can provide either of these, | |
if not title: | |
title = window_id # or both. | |
table = html_table_from_rows(rows, title=title, header=header, style_dict=style) | |
self.text(table, title=title, window_id=window_id) | |
def bar(self, X_data, numbins=10, title=None, window_id=None): | |
window = None | |
if window_id and window_id in self.windows: | |
window = self.windows[window_id] | |
self.vis.bar(X=X_data, win=window, opts=dict(title=title, numbins=numbins)) | |
else: | |
new_window = self.vis.bar(X=X_data, opts=dict(title=title, numbins=numbins)) | |
if window_id: | |
self.windows[window_id] = new_window | |
def hist(self, X_data, numbins=10, title=None, window_id=None): | |
window = None | |
if window_id and window_id in self.windows: | |
window = self.windows[window_id] | |
self.vis.histogram( | |
X=X_data, win=window, opts=dict(title=title, numbins=numbins) | |
) | |
else: | |
new_window = self.vis.histogram( | |
X=X_data, opts=dict(title=title, numbins=numbins) | |
) | |
if window_id: | |
self.windows[window_id] = new_window | |