20160719

Wilson-Cowan neural fields in WebGL

Update: Dropbox no longer serves live pages from their public folders, so hosting has moved to Github. Basic WebGL example have moved to the "webgpgpu" repository, including the psychedelic example pictured to the left. Additional neural field models are hosted at the "neuralfield" repository

WebGL offers a simple way to write portable general-purpose GPU (GPGPU) code with visualization. The Github repository WebGPGPU walks through a series of examples to bring up a port of Wilson-Cowan neural field equations in WebGL.

The Wilson-Cowan equations are a mean-field approximation of neural activity under the assumption that spiking is asynchronous, and that observations are averaged over a large number of uncorrelated neurons. Wilson-Cowan neural fields have been used to describe visual hallucinations, flicker phosphines, and many other wave phenomena in the brain.


The Wilson-Cowan simulation demo is rudimentary at the moment, but contains a couple presets and rich and diverse dynamics are possibly by varying parameters. For entertainment, there is also an example of a full-screen pattern forming system mapped to (approximate) retinal coordinates using the log-polar transform.

Other cool WebGL implementations pattern-forming systems include the Gray-Scott reaction diffusion equations by pnmeila and Felix Woitzel's reaction diffusion and fluid dynamics simulations. Robin Houston's reaction diffusion implementation is also a good reference example for learning WebGL coding, and Robter Muth's smoothlife implementation is mesmerizing. The hope is that the examples in the WebGPGPU project provide a walk-through for how to build similar simulations in WebGL, something that is not immediately obvious if following existing WebGL tutorials.

Technical notes


I've avoided using extensions like floating point textures that aren't universally supported. Hopefully the examples in WebGPGPU will run on most systems, but compatibility issues likely remain.

Most of the examples store floating point values in 8-bit integers. This works for the firing rate version of the Wilson-Cowan equations because the firing rate is bounded between 0 and 1, so fixed precision is adequate. There are some caveats here. For example, how floating point operations are implemented, and how floats are rounded when being stored in 8-bit values, are implementation dependent. These simulations a quite sensitive to parameters and rounding errors, so different implementations can lead to different emergent dynamics. A partial workaround is to manually control how floats are quantized into 8-bit values. Floats can also be stored in 16 or 32 bit fixed-point precision, at the cost of performance. My understanding is that the default precision for fast floating point operations on the GPU is fairly low, such that 16 bits can capture all of the available precision for the [0,1] range.

The quantization of state variables can lead to numerical errors if the integration step size is too small relative to the timescales of the system. In short, if states are changing too slowly, their increments becomes smaller than 1/256, and numerical accuracy degrades because state changes are rounded-out. Moving to 16-bit precision lessens this issue, but at a cost of an approximately 2-fold slowdown, and so is not implemented except in one example.

Working with the WebGL library feels quite clumsy, because in essence the API exposes the GPU as a state machine. WebGPGPU includes some libraries that hide a lot of the boilerplate and expose a more functional interface for GPU shaders (kernels). For simulations on a grid, there is additional boilerplate to gain access to single pixes. One must tile the viewport with polygons, provide a default fragment shader, and set the viewport and canvas sizes to match the on-screen size. WebGPGPU hides this difficulty, but also walks through this process in the early examples to make it clear what is really happening.

Passing parameters to shaders involves a fair amount of overhead in Javascript, which becomes prohibitive for shaders with a large number of parameters. However, compiling shaders has relatively little Javascript overhead. In practice it is faster to include scalar parameters as #defines rather than pass them as uniforms. WebGPGPU contains some routines to phrase shader compilation as a sort of 'partial evaluation'.

This is a work in progress.

20160708

Numerically stable Viterbi algorithm in Python for hidden markov model state inference

The Python demonstration of the Viterbi algorithm on Wikipedia is numerically unstable for moderate to large problem sizes. This implementation is phrased in terms of log probabilities, and so has better numerical properties. Please reuse, creative commons.

def hmm_viterbi(Y,logP,logA,logB):
    '''
    See https://en.wikipedia.org/wiki/Viterbi_algorithm

    Parameters
    ----------
    Y : 1D array
        Observations (integer states)
    logP : array shape = (nStates ,)
        1D array of priors for initial state
        given in log probability
    logA : array (nStates,nStates)
        State transition matrix given in log probability
    logB : ndarray K x N
        conditional probability matrix
        log probabilty of each observation given each state
    '''
    K = len(logP)         # Number of states
    T = len(Y)            # Number of observations
    N = np.shape(logB)[1] # Number of states
    Y = np.int32(Y)

    assert np.shape(logA)==(K,K)
    assert np.shape(logB)==(K,N)

    # The initial guess for the first state is initialized as the
    # probability of observing the first observation given said 
    # state, multiplied by the prior for that state.
    logT1 = np.zeros((K,T),'float') # Store probability of most likely path
    logT1[:,0] = logP + logB[:,Y[0]]

    # Store estimated most likely path
    T2 = np.zeros((K,T),'float')

    # iterate over all observations from left to right
    for i in range(1,T):
        # iterate over states 1..K (or 0..K-1 with zero-indexing)
        for s in range(K):
            # The likelihood of a new state is the likelihood of 
            # transitioning from either of the previous states.
            # We incorporate a multiplication by the prior here
            log_filtered_likelihood = logT1[:,i-1] + logA[:,s] + logB[s,Y[i]]
            best = np.argmax(log_filtered_likelihood)
            logT1[s,i] = log_filtered_likelihood[best]
            # We save which state was the most likely
            T2[s,i] = best

    # At the end, choose the most likely state, then
    # Iterate backwards over the data and fill in the state estimate
    X     = np.zeros((T,) ,'int'  ) # Store our inferred hidden states
    X[-1] = np.argmax(logT1[:,-1])
    for i in range(1,T)[::-1]:
        X[i-1] = T2[X[i],i]
    return X

20160509

More colors for Matplotlib

 
The default Matplotlib color scheme is not good. While searching for something better for my thesis, I stumbled upon Bridget Riley's painting "Gather" in the RISD museum. Is uses five colors: white, black, ochre, blue, turquoise, and a rust-colored red. But, from a distance they combine to create something far more vibrant. The blue and the turquoise hues are similar, so perhaps not the best to combine in a plot, but the others form an attractive and distinct pallet:

White #f1f0e9
Black #44525c
Rust #eb7a59
Ochre #eea300
Azure #5aa0df
Turquoise #00bac9

Surprisingly, when I ran this through a color-blindness simulator , some colors become even more distinct, so it is fairly color-blind friendly. I added colors to expand the pallet, to handle gradients and plots with extra lines.

Yellow #efcd2b
Moss #77ae64
Mauve #b56ab6
Magenta #cc79a7
Violet #8d5ccd
Indigo #606ec3
Viridian #11be8d
Chartreuse #b59f1a

These are less distinct, and not all combinations are color-blind friendly. Here's a bit of Python to define and tests these colors:

from pylab import *
from matplotlib import patches

WHITE = mpl.colors.to_rgb('#f1f0e9') RUST = mpl.colors.to_rgb('#eb7a59') OCHRE = mpl.colors.to_rgb('#eea300') AZURE = mpl.colors.to_rgb('#5aa0df') TURQUOISE = mpl.colors.to_rgb('#00bac9') BLACK = mpl.colors.to_rgb('#44525c') YELLOW = mpl.colors.to_rgb('#efcd2b') INDIGO = mpl.colors.to_rgb('#606ec3') VIOLET = mpl.colors.to_rgb('#8d5ccd') MAUVE = mpl.colors.to_rgb('#b56ab6') MAGENTA = mpl.colors.to_rgb('#cc79a7') CHARTREUSE = mpl.colors.to_rgb('#b59f1a') MOSS = mpl.colors.to_rgb('#77ae64') VIRIDIAN = mpl.colors.to_rgb('#11be8d')

GATHER = [WHITE,RUST,OCHRE,AZURE,TURQUOISE,BLACK] COLORS = [BLACK,WHITE,YELLOW,OCHRE,CHARTREUSE,MOSS,VIRIDIAN,TURQUOISE,AZURE,INDIGO,VIOLET,MAUVE,MAGENTA,RUST] CYCLE = [BLACK,RUST,AZURE,OCHRE,TURQUOISE,MAUVE,YELLOW,INDIGO] mpl.rcParams['axes.prop_cycle'] = mpl.cycler(color=CYCLE)

