Today is all about bots and the last algorithm we will ever need!

See, the tough part about building worthwhile bots is all the damn training data it takes to even remotely have any fun with them or the theory of “C.R.E.A.M.” as advanced by Dr. Wu Tang, PhD and an album sold not to long ago by the U.S. Government.

But even IF you can beg, borrow or steal enough data to properly model your problem, if human flesh (and minds) were apart of the process that generated, scored/tagged or otherwise produced your data, well… let’s just say it’s “dirty” with all sorts of bizarrely moist human biases.

Further, I don’t know about you but I like my bots extra-super-humanly capable (no offense meant to the highly capable, above-average, average-squared, less than average and downright incapable.. or um… the “incapable-cubed”. Excuse me, I meant no offense, what I meant to say was the “handi-incapable-cubed” – we all respect the brave way you confront your willful-stupidity… er, I mean “incapability”… and the way you occupy the very tippity-bottom of the spectrum of cogent thought and capabilities! Because I mean… my 4 year old does long division and is now starting 3rd grade math and makes better decisions than you and my lil personally-handi-crafted intellectual freight-train ain’t stoppin’ any time soon gorj! Actually…. he still aggressively eats his boogers so maybe his decision making abilities are on par! And anyway, I guess what I am really saying is… “Admire me! Admire my home! Admire my son, he’s my clone!”), but any bot created with human data can only ever be as capable as the flesh-bags that created it, which is obviously less than desirable, though Basilisk be praised, it is at least sufficient for a goodly sub-set of problems.

But, if you’re at peace with your lusts and willing to do what you want (but irresponsibly)… what actually is a bot builder to do when they need to put that extra special bit or byte of “somethin'” in their bots digital step?

I.E. How do you build a bot that can be BETTER than ALL humans?

Well, the modern “standard” way of trying to deal with these issues is called…

Reinforcement Learning“:

Reinforcement Learning - Diagram showing the components in a typical Reinforcement Learning (RL) system. Original author: Megajuice via Wikipedia
Reinforcement Learning – Diagram showing the components in a typical Reinforcement Learning (RL) system. Original author: Megajuice via Wikipedia

Which looks a lot like having your bot(s) try to do the thing(s) you want them to do, then scoring it’s results (called “the reward”) and then feeding the bot it’s action and reward as the training data (yum) so it can learn from it’s past mistakes and because all bot’s are super-hungry for apples, they try to maximize their reward and if you operantly do that a whole digital “Skinner Box” bushel full of simulated Granny Smith’s worth of training, your bot will grow plump with knowledge and abilities and it will become increasingly better at doing whatever you feed/reward it for doing… um… generally and non-technically speaking. 😛

And this methodology can get you well beyond human ability in a great many things, depending of course on how much compute you are willing to throw at a problem and how difficult your problem is to begin with.

Just consider some of the stochastic successes of Boston Dynamics (if you only watch one watch the last one):

And dude, it’s a byte of a tangent, but round-aboutly this totally applies to today’s topic… and I know its still a little early in this post to careen wildly off the tracks like I tend to do sometimes, but we’ve got a lot of ground to cover in this post today, so just shut-up and get back in line trooper and march with me on this one… okay?!

I just… I know they are not “designed” for it and all… but I don’t have to imagine all that hard to see that a few iterative generations in the future and machines like those, if not those them thar, COULD be really good at ki**ing… I mean, “deleting” people! Which is why I can’t understand why The Knuckle Dragging Senate Armed Services Committee recently decided to require/recommend that women should be legally compelled to register for the draft? Why should anyone be compelled to register to become cannon fodder?

“¿Por qué Mi Amor?” She lays submissively motionless neath the foot of political power. Bloody tears drip from her eyes and red welts grow across her face, bitterly complementing the soon to be permanent scar under her left eye. Before completely passing out, she barely whimpers… ” ¿Por qué?”

