Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PySide GUI alternative for LiveMonitoring extension #1328

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

AdamStone
Copy link
Contributor

The existing live plot functionality in /train_extensions/live_monitoring.py (LiveMonitor.follow_channels) uses matplotlib's interactive mode to continuously update the plot within a while loop, but the plot was not displaying at all for me (on Ubuntu 14.04). I've had trouble in the past trying to use matplotlib's interactive mode in this way, with inconsistent behavior between Ubuntu and Windows, and I think the reason is that ion() is really intended only for interactive updates directly from the terminal and may or may not happen to work in constructs like loops. For this sort of dynamically updating use case, the recommended approach seems to be using a UI toolkit (see e.g. http://stackoverflow.com/questions/1940387/interactive-mode-in-matplolib).

This proposed modification adds a basic implementation of a PySide Qt-based GUI for live-plotting the channels (selected with an optional arg "use_qt"). This is just a basic display of the plot, but it would be straightforward to add other dynamic UI features such as the option to select and change the plotted channels while the plot is running.

I also fixed a typo in the original follow_channels method.

@AdamStone
Copy link
Contributor Author

The initial pull request had formatting problems and was inconsistent with the style guide, so I have tried to fix it.

@daemonmaker
Copy link
Contributor

+goodfeli sent a message to pylearn-users yesterday related to formatting issues. Is your last commit related to that E-mail?

@AdamStone
Copy link
Contributor Author

I was worried I broke something when I saw that, but since this hasn't been merged, I would think he must be referring to something else? My commits to this PR were all related to fixing errors in the parts that I added, though. I didn't change the existing code besides fixing the typo.

Are the automated TravisCI tests the same as the test that's failing?

@goodfeli
Copy link
Contributor

goodfeli commented Jan 9, 2015

@daemonmaker , no, @AdamStone doesn't touch the part that has the problem. The problem is here:
https://github.com/lisa-lab/pylearn2/blob/master/pylearn2/train_extensions/tests/test_live_monitor.py#L12
You can't raise SkipTest in global scope, because it prevents the format checker from running.

So this PR is OK but someone should clean up test_live_monitor.py separately.

@goodfeli
Copy link
Contributor

goodfeli commented Jan 9, 2015

Just answered on github. Adam's PR is fine.

Dustin's test works fine on Travis because zmq is installed on Travis. That
test file fails the format checks when you run the format test on any
machine that does not have zmq installed because the SkipTest kills the
format checker.
On Fri Jan 09 2015 at 11:32:52 AM Adam Stone [email protected]
wrote:

I was worried I broke something when I saw that, but since this hasn't
been merged, I would think he must be referring to something else? My
commits to this PR were all related to fixing errors in the parts that I
added, though. I didn't change the existing code besides fixing the typo.

Are the automated TravisCI tests the same as the test that's failing?


Reply to this email directly or view it on GitHub
#1328 (comment).

@AdamStone
Copy link
Contributor Author

Ah, ok. Regarding my additions, I've been using the GUI the last few days and I find that it often shows the window as "not responding" when the update frequency is out of sync with the rate of monitor updates. I expect the main thread is getting stuck somewhere in the call to update_channels, and not returning until the epoch completes. I didn't see this initially with very short epochs, but it becomes annoying with long epochs to have the window hang for long periods of time.

It may be best to wait to merge until I can find a way to make the call to update non-blocking.

@AdamStone
Copy link
Contributor Author

Also, I wonder if it would be better in the long run to modify the original follow_channels function to provide either behavior, based on an optional arg (e.g. use_qt=True), rather than making them separate functions?

@daemonmaker
Copy link
Contributor

My apologies for the confusion +goodfeli. I realized after posting that it couldn't have been due to the changes that +AdamStone made for the exact reason he pointed out (i.e. the PR had not been merged). I will fix the problem and submit PR.

Regarding the "not responding" problem Adam. You are correct. The various calls are blocking calls. Perhaps a work around would be to put the calls into a thread separate from the thread that renders the GUI?