def test_panel(COLORS): ax = gca() NCOLORS = len(COLORS) axis('off') xlim(0,NCOLORS) ylim(NCOLORS,0) for j in range(NCOLORS): for i in range(NCOLORS): ax.add_patch(patches.Rectangle((i,j),1,1,linewidth=1, edgecolor='none',facecolor=COLORS[i])) ax.add_patch(patches.Rectangle((i+.25,j+.25),.5,.5,linewidth=1, edgecolor='none',facecolor=COLORS[j])) axis('equal')

figure(figsize=(6,3),dpi=200) subplots_adjust(0,0,1,1,0.1,0) subplot(111) test_panel(COLORS) savefig('colorblind_test_panel.png',bbox_inches='tight',pad_inches=0) </pre></div>

Two squences form decent color maps. They aren't perceptually uniform, but pass the color blindness simulator tests. Adding violet, mauve, and moss, to the original Gather pallet creates a hue wheel. This one flunks color-blindness test (see Crameri et al. ). Here they are in python:

riley2 = matplotlib.colors.LinearSegmentedColormap.from_list('riley2',
    [INDIGO,VIOLET,MAUVE,MAGENTA,RUST,OCHRE])

riley3 = matplotlib.colors.LinearSegmentedColormap.from_list('riley3', [OCHRE,CHARTREUSE,MOSS,VIRIDIAN,TURQUOISE,AZURE])

# Smoothed out mauve, violet, rust, ochre, moss, turquoise, azure, in a loop hues = ['#8c62cc', '#9560c8', '#9e62c3', '#a765be', '#b068b6', '#bb6caa', '#c66f98', '#d27384', '#dd7670', '#e67c5c', '#ea8348', '#ec8b34', '#ec9421', '#e99c13', '#dea212', '#c9a620', '#b0a934', '#96ab4a', '#7cae60', '#62b076', '#48b38c', '#2eb5a2', '#1ab7b6', '#12b6c5', '#1cb2ce', '#2dadd4', '#41a7d8', '#529fdb', '#6194db', '#6d86d8', '#7977d4', '#836ad0'] riley = matplotlib.colors.LinearSegmentedColormap.from_list('riley',hues)

# Make new maps behave like native Matplotlib maps plt.register_cmap(name='riley2',cmap=riley2) plt.register_cmap(name='riley3',cmap=riley3) plt.register_cmap(name='riley' ,cmap=riley )

# Show as figure figure(figsize=(5,1),dpi=300) subplot(311) imshow([linspace(0,1,256)],cmap='riley2',aspect='auto') axis('off'); tight_layout() subplot(312) imshow([linspace(0,1,256)],cmap='riley3',aspect='auto') axis('off'); tight_layout() subplot(313) imshow([linspace(0,1,256)],cmap='riley',aspect='auto') axis('off'); tight_layout() subplots_adjust(hspace=0.3) savefig('moremaps.png') </pre></div>

20160410

The rent-seeking treadmill

A common cause of socioeconomic inequality is rent-seeking. Optimistically, we might expect that rent seeking can be curtailed through social activism. This works if the progress of activism matches or outpaces the rate of increase in rent-seeking behavior. Apart from the usual tactics to stymie social activism, companies escape this activism by superficially "innovating" in ways that allow them to escape public regulation. This strategy is reminiscent of planned obsolescence.

 

The rent-seeking treadmill

Four friends and I were discussing "rent seeking", wherein entities monopolize critical resources and charge "rent" far in excess of the upkeep costs. One friend commented that a general form of this is simply "Life will afford some individuals lucrative opportunities". This is true, no doubt, and I wish to be clear: I do not intend to deprive individuals of the fruits of their labor, nor do I advocate for confiscating wealth gained by good luck. I do however, wish to prevent corporations, governments, and individuals from extracting wealth from others simply because they have a power advantage.

There are numerous forms of rent seeking that should be familiar, but I suppose the most familiar lies in the origin of the term itself: rent. People need jobs to survive. Therefore, where people live is often limited by what job they can get. Where housing demand is high, landlords may charge exorbitant rents for even unsafe housing, reaping profits far in excess of their upkeep costs. Renters and homeowners can conspire to limit new, high-density development that might bring rent down. This is generally viewed as a bad thing, as the renters have no choice in the matter, and the landlords are able to extract large sums of money from a vulnerable population without adding any real value.

Rent-seeking emerges whenever there is a power imbalance in society. Socialized services may fall to corruption, diverting public resources into private accounts. Corporations may form global or local monopolies, and thus escape the market pressures that normally keep costs "fair". Even unions may abuse a strong bargaining position and hamstring an industry or public service by acting as a labor monopoly. The important thing in these examples is that socialized governments, corporations, and unions are not evil, but they can all act antisocially if they acquire a disproportionate amount of power, and wield this power without regard for the common good. However, at present most rent-seeking in society is perpetuated by corporations and landlords, and these are the actors I have in mind.

A more insidious form of rent-seeking occurs at the grey boundary of "essential" services. For now, let's define an essential service as a service the lack of which creates a serious barriers to economic mobility (leaving the meaning of the term "serious" is open to debate). Most agree that clean water, electricity, food, housing, and education are essential services and human rights. Then there are the services that are essential in practice, but not considered human rights. It is hotly debated whether people have a right to transportation, internet access, cell phones, competent legal council, health care, affordable prescription drugs, higher education, and internet access. Nevertheless, most people reading this communication would agree that denial of any of the above would present a barrier to economic mobility and lead to reduced quality of life. Such services are de-facto essential. 

For example, having a job is mandatory, so then is having a permanent address and a bank account (jobs typically require both). Most people must travel to work, and therefore transit is also essential. Cellular phones or even smartphones have become the primary way to access services like employment, bank accounts, public transit, and public support infrastructure. I cannot log in to my bank website, or log in to my university account, without using a phone as a second factor. In practice, phone (and increasingly: smartphone) services are not optional; yet they are managed by de-facto monopolies in many places. For example, as of 2016, debit and credit cards cannot be used as a means of payment for many stations in the Massachusetts transportation network—but payment by app is supported. I have seen many distressed foreign travelers pondering anxiously in their native language just how the heck they are supposed to pay the train fair. Wouldn't life be so much easier if you just bought a smartphone!

Now, perhaps it is simple. As my friend said, perhaps "the best thing we can do is identify instances of rent seeking as they emerge and move against them". At first glance, this looks like a solution. Sure, there will be some latency between when a new service becomes de-facto essential, and when it has been tamed for social good, but we will progress. I am not so certain.

There are some areas well outside what we would consider "essential" or even "marginally essential", that will always be vulnerable to exploitation. These sectors seem at first glance to be luxury goods, but in practice have a large and guaranteed captive market. That enables practices resembling rent-seeking without overt negative moral implications. There are four instances which I address below: monopolization via standards, DRM and DRM-like lock out of competition, monopolization of communication, and monopolization of culture. 

Monopolization via standards

Instances where a private entity can establish a standard, and then de-facto monopolize e.g. a subset of business or social services because individuals must interoperate. 

For example, many government and private companies require that documents be sent in Microsoft Word, the file format of which is so arcane that no one has been able to fully support it—not even Microsoft itself. At work we use Dropbox to communicate, forcing others onto the same platform whether they want to or not. Various subsets of my social network use either Venmo or Square to handle financial transactions, forcing one network or the other on their peers. Apple computer changes its cables frequently enough that Apple itself enjoys a monopoly on the production of compatible peripherals. And even in the case that suitable peripherals are eventually produced by a third party, the fact that such peripherals do not interoperate with other industry standards force people to maintain two sets of equipment. Standardized testing and textbook services are another example, being a gatekeeper to higher education, which has itself become essential in today's economy.

DRM and DRM-like lock out of competition

Then there is the classic give-away-the-razor-and-overcharge-on-the-blades revenue model that printer manufactures love so much. In addition to deliberately eschewing standards in order to prevent third parties from repairing or producing accessories for a product, companies can actively invest in anti-features that create unnatural incompatibilities. Digital Rights Management (DRM) features on camera batteries and coffee pods come to mind. Locking out consumers from the error codes needed to remain their cars is another example. Note that the uses of DRM here are very different for DRM used to protect cultural output like music and video. In this case, DRM is being used to stymie competition and enable over-charging. These business models are abusive and antisocial, but are typically employed on "luxury" goods and so perhaps relative benign.

Monopolization of communication
 
After basic needs like air, water, etc, it is commonly accepted that humans need to communicate with each-other to survive. A strong social network is vital for our species. This can be exploited. 

Communication has shifted from in-person and post, to phones, to email, to facebook messages, to snapchats and god knows what else by the time you read this. If a social network wishes to mutually communicate, it is beneficial to use a common medium. We long ago recognized that a postal service was essential to society. Eventually, we also recognize that the telephone networks were essential, and enacted the common carrier laws. 

Today, we are fighting over whether the internet has become similarly essential. Private entities should take note, as developing a new mode of communication that becomes culturally accepted all but guarantees several lucrative decades of rent extraction, or more if you can bribe the right congress-folk.

While we fight the large telecom monopolies over net neutrality, the cultural real-estate of the Old Internet is being cannibalized by the less regulated, and more expensive, mobile computing platforms of tablets and smartphones. By the time we establish the Internet as a common carrier, smartphones will have become essential not just for social communication but for all other aspects of life. 

This is no accident. The telecoms understand this business model well, and diverted the money taxpayers gave them to upgrade internet infrastructure into their mobile networks for good reason. Once a platform becomes sufficiently regulated that antisocial behavior is prevented, telecoms move on to another, first promoting it as a luxury, then gradually making it a necessity. This is, in effect, a rent-seeking treadmill, and it will remain endlessly profitable.

Monopolization of culture

Similar to the monopoly treadmill of communication platforms, it is possible to monopolize culture. Culture defines who we are. It bonds us together, makes us human. While communications platforms provide the infrastructure for social networking, culture defines the content carried on such platforms, and both are needed for a healthy society. We outlined how a large corporation might extract rent from communications infrastructure, but what about the content of that infrastructure? 

It would be ridiculous to argue that music and video are essential. Nevertheless, many people will feel social ostracization if they cannot communicate or relate to shared cultural experiences of those around them. Thus, if you can convince a large group to use your product, be it arts, entertainment, or fashion, you force members of the out group to also buy into said product. 

By manipulating culture so that what is "in" changes constantly, corporations can ensure themselves an endless stream of profit. If one believes fashion and entertainment to be the be-all and end-all of human existence, this may not be a bad thing. I would be hard-pressed to say that anyone was ever deprived for not having seen the latest movie, heard the latest record, or carrying the latest handbag. Thus, cultural capture is not so much an antisocial barrier to economic mobility, as it is a tried-and-true way for those with money to continue to make money by taking advantage of human nature.

This is not a radical proposition. For example, it is long-recognized that the revenue models of many clothing manufacturers depend on fast-fashion. This culture is promoted through advertising, and it is one of the things killing the planet.

Planned obsolesce

The latter two concepts: communications monopolies and cultural capture, are conceptually related to planned obsolesce. Planned obsolesce typically refers to companies that make products built to break, or computer manufacturers who render new models incompatible with older software and peripherals. Likewise,
if a communications platform or cultural product has ceased to be lucrative, companies can dismantle it to move demand to a new sector of the market that they control. 

Allowing the internet infrastructure in the USA to age while pouring investments into mobile is a good example of how this might be accomplished in practice. Planned obsolescence of infrastructure and culture become and additional revenue source to add to the toolkit. 

Conclude

The problem with rent-seeking is not so much that it makes a few people rich without doing work. It is that those resources are shunted from other pro-social products. To the extent that overcharged services are mandatory, they act as a regressive tax that most affects those lease able to pay. 

We have made great strides in stamping out abuses when they emerge, but it seems that new ways to abuse emerge faster than we can regulate against them. Sadly, it may not be the case that this struggle reaches a conclusion. Powerful individuals and organizations can manipulate society and continually escape attempts to regulate against them.

What is the significance of allowing escape-from-regulation to drive private sector innovation? Are there ways to redirect innovation into more prosocial efforts? Is this innovation, though superficially selfish and antisocial, somehow valuable?