mirror of
https://github.com/deepfakes/faceswap
synced 2025-06-07 10:43:27 -04:00
Analysis Fixups
- Move stats calculations to LongRunningTasks - Fix divide by zero error on rate calculations
This commit is contained in:
parent
4ce8edf689
commit
ebea2b7142
4 changed files with 189 additions and 74 deletions
76
CODE_OF_CONDUCT.md
Normal file
76
CODE_OF_CONDUCT.md
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
# Contributor Covenant Code of Conduct
|
||||||
|
|
||||||
|
## Our Pledge
|
||||||
|
|
||||||
|
In the interest of fostering an open and welcoming environment, we as
|
||||||
|
contributors and maintainers pledge to making participation in our project and
|
||||||
|
our community a harassment-free experience for everyone, regardless of age, body
|
||||||
|
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||||
|
level of experience, education, socio-economic status, nationality, personal
|
||||||
|
appearance, race, religion, or sexual identity and orientation.
|
||||||
|
|
||||||
|
## Our Standards
|
||||||
|
|
||||||
|
Examples of behavior that contributes to creating a positive environment
|
||||||
|
include:
|
||||||
|
|
||||||
|
* Using welcoming and inclusive language
|
||||||
|
* Being respectful of differing viewpoints and experiences
|
||||||
|
* Gracefully accepting constructive criticism
|
||||||
|
* Focusing on what is best for the community
|
||||||
|
* Showing empathy towards other community members
|
||||||
|
|
||||||
|
Examples of unacceptable behavior by participants include:
|
||||||
|
|
||||||
|
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||||
|
advances
|
||||||
|
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||||
|
* Public or private harassment
|
||||||
|
* Publishing others' private information, such as a physical or electronic
|
||||||
|
address, without explicit permission
|
||||||
|
* Other conduct which could reasonably be considered inappropriate in a
|
||||||
|
professional setting
|
||||||
|
|
||||||
|
## Our Responsibilities
|
||||||
|
|
||||||
|
Project maintainers are responsible for clarifying the standards of acceptable
|
||||||
|
behavior and are expected to take appropriate and fair corrective action in
|
||||||
|
response to any instances of unacceptable behavior.
|
||||||
|
|
||||||
|
Project maintainers have the right and responsibility to remove, edit, or
|
||||||
|
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||||
|
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||||
|
permanently any contributor for other behaviors that they deem inappropriate,
|
||||||
|
threatening, offensive, or harmful.
|
||||||
|
|
||||||
|
## Scope
|
||||||
|
|
||||||
|
This Code of Conduct applies both within project spaces and in public spaces
|
||||||
|
when an individual is representing the project or its community. Examples of
|
||||||
|
representing a project or community include using an official project e-mail
|
||||||
|
address, posting via an official social media account, or acting as an appointed
|
||||||
|
representative at an online or offline event. Representation of a project may be
|
||||||
|
further defined and clarified by project maintainers.
|
||||||
|
|
||||||
|
## Enforcement
|
||||||
|
|
||||||
|
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||||
|
reported by contacting the project team at deefakesrepo@gmail.com. All
|
||||||
|
complaints will be reviewed and investigated and will result in a response that
|
||||||
|
is deemed necessary and appropriate to the circumstances. The project team is
|
||||||
|
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||||
|
Further details of specific enforcement policies may be posted separately.
|
||||||
|
|
||||||
|
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||||
|
faith may face temporary or permanent repercussions as determined by other
|
||||||
|
members of the project's leadership.
|
||||||
|
|
||||||
|
## Attribution
|
||||||
|
|
||||||
|
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
||||||
|
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
|
||||||
|
|
||||||
|
[homepage]: https://www.contributor-covenant.org
|
||||||
|
|
||||||
|
For answers to common questions about this code of conduct, see
|
||||||
|
https://www.contributor-covenant.org/faq
|
|
@ -11,7 +11,7 @@ from .display_graph import SessionGraph
|
||||||
from .display_page import DisplayPage
|
from .display_page import DisplayPage
|
||||||
from .stats import Calculations, Session
|
from .stats import Calculations, Session
|
||||||
from .tooltip import Tooltip
|
from .tooltip import Tooltip
|
||||||
from .utils import ControlBuilder, FileHandler, get_config, get_images
|
from .utils import ControlBuilder, FileHandler, get_config, get_images, LongRunningTask
|
||||||
|
|
||||||
logger = logging.getLogger(__name__) # pylint: disable=invalid-name
|
logger = logging.getLogger(__name__) # pylint: disable=invalid-name
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ class Analysis(DisplayPage): # pylint: disable=too-many-ancestors
|
||||||
self.session = None
|
self.session = None
|
||||||
self.add_options()
|
self.add_options()
|
||||||
self.add_main_frame()
|
self.add_main_frame()
|
||||||
|
self.thread = None # Thread for compiling stats data in background
|
||||||
logger.debug("Initialized: %s", self.__class__.__name__)
|
logger.debug("Initialized: %s", self.__class__.__name__)
|
||||||
|
|
||||||
def set_vars(self):
|
def set_vars(self):
|
||||||
|
@ -60,10 +61,8 @@ class Analysis(DisplayPage): # pylint: disable=too-many-ancestors
|
||||||
def load_session(self):
|
def load_session(self):
|
||||||
""" Load previously saved sessions """
|
""" Load previously saved sessions """
|
||||||
logger.debug("Loading session")
|
logger.debug("Loading session")
|
||||||
get_config().set_cursor_busy()
|
|
||||||
fullpath = FileHandler("filename", "state").retfile
|
fullpath = FileHandler("filename", "state").retfile
|
||||||
if not fullpath:
|
if not fullpath:
|
||||||
get_config().set_cursor_default()
|
|
||||||
return
|
return
|
||||||
self.clear_session()
|
self.clear_session()
|
||||||
logger.debug("state_file: '%s'", fullpath)
|
logger.debug("state_file: '%s'", fullpath)
|
||||||
|
@ -71,7 +70,6 @@ class Analysis(DisplayPage): # pylint: disable=too-many-ancestors
|
||||||
logger.debug("model_dir: '%s'", model_dir)
|
logger.debug("model_dir: '%s'", model_dir)
|
||||||
model_name = self.get_model_name(model_dir, state_file)
|
model_name = self.get_model_name(model_dir, state_file)
|
||||||
if not model_name:
|
if not model_name:
|
||||||
get_config().set_cursor_default()
|
|
||||||
return
|
return
|
||||||
self.session = Session(model_dir=model_dir, model_name=model_name)
|
self.session = Session(model_dir=model_dir, model_name=model_name)
|
||||||
self.session.initialize_session(is_training=False)
|
self.session.initialize_session(is_training=False)
|
||||||
|
@ -79,7 +77,6 @@ class Analysis(DisplayPage): # pylint: disable=too-many-ancestors
|
||||||
if len(msg) > 70:
|
if len(msg) > 70:
|
||||||
msg = "...{}".format(msg[-70:])
|
msg = "...{}".format(msg[-70:])
|
||||||
self.set_session_summary(msg)
|
self.set_session_summary(msg)
|
||||||
get_config().set_cursor_default()
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_model_name(model_dir, state_file):
|
def get_model_name(model_dir, state_file):
|
||||||
|
@ -96,28 +93,40 @@ class Analysis(DisplayPage): # pylint: disable=too-many-ancestors
|
||||||
def reset_session(self):
|
def reset_session(self):
|
||||||
""" Reset currently training sessions """
|
""" Reset currently training sessions """
|
||||||
logger.debug("Reset current training session")
|
logger.debug("Reset current training session")
|
||||||
get_config().set_cursor_busy()
|
|
||||||
self.clear_session()
|
self.clear_session()
|
||||||
session = get_config().session
|
session = get_config().session
|
||||||
if not session.initialized:
|
if not session.initialized:
|
||||||
logger.debug("Training not running")
|
logger.debug("Training not running")
|
||||||
print("Training not running")
|
print("Training not running")
|
||||||
get_config().set_cursor_default()
|
|
||||||
return
|
return
|
||||||
msg = "Currently running training session"
|
msg = "Currently running training session"
|
||||||
self.session = session
|
self.session = session
|
||||||
# Reload the state file to get approx currently training iterations
|
# Reload the state file to get approx currently training iterations
|
||||||
self.session.load_state_file()
|
self.session.load_state_file()
|
||||||
self.set_session_summary(msg)
|
self.set_session_summary(msg)
|
||||||
get_config().set_cursor_default()
|
|
||||||
|
|
||||||
def set_session_summary(self, message):
|
def set_session_summary(self, message):
|
||||||
""" Set the summary data and info message """
|
""" Set the summary data and info message """
|
||||||
logger.debug("Setting session summary. (message: '%s')", message)
|
if self.thread is None:
|
||||||
self.summary = self.session.full_summary
|
logger.debug("Setting session summary. (message: '%s')", message)
|
||||||
self.set_info("Session: {}".format(message))
|
self.thread = LongRunningTask(target=self.summarise_data, args=(self.session, ))
|
||||||
self.stats.session = self.session
|
self.thread.start()
|
||||||
self.stats.tree_insert_data(self.summary)
|
self.after(1000, lambda msg=message: self.set_session_summary(msg))
|
||||||
|
elif not self.thread.complete.is_set():
|
||||||
|
logger.debug("Data not yet available")
|
||||||
|
self.after(1000, lambda msg=message: self.set_session_summary(msg))
|
||||||
|
else:
|
||||||
|
logger.debug("Retrieving data from thread")
|
||||||
|
self.summary = self.thread.get_result()
|
||||||
|
self.thread = None
|
||||||
|
self.set_info("Session: {}".format(message))
|
||||||
|
self.stats.session = self.session
|
||||||
|
self.stats.tree_insert_data(self.summary)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def summarise_data(session):
|
||||||
|
""" Summarise data in a LongRunningThread as it can take a while """
|
||||||
|
return session.full_summary
|
||||||
|
|
||||||
def clear_session(self):
|
def clear_session(self):
|
||||||
""" Clear sessions stats """
|
""" Clear sessions stats """
|
||||||
|
@ -130,16 +139,13 @@ class Analysis(DisplayPage): # pylint: disable=too-many-ancestors
|
||||||
def save_session(self):
|
def save_session(self):
|
||||||
""" Save sessions stats to csv """
|
""" Save sessions stats to csv """
|
||||||
logger.debug("Saving session")
|
logger.debug("Saving session")
|
||||||
get_config().set_cursor_busy()
|
|
||||||
if not self.summary:
|
if not self.summary:
|
||||||
logger.debug("No summary data loaded. Nothing to save")
|
logger.debug("No summary data loaded. Nothing to save")
|
||||||
print("No summary data loaded. Nothing to save")
|
print("No summary data loaded. Nothing to save")
|
||||||
get_config().set_cursor_default()
|
|
||||||
return
|
return
|
||||||
savefile = FileHandler("save", "csv").retfile
|
savefile = FileHandler("save", "csv").retfile
|
||||||
if not savefile:
|
if not savefile:
|
||||||
logger.debug("No save file. Returning")
|
logger.debug("No save file. Returning")
|
||||||
get_config().set_cursor_default()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
write_dicts = [val for val in self.summary.values()]
|
write_dicts = [val for val in self.summary.values()]
|
||||||
|
@ -151,7 +157,6 @@ class Analysis(DisplayPage): # pylint: disable=too-many-ancestors
|
||||||
csvout.writeheader()
|
csvout.writeheader()
|
||||||
for row in write_dicts:
|
for row in write_dicts:
|
||||||
csvout.writerow(row)
|
csvout.writerow(row)
|
||||||
get_config().set_cursor_default()
|
|
||||||
|
|
||||||
|
|
||||||
class Options():
|
class Options():
|
||||||
|
@ -202,6 +207,7 @@ class StatsData(ttk.Frame): # pylint: disable=too-many-ancestors
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.pack(side=tk.TOP, padx=5, pady=5, fill=tk.BOTH, expand=True)
|
self.pack(side=tk.TOP, padx=5, pady=5, fill=tk.BOTH, expand=True)
|
||||||
self.session = None # set when loading or clearing from parent
|
self.session = None # set when loading or clearing from parent
|
||||||
|
self.thread = None # Thread for loading data popup
|
||||||
self.selected_id = selected_id
|
self.selected_id = selected_id
|
||||||
self.popup_positions = list()
|
self.popup_positions = list()
|
||||||
|
|
||||||
|
@ -318,8 +324,6 @@ class StatsData(ttk.Frame): # pylint: disable=too-many-ancestors
|
||||||
If there are fewer data points than this, switch the default
|
If there are fewer data points than this, switch the default
|
||||||
to smoothed
|
to smoothed
|
||||||
"""
|
"""
|
||||||
get_config().set_cursor_busy()
|
|
||||||
get_config().root.update_idletasks()
|
|
||||||
logger.debug("Popping up data window")
|
logger.debug("Popping up data window")
|
||||||
scaling_factor = get_config().scaling_factor
|
scaling_factor = get_config().scaling_factor
|
||||||
toplevel = SessionPopUp(self.session.modeldir,
|
toplevel = SessionPopUp(self.session.modeldir,
|
||||||
|
@ -339,7 +343,6 @@ class StatsData(ttk.Frame): # pylint: disable=too-many-ancestors
|
||||||
str(position[0]),
|
str(position[0]),
|
||||||
str(position[1])))
|
str(position[1])))
|
||||||
toplevel.update()
|
toplevel.update()
|
||||||
get_config().set_cursor_default()
|
|
||||||
|
|
||||||
def data_popup_title(self):
|
def data_popup_title(self):
|
||||||
""" Set the data popup title """
|
""" Set the data popup title """
|
||||||
|
@ -386,17 +389,18 @@ class SessionPopUp(tk.Toplevel):
|
||||||
"datapoints: %s)", self.__class__.__name__, model_dir, model_name, session_id,
|
"datapoints: %s)", self.__class__.__name__, model_dir, model_name, session_id,
|
||||||
datapoints)
|
datapoints)
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
self.thread = None # Thread for loading data in a background task
|
||||||
self.default_avg = 500
|
self.default_avg = 500
|
||||||
self.default_view = "avg" if datapoints > self.default_avg * 2 else "smoothed"
|
self.default_view = "avg" if datapoints > self.default_avg * 2 else "smoothed"
|
||||||
self.session_id = session_id
|
self.session_id = session_id
|
||||||
self.session = Session(model_dir=model_dir, model_name=model_name)
|
self.session = Session(model_dir=model_dir, model_name=model_name)
|
||||||
self.initialize_session()
|
self.initialize_session()
|
||||||
|
|
||||||
|
self.graph_frame = None
|
||||||
self.graph = None
|
self.graph = None
|
||||||
self.display_data = None
|
self.display_data = None
|
||||||
|
|
||||||
self.vars = dict()
|
self.vars = {"status": tk.StringVar()}
|
||||||
self.graph_initialised = False
|
self.graph_initialised = False
|
||||||
self.build()
|
self.build()
|
||||||
logger.debug("Initialized: %s", self.__class__.__name__)
|
logger.debug("Initialized: %s", self.__class__.__name__)
|
||||||
|
@ -418,13 +422,20 @@ class SessionPopUp(tk.Toplevel):
|
||||||
def build(self):
|
def build(self):
|
||||||
""" Build the popup window """
|
""" Build the popup window """
|
||||||
logger.debug("Building popup")
|
logger.debug("Building popup")
|
||||||
optsframe, graphframe = self.layout_frames()
|
optsframe = self.layout_frames()
|
||||||
|
self.set_callback()
|
||||||
self.opts_build(optsframe)
|
self.opts_build(optsframe)
|
||||||
self.compile_display_data()
|
self.compile_display_data()
|
||||||
self.graph_build(graphframe)
|
|
||||||
logger.debug("Built popup")
|
logger.debug("Built popup")
|
||||||
|
|
||||||
|
def set_callback(self):
|
||||||
|
""" Set a tk boolean var to callback when graph is ready to build """
|
||||||
|
logger.debug("Setting tk graph build variable")
|
||||||
|
var = tk.BooleanVar()
|
||||||
|
var.set(False)
|
||||||
|
var.trace("w", self.graph_build)
|
||||||
|
self.vars["buildgraph"] = var
|
||||||
|
|
||||||
def layout_frames(self):
|
def layout_frames(self):
|
||||||
""" Top level container frames """
|
""" Top level container frames """
|
||||||
logger.debug("Layout frames")
|
logger.debug("Layout frames")
|
||||||
|
@ -434,11 +445,11 @@ class SessionPopUp(tk.Toplevel):
|
||||||
sep = ttk.Frame(self, width=2, relief=tk.RIDGE)
|
sep = ttk.Frame(self, width=2, relief=tk.RIDGE)
|
||||||
sep.pack(fill=tk.Y, side=tk.LEFT)
|
sep.pack(fill=tk.Y, side=tk.LEFT)
|
||||||
|
|
||||||
rightframe = ttk.Frame(self)
|
self.graph_frame = ttk.Frame(self)
|
||||||
rightframe.pack(side=tk.RIGHT, fill=tk.BOTH, pady=5, expand=True)
|
self.graph_frame.pack(side=tk.RIGHT, fill=tk.BOTH, pady=5, expand=True)
|
||||||
logger.debug("Laid out frames")
|
logger.debug("Laid out frames")
|
||||||
|
|
||||||
return leftframe, rightframe
|
return leftframe
|
||||||
|
|
||||||
def opts_build(self, frame):
|
def opts_build(self, frame):
|
||||||
""" Build Options into the options frame """
|
""" Build Options into the options frame """
|
||||||
|
@ -581,6 +592,12 @@ class SessionPopUp(tk.Toplevel):
|
||||||
btnframe = ttk.Frame(frame)
|
btnframe = ttk.Frame(frame)
|
||||||
btnframe.pack(fill=tk.X, pady=5, padx=5, side=tk.BOTTOM)
|
btnframe.pack(fill=tk.X, pady=5, padx=5, side=tk.BOTTOM)
|
||||||
|
|
||||||
|
lblstatus = ttk.Label(btnframe,
|
||||||
|
width=40,
|
||||||
|
textvariable=self.vars["status"],
|
||||||
|
anchor=tk.W)
|
||||||
|
lblstatus.pack(side=tk.LEFT, anchor=tk.W, fill=tk.X, expand=True)
|
||||||
|
|
||||||
for btntype in ("reset", "save"):
|
for btntype in ("reset", "save"):
|
||||||
cmd = getattr(self, "optbtn_{}".format(btntype))
|
cmd = getattr(self, "optbtn_{}".format(btntype))
|
||||||
btn = ttk.Button(btnframe,
|
btn = ttk.Button(btnframe,
|
||||||
|
@ -594,11 +611,9 @@ class SessionPopUp(tk.Toplevel):
|
||||||
def optbtn_save(self):
|
def optbtn_save(self):
|
||||||
""" Action for save button press """
|
""" Action for save button press """
|
||||||
logger.debug("Saving File")
|
logger.debug("Saving File")
|
||||||
self.config(cursor="watch")
|
|
||||||
savefile = FileHandler("save", "csv").retfile
|
savefile = FileHandler("save", "csv").retfile
|
||||||
if not savefile:
|
if not savefile:
|
||||||
logger.debug("Save Cancelled")
|
logger.debug("Save Cancelled")
|
||||||
self.config(cursor="")
|
|
||||||
return
|
return
|
||||||
logger.debug("Saving to: %s", savefile)
|
logger.debug("Saving to: %s", savefile)
|
||||||
save_data = self.display_data.stats
|
save_data = self.display_data.stats
|
||||||
|
@ -608,34 +623,26 @@ class SessionPopUp(tk.Toplevel):
|
||||||
csvout = csv.writer(outfile, delimiter=",")
|
csvout = csv.writer(outfile, delimiter=",")
|
||||||
csvout.writerow(fieldnames)
|
csvout.writerow(fieldnames)
|
||||||
csvout.writerows(zip(*[save_data[key] for key in fieldnames]))
|
csvout.writerows(zip(*[save_data[key] for key in fieldnames]))
|
||||||
self.config(cursor="")
|
|
||||||
|
|
||||||
def optbtn_reset(self, *args): # pylint: disable=unused-argument
|
def optbtn_reset(self, *args): # pylint: disable=unused-argument
|
||||||
""" Action for reset button press and checkbox changes"""
|
""" Action for reset button press and checkbox changes"""
|
||||||
logger.debug("Refreshing Graph")
|
logger.debug("Refreshing Graph")
|
||||||
if not self.graph_initialised:
|
if not self.graph_initialised:
|
||||||
return
|
return
|
||||||
self.config(cursor="watch")
|
|
||||||
self.update_idletasks()
|
|
||||||
valid = self.compile_display_data()
|
valid = self.compile_display_data()
|
||||||
if not valid:
|
if not valid:
|
||||||
logger.debug("Invalid data")
|
logger.debug("Invalid data")
|
||||||
self.config(cursor="")
|
|
||||||
return
|
return
|
||||||
self.graph.refresh(self.display_data,
|
self.graph.refresh(self.display_data,
|
||||||
self.vars["display"].get(),
|
self.vars["display"].get(),
|
||||||
self.vars["scale"].get())
|
self.vars["scale"].get())
|
||||||
self.config(cursor="")
|
|
||||||
logger.debug("Refreshed Graph")
|
logger.debug("Refreshed Graph")
|
||||||
|
|
||||||
def graph_scale(self, *args): # pylint: disable=unused-argument
|
def graph_scale(self, *args): # pylint: disable=unused-argument
|
||||||
""" Action for changing graph scale """
|
""" Action for changing graph scale """
|
||||||
if not self.graph_initialised:
|
if not self.graph_initialised:
|
||||||
return
|
return
|
||||||
self.config(cursor="watch")
|
|
||||||
self.update_idletasks()
|
|
||||||
self.graph.set_yscale_type(self.vars["scale"].get())
|
self.graph.set_yscale_type(self.vars["scale"].get())
|
||||||
self.config(cursor="")
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def set_help(control):
|
def set_help(control):
|
||||||
|
@ -669,30 +676,48 @@ class SessionPopUp(tk.Toplevel):
|
||||||
|
|
||||||
def compile_display_data(self):
|
def compile_display_data(self):
|
||||||
""" Compile the data to be displayed """
|
""" Compile the data to be displayed """
|
||||||
logger.debug("Compiling Display Data")
|
if self.thread is None:
|
||||||
|
logger.debug("Compiling Display Data in background thread")
|
||||||
|
loss_keys = [key for key, val in self.vars["loss_keys"].items()
|
||||||
|
if val.get()]
|
||||||
|
logger.debug("Selected loss_keys: %s", loss_keys)
|
||||||
|
|
||||||
loss_keys = [key for key, val in self.vars["loss_keys"].items()
|
selections = self.selections_to_list()
|
||||||
if val.get()]
|
|
||||||
logger.debug("Selected loss_keys: %s", loss_keys)
|
|
||||||
|
|
||||||
selections = self.selections_to_list()
|
if not self.check_valid_selection(loss_keys, selections):
|
||||||
|
logger.warning("No data to display. Not refreshing")
|
||||||
|
return False
|
||||||
|
self.vars["status"].set("Loading Data...")
|
||||||
|
kwargs = dict(session=self.session,
|
||||||
|
display=self.vars["display"].get(),
|
||||||
|
loss_keys=loss_keys,
|
||||||
|
selections=selections,
|
||||||
|
avg_samples=self.vars["avgiterations"].get(),
|
||||||
|
smooth_amount=self.vars["smoothamount"].get(),
|
||||||
|
flatten_outliers=self.vars["outliers"].get(),
|
||||||
|
is_totals=self.is_totals)
|
||||||
|
self.thread = LongRunningTask(target=self.get_display_data, kwargs=kwargs, widget=self)
|
||||||
|
self.thread.start()
|
||||||
|
self.after(1000, self.compile_display_data)
|
||||||
|
elif not self.thread.complete.is_set():
|
||||||
|
logger.debug("Popup Data not yet available")
|
||||||
|
self.after(1000, self.compile_display_data)
|
||||||
|
else:
|
||||||
|
logger.debug("Getting Popup from background Thread")
|
||||||
|
self.display_data = self.thread.get_result()
|
||||||
|
self.thread = None
|
||||||
|
if not self.check_valid_data():
|
||||||
|
logger.warning("No valid data to display. Not refreshing")
|
||||||
|
self.vars["status"].set("")
|
||||||
|
return False
|
||||||
|
logger.debug("Compiled Display Data")
|
||||||
|
self.vars["buildgraph"].set(True)
|
||||||
|
return True
|
||||||
|
|
||||||
if not self.check_valid_selection(loss_keys, selections):
|
@staticmethod
|
||||||
logger.warning("No data to display. Not refreshing")
|
def get_display_data(**kwargs):
|
||||||
return False
|
""" Get the display data in a LongRunningTask """
|
||||||
self.display_data = Calculations(session=self.session,
|
return Calculations(**kwargs)
|
||||||
display=self.vars["display"].get(),
|
|
||||||
loss_keys=loss_keys,
|
|
||||||
selections=selections,
|
|
||||||
avg_samples=self.vars["avgiterations"].get(),
|
|
||||||
smooth_amount=self.vars["smoothamount"].get(),
|
|
||||||
flatten_outliers=self.vars["outliers"].get(),
|
|
||||||
is_totals=self.is_totals)
|
|
||||||
if not self.check_valid_data():
|
|
||||||
logger.warning("No valid data to display. Not refreshing")
|
|
||||||
return False
|
|
||||||
logger.debug("Compiled Display Data")
|
|
||||||
return True
|
|
||||||
|
|
||||||
def check_valid_selection(self, loss_keys, selections):
|
def check_valid_selection(self, loss_keys, selections):
|
||||||
""" Check that there will be data to display """
|
""" Check that there will be data to display """
|
||||||
|
@ -726,14 +751,24 @@ class SessionPopUp(tk.Toplevel):
|
||||||
logger.debug("Compiling selections to list: %s", selections)
|
logger.debug("Compiling selections to list: %s", selections)
|
||||||
return selections
|
return selections
|
||||||
|
|
||||||
def graph_build(self, frame):
|
def graph_build(self, *args): # pylint:disable=unused-argument
|
||||||
""" Build the graph in the top right paned window """
|
""" Build the graph in the top right paned window """
|
||||||
|
if not self.vars["buildgraph"].get():
|
||||||
|
return
|
||||||
|
self.vars["status"].set("Loading Data...")
|
||||||
logger.debug("Building Graph")
|
logger.debug("Building Graph")
|
||||||
self.graph = SessionGraph(frame,
|
if self.graph is None:
|
||||||
self.display_data,
|
self.graph = SessionGraph(self.graph_frame,
|
||||||
self.vars["display"].get(),
|
self.display_data,
|
||||||
self.vars["scale"].get())
|
self.vars["display"].get(),
|
||||||
self.graph.pack(expand=True, fill=tk.BOTH)
|
self.vars["scale"].get())
|
||||||
self.graph.build()
|
self.graph.pack(expand=True, fill=tk.BOTH)
|
||||||
self.graph_initialised = True
|
self.graph.build()
|
||||||
|
self.graph_initialised = True
|
||||||
|
else:
|
||||||
|
self.graph.refresh(self.display_data,
|
||||||
|
self.vars["display"].get(),
|
||||||
|
self.vars["scale"].get())
|
||||||
|
self.vars["status"].set("")
|
||||||
|
self.vars["buildgraph"].set(False)
|
||||||
logger.debug("Built Graph")
|
logger.debug("Built Graph")
|
||||||
|
|
|
@ -88,7 +88,8 @@ class TensorBoardLogs():
|
||||||
continue
|
continue
|
||||||
for logfile in sides.values():
|
for logfile in sides.values():
|
||||||
timestamps = [event.wall_time
|
timestamps = [event.wall_time
|
||||||
for event in tf.train.summary_iterator(logfile)]
|
for event in tf.train.summary_iterator(logfile)
|
||||||
|
if event.summary.value]
|
||||||
logger.debug("Total timestamps for session %s: %s", sess, len(timestamps))
|
logger.debug("Total timestamps for session %s: %s", sess, len(timestamps))
|
||||||
all_timestamps[sess] = timestamps
|
all_timestamps[sess] = timestamps
|
||||||
break # break after first file read
|
break # break after first file read
|
||||||
|
@ -276,7 +277,7 @@ class SessionsSummary():
|
||||||
"start": ts_data["start_time"],
|
"start": ts_data["start_time"],
|
||||||
"end": ts_data["end_time"],
|
"end": ts_data["end_time"],
|
||||||
"elapsed": elapsed,
|
"elapsed": elapsed,
|
||||||
"rate": (batchsize * iterations) / elapsed,
|
"rate": (batchsize * iterations) / elapsed if elapsed != 0 else 0,
|
||||||
"batch": batchsize,
|
"batch": batchsize,
|
||||||
"iterations": iterations})
|
"iterations": iterations})
|
||||||
compiled = sorted(compiled, key=lambda k: k["session"])
|
compiled = sorted(compiled, key=lambda k: k["session"])
|
||||||
|
@ -439,6 +440,9 @@ class Calculations():
|
||||||
batchsize = batchsizes[sess_id]
|
batchsize = batchsizes[sess_id]
|
||||||
timestamps = total_timestamps[sess_id]
|
timestamps = total_timestamps[sess_id]
|
||||||
iterations = range(len(timestamps) - 1)
|
iterations = range(len(timestamps) - 1)
|
||||||
|
print("===========\n")
|
||||||
|
print(timestamps[:100])
|
||||||
|
print([batchsize / (timestamps[i + 1] - timestamps[i]) for i in iterations][:100])
|
||||||
rate.extend([batchsize / (timestamps[i + 1] - timestamps[i]) for i in iterations])
|
rate.extend([batchsize / (timestamps[i + 1] - timestamps[i]) for i in iterations])
|
||||||
logger.debug("Calculated totals rate: Item_count: %s", len(rate))
|
logger.debug("Calculated totals rate: Item_count: %s", len(rate))
|
||||||
return rate
|
return rate
|
||||||
|
|
|
@ -568,14 +568,14 @@ class Config():
|
||||||
|
|
||||||
def set_cursor_busy(self, widget=None):
|
def set_cursor_busy(self, widget=None):
|
||||||
""" Set the root or widget cursor to busy """
|
""" Set the root or widget cursor to busy """
|
||||||
logger.trace("Setting cursor to busy")
|
logger.debug("Setting cursor to busy. widget: %s", widget)
|
||||||
widget = self.root if widget is None else widget
|
widget = self.root if widget is None else widget
|
||||||
widget.config(cursor="watch")
|
widget.config(cursor="watch")
|
||||||
widget.update_idletasks()
|
widget.update_idletasks()
|
||||||
|
|
||||||
def set_cursor_default(self, widget=None):
|
def set_cursor_default(self, widget=None):
|
||||||
""" Set the root or widget cursor to default """
|
""" Set the root or widget cursor to default """
|
||||||
logger.trace("Setting cursor to default")
|
logger.debug("Setting cursor to default. widget: %s", widget)
|
||||||
widget = self.root if widget is None else widget
|
widget = self.root if widget is None else widget
|
||||||
widget.config(cursor="")
|
widget.config(cursor="")
|
||||||
widget.update_idletasks()
|
widget.update_idletasks()
|
||||||
|
@ -940,7 +940,7 @@ class LongRunningTask(Thread):
|
||||||
self.widget = widget
|
self.widget = widget
|
||||||
self._config = get_config()
|
self._config = get_config()
|
||||||
self._config.set_cursor_busy(widget=self.widget)
|
self._config.set_cursor_busy(widget=self.widget)
|
||||||
self._complete = Event()
|
self.complete = Event()
|
||||||
self._queue = Queue()
|
self._queue = Queue()
|
||||||
logger.debug("Initialized %s", self.__class__.__name__,)
|
logger.debug("Initialized %s", self.__class__.__name__,)
|
||||||
|
|
||||||
|
@ -950,7 +950,7 @@ class LongRunningTask(Thread):
|
||||||
if self._target:
|
if self._target:
|
||||||
retval = self._target(*self._args, **self._kwargs)
|
retval = self._target(*self._args, **self._kwargs)
|
||||||
self._queue.put(retval)
|
self._queue.put(retval)
|
||||||
self._complete.set()
|
self.complete.set()
|
||||||
finally:
|
finally:
|
||||||
# Avoid a refcycle if the thread is running a function with
|
# Avoid a refcycle if the thread is running a function with
|
||||||
# an argument that has a member that points to the thread.
|
# an argument that has a member that points to the thread.
|
||||||
|
@ -958,7 +958,7 @@ class LongRunningTask(Thread):
|
||||||
|
|
||||||
def get_result(self):
|
def get_result(self):
|
||||||
""" Return the result from the queue """
|
""" Return the result from the queue """
|
||||||
if self._complete.is_set():
|
if self.complete.is_set():
|
||||||
logger.debug("Getting result from thread")
|
logger.debug("Getting result from thread")
|
||||||
retval = self._queue.get()
|
retval = self._queue.get()
|
||||||
logger.debug("Got result from thread")
|
logger.debug("Got result from thread")
|
||||||
|
|
Loading…
Add table
Reference in a new issue