@daemonmaker
Copy link
Contributor

Also, I'm thinking that we should separate the fix for the spelling mistake and your GUI enhancements while we work on the "not responding" issue. I can include the fix for the spelling mistake in my PR to fix the problem with SkipTest. Does this seem reasonable to you two?

@AdamStone
Copy link
Contributor Author

Sure, that's fine. I'm trying a threaded call in the GUI right now, so if
all goes well I should have a fix for that soon as well.

On Sat, Jan 10, 2015 at 9:08 AM, daemonmaker [email protected]
wrote:

Also, I'm thinking that we should separate the fix for the spelling
mistake and your GUI enhancements while we work on the "not responding"
issue. I can include the fix for the spelling mistake in my PR to fix the
problem with SkipTest. Does this seem reasonable to you two?


Reply to this email directly or view it on GitHub
#1328 (comment).

@AdamStone
Copy link
Contributor Author

In a separate branch (EpochMonitor), I wrote a class for update_callbacks
that runs monitor.call updates within epochs, because for big datasets
I was having to wait a long time just to see the first update and confirm
that it was making progress (This was suggestion by Ian here
https://groups.google.com/forum/#!topic/pylearn-users/Mz1_1yqSYeA).

I'm noticing that on the live monitor graph, these additional updates are
being plotted, but only at the end of each epoch, and all stacked at the
same X coordinate of the finished epoch. It seems like on_monitor may be
only firing at the end of the epoch and not when monitor.call is used
outside the normal chain of events. I don't know if that's the intended
behavior or not, but do you see any reasonable way to get data points with
fractional epoch coordinates for the plot?

On Sat, Jan 10, 2015 at 10:15 AM, Adam Stone [email protected] wrote:

Sure, that's fine. I'm trying a threaded call in the GUI right now, so if
all goes well I should have a fix for that soon as well.

On Sat, Jan 10, 2015 at 9:08 AM, daemonmaker [email protected]
wrote:

Also, I'm thinking that we should separate the fix for the spelling
mistake and your GUI enhancements while we work on the "not responding"
issue. I can include the fix for the spelling mistake in my PR to fix the
problem with SkipTest. Does this seem reasonable to you two?


Reply to this email directly or view it on GitHub
#1328 (comment).

@AdamStone AdamStone force-pushed the LiveMonitorGUI branch 2 times, most recently from 952903a to 48ad0d8 Compare January 10, 2015 22:34
@AdamStone
Copy link
Contributor Author

I fixed the GUI non-responsiveness by moving the blocking update_channels call into its own thread, although I was unable to find a way to properly close the thread if the window is closed. I tried using zmq.Poller to periodically timeout and refresh the requested update so that closing the window would only take at most as long as the timeout length, but found that subsequent requests after the first timeout did not work. So for now the thread is simply killed, which raises a warning but doesn't seem to affect anything.

I also figured that the simplest way to deal with sub-epoch data was to just distribute it evenly across the epoch. So rather than three points stacked at epoch three, for example, it will plot one at 2.33, one at 2.66, and one at 3. The main downside is, the plot still only updates at the end of each epoch, so for long epochs this is still a bit unsatisfying.

@dwf
Copy link
Contributor

dwf commented Feb 11, 2015

@goodfeli @daemonmaker It sounds like this might be ready, PTAL

@goodfeli
Copy link
Contributor

Drop me from this thread, I was only here to reply to a question about whether this PR caused a bug I had reported.

TNick added a commit to TNick/pylearn2 that referenced this pull request Mar 25, 2015
@alfonsomhc
Copy link

Hello. I cannot see that this has been merged with master? In any case, I think there is a small bug:
line 641 should be:
´for splot_i in range(len(self.channel_dict)):´
instead of
´for splot_i in enumerate(len(self.channel_dict)):´
After that fix, I can run example code provided in blog post. However, I get errors when trying to execute the code again from same IPython session:
´RuntimeError: A QApplication instance already exists.´

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants