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

[WIP] Add Jupyter Notebook to visualise topologies #234

Closed
wants to merge 3 commits into from
Closed

[WIP] Add Jupyter Notebook to visualise topologies #234

wants to merge 3 commits into from

Conversation

whzup
Copy link
Collaborator

@whzup whzup commented Aug 21, 2018

Description

This is a Jupyter notebook with animations of different topologies and some general information about the topologies themselves.

Related Issue

#156

Motivation and Context

The goal of this PR is to visualise the differences between the topologies that have been implemented so far. Additionally, it provides another resource where one might look up how to use the pyswarms library. A Jupyter notebook is added where animations of different topologies are shown so one can compare the different neighbourhood properties visually.

How Has This Been Tested?

TBD

Screenshots (if appropriate):

TBD

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

Checklist:

TBD

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Added a Jupyter Notebook to visualise the topologies.
@whzup
Copy link
Collaborator Author

whzup commented Aug 21, 2018

@ljvmiranda921 could you check if you get the same error as I did? I copied the necessary bits from the visualise example and installed ffmpeg I have no idea what this error message means. Maybe you know a quick fix for that 😧

@whzup whzup added documentation Documentation improvements or fixes v.1.1.0 In pipeline for next version labels Aug 21, 2018
@ljvmiranda921
Copy link
Owner

ljvmiranda921 commented Aug 22, 2018

Works for me, what OS are you on? It would be helpful if you can write (or copy-paste) the whole traceback and some details on your machine so that we can find potential solutions like this:

Logger

INFO:matplotlib.animation:Animation.save using <class 'matplotlib.animation.FFMpegWriter'>
INFO:matplotlib.animation:MovieWriter.run: running command: ['ffmpeg', '-f', 'rawvideo', '-vcodec', 'rawvideo', '-s', '720x576', '-pix_fmt', 'rgba', '-r', '12.5', '-loglevel', 'quiet', '-i', 'pipe:', '-vcodec', 'h264', '-pix_fmt', 'yuv420p', '-y', '/tmp/tmpjfc80jm5.m4v']
INFO:matplotlib.animation:MovieWriter -- Error running proc:
b''
b''

Traceback

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-98fc35d22b0a> in <module>()
      3 topology = top.Star()
      4 
----> 5 plot_optimization(options, topology)

<ipython-input-4-ac035cf64f85> in plot_optimization(options, topology)
     33 
     34     # Enables us to view it in a Jupyter notebook
---> 35     HTML(animation.to_html5_video())
     36     HTML(animation3d.to_html5_video())

/usr/lib64/python3.6/site-packages/matplotlib/animation.py in to_html5_video(self, embed_limit)
   1351                                 bitrate=rcParams['animation.bitrate'],
   1352                                 fps=1000. / self._interval)
-> 1353                 self.save(f.name, writer=writer)
   1354 
   1355             # Now open and base64 encode

/usr/lib64/python3.6/site-packages/matplotlib/animation.py in save(self, filename, writer, fps, dpi, codec, bitrate, extra_args, metadata, extra_anim, savefig_kwargs)
   1198                         # TODO: See if turning off blit is really necessary
   1199                         anim._draw_next_frame(d, blit=False)
-> 1200                     writer.grab_frame(**savefig_kwargs)
   1201 
   1202         # Reconnect signal for first draw if necessary

/usr/lib64/python3.6/contextlib.py in __exit__(self, type, value, traceback)
     97                 value = type()
     98             try:
---> 99                 self.gen.throw(type, value, traceback)
    100             except StopIteration as exc:
    101                 # Suppress StopIteration *unless* it's the same exception that

/usr/lib64/python3.6/site-packages/matplotlib/animation.py in saving(self, fig, outfile, dpi, *args, **kwargs)
    239             yield self
    240         finally:
--> 241             self.finish()
    242 
    243 

/usr/lib64/python3.6/site-packages/matplotlib/animation.py in finish(self)
    365     def finish(self):
    366         '''Finish any processing for writing the movie.'''
--> 367         self.cleanup()
    368 
    369     def grab_frame(self, **savefig_kwargs):

/usr/lib64/python3.6/site-packages/matplotlib/animation.py in cleanup(self)
    403     def cleanup(self):
    404         '''Clean-up and collect the process used to write the movie file.'''