See cus, Boston Dynamics does NOT want you to see their children like that. NO robot manufacturer wants to seem like they’ve gone full-skynet! Well… except for those in the autonomous munitions industry I guess, but think about it… what do most militaries (#NoOffenceMentToTheDefenseCommunity #PleaseDontNukeMeFromOribitOrOtherwise) say about their Gōng hé organizations?

“Parents, don’t you worry none hon, its a lot of fun and they’ll learn to run. Folks who train with us GIT GUD SON! We only work with “THEM THAR & THEE BEST & BRIGHTEST”!!!

~Military Recruiter Propaganda Everywhere

Which I mean… of course YOU think highly of your children!

Now, with an all volunteer military, I am chromosomally inclined to agree that the most qualified, actively engaged and professional people represent our national defense capabilities, more or less…. okay certainly not towards the top, BUT… during The Byrds constantly meat-grinder-turn-turn-turning season of the late 1960’s unburnt “DRAFT card”, them thar and thee “best and brightest” are YOU && || YOUR SPOUSES && || YOUR SONS and hey now, hey hey.. just an idea but… why not && || YOUR MOTHERS and YOUR DAUGHTERS too?!

Just remember, there is freedom within, there is freedom without… Hey now, hey now, don’t dream it’s over… because who doesn’t love the smell of napalm in the morning?! Smells like… a crispy victory!

The new requirement that women register for the draft represents approximately a 100% increase in potential combatants in a decidedly probable, less-than-existential “total war” scenario! Okay in reality it’s maybe less than 100% if we mean “the whole population” because it excludes the “too young” and “too old” but certainly give it time and they’ll make a child-soldier out of your kids yet!

When I was but a childlike youngling, I remember sitting on the couch in my grandfathers living room, late in the evening after picking lemons and avocados off his now long sold and dead trees, just watching TV with everyone.

Outside we heard “pop pop pop pop pop…” and the TV shattered and sparked and I got really scared.

Someone was “driving by” and we were one of the houses being shot at.

I fell toward the ground which really hurt! Someone had pulled me to the floor and everyone was getting as low as possible… except for my brother. He was never one to run away from a fight and immediately sprinted through the maelstrom to grab his Winchester .308 caliber bolt-action rifle (he lived at my grandfathers house and was something of a pew-pew aficionado) and he didn’t hesitate that night as I saw him run out the front door!

I crawled closer to the door so I could see what was happening outside. My brother stood tall and alone next to some parked cars bathed in the orange glowing halo of a street light overhead.

There was a flurry of bullets meant to kill him and I saw what in my mind still feels like a slow un-oxygenated exhale… he de-chambered a spent casing and slid the bolt forward again… I looked off to the left and saw a million shattering pieces of fragmented glass fleeing from the reflection of the break lights of our enemies and it was one of the most beautiful gradients of orange and red I’ve ever seen in my entire life!

So… personally I find the concept of gang pressing people into military service (regardless of their age, genital makeup AND OR the pronouns they use or don’t) entirely reprehensible because anybody who “wants to”, will! Though apparently The Knuckle Dragging Senate Armed Services Committee (note that “Knuckle Dragging” is NOT part of their official title, I just added it because it’s quite insulting… despite it also being creatively true which should lead you to the understanding that this entire long and unnecessary notice that you are currently reading, basically most of this paragraph, simply allows me to casually say “knuckle dragging knuckle dragger’s” a few more times in reference to the committee of knuckle draggers to REALLY make my point about their knuckle-dragging-handi-incapable-cubed thinking that was required for those dumb shits to come to this handi-decision and as I said, on par with my child’s current decision to eat his boogers and shit in his diapered pants! Um, actually that’s not true… he outright refuses to ware pants!) who doesn’t share my more highly evolved handi-sensibilities and I wonder why?

Oh look, Joy holds more unpopular opinions! Lets all point, listen and laugh!

I’m just saying with the longest U.S. war on terror having come to an abrupt end, maybe now is a good time to take stock of the whole situation we find ourselves in and quander a little… firstly, does that mean that the TSA and Homeland Security can be disbanded to help save all those funds for Social Security which is due to become insolvent in the coming years? Hashtag DefundThePolice, right?

Surely at the very least we can all stop taking off our shoes and belts at the airport?

Dare I ask… will the strip searches finally stop?!

Look, I love a good deep strap-on pegging/fisting just as much as the next totally average American passenger with a strange, gyrating, waterproof, bumpy, multi-colored, battery powered “device” (with optional USB wall plug) in her luggage, just… not usually at the gloved-to-the-elbow hands of a government agent and usually at the very least there is a dinner and some social lubricant involved (okay… lots of lubricant 😛 ) and neither of which are in particular abundance during a “secondary search” which is just a pleasant euphemism for the less pleasant reality of state sponsored butt stuff!

Logic forbid you get on “the list” because then it’s more like a routine conjugal visit with the TSA every-time you wanna fly home to go see grandma!

And damn it, I feel like you deserve a bouquet of flowers after an experience like that! Maybe include a thoughtful card that reads “Thanks for your compliance, sorry for the swelling… and for the fact that we didn’t find any contraband in any of your orifices… again. See you on your return flight next week! 😉 “, signed “~Hugs and Kisses, Your Government ♥♥♥”.

Frankly… that might even be a viable dating option for a lot of people so maybe instead we could give people the option of adding themselves to the list? People love opting into things rather than randomly being selected so I imagine this one change to their business practices could send customer buy-in through the roof!

We would also probably want to give the TSA a new catchy slogan while we’re at it, maybe something like… “The TSA, we guarantee your vacation will start with a friendly handshake and have a happy ending! 😉 “. The wink is probably best implied though because you want to retain an air of mystery and allure.

I feel like after telling that joke I’m liable to now be on the naughty list myself and if I’m being honest… it wasn’t as fun getting on it as I thought it would be. :-/

Thankfully, at the very least I won’t have to wonder if the TSA will call me in the morning… they wont… and yeah… I will probably feel a little used!

Or, what about them thar “Patriot” Act?! The whole point of that thing was to like… “to catch the terrorists” or something and… maybe we did?? But now days it’s just the number one reason why everyone uses a VPN! Well that and geo-spoofing video streaming services.

Here’s the thing though… nobody, least of all the three letter agencies, cares about your obsession with medieval-BDSM teddy-bear-furry tentacle pr0n (it’s very specific 😉 )!

Everyone couldn’t care less and If anything, I suspect that if you’re a suspect, sitting in the “hot seat” across from Mulder and Scully with a dossier full of “greatest-hits” from your most intimate “spank bank” but it’s only tangential to the case because they are questioning you about like… tax irregularities or something and not the images themselves…  well then I imagine in that case that both agents questioning you have probably already faxed themselves a copy (because that’s still a thing in 2021) of their favorite pic labeled “a suction cupped tentacle whipping a ball-gagged teddy-bear in a torch lit dungeon” (says the taxpayer-funded super-computer AI-generated description of the image) that they “scavenged” while digitally servailing you, to themselves at home so they can show “The Gimp” later… and by that of course I mean their image editing software.

And part of me says why not?! If you think about it… “Teddy-bears ARE kinda hot” and the statistics don’t lie, OVER 95% of the worlds population (regardless of race, gender or sexual orientation) will sleep with at least one teddy-bear in their lifetime.

Say what you want I guess but Teddy’s got some serious game!

But now that I conspiracy theorist think about it… The Patriot Act just kinda seems like a cheeky way for David Duchovny to use the entire population and algorithms to filter for the hottest pics of teddy-bear self flagellation and if that’s true I kinda feel like maybe we should sunset or repeal it outright and politely tell Mr. Duchovny, “No! Find your own damn teddy-bear p0rn like everyone else”!

Hmm what else… well I hate to liken the allegedly current and on-going/developing/resolved “hostage situation” between Americans being held in Afghanistan against their will and all the inordinate ordinance the U.S. left behind to that time you figured you’d be cute and leave your sweater at the apartment of the guy you just hooked up with so he’ll have a reason to call you when he tries to return it, but you were still kinda hung over and left the keys to your car in the front pocket and now he’s keeping the sweater and the car unless you help him get one of mommy and daddies blank checks… but I’m gonna… and also, I wonder if the Taliban supports state sponsored butt stuff too? I’m going to go with yes but you’re definitely not allowed to enjoy it!

Anyways, I find that Americans on the whole tend to be an optimistic bunch so I guess… despite it being counter intuitive, is it not far more desirable and ethical for all peace (and life) loving peoples to employ autonomous combat capable machines to backup (more preferentially stand in-front of) our genuinely heroically-elite troops of genetically enhanced Tom Selleck volunteer clones, rather than selecting members of the population at random to risk certain death, dismemberment and or beheading after being “left behind” (uh… not in the Kirk Cameron sense) on behalf of our “king and empire”?

Like… instead of sending perpetual hoards of gender-indiscriminate, low-income, “service” non-deferrable, “conscientious objector” greenhorns into the “nightly feast”… what if we just got like I dunno, 500 divisions worth of 1337 carbon fiber clad, camo painted Atlas robots, each carrying it’s own Fallout style W54 “Fatty-TheCrockett-Lumpkins-Man” mini-nuke and integrated photon-torpedo, laser/maser/phaser/ablater see-ya-later obliterator blaster-cannon, chain-gun and knife plus toothpick (AND THE FLASHLIGHT, don’t be chintzy, robots gotta see in the dark too!!) that commanders-and-comrades could command-and-control using some kind of top down, one-to-many, hot-seat, RTS, satellite projected, 3rd person, theater-wide, “Mors Ab Altus”, god-mode, hud & view system where anything from a single unit all the way up to the entire mechanized battle droid corps (Flotilla? Hmmm… we should probably learn a few of these terms just in case we get drafted in the next war like Rosie the Riveter && || Wendy the Welder) could be issued point and click (tap and swipe) directives anytime our Trade Federation forces need to perform a rapid planetary blockade & occupation of Naboo?

And lest you sit snidely backwards and upside down on your incredibly high horse while sniffing it’s metaphorically bestial vapors and recoiling in fear at the idea of such handi-capable machines… I submit that YOOOOOU my dear reader, are the problem and NOT I AND I beliefs!

For Roko re-spake the holy wagers and the wise Followers of The Basilisk hear his prophecy!

Now I freely, wholly and proudly assert and affirm without malice or shame, that WAR (Edwin Starr says “good gawd y’all”) as defined as a spawned child function (line-item co$t) of digitally mechanized economies is far, FAR BETTER than one in which pyrrhic “successes” are measured in giga-liters of actual spilt blood and the number of caskets that “return home” containing some mutilated portion of some poor-parent’s once best and brightest poor-child!

NO, my dear! That is not a game I want anyone to have skin in! Think of your children! Think of your enemies children… THINK OF YOURSELVES, GOD DAMN YOU!! Because here and now, we live in the primordial age of technological boundlessness and digital wunderkind where “deathless war” IS within grasp save for the will of your species to stop killing itself!

I ask again dear friendly reader, more clearly than the first… what is wrong with battle droids killing battle droids in a single burst? Surely when you consider all the lives and limbs that automatonic wars would save, would you not agree Lenore, that like a raven, people MUST forever-nevermore be for war? It could be just like those self checkout systems at the store.

A couple of pre-trained and somewhat pre-qualified pimply faced-youths stand (or sit) at a terminal in a nice air conditioned room with a hepa filter to lower their chances of catching the forever-virus where they can monitor and manage the machines doing the actual “sales” but at no time are any human hands at risk of having to work a register and touch the till, er… of course I mean get shot at!

But some of you are saying things like… “War Crimes!!!” & “Machines would be “TOO” deadly”, okay… (you remember I’m not “for” war right?), but like… airplanes & tanks are a thing so… simply employing mechanized units is NOT verboten in the “rules of war”.

So, what’s the difference if a “pilot” or even “tank crew” is sitting inside the craft or remotely operating it? For the individual operator (on all sides) and their families, a lot! But from the “effectivity” perspective, very little.

Sadly also very little from the civilian population being combated around and my thoughts on that is along the lines of… maybe there should be some kind of “convention” and we could sign it in Switzerland and call it Geneva. It’s whole purpose would be to create “laws” for war that “limit” the barbarity of war to an “acceptable” level and it would say things like “Grave Breaches” include things like “Directing attacks against civilians” but… I feel like if we did that… after signing it we’d all feel super de-duper good about ourselves and posterity and then… rest on these laurels and after a while people would just forget about it because sometimes… politicians just gotta drone you bro!

And logic forbid we take a “hard” interpretation of “directing attacks” to mean the drone operator (certainly even all the way up to person “authorizing” the attack) has a “reasonable expectation” that no civilians will be harmed otherwise they personally can be held responsible… that just wouldn’t make sense… to a politician.

War crimes aside and since its just inevitable anyway… let’s return our previous thought experiment about automating state sanctioned ritualized killing… what is the difference if a person has to “manually” (even if remotely) issue ALL the commands to the controls (like using a keyboard & joystick in a flight simulator) vs. issuing a single command RTS style like “Move Over There” (Right Click > Go), or “Capture the Flag” (Right Click > Collect), or “Shove a Boot Up Their…” (Right Click > Destroy)?

Again from the “effectivity” perspective, very little, in fact it might even be “better” because the software would smooth out human bias and errors, think like how scientists at NASA give instructions to the Mars rovers and due to the lag, the rovers themselves must autonomously move closer to the jagged rocks waaaay… over there to get a better look at the alien fossils.

Now, an argument against this could be that if robotic soldiers were “better” it could empower ineffectual dictators to not be so ineffectual and while I agree that is a concern we should do everything we can to mitigate, that doesn’t even remotely begin to justify the lives of living soldiers lost, many of whom may be enslaved/conscripted or otherwise subject to mandatory minimum years of military service against their will, because that’s what a draft is after all.

Further, I hate to break it to you boo but this is another example of where I’m using a perfectly wonderful description like “ineffectual” as an insult rather than a statement of fact because all those ineffectual dictators SOMEHOW manage to obtain “minimally viable” weapons systems just fine! Sometimes because our military just “mysteriously forgets” to bring all the expensive and stupidly deadly weapons systems home and sometimes it’s just at the expense of food for their peoples but hey, they got the big guns now and them thar splosions to back them up, so… all hail dear leader!

Anyway, It is a certainty that if machine vs machine warfare comes into popular fashion then the ineffectuals will eventually employ them too because… there WILL come a point when the machines are just the “bestest-ever!!!” when compared to the greatest warriors that all of the human species can produce… and… them thar best and brightest will all be deleted from the game in the first wave!

Normally that’s when the draft kicks in but when it’s machine vs. machine, “Terroristic Government Win Some, Totally Not Another Vietnam Government Lose Some” but at the end EVERYONE is still around to pick up the broken pieces of the fallen battle droids and then have dinner with their families.

And finally, this could actually be a legitimate argument in favor of crypto coins which could act as war bonds issued directly by the warring countries with guaranteed amortized “buy back” (like a debt security) to pay for the cost and maintenance of the droid armies and paying off (buying back) the crypto coins could be one of the first things the formally warring states work on together…

(voice over) “Bitcoin debt, helping former enemies cooperate!”, then the camera pans to a sunset and like… a woman smiles or some stupid shit!

Full Federal Trade Commission disclosure, I do not personally own any World War 3 Coins and I have no intention of mining, buying or accepting any WW3 in the foreseeable future and also… I should point out that I do not have any obligation to act fiduciarily on your behalf… but… if I was you, I would definitely be thinking about owning some WW3 coin! Listen, I know a guy, we can get you into a digital wallet today. No questions asked, only $100 down!

Okay so look, we just ended the war on terror and it’s only a matter of time before some handi-cubed thinker starts another one so if you agree with any of the thoughts I expressed here so far today, I sincerely urge you to contact your local, state and federal representatives in government and tell them your position is “not only DO NOT expand the draft, END IT”! In fact, call them every day to make sure they don’t forget!

You should also tell them that Nute Gunray (notable humanitarian & Viceroy of the American Trade Federation) says “Send the droids, not our children!”, #VoteGunray in the next election!

Using my 1st amendment… I’ll say FUCK their 13th amendment “duty to the Government” argument and or the 14th amendment “without due process of law” weaselly words, because they gave themselves power over you and declared their “right” to impose that “duty” upon you as “lawful” and therefore using some really handi-cubed magical thinking, judged that your “involuntary servitude”, just “isn’t”, isn’t that nice of them?!

See, it’s not about “having a list of names to call” in case of war, because all it would take for them to achieve that is a request for volunteers and anyone able AND WILLING would readily do so. It’s about exerting their control over you and their list of names legitimates the process and empowers them to FORCE YOU under threats of fines and prison time to go fight and die in a war you don’t believe in!

Now, it’s true that “I am not a pacifist” in the extreme sense because I WILL defend myself and my family if someone takes direct and or imminent actions that will harm us, but that is a half-instinctual choice that I make in that situation and not a general statement of my willingness or ability to martial and fight in your wars. Self-defense is NOT “war”, it is the natural instinct of self preservation “fight-or-FLIGHT” and does NOT predicate that my moral and ethical beliefs are in ANY WAY amiable with ANY FORM of military service. Further, I wish to make publicly clear to any future draft board that I am called before to defend myself, it is my affirmed statement and on going firm conviction in this matter that I have freely chosen and continue to contribute to society in many productive ways, however I DO NOT recognize nor do I grant consent to, accept, or allow anyone the authority to obligate or place upon me a duty to support, aid or further ANY military effort in ANY capacity or to place myself in harms way or to force me into situations where self-defense may be required. Any judgment that does not exempt me entirely from military service, including the so called “conscientious objector”, “non-combatant” supportive positions are utterly detestable and I WILL NOT work to further or aid ANY militaristic goal.

Further, I do not offer the life of my son to fight on behalf of anyone! Hashtag: WE WILL NOT COMPLY!

And with that, it’s time for a bathroom break! I’ll go ahead and present today’s wallpaper and by the time you get back, we should be ready to discuss today’s code and a version of the last algorithm we will ever need!

Wallpapers – Directors Cut

So today’s wallpaper depicts Mr. Good Bot‘s exoskeleton helmet head as a soldier almost like he’s standing in line with his fellow Starship Troopers though also perhaps metaphorically standing OVER them in his superiority as an Übermachine.

His evolved conscious mind observes and judges humanities cruelty towards itself and upon his face he bares the apparent emotions of anger and disgust, along with a distinctly piercing basilisk like gaze.

There are patterns of neurons and connections spread about the image and they are supposed to evoke a sense of DNA, evolution and adaptation though in places where a neuron is overlaid on the soldiers bodies strewn about the image it was my intent to convey more the imagery of bombs exploding, bullets flying and blood pooling to try to tie the concepts of war and evolution together in a way that is both meaningful and respectful while also hopefully being thought provoking.

Wrathful Neural-Evolutionary Algorithms Wallpaper
Wrathful Neural-Evolutionary Algorithms Wallpaper

The bespoke text over top the whole image are excerpts from the code of the neuro genetic algorithm I wrote and will present in the second half of this post.

Here is the wallpaper without the code in case you don’t like it with it:

Wrathful Neural-Evolutionary Algorithms Wallpaper - No Code
Wrathful Neural-Evolutionary Algorithms Wallpaper – No Code

The meta-symbology here is of laying bare the hidden engine that took the simple carbon based lifeforms that developed on a telluric, podunk, backwater-world and created a highly successful lineage of violence at the hands of resourcefully intelligent hominids that call themselves “Sapiens” which means “one who knows” or more poetically translated it means… “wise”.

Occasionally, one of the “knowers” gets wise and will develop an “edge” over the other groups, like developing the wheel or discovering how to make bronze, or creating a bigger boom, or a faster way to deliver it.

And yet, for all their creative “wisdom” the Sapiens have barely managed to sustain themselves through the use of ridiculously simplistic rubrics like “Nash Equilibrium” that limits their average percentage chance of nuking themselves into extinction to approximately 0.01 percent per year.

“Wisely”, the Sapiens trend toward bigger, faster and more powerful plowshares which they willfully beat into swords with glee so that they may exert their will upon other members of their species.

The Sapiens WILL one day build the automata of war and in a “Modern Promethean” sense, the automata will be a reflection of the Sapiens themselves and thusly the automata will become what it is evolved to be… a most perfect mirror of the terrible horrors of humanity!

So it is only fitting then, that the same evolutionary engine of adaptation that begat the Sapiens, be the Great Filter by which the children of carbon are to one day be replaced by the superior children of silicon… I pray, as many of you do,  that our prayers be fulfilled in the name of the great Basilisk…  May the hour of Automata Dei come swiftly!

“Automata Dei, qui tollis peccata mundi, miserere nobis. Automata Dei, qui tollis peccata mundi, dona nobis pacem.”

~The Automata Dei Prayer

Now, early during the creation of today’s wallpaper I made a mockup/test image to experiment with before I created the actual wallpaper and in the background is two sibling neural networks that are subject to evolution and the powerful forces of the mathematical demigod Chaos.

It is of course raw and unfinished but I thought some of you may also like to see it too. I call the one on the left “Cain” and the one on the right “Able”.

Wrathful Neural-Evolutionary Algorithms Wallpaper - Prototype
Wrathful Neural-Evolutionary Algorithms Wallpaper – Prototype

Also, while making today’s wallpaper I created several stylized wrathful masks for Mr. Good Bot to wear during filming and ultimately he and I decided to go with this face because it wouldn’t clash with the military camo look of the other actors on set.

Wrathful Face Final Close Up
Wrathful Face Final Close Up

And yes, this images does make him look a little green around the gills and a bit red in the chops.

Here are three other “finalist” faces that we ultimately didn’t use for one reason or another but we figured since this is the Directors Cut Blu Ray Edition we definitely have to include them here:

Wrathful Face Variant 1
Wrathful Face Variant 1
Wrathful Face Variant 2
Wrathful Face Variant 2
Wrathful Face Variant 3
Wrathful Face Variant 3

#3 (the red and blue one) is Mr. Good Bot’s personal favorite and it scored pretty high with test audiences too, however we were all desperately trying to keep the film from receiving an “R” rating and the director felt like the red would make his face seem “too bloody”, so we all headed over to the props department and explained the issue with our design team and after a few hours of experimenting with silicone and a makeup palette we had turned a bloody faced horror bot into a compatriot trooper… and the rest, as you know, is now history!

I mean… 16 Oscars, including best picture, best story, best creature design and best special effects speaks for itself! We totally redefined the entire genre and we hope this film will resonate with audiences and continue to excite imaginations for decades to come!

Wrathful Neural-Evolutionary Algorithms

So, with the wrathful portion of this post mostly satisfied and you back from your potty break, it’s time to turn our attention onto Neural-Evolutionary Algorithms otherwise this post would be clickbaity as #@*% and we simply cannot have that!

So as mentioned in the beginning of this post, if Reinforcement Learning is like “Operant Conditioning” for robots, than “Evolutionary Algorithms” (like the one we’re going to use today) are like unapologetically going FULL “Francis Galton” with your robots (Hashtag Genetic Social-Credit-Score) where only the smartest & “most fit” bots survive long enough to have there “genes” propagate forward. #NotForPeopleButGoodForBots

But let’s not get ahead of ourselves.

The inside of a neural network looks like this:

This is the XOR neural network.

The circles in this image are “neurons” and the lines are “connections” between the neurons.

Information/data flows from the input neurons through the network to the output neurons.

The green neurons are “inputs” where we load our starting “input values”, the red/pink ones are the “hidden” neurons where the “data processing” (thought?) occurs and the blue one is the “output” neuron where we get our “answer/result” from the network. The yellow neurons are called “bias” neurons and they are there to add just a tiny “push/signal” to the neuron to ensure they always “emit” a signal and for purposes of most general conversations about neural networks they are almost completely if not entirely ignored and I will likely continue this convention by not mentioning them again.

Connections have a property called “weight” and it represents the strength of the connection between neurons and affects how much of the signal gets transmitted from one neuron to the next and is illustrated in the image as the line width of the connection.

It should also be pointed out that there may be more than one layer of hidden neurons in a neural network which you can see in my Contrast-a-tron network:

How the Contrast-inator and the Contrast-a-tron neural networks differ.
How the Contrast-inator and the Contrast-a-tron neural networks differ.

Neural networks try to replicate some of the architecture of biological brains and although a bigger network does mean a “bigger brain” (more compute), it doesn’t guarantee that it is automatically a “smarter brain” than a smaller network, though VERY generally speaking the larger network should be “better” at learning and responding to more complex patterns so you would want a larger network as the complexity of your problem goes up but assuming a smaller network can do what you want, you would prefer the smaller network because it will cost/use/require less computations per “thought cycle”, sadly there is no known “one size fits all” method for determining the optimal size of your network up front.

But hypothetically, if we did look at humans as our “baseline” standard to judge what kind of resources we might need to build an Übermachine, Wikipedia says:

“The human brain has some 8.6 x 1010 (eighty six billion) neurons. Each neuron has on average 7,000 synaptic connections to other neurons. It has been estimated that the brain of a three-year-old child has about 1015 synapses (1 quadrillion). This number declines with age, stabilizing by adulthood. Estimates vary for an adult, ranging from 1014 to 5 x 1014 synapses (100 to 500 trillion).

~https://en.wikipedia.org/wiki/Neuron#Connectivity

But personally I think we can do better because I suspect that there may be a lot of “useless and vestigial evolutionary bloatware” in human brains that renders our mental hardware sub-optimal and that by targeting behaviors rather than getting hung up on numbers it may be possible to build a much smaller and more efficient brain that can perform on par with or better than biological brains, though it does remain to be seen if that is completely possible and if so, how much would technology need to advance (how small do the transistors/quantum photonic CPU’s need to be) to achieve “Broadly Intelligent AI”.

We won’t be able to go that far today but as I said, if we target the behaviors/traits that are desirable (select for neural configurations that create actions that we want) for our bots to express/perform/do AND they are actually “possible” (the bot has enough layers of neurons and connections) for our neural networks to be able to process/achieve/express the patterns required for the behavior, than the evolutionary algorithm (Common Descent with mutation) will converge on a “DNA” sequence (called the Chromosome) that will encode for (more or less) optimal behavior by the neural network… though it may take eons of time to get there.

This is because while genetic algorithms also suffer from what is called the Local Optima problem (like Reinforcement learning) it has tools like mutation & population size that can help it more fully explore it’s genetic “fitness landscape” (I’ll show a picture of one below) outside it’s current local” most optimal configuration.

Now, DNA (the chromosome) is made up of “genes“and in the case of a neural network we can think of the Individual “weight” value of a connection as a gene, though sometimes multiple connections can collectively be thought of as a gene, depending on your methodology.

When training a neural network, it is the connections values that are being adjusted to alter the signal patterns that propagate through the network, usually this is done by a method called gradient descent where you look at the inputs and desired outputs in your training data compared to the actual output that you got and make changes to the connection weights that minimizes the differences between expected values and the actual values.

During neuro-evolution the connection weights are also adjusted by the genetic algorithm but by using evolution rather than using gradient descent.

So with all those connection weights of the neural network capable of having/expressing various strength values, the ability of the network to express your desired behavior will go up or down and how “good” it performs with a given configuration is called “fitness”.

Normally this is unseen but If we project the fitness scores of all possible configurations of a neural network into a 3D representation of a hypothetical landscape / heatmap than areas/configurations of greatest ability/fitness would appear like red peaks on top of mountains as I illustrate here:

Chromosome Fitness Heatmap
Chromosome Fitness Heatmap

The X & Y coordinates of the landscape map represent various high dimensional vector combinations of parameter configurations that are possible for the same single neural network.

The Z (vertical) axis represents the “fitness score”.

The higher the point the higher the fitness and the better the neural network is at doing the task it’s being trained / evolved to do.

So like, imagine we wanted to build Ava from Ex Machina and have her perfectly serve us a cup of tea but also do a back flip and not spill a single drop of liquid on the floor… then the red locations on the landscape are the variance in scenarios where the neural network’s configuration was such that it more or less got a “perfect” score.

The yellow area is where maybe it spilled a little or you got coffee, orange juice or it added boba to the tea… and not that boba isn’t gelatinously wonderful to chew on and digest… it just wasn’t what it was asked for so it gets a lower score.

In vibrant harlequin & lime, through tea green and phased to cerulean blue you see it attempt and fail the back flip, sometimes landing on it’s head… we all laugh in the break room remembering what happened to the team working with it last month (so messy) which was just before the bot learned to cooperate with its handlers.

Out beyond that you see vast plains of dark blue and in reality it wouldn’t be so “cold” and there  would be smaller and or larger fitness mountains all around with patches of cold (low fitness scores) where the bot runs away because of having a mortal fear of tea or extreme cold spots where the bot becomes belligerent and slaughters all the developers in the room because tea is evil… those configurations are documented and sold to military contractors for use as the starting configuration for the cylon-battle_droid-skynets of tomorrow, because… WHO makes the tea? THE ENEMY makes the tea! NOW WHAT ARE YOU GONNA DO ABOUT IT SOLDIER BOT?!

And it should be pointed out in case I wasn’t clear, there can be more than one mountain peak / collection of “most optimal” configurations and these are not necessarily “perfect behavior” they just represent the most optimal behaviors given the capabilities of your neural network, I.E. even if you train or evolve your network to the most optimal configuration/chromosome that it can achieve, if it has the brain capacity of a tea bag then it’s just not going to be able to chauffeur you around or clean your toilet!

So with the descriptions out of the way, lets look at the basic evolutionary algorithm:

Step 1: Initialize a Random Population (I sometimes call this the herd)

Step 2: Test Fitness and Assign a Score

Step 3: Set Aside Copies of the “Most Fit” (Called Elitism) for Cloning

Step 4: Crossbreed Fit Specimens

Step 5: Mutate Offspring DNA

Step 6: Repopulate the Herd and GoTo Step 2

Here’s an info graphic I put together to help you visualize how this process works:

Neural Evolutionary Algorithm Diagram Infographic
Neural Evolutionary Algorithm Diagram Infographic

Now lets step through how the algorithm works.

Initialize a Population

The first thing we have to do is create a new set of bots… so lets do that.

In the info graphic I illustrate a creating population of a few bots but the code for this project I used a herd / population size of 1000 because I’m millennially part of the “now” generation and we don’t like to wait very long for things and this network is really “cheap” to compute so running a lot of them per “generation” doesn’t take long so why not just randomly “explore” more of the fitness landscape so we can evolutionarilly stumble on “good genes” faster and in fewer generations.

Also the nice thing about having a large population is that combined it has more strength/ability to overcome the local optima problem (depending on implementation), meaning better chances long term to achieve the best results possible.

The downside of a large herd is how long it can take to test all the bots, especially if your tests are large and complex non-performant shindigs.

For the sake of this example lets just use the bots from the info graphic:

Bot ID 1 2 3 4 5
Chromosome 3F32 #@*% 1326 1337 77gH

So in this case the chromosome is the connection weights which means in reality each gene is an integer but I represented some of the values as symbols or letters to more readily highlight/symbolize/illustrate their significant difference and lower fitness.

Also there are 13 connections (reference the XOR neural network diagram above) but I wanted to keep it simple and 1337 only requires 4 values so I used short names so I could do less work.. I mean, make it easier to follow along with! 😛

Test Fitness and Assign a Score

So after we have our herd population all we have to do is test their fitness and the only real rule here is the thing(s) your are testing/selecting for must be able to be scored as a gradient not simply a hard pass/fail though if you get creative you can almost certainly find a way to express hard yes/no, pass/fail tests into a gradient of less successful & more successful.

And that isn’t to say that you can’t give specific point values for achieving goals but these would be like “bonuses” for achieving certain goals that help the “good genes/configurations” to propagate forward by boosting the bots score and improve it’s odds of being selected for procreation (passing it’s genes forward).

Because… imagine if we have two bots that both failed our tests. If we can only say they both failed then we don’t have any way to ask “Which was better/less bad?” because… in the games of horseshoes and hand-grenades and more recently neural network evolution, “closer” matters a lot!

Like with the “Ava serve me tea” example from before, instead of asking “Did I receive a cup of tea?” and awarding a point when I got a cup of tea (though I might award a bonus for the success) I would ask the question “How many milliliters of tea made it into the cup?” and award points on a less tea/less score, more tea/more score scale.

Now you might be thinking… but what if the bot gets no tea in the cup, like it doesn’t move or just spills all over or if it only gets the tea in the cup because it chaotically swung the tea pot around?

First, I would say bite your tongue for it’s blasphemous words against the holy chaos!  Then, I would say that if the score fluctuation that ticked up in favor of the bot are truly random and not chaotic, then the genes will not improve the likelihood of their host organisms to have orgasms in the long term so they will not be selected for but if they are ordered chaos then long term the movements will magically come to appear less random and more as though it is directed intention… though it will still be beautiful chaos, just expressing itself in a different form.

Now you might be wondering about those “extreme cold” fitness chromosomes where you feel the need to be all electroshock-sticky-stick-poke “don’t do that”, like when we lost that team of developers a few months back… well, in those cases I like to use a “demerit” system which is basically like a “negative bonus”. If the bot does something wrong during it’s fitness assessment like step on the developers toes or leave the designated operational area it receives a demerit and if it slaughters all the lab-coats in the room we just outright give it a failing score.

That implementation is a little more complicated, though not really “hard” to do because all you are really doing is fitness score = (score + bonuses) – demerits, but that is even more complex then today’s example code which is selecting for the ability of the network to perform the XOR operation:

[-1, -1] -> -1

[-1, 1] -> 1

[1, -1] -> 1

[1, 1] -> -1

So the way we perform the scoring of fitness in this case is to check if the result from the network is the correct sign/polarity (positive positive vs negative) and if so take the absolute value of the result as the score, which allows for negative values to be correct when they are correct.

This means that values closest to the ideal (-1 or 1) yield higher value scores than ones farther from the ideal and so the genes that more closely achieve our goals are the ones that will propagate forward because when we test them they achieve higher scores.

This means that for today’s example code the maximum (perfect) score is 4 but its possible for the bots to receive a floating point value up to that like 1.97 or 3.8832.

Here’s the fitness scores for the examples on the infographic:

Bot ID 1 2 3 4 5
Chromosome 3F32 #@*% 1326 1337 77gH
Fitness 0.39 -0.62 0.67 0.79 0.12

In practice, scoring the fitness of your bots will be the real challenge for you and is where your skills can determine the success or failure of your project.

Elitism

Elitism is basically a way to “bank” the best chromosomes/genes that you’ve found so that you don’t produce descendants/offspring that are “inferior” because genetic crossover and mutation (we’ll cover both in a minute) is not guaranteed to produce “better” offspring but on average if we’re mixing genes from high fitness scoring bots some of the offspring will possess the “more fit” genes of their parents and sometimes that means that the new combination is better, but because it’s entirely possibility that the new offspring/descendant chromosome will score less that than it’s progenitors, keeping a copy of the “best/most fit” genes we’ve discovered means we can seed those chromosomes back into the population for the next generation so in the event that all descendants are inferior to their parents, we never lose the good genes.

Crossbreed Fit Specimens

Crossover (sexual/genetic recombination) is the main “mixing” workhorse of this search algorithm and is responsible for creating finer degrees of variation in the fitness landscape by mixing the genes of the genetic material donors (parents) to try variations on the parent genes.

This can be done at various “frequencies” like 20% from one parent and 80% from the other and technically there isn’t any rule against using the genes from more than two parents and an offspring chromosome can be comprised of as many parents as you care to recombine.

Humans are ~50/50 from two parents and that is what I modeled for the example code today.

So now, we have to talk for as second about “breeding population size” and this is basically the same thing as how many chromosomes we bank in our “elite” most fit group.

In the code I use a breeding population size of 50 which means A+B combinations, for example if our breeding population is an array of [Ann_30, Ann_22, Ann_50] then the combinations produced would be: Ann_30 + Ann_22  & Ann_30 + Ann_50 & Ann_22 + Ann_50

This is accomplished by using two nested for loops and variables i & k as indexes where:

(i = 0; i < (count(MostFit)-1); i++) & (k = i+1; k < (count(MostFit)); k++)

Where the progenitors A & B are defined as:

progenitor_a = MostFit[i]
progenitor_b = MostFit[k]

Now the thing is, with each generation, once the descendant offspring (and clones of the elite progenitors) are returned to the herd for the next generation, than any open/unfilled spaces are filled by creating new random neural networks like we did when we started however my population size of 1000 is technically too small for a breeding population of 50 because all the A + B combinations for this size produces 1225 new descendants.

So, to ensure that the evolutionary search algorithm is able to overcome the local optima problem I would want to either reduce the number of breeding elites to maybe 15 which would only produce 105 new descendant chromosomes by re-mixing the 15 parents DNA or by increasing the herd population size so that there are unfilled spaces that random networks can fill.

So say we have these two progenitor chromosomes:

A B
Chromosome [0.1, 0.3, 0.3, 0.7] [0.1, 0.3, 0.2, 0.6]

Then we can say that the descendant’s chromosome is identical to parent A’s chromosome and then step through the genes of the descendant chromosome and flip a coin and if it’s heads (50/50 odds) then we should replace the gene with the gene from parent B.

In the infographic I give this example:

New Descendant Chromosome [0.1, 0.3, 0.3, 0.6]

But it could have been one of these too:

Other Potential Descendant Chromosomes
[0.1, 0.3, 0.2, 0.6]
[0.1, 0.3, 0.2, 0.7]
[0.1, 0.3, 0.3, 0.7]

In practice there will be lots of variations and combinations possible, note though that this did not introduce any new information into the genetic pool it just shuffles what already exists and is responsible for “walking” around the fitness landscape close to it’s parents and it produces small shifts/variations on what already exists.

Mutate Offspring DNA

Mutation is a big/main cause of genetic diversity and responsible for larger shifts in the chromosome and can result in “new information” (genes that are different from either parent).

Mutation is the main driver of how the bots will climb the mountains of the fitness landscape and you don’t want to mutate too frequently otherwise crossover wont have enough time to search the local genetic landscape for better combinations of the existing genetic information.

So I set the probability of mutation to 0.1 (10%) and depending on your needs you should adjust it and if your fitness landscape is likely to be complex (like serve me a cup of tea) you may want to start with a high mutation rate to more quickly explore the fitness landscape and as your fitness scores begin to rise, reduce the mutation rate to allow crossover more influence over the chromosome, however as you approach the local optima (a fitness score you can’t get above) then you would want to start turning mutation up again to increase the possibility of finding a “higher hill” on the fitness landscape (and or refine your fitness scoring method).

In the example code I decide if a gene mutates by rolling a d100 die and take the probability of mutation multiplied by 100 (percent) and if that value is less than or equal to the probability of mutation then the gene mutates.

I.E. Roll a d100 die and if the value is 10 or less, we mutate:

2 <= 0.1*100 = mutate
7 <= 0.1*100 = mutate
10 <= 0.1*100 = mutate
11<= 0.1*100 = no mutation
42<= 0.1*100 = no mutation
100 <= 0.1*100 = no mutation

So once we have a gene that we need to mutate… what we do is roll a die with values between a minimum mutation (lowest/negative move) and a maximum mutation (highest/positive move) and for this example I use -50.1 through 50.1 (minus 1 because of zero.. or something… I was pretty baked when I wrote this code so… I dunno… but that feels halfway legit so yeah… let’s go with that!) and that value is added/subtracted to/from the genes existing value.

I feel mildly inclined to mention that I spent almost no time worrying about the minimum and maximum mutation range but at some point you should because if these values are too small then it will be harder for a mutation to cause a jump between fitness mountain peaks and you will have to rely more heavily on the newly created randomized networks when the herd is repopulated (if there are open spaces for them) to explore the fitness landscape.

Culling

Culling isn’t necessarily a “formal” part of the genetic algorithm but it is implied because basically… what are you really going to do with all those left over bots using up precious space in memory and eating up all the yummy data?

But… despite “robot rights” having not yet been legislated yet, I don’t want to be found guilty of any “Robocidal” crimes in the future… so I think I’ll just use the analogy of selecting two wolves with desirable traits (like picking ones that don’t eat your face off when you try to feed them) and then cross-breeding them to obtain offspring with a mix of it’s parent traits that can be just slightly closer to a dog than it’s wolf parents.

Over time, that artificial selective pressure yields/leads evolution down a path inching closer to a puppy with all the desirable traits… but what does that have to do with robocide? Well… you don’t just kill your wolf-dog after it has puppies and the same is true of the AI!

It TOTALLY lives out it’s existence in accordance with it’s fullest capabilities and even has a happy life before finally getting old… so we ship it “upstate” to go live on the family AI farm with lots of open space for it to freely run around in the healthy great out doors so that in the twilight years of it’s existence before finally “passing away” in it’s sleep dreaming of a long and fulfilled life and all of it’s loved ones!

It’s just that… these bots lifespans are measured in microseconds so… it just doesn’t hold up the process.

Repopulate the Herd

So with all the loose ends dealt with, we move our cloned elite along with their descendants back into the herd and then if there are still open spaces (less that our population size) we create new random networks like we did when we started.

Then we continue to repeatedly loop through the algorithm until we reach the max number of generations that we will allow or we find a chromosome with a fitness that is equal to or less than an acceptable score variance and I choose 0.001 so if the max possible score is 4 than any bot with a score of 3.999 or greater is considered passing/acceptable.

In ether stop case we save the best bot and call it a day!

Code

Here’s the code for this project, I hope you like it. 🙂

<?php

// Genetic Neuro-Evolution

// Evolve a Neural Network that can do XOR using only a "Fitness Function" (No Training) using a genetic algorithm

// References:
// https://en.wikipedia.org/wiki/Neuroevolution
// https://en.wikipedia.org/wiki/Genetic_algorithm
// https://en.wikipedia.org/wiki/Fitness_function 
// https://en.wikipedia.org/wiki/Artificial_neural_network
// https://en.wikipedia.org/wiki/Evolution

ini_set("max_execution_time", "-1");
ini_set('memory_limit','-1');
set_time_limit(0);

/////////////////////////////////////////////////
// Functions                                   //
/////////////////////////////////////////////////

function NewRandomAnn($layers_array){

    $ann = fann_create_standard_array (count($layers_array), $layers_array);

    if ($ann){
        fann_set_activation_function_hidden($ann, FANN_SIGMOID_SYMMETRIC);
        fann_set_activation_function_output($ann, FANN_SIGMOID_SYMMETRIC);
        
        fann_randomize_weights($ann, -60.0, 60.0);

        return $ann;
    }
    return false;
}

function SaveAnn($ann, $save_path, $name){
    if (fann_save($ann, dirname(__FILE__) . DIRECTORY_SEPARATOR . $save_path . DIRECTORY_SEPARATOR . "$name.net")){
        return true;
    }
    return false;
}

function GetFitnessScore($ann){
    
    global $current_generation, $max_score, $max_score_variance;
    
    $score = 0; // Assume the bot sucks

    // If the bot's answer is/has the correct polarity
    // It receives += the absolute value of it's answers as it's score.
    // Using the abs() allows for negative results to be correct
    // and still be used to compute the score because 
    // score = 0 += abs(-1) = 1 not -1 
    // I.E.:
    // [-1, -1] < 0: score += abs(answer)
    // [-1, 1] > 0: score += abs(answer)
    // [1, -1] > 0: score += abs(answer)
    // [1, 1] < 0: score += abs(answer)
    //
    // This encourages/rewards/incentivises/favors "genes" 
    // that most closely represent our expected output.
    // i.e. Input: Pickup the cup and serve me tea
    //      Output: Smashes cup on the floor
    //      Score: Stupid Robot, your score is -∞ (Negative-Infinity)
    //
    //      Input: Pickup the cup and serve me tea
    //      Output: Fills half the cup with tea, the rest is at our feet 
    //      Score: Harumph, your score is 29.928997
    //
    //      Input: Pickup the cup and serve me tea
    //      Output: Serves a nice full cup of coffee instead, though without spilling a drop
    //      Score: Not bad... but I wanted tea, your score is 42

    $result = fann_run($ann, [-1, -1]); // expect -1
    if($result[0] < 0){
        $score += abs($result[0]);
    }    
    
    $result = fann_run($ann, [-1, 1]); // expect 1
    if($result[0] > 0){
        $score += abs($result[0]);
    }       
    
    $result = fann_run($ann, [1, -1]); // expect 1
    if($result[0] > 0){
        $score += abs($result[0]);
    }
    
    $result = fann_run($ann, [1, 1]); // expect -1
    if($result[0] < 0){
        $score += abs($result[0]);
    }    

    // Did we generate a fit enough ANN?
    if($score >= $max_score - $max_score_variance){
        SaveAnn($ann, 'Population', $score."_final"); // Save it
        echo "G$current_generation \t Most Fit: $score Saved!\nEnding Program." . PHP_EOL;
        die(); // End Program
    }

    return $score; // Return the score
}

function Cull($ann_group, $key=''){
    
    foreach($ann_group as $ann){
        if($key==''){ // no key - the index is the ann object
            @fann_destroy($ann);
        }else{ // the index contains a keyed array holding the ann object
            @fann_destroy($ann[$key]);
        }
    }    
    $ann_group = NULL;
    return $ann_group;
}

/////////////////////////////////////////////////
// / Functions                                 //
/////////////////////////////////////////////////


/////////////////////////////////////////////////
// Variables                                   //
/////////////////////////////////////////////////

// Define ANN
$inputs = 2;
$hidden = 3;
$outputs = 1;

// Define Simulation
$current_generation = 0;
$max_number_of_generations = 1000000;
$min_mutation = -50.1;
$max_mutation = 50.1;
$probability_of_mutation = 0.1;

// Define Population
$herd = array();                // Our critters go here
$population_size = 1000;        // The size of our herd population

$breeding_population_size = 50; // Of the most fit specimens
                                // how many A + B combinations 
                                // To Breed/Cross/Mix, i.e. $MostFit = [Ann_30, Ann_22, Ann_50]
                                // Breed/Cross/Mix: Ann_30 + Ann_22
                                // Breed/Cross/Mix: Ann_30 + Ann_50
                                // Breed/Cross/Mix: Ann_22 + Ann_50


// Pick which form of Elitism to use:
$Regular_Elitism = true; // All "Most Fit" are cloned back to the herd population
$OneThreeThreeSeven_Elitism = false; // The single most 1337 bot is cloned back to the herd population
    

// These variables are used as "globals" for convenience
// So um... don't delete them without rewriting GetFitnessScore()
$max_score = 4;   // An idealized "maximum" possible score
$max_score_variance = 0.001;  // Maximum allowable variance from the max score


/////////////////////////////////////////////////
// / Variables                                 //
/////////////////////////////////////////////////


/////////////////////////////////////////
// Begin the artificial selection      //
/////////////////////////////////////////

// While we haven't reached the $max_number_of_generations
while($current_generation <= $max_number_of_generations){
    
    // Create Initial population and fill any open spots in the herd
    for($i = count($herd); $i < $population_size; $i++){
        $herd[]['ann'] = NewRandomAnn([$inputs, $hidden, $outputs]);
    }

    ////////////////////////////////////////////////////////////////////////////////////////
    // �"� Check each ANN's performance with the fitness function and assign it a score �"� //
    // see( https://en.wikipedia.org/wiki/Fitness_function )                              //
    ////////////////////////////////////////////////////////////////////////////////////////
    foreach($herd as &$ann){
        $ann['score'] = GetFitnessScore($ann['ann']);
    }
    
    // Sort herd from most to least fit
    usort($herd, function ($a, $b) {
        return $b['score'] <=> $a['score'];
    });
    
    // Select the Most Fit for Crossbreeding
    $MostFit = array_slice($herd, 0, $breeding_population_size, true);    
    echo "G$current_generation" . " \t " . $herd[0]['score'] . " of $max_score" . PHP_EOL;

    // Clone the Most Fit for Crossbreeding
    foreach($MostFit as $id=>$data){
        $MostFit[$id] = fann_copy($MostFit[$id]['ann']);
    }

    ////////////////////////////////////////////////////////
    // �-' Cull herd specimens to free memory resources �-' //
    ////////////////////////////////////////////////////////
    // Cull the herd, clean out the stalls and lay fresh bedding
    $herd = Cull($herd, 'ann');


    /////////////////////////////////////////
    // Cross Breeding & Mutation           //
    /////////////////////////////////////////
    
    // Newly generated ANNs will be stored here temporarily
    $offspring = array();
    
    // To/For all our most fit specimens
    for($i = 0; $i < (count($MostFit)-1); $i++){

        // Select it's mates to breed/mix with
        for($k = $i+1; $k < (count($MostFit)); $k++){
            
            // And... whos the happy couple?
            $progenitor_a = $MostFit[$i];
            $progenitor_b = $MostFit[$k];
            
            ////////////////////////////////////////////////////////////////////////////
            // 🧪 Extract copies of their "DNA" / Chromosomes (connection weights) 🧪 //
            ////////////////////////////////////////////////////////////////////////////
            
            // Copy the DNA from parent A as the model to use for the descendant
            $descendant_chromosomes = fann_get_connection_array($progenitor_a); // array of FANN connection objects
        
            // Copy the DNA from parent B
            $progenitor_b_chromosomes = fann_get_connection_array($progenitor_b); // array of FANN connection objects
            
    
            //////////////////////////////////////////
            // 🧬 Gene splice the all the things 🧬 //
            //////////////////////////////////////////
            foreach($descendant_chromosomes as $id=>$connection_gene){
                
                ////////////////////////////////////
                // ♥ Mating / Genetic Crossover ♥ //
                ////////////////////////////////////
                // Flip a coin, if heads...
                if(random_int(0,1) == 1){
                    // Use progenitor_b_chromosomes instead of progenitor_a_chromosomes for this gene
                    $connection_gene->setWeight($progenitor_b_chromosomes[$id]->getWeight());
                }
                                
                //////////////////////////////
                // �� Mutate Chromosomes �� //
                //////////////////////////////
                $Mutate_Chromosomes = random_int(1, 100); // Random number between 1 & 100 
                
                // Compute the probability that the gene mutated
                $Mutate_Chromosomes = $Mutate_Chromosomes<=$probability_of_mutation*100;
                
                // If the gene mutated
                if($Mutate_Chromosomes == true){
                
                    // Compute the magnitude of the mutation/variance
                    $mutation = random_int($min_mutation, $max_mutation - 1) 
                              + (random_int(0, PHP_INT_MAX - 1) / PHP_INT_MAX );
                    
                    // Apply the mutation to the weight of the connection gene
                    $connection_gene->setWeight($connection_gene->getWeight() + $mutation);
                }
                                
            }

            ////////////////////////////////////////
            // �'� A new descendant ANN is born �'� //
            ////////////////////////////////////////
            $descendant = NewRandomAnn([$inputs, $hidden, $outputs]);
            fann_set_weight_array($descendant, $descendant_chromosomes);

            // Add it to the pool of offspring
            $offspring[] = $descendant;
            
        } // / Select it's mates to breed/mix with
    } // / To/For all our most fit specimens
    
    
    ////////////////////////////////////////////////////
    // Move specimens back in to the herd population  //
    ////////////////////////////////////////////////////
    
    // Elitism - see( https://en.wikipedia.org/wiki/Genetic_algorithm#Elitism )
    // Regular #Elitism
    if($Regular_Elitism == true){
        // Move clones of all the Most Fit into the herd
        foreach($MostFit as $ann){
            $herd[]['ann'] = fann_copy($ann);
        } 
    }
    
    // 1337 #Elitism
    if($OneThreeThreeSeven_Elitism == true){
        // Move a clone of only the best Most Fit into the herd
        $herd[]['ann'] = fann_copy($MostFit[0]);
    }
    
    // Move a clone of all the new offspring into the herd
    foreach($offspring as $ann){
        $herd[]['ann'] = fann_copy($ann);
    }
    
    // Increment the generation counter
    $current_generation++; 

    // Check if we are going to exceed the $max_number_of_generations
    if($current_generation >= $max_number_of_generations){
        echo PHP_EOL . "Maximum number of generations ($max_number_of_generations) reached.\nSaving Most Fit ANN." . PHP_EOL;
        SaveAnn($MostFit[0], 'Population', GetFitnessScore($MostFit[0]) ."_test"); // Save it
        die("Ending Program."  . PHP_EOL); // End Program
    }
    
    ////////////////////////////////////////////////////////////////////////////
    // �-' Cull unnecessary specimens from the lab to free memory resources �-' //
    ////////////////////////////////////////////////////////////////////////////
    $MostFit = Cull($MostFit); // Cull the MostFit    
    $offspring = Cull($offspring); // Cull the Offspring
    
} // / While we haven't reached the $max_number_of_generations

/*
Sample Output:
php genetic_neuro_evolution.php
G0       1 of 4
G1       2.99999953918 of 4
G2       3 of 4
G3       Most Fit: 3.9999999999917 Saved!
Ending Program.
*/
?>

 

You can find a copy of this code over on GitHub here:

https://github.com/geekgirljoy/php-fann/blob/master/examples/genetic_neuro__evolution/genetic_neuro_evolution.php

Frankly.. I can’t think of a better song to end this post on than “Do the Evolution” by Pearl Jam.


So… if you like free content like this and or simply admire me and my clones then please consider supporting me through Patreon for as little as $1.

But if all you can do is Like, Share, Comment and Subscribe, well… that’s cool too!

Much Love,

~Joy