Video abstract for "An Adaptive Homeostatic Algorithm for the Unsupervised Learning of Visual Features"

This video shows the results of unsupervised learning with different type of kezrnel normalization. This is to illustrate the results obtained in this paper on the An Adaptive Homeostatic Algorithm for the Unsupervised Learning of Visual Features which is now in press.



In [1]:
%matplotlib inline
In [2]:
%load_ext autoreload
%autoreload 2
%ls -l /tmp/cache_dir /tmp/2019-09-11*%ls -ltr /tmp/2019-09-11* %rm /tmp/cache_dir/*lock* %rm /tmp/2019-09-11*png%rm /tmp/2019-09-11_Perrinet19_None_*.png%rm /tmp/cache_dir/*
In [4]:
%%writefile /tmp/video_abstract.py
import os
import numpy as np
seed = 51
np.random.seed(seed)

from shl_scripts.shl_experiments import SHL
name = '2019-09-11_Perrinet19'

datapath = '/tmp/database'
opts = dict(datapath=datapath, verbose=True, cache_dir='/tmp/cache_dir', n_iter=2**5 + 1, seed=seed)
shl = SHL(**opts)
data = shl.get_data(matname=f'{name}_data')

homeo_methods = ['None', 'OLS', 'HEH', 'HAP']
N_step = 18

d_new, d_old = 1, 1
fibo = [d_old]
for i_step in range(N_step+1):
    fibo.append(d_new)
    d_new, d_old = d_new + d_old, d_new
print('Fibonacci=', fibo)

from shl_scripts import touch
#from shl_scripts.shl_experiments import SHL_set
for homeo_method in homeo_methods:
    print(f'=> homeo_method={homeo_method}')
    flockname = os.path.join(shl.cache_dir, f'{name}_{homeo_method}_lock')
    if not os.path.isfile(flockname):
        touch(flockname)        
        dictionary, P_cum = None, None
        opts_ = opts.copy()
        opts_.update(homeo_method=homeo_method, n_iter=1,)
        shl = SHL(**opts_)
        for i_step in range(N_step):
            print(f'==> i_iter={i_step} / n_iter={fibo[i_step+1]}')
            shl.n_iter = fibo[i_step]
            dico = shl.learn_dico(data=data, dictionary=dictionary, P_cum=P_cum, matname=f'{name}_{homeo_method}_{i_step}')
            dictionary = dico.dictionary
            P_cum = dico.P_cum
                          
        if os.path.isfile(flockname): os.remove(flockname)
                       
Overwriting /tmp/video_abstract.py
In [5]:
%run  /tmp/video_abstract.py
Extracting data..loading the data called : /tmp/cache_dir/2019-09-11_Perrinet19_data_data
Data is of shape : (65520, 441) - done in 0.15s.
Fibonacci= [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765]
=> homeo_method=None
==> i_iter=0 / n_iter=1
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_0_dico.pkl
==> i_iter=1 / n_iter=2
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_1_dico.pkl
==> i_iter=2 / n_iter=3
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_2_dico.pkl
==> i_iter=3 / n_iter=5
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_3_dico.pkl
==> i_iter=4 / n_iter=8
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_4_dico.pkl
==> i_iter=5 / n_iter=13
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_5_dico.pkl
==> i_iter=6 / n_iter=21
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_6_dico.pkl
==> i_iter=7 / n_iter=34
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_7_dico.pkl
==> i_iter=8 / n_iter=55
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_8_dico.pkl
==> i_iter=9 / n_iter=89
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_9_dico.pkl
==> i_iter=10 / n_iter=144
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_10_dico.pkl
==> i_iter=11 / n_iter=233
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_11_dico.pkl
==> i_iter=12 / n_iter=377
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_12_dico.pkl
==> i_iter=13 / n_iter=610
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_13_dico.pkl
==> i_iter=14 / n_iter=987
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_14_dico.pkl
==> i_iter=15 / n_iter=1597
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_15_dico.pkl
==> i_iter=16 / n_iter=2584
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_16_dico.pkl
==> i_iter=17 / n_iter=4181
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_17_dico.pkl
=> homeo_method=OLS
==> i_iter=0 / n_iter=1
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_0_dico.pkl
==> i_iter=1 / n_iter=2
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_1_dico.pkl
==> i_iter=2 / n_iter=3
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_2_dico.pkl
==> i_iter=3 / n_iter=5
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_3_dico.pkl
==> i_iter=4 / n_iter=8
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_4_dico.pkl
==> i_iter=5 / n_iter=13
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_5_dico.pkl
==> i_iter=6 / n_iter=21
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_6_dico.pkl
==> i_iter=7 / n_iter=34
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_7_dico.pkl
==> i_iter=8 / n_iter=55
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_8_dico.pkl
==> i_iter=9 / n_iter=89
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_9_dico.pkl
==> i_iter=10 / n_iter=144
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_10_dico.pkl
==> i_iter=11 / n_iter=233
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_11_dico.pkl
==> i_iter=12 / n_iter=377
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_12_dico.pkl
==> i_iter=13 / n_iter=610
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_13_dico.pkl
==> i_iter=14 / n_iter=987
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_14_dico.pkl
==> i_iter=15 / n_iter=1597
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_15_dico.pkl
==> i_iter=16 / n_iter=2584
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_16_dico.pkl
==> i_iter=17 / n_iter=4181
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_17_dico.pkl
=> homeo_method=HEH
==> i_iter=0 / n_iter=1
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_0_dico.pkl
==> i_iter=1 / n_iter=2
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_1_dico.pkl
==> i_iter=2 / n_iter=3
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_2_dico.pkl
==> i_iter=3 / n_iter=5
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_3_dico.pkl
==> i_iter=4 / n_iter=8
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_4_dico.pkl
==> i_iter=5 / n_iter=13
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_5_dico.pkl
==> i_iter=6 / n_iter=21
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_6_dico.pkl
==> i_iter=7 / n_iter=34
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_7_dico.pkl
==> i_iter=8 / n_iter=55
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_8_dico.pkl
==> i_iter=9 / n_iter=89
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_9_dico.pkl
==> i_iter=10 / n_iter=144
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_10_dico.pkl
==> i_iter=11 / n_iter=233
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_11_dico.pkl
==> i_iter=12 / n_iter=377
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_12_dico.pkl
==> i_iter=13 / n_iter=610
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_13_dico.pkl
==> i_iter=14 / n_iter=987
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_14_dico.pkl
==> i_iter=15 / n_iter=1597
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_15_dico.pkl
==> i_iter=16 / n_iter=2584
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_16_dico.pkl
==> i_iter=17 / n_iter=4181
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_17_dico.pkl
=> homeo_method=HAP
==> i_iter=0 / n_iter=1
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_0_dico.pkl
==> i_iter=1 / n_iter=2
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_1_dico.pkl
==> i_iter=2 / n_iter=3
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_2_dico.pkl
==> i_iter=3 / n_iter=5
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_3_dico.pkl
==> i_iter=4 / n_iter=8
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_4_dico.pkl
==> i_iter=5 / n_iter=13
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_5_dico.pkl
==> i_iter=6 / n_iter=21
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_6_dico.pkl
==> i_iter=7 / n_iter=34
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_7_dico.pkl
==> i_iter=8 / n_iter=55
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_8_dico.pkl
==> i_iter=9 / n_iter=89
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_9_dico.pkl
==> i_iter=10 / n_iter=144
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_10_dico.pkl
==> i_iter=11 / n_iter=233
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_11_dico.pkl
==> i_iter=12 / n_iter=377
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_12_dico.pkl
==> i_iter=13 / n_iter=610
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_13_dico.pkl
==> i_iter=14 / n_iter=987
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_14_dico.pkl
==> i_iter=15 / n_iter=1597
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_15_dico.pkl
==> i_iter=16 / n_iter=2584
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_16_dico.pkl
==> i_iter=17 / n_iter=4181
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_17_dico.pkl
In [6]:
phi = (np.sqrt(5) + 1. ) /2
fig_width = 15
dpi_export = 300
#dpi_export = 0
colors = ['black', 'orange', 'blue', 'red']

import matplotlib.pyplot as plt
def plot_dico(dico, color, dim_graph = (8, 8)):
    subplotpars = dict(left=0.05, right=.95, bottom=0.05, top=.95, wspace=0.05, hspace=0.05,)
    fig, axs = plt.subplots(1, 2, figsize=(fig_width, fig_width/phi), gridspec_kw=subplotpars)
    for ax in axs:
        ax.axis(c='b', lw=2, axisbg='w')
        ax.set_facecolor('w')
        
    from shl_scripts import show_dico
    fig, axs[0] = show_dico(shl, dico, data=data, dim_graph=dim_graph, fig=fig, ax=axs[0], order=False, seed=51)
    
    if False:
        from shl_scripts import plot_P_cum
        fig, axs[1] = plot_P_cum(dico.P_cum, ymin=0.6, ymax=1.001, 
                             title=None, suptitle=None, ylabel='non-linear functions', 
                             verbose=False, n_yticks=21, alpha=.02, c=color, fig=fig, ax=axs[1])
        axs[1].plot([0], [0], lw=1, color=color, label=homeo_method, alpha=.6)
    
    else:
        from shl_scripts import plot_proba_histogram
        coding = shl.code(data, dico)
        fig, axs[1] = plot_proba_histogram(coding, fig=fig, ax=axs[1], lw=2., alpha=1., color='gray')
        axs[1].plot([0], [0], lw=1, color=color, label=homeo_method, alpha=.6)
    # ax.set_ylabel(homeo_method)

    #ax.text(-8, 7*dim_graph[0], homeo_method, fontsize=12, color='k', rotation=90)#, backgroundcolor='white'
    #axs[1].legend(loc='lower right')
    # pos : [left, bottom, width, height] =    The new position of the in `.Figure` coordinates.
    axs[0].set_position([0.0, 0.0, .618, 1.0])
    axs[1].set_position([0.618+0.05, 0.0+0.05, .382-0.07, 1.0-0.052])

    return fig, axs

for homeo_method, color in zip(homeo_methods, colors):
    print(f'=> homeo_method={homeo_method}')
    flockname = os.path.join(shl.cache_dir, f'{name}_{homeo_method}_lock')
    if not os.path.isfile(flockname):
        for i_step in range(N_step):
            dico = shl.learn_dico(data=data, matname=f'{name}_{homeo_method}_{i_step}', list_figures=[])

            print(f'==> i_iter={i_step} / n_iter={fibo[i_step+1]}')
            figname = f'/tmp/{name}_{homeo_method}_{i_step}.png'
            if not os.path.isfile(figname):
                fig, axs = plot_dico(dico, color)
                axs[1].set_xlim(0., 1.9)
                axs[1].text(0.1, 32, f'homeo_method={homeo_method}', fontsize=24, color=color, backgroundcolor='white')
                axs[1].text(0.1, 92, f'n_iter={fibo[i_step+1]:4d}', fontsize=24, color='k', backgroundcolor='white')
                plt.show()
                if dpi_export > 0 : fig.savefig(figname, dpi=dpi_export, bbox_inches='tight')
          
=> homeo_method=None
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_0_dico.pkl
==> i_iter=0 / n_iter=1
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_1_dico.pkl
==> i_iter=1 / n_iter=2
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_2_dico.pkl
==> i_iter=2 / n_iter=3
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_3_dico.pkl
==> i_iter=3 / n_iter=5
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_4_dico.pkl
==> i_iter=4 / n_iter=8
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_5_dico.pkl
==> i_iter=5 / n_iter=13
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_6_dico.pkl
==> i_iter=6 / n_iter=21
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_7_dico.pkl
==> i_iter=7 / n_iter=34
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_8_dico.pkl
==> i_iter=8 / n_iter=55
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_9_dico.pkl
==> i_iter=9 / n_iter=89
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_10_dico.pkl
==> i_iter=10 / n_iter=144
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_11_dico.pkl
==> i_iter=11 / n_iter=233
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_12_dico.pkl
==> i_iter=12 / n_iter=377
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_13_dico.pkl
==> i_iter=13 / n_iter=610
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_14_dico.pkl
==> i_iter=14 / n_iter=987
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_15_dico.pkl
==> i_iter=15 / n_iter=1597
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_16_dico.pkl
==> i_iter=16 / n_iter=2584
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_None_17_dico.pkl
==> i_iter=17 / n_iter=4181
Coding data with algorithm  mp 
No description has been provided for this image
=> homeo_method=OLS
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_0_dico.pkl
==> i_iter=0 / n_iter=1
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_1_dico.pkl
==> i_iter=1 / n_iter=2
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_2_dico.pkl
==> i_iter=2 / n_iter=3
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_3_dico.pkl
==> i_iter=3 / n_iter=5
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_4_dico.pkl
==> i_iter=4 / n_iter=8
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_5_dico.pkl
==> i_iter=5 / n_iter=13
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_6_dico.pkl
==> i_iter=6 / n_iter=21
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_7_dico.pkl
==> i_iter=7 / n_iter=34
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_8_dico.pkl
==> i_iter=8 / n_iter=55
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_9_dico.pkl
==> i_iter=9 / n_iter=89
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_10_dico.pkl
==> i_iter=10 / n_iter=144
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_11_dico.pkl
==> i_iter=11 / n_iter=233
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_12_dico.pkl
==> i_iter=12 / n_iter=377
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_13_dico.pkl
==> i_iter=13 / n_iter=610
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_14_dico.pkl
==> i_iter=14 / n_iter=987
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_15_dico.pkl
==> i_iter=15 / n_iter=1597
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_16_dico.pkl
==> i_iter=16 / n_iter=2584
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_OLS_17_dico.pkl
==> i_iter=17 / n_iter=4181
Coding data with algorithm  mp 
No description has been provided for this image
=> homeo_method=HEH
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_0_dico.pkl
==> i_iter=0 / n_iter=1
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_1_dico.pkl
==> i_iter=1 / n_iter=2
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_2_dico.pkl
==> i_iter=2 / n_iter=3
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_3_dico.pkl
==> i_iter=3 / n_iter=5
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_4_dico.pkl
==> i_iter=4 / n_iter=8
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_5_dico.pkl
==> i_iter=5 / n_iter=13
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_6_dico.pkl
==> i_iter=6 / n_iter=21
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_7_dico.pkl
==> i_iter=7 / n_iter=34
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_8_dico.pkl
==> i_iter=8 / n_iter=55
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_9_dico.pkl
==> i_iter=9 / n_iter=89
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_10_dico.pkl
==> i_iter=10 / n_iter=144
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_11_dico.pkl
==> i_iter=11 / n_iter=233
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_12_dico.pkl
==> i_iter=12 / n_iter=377
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_13_dico.pkl
==> i_iter=13 / n_iter=610
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_14_dico.pkl
==> i_iter=14 / n_iter=987
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_15_dico.pkl
==> i_iter=15 / n_iter=1597
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_16_dico.pkl
==> i_iter=16 / n_iter=2584
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HEH_17_dico.pkl
==> i_iter=17 / n_iter=4181
Coding data with algorithm  mp 
No description has been provided for this image
=> homeo_method=HAP
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_0_dico.pkl
==> i_iter=0 / n_iter=1
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_1_dico.pkl
==> i_iter=1 / n_iter=2
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_2_dico.pkl
==> i_iter=2 / n_iter=3
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_3_dico.pkl
==> i_iter=3 / n_iter=5
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_4_dico.pkl
==> i_iter=4 / n_iter=8
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_5_dico.pkl
==> i_iter=5 / n_iter=13
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_6_dico.pkl
==> i_iter=6 / n_iter=21
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_7_dico.pkl
==> i_iter=7 / n_iter=34
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_8_dico.pkl
==> i_iter=8 / n_iter=55
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_9_dico.pkl
==> i_iter=9 / n_iter=89
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_10_dico.pkl
==> i_iter=10 / n_iter=144
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_11_dico.pkl
==> i_iter=11 / n_iter=233
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_12_dico.pkl
==> i_iter=12 / n_iter=377
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_13_dico.pkl
==> i_iter=13 / n_iter=610
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_14_dico.pkl
==> i_iter=14 / n_iter=987
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_15_dico.pkl
==> i_iter=15 / n_iter=1597
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_16_dico.pkl
==> i_iter=16 / n_iter=2584
Coding data with algorithm  mp 
No description has been provided for this image
loading the dico called : /tmp/cache_dir/2019-09-11_Perrinet19_HAP_17_dico.pkl
==> i_iter=17 / n_iter=4181
Coding data with algorithm  mp 
No description has been provided for this image

Creating the movie using the (excellent) MoviePy library:

In [12]:
from moviepy.editor import VideoFileClip, ImageClip, TextClip, CompositeVideoClip


H = 500
W = 800
SIZE = (W, H)


# a list of sub clips that will be compsited at the end
clip = []
t = 0 
texts = ["An Adaptive Homeostatic Algorithm\n for the Unsupervised Learning\n of Visual Features",
         "as published Sep 2019\n in the journal Vision"
        ]
colors_intro = ['orange', 'white']

txt_opts = dict(fontsize=50, font="Amiri-Bold", stroke_color='gray', stroke_width=.5, size=(W,H))
duration = 2
for text, color in zip(texts, colors_intro):
    txt_clip = TextClip(text, color=color, **txt_opts)
    txt_clip = txt_clip.set_start(t).set_pos('center').set_duration(duration)#.resize(height=H, width=W)
    
    t += duration
    clip.append(txt_clip)
    

sub_opts = dict(fontsize=32, font="Amiri-Bold", stroke_color='gray',  method='caption', align='South', 
                stroke_width=.5, size=(W,H))
for subtitle in ["This paper shows the role of... ", "... homeostasis mechanisms ...", "... in unsupervised learning algorithms."]:
    sub_duration = 1.5
    sub_clip = TextClip(subtitle, color='yellow', **sub_opts)
    sub_clip = sub_clip.set_start(t).set_duration(sub_duration) #set_pos('bottom').
    t += sub_duration
    clip.append(sub_clip)    
    
texts = ["Without homeostasis", "Olshausen (1997)", "Histogram Equalization", "Activation Probability"]
subtitles = {}
subtitles['None'] = [
    'I show here the result of a simple algorithm of ...',
    '... unsupervised learning based on sparse coding.',
    'On the left, we show 64 randomly picked kernels...',
    '... from the 661 receptive fields of the neurons and ...',
    '... on the right the histogram of activation probability.',
    '... Looking at results as learning iterates, ...',
    '... edge-like filters appear after some iterations...',
    '... but the histogram shows a desequilibrium in the ...',
    '... activation probability, even though  ...',
    '... the norm of the kernels are normalized.',
]
subtitles['OLS'] = [
    'The original algorithm developped ...',
    '... by Olshausen and Field (1997) included a more  ...',
    '... elaborated adaptation of this norm based on  ...',
    "... coefficients' energy, yielding a better balance...",
    '... and a better looking set of filters.',
    'Still, this causes an under-optimisation of the ... ',
    '... representation as some neurons are a priori ...',
    '... more likely to be selected than others.',
    ' A proper homeostasis is necessary.'
]
subtitles['HEH'] = [
    'Such an objective can be simply optimized...',
    '... by introducing an adaptive non-linearity in our ...',
    '... sparse coding algorithm. This non-linearity  ...',
    '... is based on well-known histogram equalization ...',
    '... to make sure that all neurons are always picked up.',
    '...  with a priori the same probability ...',
    '... We called it Histogram Equalization Homeostasis ...',
    '... and it effectively works very well, as well ...',
    '... qualitatively (left) ...', '... than quantitatively (right).',
]
subtitles['HAP'] = [
    'A problem of Histogram Equalization Homeostasis ...',
    '... is that it is computationally more expensive  ...',
    '... and less plausible to be implemented in real ...',
    '...  biological neurons. We thus explored another ...',
    '... algorithm simply based on  activation probability.',
    'This Homeostasis on Activation Probability  ... ',
    '... performed qualitatively as well as HEH ...',
    '... and also quantitatively similarly ...',
    'Yet it comes at a very low cost and it is ...',
    '... compatible with biomimetic algorithms.',
]

# http://zulko.github.io/moviepy/ref/VideoClip/VideoClip.html?highlight=compositevideoclip#textclip
txt_opts = dict(fontsize=65, font="Amiri-Bold", stroke_color='gray', stroke_width=2.5, size=(W,H), bg_color='white')
sub_opts = dict(fontsize=32, font="Amiri-Bold", stroke_color='gray',  method='caption', align='South', 
                stroke_width=.5, size=(W,H))
for homeo_method, text, color in zip(homeo_methods, texts, colors):
    print(f'=> homeo_method={homeo_method}')
    duration = 1
    txt_clip = TextClip(text, color=color, **txt_opts)
    txt_clip = txt_clip.set_start(t).set_pos('center').set_duration(duration)
    t += duration
    clip.append(txt_clip)

    for i_step in range(N_step):
        duration = 1
        im_clip = ImageClip(f'/tmp/{name}_{homeo_method}_{i_step}.png')
        im_clip = im_clip.set_start(t).set_duration(duration).set_pos('top').resize(height=int(H*.925), width=int(W*.925))
        t += duration
        clip.append(im_clip)

    # please be kind, rewind
    t_sub = t - duration * N_step
    sub_duration = duration * N_step / len(subtitles[homeo_method])
    for subtitle in subtitles[homeo_method]:
        sub_clip = TextClip(subtitle, color='yellow', **sub_opts)
        sub_clip = sub_clip.set_start(t_sub).set_duration(sub_duration) #set_pos('bottom').
        t_sub += sub_duration
        clip.append(sub_clip)
        
texts = ["... for more info,\n and open-sourced code\n visit ",
    "https://laurentperrinet.github.io/publication/perrinet-19-hulk"]
colors_outro = ['orange', 'white']

txt_opts = dict(fontsize=30, font="Amiri-Bold", stroke_color='gray', stroke_width=.5, size=(W,H))
duration = 3
for text, color in zip(texts, colors_outro):
    txt_clip = TextClip(text, color=color, **txt_opts)
    txt_clip = txt_clip.set_start(t).set_pos('center').set_duration(duration)
    t += duration
    clip.append(txt_clip)
      
#sub_clip = TextClip("Thanks for your attention!", color='yellow', **sub_opts)
#sub_clip = sub_clip.set_start(t-.5).set_duration(.5) #set_pos('bottom').
#clip.append(sub_clip)
    
# Overlay the text clip on the first video clip
video = CompositeVideoClip(clip)
vext = 'mp4'
# Write the result to a file (many options available !)
video.write_videofile(f'../files/{name}.{vext}', fps=5)
=> homeo_method=None
=> homeo_method=OLS
=> homeo_method=HEH
=> homeo_method=HAP
t:   1%|          | 5/453 [00:00<00:10, 42.60it/s, now=None]
Moviepy - Building video ../files/2019-09-11_Perrinet19.mp4.
Moviepy - Writing video ../files/2019-09-11_Perrinet19.mp4

                                                              
Moviepy - Done !
Moviepy - video ready ../files/2019-09-11_Perrinet19.mp4
!open ../files/2019-09-11_Perrinet19.mp4

some book keeping for the notebook

In [9]:
%load_ext version_information
%version_information numpy, scipy, matplotlib, MotionClouds
Out[9]:
Software Version
Python 3.7.4 64bit [Clang 10.0.1 (clang-1001.0.46.4)]
IPython 7.8.0
OS Darwin 18.7.0 x86_64 i386 64bit
numpy 1.17.2
scipy 1.3.1
matplotlib 3.1.1
MotionClouds 20180606
Mon Sep 16 10:05:56 2019 CEST