--> 405         out, err = self._proc.communicate()
    406         self._frame_sink().close()
    407         _log.debug('MovieWriter -- Command stdout:\n%s', out)

/usr/lib64/python3.6/subprocess.py in communicate(self, input, timeout)
    841 
    842             try:
--> 843                 stdout, stderr = self._communicate(input, endtime, timeout)
    844             finally:
    845                 self._communication_started = True

/usr/lib64/python3.6/subprocess.py in _communicate(self, input, endtime, orig_timeout)
   1503                     selector.register(self.stdin, selectors.EVENT_WRITE)
   1504                 if self.stdout:
-> 1505                     selector.register(self.stdout, selectors.EVENT_READ)
   1506                 if self.stderr:
   1507                     selector.register(self.stderr, selectors.EVENT_READ)

/usr/lib64/python3.6/selectors.py in register(self, fileobj, events, data)
    349 
    350         def register(self, fileobj, events, data=None):
--> 351             key = super().register(fileobj, events, data)
    352             poll_events = 0
    353             if events & EVENT_READ:

/usr/lib64/python3.6/selectors.py in register(self, fileobj, events, data)
    235             raise ValueError("Invalid events: {!r}".format(events))
    236 
--> 237         key = SelectorKey(fileobj, self._fileobj_lookup(fileobj), events, data)
    238 
    239         if key.fd in self._fd_to_key:

/usr/lib64/python3.6/selectors.py in _fileobj_lookup(self, fileobj)
    222         """
    223         try:
--> 224             return _fileobj_to_fd(fileobj)
    225         except ValueError:
    226             # Do an exhaustive search.

/usr/lib64/python3.6/selectors.py in _fileobj_to_fd(fileobj)
     37         except (AttributeError, TypeError, ValueError):
     38             raise ValueError("Invalid file object: "
---> 39                              "{!r}".format(fileobj)) from None
     40     if fd < 0:
     41         raise ValueError("Invalid file descriptor: {}".format(fd))

ValueError: Invalid file object: <_io.BufferedReader name=61>

@ljvmiranda921
Copy link
Owner

ljvmiranda921 commented Aug 22, 2018

@whzup do you already have ffmpeg enabled (not just installed, maybe append it into your path, etc.) or ImageMagick? One trick I use in debugging is to google the actual traceback (usually the last few lines so that it's matplotlib-specific). This should help you solve your problem:

@ljvmiranda921
Copy link
Owner

ljvmiranda921 commented Aug 22, 2018

Also check if you have this declared before calling any animators in your notebook (check visualization cell 6 example):

rc('animation', html='html5')

I also recommend you work on the development branch. himmelblau_func should already be himmelblau given #222

Also, it turns out that the HTML() method should be used outside the plot_optimization() method. So what I did was have plot_optimization() return animation and animation3d, and call HTML() on them separately (in different cells).

screenshot from 2018-08-22 09-57-39
screenshot from 2018-08-22 09-57-56

@whzup
Copy link
Collaborator Author

whzup commented Aug 22, 2018

Hmm, in the links you provided the people use CentOS I actually use OpenSUSE. I reinstalled ffmpeg and included it in the path using export PATH=$PATH:. Moving the HTML() functions out of the function didn't change anything either 😕

Here is my ffmpeg version with all the libs:

ffmpeg version 3.4.4 Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 7 (SUSE Linux)
configuration: --prefix=/usr --libdir=/usr/lib64 --shlibdir=/usr/lib64 --incdir=/usr/include/ffmpeg --extra-cflags='-fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g' --optflags='-fmessage-length=0 -grecord-gcc-switches -O2 -Wall -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables -fasynchronous-unwind-tables -fstack-clash-protection -g' --disable-htmlpages --enable-pic --disable-stripping --enable-shared --disable-static --enable-gpl --disable-openssl --enable-avresample --enable-libcdio --enable-gnutls --enable-ladspa --disable-cuda --disable-cuvid --enable-libass --enable-libbluray --enable-libcelt --enable-libcdio --enable-libdc1394 --enable-libfreetype --enable-libgsm --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libzimg --enable-libzvbi --enable-vaapi --enable-vdpau --enable-muxers --enable-demuxers --disable-encoders --disable-decoders --disable-decoder='mpeg4,h263,h264,hevc,vc1' --enable-encoder='apng,ass,ayuv,bmp,ffv1,ffvhuff,flac,gif,huffyuv,jpegls,libgsm,libmp3lame,libopenjpeg,libopus,libschroedinger,libspeex,libtheora,libtwolame,libvorbis,libvpx_vp8,libvpx_vp9,libwebp,libwebp_anim,mjpeg,mp2,mp2fixed,opus,pam,pbm,pcm_alaw,pcm_f32be,pcm_f32le,pcm_f64be,pcm_f64le,pcm_mulaw,pcm_s16be,pcm_s16be_planar,pcm_s16le,pcm_s16le_planar,pcm_s24be,pcm_s24le,pcm_s24le_planar,pcm_s32be,pcm_s32le,pcm_s32le_planar,pcm_s8,pcm_s8_planar,pcm_u16be,pcm_u16le,pcm_u24be,pcm_u24le,pcm_u32be,pcm_u32le,pcm_u8,pcx,pgm,pgmyuv,png,ppm,sgi,srt,ssa,sunrast,targa,text,tiff,v210,v308,v408,v410,vorbis,xbm,xwd,y41p,yuv4,zlib,' --enable-decoder='ac3,ansi,apng,ass,ayuv,bmp,dirac,exr,ffv1,ffvhuff,ffwavesynth,flac,gif,gsm,huffyuv,libcelt,libgsm,libopenjpeg,libopus,libschroedinger,libspeex,libvorbis,libvpx_vp8,libvpx_vp9,mjpeg,mpeg1video,mpeg2video,,mp1,mp1float,mp2,mp2float,mp3,mp3float,opus,pam,pbm,pcm_alaw,pcm_bluray,pcm_dvd,pcm_f32be,pcm_f32le,pcm_f64be,pcm_f64le,pcm_mulaw,pcm_s16be,pcm_s16be_planar,pcm_s16le,pcm_s16le_planar,pcm_s24be,pcm_s24le,pcm_s24le_planar,pcm_s32be,pcm_s32le,pcm_s32le_planar,pcm_s8,pcm_s8_planar,pcm_u16be,pcm_u16le,pcm_u24be,pcm_u24le,pcm_u32be,pcm_u32le,pcm_u8,pcx,pgm,pgmyuv,pgssub,png,ppm,rawvideo,sgi,srt,ssa,sunrast,targa,text,theora,tiff,v210,v210x,v308,v408,v410,vorbis,vp3,vp5,vp6,vp6a,vp6f,vp8,vp9,webp,xbm,xwd,y41p,yuv4,zlib,'
libavutil      55. 78.100 / 55. 78.100
libavcodec     57.107.100 / 57.107.100
libavformat    57. 83.100 / 57. 83.100
libavdevice    57. 10.100 / 57. 10.100
libavfilter     6.107.100 /  6.107.100
libavresample   3.  7.  0 /  3.  7.  0
libswscale      4.  8.100 /  4.  8.100
libswresample   2.  9.100 /  2.  9.100
libpostproc    54.  7.100 / 54.  7.100

Is maybe something missing?

@ljvmiranda921
Copy link
Owner

Have you tried the SO solution above? They're both linux so they should complement.
It says that you may be missing --enable-gpl --enable-libx264. You already have --enable-gpl. Now do you have --enable-libx264? Check the config you copy-pasted 👍

I'm clueless after that. Try some workarounds:

Then set this: rc('animation', html='html5')

@ljvmiranda921 ljvmiranda921 self-requested a review August 22, 2018 13:17
Copy link
Owner

@ljvmiranda921 ljvmiranda921 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you want, I can take this PR on. But if you have solved the matplotlib problem, then feel free 👍

@whzup
Copy link
Collaborator Author

whzup commented Aug 22, 2018

I'm reinstalling FFmpeg at the moment let me see if this works. Gonna keep you posted 👍

@whzup
Copy link
Collaborator Author

whzup commented Aug 22, 2018

It works now 👍 Thanks for the help!

@whzup
Copy link
Collaborator Author

whzup commented Aug 22, 2018

plot_contour

I found this very weird behaviour that the 4 particles on the right side don't even move for a huge part of the optimization process. Do you think this is related to the boundaries issue #150? If so we urgently need the PR from them! 😮

Also, I think the best function to see the different behaviours might be the sphere function. What do you think?

@ljvmiranda921
Copy link
Owner

ljvmiranda921 commented Aug 22, 2018

I found this very weird behaviour that the 4 particles on the right side don't even move for a huge part of the optimization process. Do you think this is related to the boundaries issue #150? If so we urgently need the PR from them! 😮

Could be, but the stopping condition is usually for high dimensional search (we only have 2 dimensions). Many reasons exist: high cognitive param, inertia settings, etc. I suggest you try different options/ settings first with what we have.

I’d follow up with them (@jolayfield and co.) at the end of this month.

Also, I think the best function to see the different behaviours might be the sphere function. What do you think?

Sphere is very easy tho, the particles might just move like in the Star topology. I suggest you try an objective function with many local optima and one or very few global optima. From there we can see how other topologies will shine.

@ljvmiranda921
Copy link
Owner

ljvmiranda921 commented Aug 23, 2018

Hi @whzup, I think it's better to work with what we have first. Won't an ackley function suffice?

@whzup
Copy link
Collaborator Author

whzup commented Aug 23, 2018

@ljvmiranda921, sure! I'll go with the holdertable, though. It has some difficulty to it and doesn't cram the whole plot like some other functions do. 👍 The issue with the non-moving particles is very serious though! In every plot I've made so far there were particles that don't move at all!!! Even with different parameters!

Finished the Star topology section
@ljvmiranda921
Copy link
Owner

ljvmiranda921 commented Aug 24, 2018

@ljvmiranda921, sure! I'll go with the holdertable

Problem with holdertable is that it's global minima is at the edges and corners, kinda hard to see when visualizing it as a contour. Your initial choice, ackley, seems fine for me though. Let's just stick with that.

screenshot from 2018-08-24 09-57-06

Code to reproduce:

def plot_optimization(options, topology):

    bounds = (np.array([-5, -5]), np.array([5, 5]))
    optimizer = ps.single.GeneralOptimizerPSO(n_particles=50,
                                              dimensions=2,
                                              options=options,
                                              topology=topology,
                                              bounds=bounds)
    
    optimizer.optimize(fx.ackley, iters=500)
    
    m = Mesher(func=fx.ackley,
               delta=0.01,
               limits=[(-5, 5), (-5, 5)],
               levels=np.arange(-20,20,1))
    
    d = Designer(limits=[(-5, 5), (-5, 5), (-10, 0)],
                 label=['x-axis', 'y-axis', 'z-axis'])
    
    animation = plot_contour(pos_history=optimizer.pos_history,
                             designer=d,
                             mesher=m,
                             mark=[0,0])
    
    pos_history_3d = m.compute_history_3d(optimizer.pos_history)
    animation3d = plot_surface(pos_history=pos_history_3d,
                               mesher=m,
                               designer=d,
                               mark=[0,0,0])
    
    return (animation, animation3d), optimizer

@ljvmiranda921
Copy link
Owner

The issue with the non-moving particles is very serious though! In every plot I've made so far there were particles that don't move at all!!! Even with different parameters!

@whzup Don't panic. Can you help me investigate that? Things we can check:

  • Check how the velocity matrix changes with respect to time. They're not moving probably because of zero-velocity. Let's first confirm if that's the case.
  • Then, we can check if velocity updates correlate to global best and personal best positions as intended by the algorithm. Try a test swarm first and see if it's actually working
  • My guesses: some particles are stuck in local optima. But still there should be atleast a change to bring them out there.

@whzup
Copy link
Collaborator Author

whzup commented Aug 24, 2018

Your initial choice, ackley, seems fine for me though. Let's just stick with that.

I found that the ackley function was too similar to the sphere function in the sense that the particles are just pulled to the center and that we might not be able to distinguish the effects of the different topologies. But it's hard to tell with over half the swarm not moving at all 😄

Can you help me investigate that?

Yes, I'll go ahead and check those 👍 !

@whzup
Copy link
Collaborator Author

whzup commented Sep 12, 2018

Gonna work on this after we got #238 .

@ljvmiranda921
Copy link
Owner

I'll close this one for now. This is just a notebook so I think we can rebranch this from the new development branch (my bad). cc: @whzup

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Documentation improvements or fixes v.1.1.0 In pipeline for next version
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants