Thursday, 31 May 2018

Making Data Human

This month we had a more thoughtful session contemplating how algorithms and data can oppress people.



We were very lucky to have Ed Fish, an artist who uses technology, algorithms and code, to create powerful contemplative and thought-provoking work.

The slides for this talk are here [link].

A video recording of the talk is here [link].


66,081 and Statistical Numbing

Ed started with a bang. He presented a single number, in a plain white font on a dark background:


That number 66,081 is the number of civilian casualties of the Iraq War recognised by the Allies. Ed's starting point was his initial response to this number of deaths - or rather, lack of response. That bothered and intrigued him.

This led to the idea that humans have different responses to, say, 1 death than 100 deaths. The emotional response is not a hundred times greater for 100 deaths. He reflected on the saying that one death is a tragedy, and a million is merely a statistic.

Ed's motivation was then to understand how and why this difference in response happens - and how to then create art that actually does resonate with those experiencing it in a way that more truly reflects a tragedy.

Ed pointed us to Paul Slovic who is an authority on statistical numbing - this very effect of us having more emotional connection, empathy and response to 1 death than 100 deaths.


Ed then showed a powerful graph demonstrating the non-linear response we, humans, have to different physical stimuli as they grow.


For example:
  • In a darkened room, a small light makes significant impression. Doubling the intensity of the light increases our response but doesn't double it. As the light continues to get brighter, our perception of it doesn't double. The largest change in response is between complete darkness and some light. 
  • Sound is similar to light - small noises against silence are perceived with greater difference than loud sounds compared with even louder sounds.
  • Heaviness works in the opposite way - small tiny weights are imperceptible. Larger weights are definitely felt, and doubling a weight feels as if the weight was more than doubled. Electric shocks, like heaviness, are a direct pain sensation and we don't desensitise to them either.

There is some justification for these effects - evolution required us to be sensitive to small sounds and light - in order to survive in a sometimes hostile natural environment.

From experiments, a similar graph can be constructed for human response for number of victims. It shows that our desire to help victims is most felt when there few victims. When there are many victims, our response doesn't multiply to the same extent.


Large numbers of victims are more anonymous - statistics - harder to identify with as individuals.


Iraq Body Count Project

Ed contacted the Iraq Body Count Project which tries to maintain a count of civilian deaths as a result of the 2003 Iraq War.

In an attempt to make the huge numbers more meaningful, and counter the effects of statistical numbing, Ed created an audio work to encourage a Slovic slow thinking response.

He extracted key parameters from the body count data, such as victim age, and passed these into the Super Collider audio programming environment. He used a method, called granular synthesis, taking small sound segments and further decomposing these in order to reconstruct a wider soundscape.

A key compositional decision was not to create an amplitude based audio work. Instead, granular synthesis based on a sampling of earth being crunched, was used to layer sounds to create a sound texture over time.

His piece, For Dead Children and Electronics (2015) is 8 minutes long.


In Ed's own words:

"A sonification of 10340 civilian deaths in Iraq since 2003. Using information provided by Wikileaks and Iraqbodycount.com the age of the fatality dicatates the duration, amplitude and reverberance of the grain. The younger the victim the louder, longer and more reverberant the pop."


Listening to the piece, even for a couple of minutes, was a sombre, thoughtful and reflective experience. Knowing that each sound grain represented a death, and the louder ones were for younger children, forced us to think and understand, in slow time, the reality of the tragedy of the Iraq War.

Ed's work of art grimly succeeded in forcing us to empathise with the human disaster, his work architected and designed to directly counter statistical numbing.

Many of us felt a sadness descend on us as we listened.


Algorithmic Bias

Ed talked next about the tyranny of algorithms that, through their inflexibility or unsophistication, cause human misery by imposing the bias of their creators on others, especially those who have different ethnic origins or are transgender.


Ed talked about an example of facial recognition software, used by government, trained on a limited diversity of faces. The failure to recognise people who might be of different ethnic origin is not just an issue of inconvenience. The fact that they are then treated as suspects or with suspicion is a major issue. In addition, the wider public seeing these individuals being pulled aside for further questioning reinforces the stereo type that people who are Asian, for example, are more likely to be doing something illegal.

The algorithm, badly designed or trained, becomes an unchallengeable tyrant.

As an artists' response to this, Zach Blas developed this own method for capturing the faces of people with diverse backgrounds and shapes. He crafted the meshes calculated from these captures into masks to be worn. But because these faces were more diverse than the software is typically expecting, the masks were an uncomfortable fit. To underline the issue, the tyranny, the masks were made of metal, and putting them on was not just uncomfortable, but a literal prison of metal bars.



Are We Complicit?

Ed then took the discussion further and asked the provocative question: are we responsible?

If these algorithms are using our data to act in undesirable ways, should we be more active in preventing our own personal data from being used?

This question led Ed to develop a work of art which focussed on the connection between us, the passive or mildly participating public, and the actions of an algorithm.

His research took him to the visualisation of slaves packed inhumanely tight into transport ships. Those slave ships themselves were consciously and intentionally designed for that purpose - to maximise the transportation of slaves with just enough room and air to keep enough alive. These macabre dimensions and proportions were used to inform the design if a pyramid sculpture which moved in response to viewers moving around and in proximity to it.


Ed reported that viewers initially couldn't understand how this triangular pyramid moves and changes in response to their own movement. The cause and effect is there - but the culpability isn't clear.

The work starkly illustrates the core idea that each of us, individually, can't easily understand our own effect on the machine, exacerbated by the machine combining data from many of us. And that, in effect, distances our responsibility for the algorithm's actions.

Ed also highlighted the converse - where a mob will deliberately subvert an algorithm by flooding it with biased or malicious data. In this sense, the culpability is real, but each individual participant of these attacks is again anonymous, hiding amongst the mob.


Group Discussion

Ed's talk stimulated us into a great passionate discussion covering a broad range of themes, included:

  • Transparency and algorithms - is it as simple as demanding they must be open source? Can most people understand open sourced algorithms?
  • How journalists and artists can better explain tragedies given an understanding of statistical number.
  • The algorithm used to create the audio piece, For Dead Children and Electronics (2015).
  • The artist as a privileged person commenting on the lives of less privileged people - is that right? Or is it a duty on privileged artists to use their talents to create art that raises awareness?
  • The challenge of teaching children and younger people around personal data hygiene and privacy. The lack of education on personal data issues - and the need to do this before corporations take a lead on getting more personal data.
  • The toll on mental health of hyper-active social media platforms - and the benefits of digital disconnection. The idea of a "medical" limit on social media analogous to limits on alcohol and sugar. 



Further Links


Sunday, 29 April 2018

Art From the PyData Art Hackathon

This week Algorithmic Art were at the annual PyData London conference, where we ran a hackathon.

Data science skills and artistic creativity is a potent mix!


Donald Trump In Words

One of the teams combined text analytics and generative deep learning to great effect.



They developed a word cloud of Donald Trump's utterances, and then fed that to Google's deep dream system to combine the word cloud with a portrait of Trump.

The result is very effective. A powerful element of the design is that the coloured shapes on the image are recognisable as words, but they are so distorted that they are hard to make sense of. This resonates with many people's view that Trump's speeches and tweets are difficult to understand, and that they bend and twist reality. As a portrait, his form is made up of these ambiguous words - a powerful statement on who his is.

Friday, 27 April 2018

Algorithmic Art Hackathon at PyData London 2018

PyData London is one of London's leading meetup communities focussing on Python, open source and data science. They also organise a popular and well regarded annual conference.

This year, Algorithmic Art have been kindly selected as a community sponsor.  As well as an expo, we will run a hackathon as part of the conference schedule.


Theme: In The News




Hackathons

An art hackathon means coming together in a shared space, and being collectively inspired to create algorithmic art at the event itself.

Hackathons are really fun, hands on practical (there's no talk or lecture), and we're often surprised how much can be created in a limited time.

Beginners are very welcome, as well as more experienced friends who can help others.


Artistic and Practical Constraints

All the best art emerges from constraints, often consciously self-imposed. This hack will have some constraints:

  • Your art must be accessible over the internet using a web browser - without the need for additional plug-ins or extensions.
  • The code which creates your art must also be available over the internet.
  • You must allow your code and work to be publicly viewable, freely copyable and reusable (CC-SA). 
  • We have 90 minutes to create the art from scratch.
  • The work must be inspired by the theme "In The News". You are free to interpret this as you wish. You may wish to consider using data or algorithms based on current affairs and issues currently in the news. Unlike more objective data visualisation, you're encouraged to infuse your art with your opinion or emotional response.
  • You should use open source tools wherever possible. Others should be able to recreate your work or re-apply your method without undue barriers.
  • Your own constraints (colour, shape, mathematical, other) - do tell us when you're showing your work.



Timing

To make sure things get done, we'll stick to the following schedule:

  • 13.30 - 13.45 Introduction, organising teams if you wish to work in a team, identifying helpers
  • 13.45 - 15.15 Art Hackathon!
  • 15.15 - 15.45 Showcase - talk about your work, inspiration, aim, method, algorithm. 
  • 15.45 Prizes awarded!



Beginners

Support will be available for beginners to get going. Volunteers for helping out really welcome!

If you're very new, an good option is using Processing - an easy to learn and use language designed for artists and designers. Code directly on the web using openprocessing which makes it even easier to use p5js, the very popular web version of Processing. You can refer to online tutorials for p5js, including:




Prizes

Three prizes will be awarded in the following categories:

  1. Complete beginner award
  2. Best use of algorithms and/or data
  3. Most effective emotional impact
  4. Most convincing algorithmic text generation


Submissions

Please complete this online form to make your submission:



Your work may be displayed on the Algorithmic Art blog or shared on Twitter @algorithmic_art. Do let us know if you prefer your work not to be shared like this.

Thursday, 26 April 2018

Recursion for Beginners

This month we had a gentle introduction to recursion - a powerful idea that can create wonderful patterns - but one that we sometimes struggle with when we first come across it.

Here's an example of the kind of pattern that can emerge from recursion.


The slides are always at: [link]. The slides also contain links to code you can experiment with.

Video of the talk is at: [skillsmatter].


Aim

The aim of the session was try to:

  • explain what recursion is, and to be able to recognise it when others use it
  • use simple examples to get a feel for the mechanics of recursion
  • to develop a way of thinking which can help make our own recursive algorithms

And to inspire members to try their own ideas for recursive algorithms.


Start With Observation

We warmed up by looking at a few examples of patterns and natural forms. We observed that a common theme amongst the images was self-similarity at different scales - which some knew to call fractal.


A good example was from nature itself - a fern leaf. Looking at the fern above, we can imagine snipping off one of the branches, and examining it to find that it looks remarkably like the whole. In fact the snippet itself has smaller branches. When you're looking for self-similarity,  you start to see it everywhere - from the artery structure of a human body to the fluffy clouds in a summer sky, from the lumps and bumps of a mountain, to the repeated motif of purely mathematical fractals like this Julia fractal.


After a few examples, our mind's eye was primed to spot this kind of self-similarity for the rest of the talk.


An Apparently Unhelpful Definition

We started our discussion, not by defining recursion or talking about someone else's definition. The reason many of us were here is because that approach hadn't worked!

We started instead by pondering this interesting conversations between ladies in a Victorian garden:


We overhear a lady asking another lady (with the rose), "what's 3?". The reply is "1 more than 2". That doesn't seem very helpful, so the lady asks again, "what's 2?". Again the reply is "1 more than 1". How annoying! The lady tries again, "what's 1?". This time the reply is a little bit more helpful, "that's how many noses you have."

It does seem like the lady with the rose is being very obtuse and determined to be unhelpful. I'm not sure I'd enjoy a conversation like that. Imagine if I'd started with "what's 100?" - the conversation would have been very long and boring.

Let's look at the conversation from a different perspective. 

The lady with the rose has actually been very clever. She has only used 2 kinds of responses:
  1. "1 more than ...."
  2. "that's how many noses you have".

Using only these two responses, she is able to describe any whole number, be that 3, 7, 99 or even 22139. Sure, the conversation that starts with "what's 22139?" will be long and boring, but remember that we can offload repetitive and boring tasks to our computers to do quickly and without fuss or boredom error. 


Let's say that again - the lady with the rose, has been able to describe any one of the infinitely many whole positive numbers using just those 2 rules. That's pretty amazing!


Visual Patterns with Just Two Rules?

Then came a thought leap. What if .. what if it was possible to describe complex patterns using just 2 rules? 

That's a powerful and ambitious statement. But let's start with a not so complicated pattern so we can focus on the idea first. 

Here are the ladies describing circles.


Again, the lady with the rose is able to respond to questions about circles of any size using only 2 replies:
  1. "... one size bigger than ..."
  2. "O"

And again, her approach is clever, because with just those 2 rules, albeit with lots of repetition, she is is able to describe circles of any size. 

We then tried to visualise this mechanism of describing something in term so the next thing, whether that's a number or a circle. Visualising something, or even trying to visualising something, is a good way of developing empathy with the mechanism at play.

We did this visualisation with just "pen and paper" not with code, to keep our focus on what's important - the concept. We started with the idea of a circle of size 3, which is one size bigger than a circle of size 2 .. which is one size bigger than a circle of size 1 .. and a circle of size one is just O. This resulted in a picture of concentric circles with the largest being of size 3.


We then asked ourselves the question - what if we had started at size 4? We know a circle of size 4 is one size bigger than a circle of size 3. That means the picture we drew starting at size 3 can be reused. We've already done the work for circles of size 3, 2 and 1. The overall picture is a little bit more complex than the one starting at size 3.


Although these concentric circles aren't very intricate in design, we can start to see how the very same 2 rules can be used to create more and more complex or detailed patterns. 


Coding

We then started thinking about how we might write code to create the previous pattern, which is visualising the relationship between circles of different sizes, as defined by the 2 rules.

To keep things clear, we wrote in plain-English pseudocode, avoiding the distractions of real programming languages and their peculiar syntax.

Our first attempt was to simple three instructions to draw a circle: circle(size = 3), circle(size = 2), and circle(size = 1). That would certainly create that pattern of three concentric circles. 


But - what if we wanted to start with a circle of size 100? We'd have to write out 100 different circle() commands!

We'd forgotten the clever ladies in the Victorian garden. They were clever enough to be able to describe numbers or circles of any size with just 2 rules. They didn't need 100 statements to describe 100 different circles. 

We tried again, this time trying to reflect the ladies' approach:


Here we're saying "let's draw a pattern of size 3", and we're defining that pattern.

The definition of a pattern of size s is a circle of size s, and a smaller pattern of size s-1. That needed a bit of thinking but is it does reflect the ladies' thinking - defining one thing in terms of the next thing. 

It can seem strange that we are allowed to define something in terms of itself, especially in a computer programming language - but many programming languages do allows us to do this - and it is incredibly useful.

And definitions which refer to themselves are recursive definitions - hence the word recursion.


Logic Error!

Let's see what happens if we invoke that newly defined my_pattern() with an size of 4, that is, my_pattern(4)

We expect to see a pattern of 4 concentric circles, like this:


If we actually ran that code, it's unlikely that we'd see these 4 circles. 

Instead we'd probably find our computer giving us an error, or becoming unresponsive. Why?

If we look again at the code, and follow it through step by step, we can see what happens:
  • my_pattern(4) means a circle of size 4, and then my_pattern(3)
  • my_pattern(3) means a circle of size 3, and then my_pattern(2)
  • my_pattern(2) means a circle of size 2, and then my_pattern(1)
  • my_pattern(1) means a circle of size 1, and then my_pattern(0)
  • my_pattern(0) means a circle of size 0, and then my_pattern(-1)
  • my_pattern(-1) means a circle of size -1, and then my_pattern(-2)
  • my_pattern(-2) means a circle of size -2, and then my_pattern(-3)
  • .... and so on

Our code doesn't stop at circle size 1 ... it carries on. 

We missed one of the two rules that the ladies' discussed, the rule that terminates this chain. With the numbers example, the rules terminated at number 1, and the circles example terminates at circle size 1. We need to terminate this pattern at pattern size 1.

Let's try again, and this time care care to include both rules:


Here we've written code to explicitly reflect the 2 rules - which we've called the continuation rule, and the termination rule. One rule checks to see if the termination condition has been reached - pattern size 1 - and if it has, then we draw the circle size 1 and finish. If we haven't reached the termination condition, we draw the circle of size s, and continue with a smaller pattern of size s-1.


Recursion - Termination and Continuation Rules

We talked about the generality of this approach in all recursive definitions:
  • a continuation rule - which defines how the current level of detail relates to the next level of detail
  • a termination rule - with defines when the continuation stops

Continuation links one level of detail to the next level of detail. It's the clever bit which recognises a symmetry or pattern that we can use to link, and keep linking, one level of detail or size to the next. 

Termination is critical - without it the continuation never stops. That might be fine in pure mathematics (eg 1 + 1/2 + 1/4 + 1/8 + 1/16 ... = 2) but when computing we can't continue to infinity.

We talked about trying to think of imagined patterns, or even forms that we see in nature, in terms of these 2 rules - good practice for becoming a more proficient algorithmic artist.


Hard Work Pays Off

Once we've put the effort into defining a pattern recursively, using the two rules, we can start to reap the benefits.

What happens if we invoke my_pattern(10). We automatically get a pattern of 10 circles! No additional work needed to be done by us. 


That's an important point. Once we've invested the effort think recursively, and define the pattern recursively, we can then very easily draw patterns of many sizes, or levels of detail.

This goes right back to the original chat the ladies had, where the lady with the rose cleverly defined rules which could describe any positive whole number. 

We could easily invoke my_pattern(1000) if we wanted to, and we'd get 1000 concentric circles.


More Interesting Patterns

Once we've got used to the the key idea of recursion and recursive thinking, we can then have a lot of fun experimenting and extending the ideas.

We discussed an imaginary pattern called The Mysterious Holocrux, which the ladies defined as a circle with two smaller holocrux patterns either side of it.


Here's a sketch of what a holocrux of size 300 looks like - a circle of size 300, with a holocrux of size 200 either side of it.


We can fill in the blanks - because the same rules tell us what a holocrux of size 200 is.


If we carry on to the next level of detail ...


This is just like the concentric circles example but the next level of detail has 2 circles for every 1 circle, and they're shifted along rather than remaining centred on the same point. 

When we talked about coding this idea, we introduced a new idea.


We've combined the termination and continuation rules. The logic is still the same, but the programming language allows us to express both concisely. Here, when we say "continue as long as the size s is more than 0" we're expressing both rules:
  • termination when the size is 0 or less
  • continuation as long as the size is more than 0

This is actually a very common way of coding recursive algorithms so worth getting used to spotting.

The results are starting to look more interesting than concentric circles. 


That pattern could do with more details, so let's change the logic so that the recursion continues for longer as the circles get smaller. Let's also change the rate at which circles get smaller.


We introduced a new idea again. This time the termination condition was changed to s > 5, and not left as s > 0. We discussed why this might be. 

The reason is that we're halving the size of the circles with every continuation. No matter how many times we halve a number, we never get to zero. That would mean our computers groan, become unresponsible and throw us an error. That's why we need to stop when size reaches a number bigger than 0, like 5.

Here's the result.


That's much more interesting than anything we've seen yet. And we're starting to see the power of recursion and the intricate patterns that might be possible.

We then saw how easy it was to extend an existing recursive pattern. The holocrux was defined a extending horizontally with every continuation. We can add a vertical extension too.


Now, a holocrux of size s, is a circle of size s, with 4 smaller holocrux patterns above, below, to the left and to the right of it.

The code changes are minimal - a benefit of the investment we made earlier. 


And the result is really rather interesting.


The ease of extending a core recursive pattern was stressed again - it's a benefit of putting the effort in early on to cast imagined patterns in terms of a termination and continuation rule.

Its super-easy to take that last pattern, and tweak how far out the smaller holocrux patterns are placed. We can even change the colouring scheme - here we're using a translucent red for the circles.


Playing and experimenting is definitely encouraged.


Randomness and Recursion

Randomness is a powerful algorithmic art method in its own right. Could we usefully combine it with recursion?

We talked about another imagined pattern the Jewel of Drax. It's very similar to the holocrux, but is based on squares not circles. The important difference is that the next level of detail could be one of two options. 


When we continue the recursion and define the next level of detail, we choose one of two possible options, chosen with equal probability:
  • 50% chance - jewels of drax placed top right and bottom left
  • 50% chance - jewels of drax placed top left and bottom right 

We've introduced an element of chance into the recursive pattern - with means the results will be different every time we run our code. Here are the results from four runs.


Randomness adds a particularly unique dimension to recursive patterns.

We continued to explore a slightly more involved example, inspired by nature - a tree in Richmond park in fact!


We can see that the tree is self-similar in it's branching. A chosen branch could be the whole tree, or a snippet form a larger branch.

We can formulate a recursive pattern for a tree:
  • continue: a tree of depth 3 is a branch with two trees of depth 2 emerging from the end of the branch
  • terminate: a tree of depth 1 is just a branch

A picture explains the idea better:


The initial results weren't very natural.


The branching is there and works fine but the overall structure is too regular. Let's introduce some randomness to the direction of the emerging branches. Here are the results of four runs.


Much more interesting and sometimes rather pleasing too. We can refine the trees further by making the branches thicker for larger depths, which results in thinner outer branches. We can also link the length of the branches to the depth, so that branches get shorter further up the tree. The results are more grasslike and really rather nice!


Nice!


Quick Test

As a test of our abilities to spot recursion we looked at these bubble images.


After some observation it because clear that the patterns are random but start with a circle with has 3 smaller circles placed at a random location on it's edge .. and those circle too have their own circles.. and so on.

This pattern was inspired by the work of an Algorithmic Art member who created a similar work at a previous hackathon.


Summary

The key points to take away were repeated - trying to think about patterns in terms of a continuation rule and a termination rule.  These might be patterns we see in nature, or patterns we're imagining.


Hopefully, the session clarified recursion, and more importantly, showed it working. A few members were inspired to try their own recursive pattern ideas - which is great!


A Slightly More Advanced Idea

At the end of the session we briefly talked about a slightly more advanced idea.


Instead of us writing code which draws patterns .. why don't we write code which grows code recursively ... and see what patterns that makes?

This is interesting on several levels. The idea of code writing code is interesting in itself. The idea of growing code recursively is really interesting too.

We started by defining a simple "turtle code' language with commands like L for left, F for forward, R for right. We also included commands to save and restore state, [ and ].  We saw how even this simple language could draw a very wide variety of patterns - the simple turtle code language is very expressive.


We then grew the code according to simple replacement rules. Each application takes a generation of code to create the next generation of code. 

Here we see the extremely simple starting code FRF have the rule F > RFLF rule applies to grow the first generation of code RFLFRRFLF and then again to grow the second generation of code which has 21 instructions.


The size of the code grows rapidly. Generation 16 has 393,213 instructions - that's over 1/3 of a million!


The resulting pattern is intricate and self-similar. Although this particular one doesn't look very pleasing, close up it is more interesting.

This method of growing code produces a wide variety of patterns .. including trees!


Other patterns that a little experimentation found include beehives, geometric growths, curly curls and rather ominous spikes.



Feedback

It's always useful to get feedback on the group's sessions. I was really pleased that many members do want more sessions aimed at beginners - they do seem popular. 

Demand for more practical hands-on sessions is strong, so we'll do more in future.

Overall I was really pleased that some members were inspired to try these ideas themselves.