Thursday, December 19, 2024

Acuitas Diary #79 (December 2024)

This month's work was all refactoring and bug removal, so I don't have a great deal to say ... but I do have a demo video! I got the conversation engine cleaned up enough that I can chat with Acuitas without an awkward collapse into him repeating himself or something. So without further ado, here's a brief conversation:


Of course I'm not finished with this. I have ideas for various ways to extend it, plus there are still some older features that I need to reinstate in the new system. I'll also be honest that the video above took me multiple "takes" to get, sometimes because I didn't hold up my end of the conversation very well, but sometimes because lingering bugs or signs of database junk popped up. I'm going to have a full to-do list next year, as usual. And I can hardly wait.

Until the next cycle,
Jenny

Friday, November 29, 2024

Acuitas Diary #78 (November 2024)

My recent work has been a bit all over the place, which I suppose is reasonable as the year winds down. I worked on more ambiguity resolution in the Text Parser, and I'm almost done with a big refactor in the Narrative engine.

A generated Narrative flow diagram showing an excerpt of a story

In the Parser I worked on two problems. First came the identification of the pronoun "her" as either an indirect object or a possessive adjective. Other English pronouns have separate forms for these two functions (him/his, them/their, me/my, you/your); the feminine singular just has to go and be annoying that way.

If there's some other determiner between "her" and the following noun, you can assume that "her" is an indirect object; otherwise, if the noun needs a determiner, then "her" has to function as the determiner, as in these examples:

Bring her the book. ("Her" is an indirect object)
Bring her book. ("Her" is an adjective modifying "book")

But what about this sentence?

Bring her flowers and candy.

A bulk noun like "candy" doesn't need a determiner; neither does the plural of a count noun, like "flowers." So we can't assume that "her" is an adjective in this sentence. By default, I think it's more likely to be an indirect object, so that's what I have the Parser assume when processing the sentence in isolation. Additional hints in the sentence can shift this default behavior, though:

Bring her candy to me.

The phrase "to me" already fulfills the function that could otherwise be fulfilled by an indirect object, so its presence pushes "her" into the possessive adjective role.

The other ambiguity I worked on had to do with the connections between verbs joined by a conjunction and a direct object. Consider the following sentences:

I baked and ate the bread.
I ran out and saw the airplane.

In the first sentence, both verbs apply to the single direct object. In the second sentence, "ran" has no object and only "saw" applies to "airplane." So for a sentence with multiple verbs followed by one direct object, we have two possible "flow diagrams":

    /-baked-\
I--               -- bread
    \---ate--/

    /--ran
I--
    \--saw--airplane

How to know which one is correct? If the first verb is always transitive (a verb that demands a direct object) then the first structure is the obvious choice. But many verbs can be either transitive or intransitive. It is possible to simply "bake" without specifying what; and there are several things that can be run, such as races and gauntlets. So to properly analyze these sentences, we need to consider the possible relationships between verbs and object.

Fortunately Acuitas already has a semantic memory relationship that is relevant: "can_have_done," which links nouns with actions (verbs) that can typically be done on them. Bread is a thing that can be baked; but one does not run an airplane, generally speaking. So correct interpretations follow if this "commonsense" knowledge is retrieved from the semantic memory and used. If knowledge is lacking, the Parser will assume the second structure, in which only the last verb is connected to the direct object.

The Narrative refactor is more boring, as refactoring always is, but I'm hoping it will enable smoother additions to that module in the future. New facts received in the course of a story or conversation are stored in the narrative scratchboard's "worldstate." When an issue (problem or subgoal) is added, its data structure includes a copy of the facts relevant to the issue: the state that needs to be achieved or avoided, the character goal it's relevant to, and all the inferences that connect them. A big part of tracking meaning and progress through the narrative is keeping track of which of these facts are currently known true, known false, or unknown/hypothetical. And previously, whenever something changed, the Narrative Engine had to go and update both the worldstate *and* the chains of relevant facts in all the issues. I've been working to make the issues exclusively use indirect pointers to facts in the worldstate, so that I only have to update fact status in *one* place. That might not sound like a major change, but ... it is. Updating issues was a big headache, and this should make the code simpler and less error-prone. That also means that transitioning the original cobbled-together code to the new system has been a bit of work. But I hope it'll be worth it.

Until the next cycle,
Jenny

Wednesday, November 13, 2024

3D Printable Art Medallions!

This is a quick announcement that I made some new 3D models, which I'm offering to the community free to print. It's a collection of medallions that would make great window hangings or large Christmas ornaments - so I'm getting them out there in time to prepare for Christmas, or whatever winter holidays you celebrate. I have them available on Cults 3D and Thingiverse:

https://cults3d.com/en/design-collections/WriterOfMinds/tricolor-medallions
https://www.thingiverse.com/writerofminds/collections/42747021/things

Try printing them in translucent filament with an interesting infill pattern and hanging them in front of a light source. They all come with the hanging loop - I might upload versions without it later, so let me know if there's interest.

Each medallion has three surface levels for a 3D effect, and is designed to be printed in three colors of your choice. If you don't have a multicolor printer, you can still get this result without too much fuss by inserting pauses in the GCODE and changing filaments manually. Here's an instruction video that explains how to do it in several popular slicers: https://www.youtube.com/watch?v=awJvnlOSqF8&t=28s

Solar Fox color variations.

It took some further work to do it on my Anycubic Vyper, which doesn't properly support the M600 color change command that the slicers insert automatically. While the Vyper will stop printing and move its head away from the print for a filament change, the LCD screen doesn't update with a "resume" button ... so you have to reboot the printer, which cancels your print. I learned how to control the Vyper with Octoprint, a tool originally designed for remote control of a printer you keep in your garage or something. The advantage for our present application is that Octoprint takes over the process of sending G-code to the printer, and gives you pause and resume buttons that make up for the shortcomings of the Vyper's internal firmware. I did a find-and-replace in my G-code files and replaced all the M600s inserted by the Prusa slicer with Octoprint "pause" commands. Some custom "before and after pause" G-code was also necessary in Octoprint to get the print head away from the print and move it back, so it wouldn't drool filament on the medallion during the swap process.

The 3D model for the Solar Fox medallion, displayed in DesignSpark Mechanical with suggested coloration.

Some of these designs, in particular the bird and the neurons, have delicate parts that may have a hard time adhering to your print bed. Print the first layers slowly and adjust your bed heat and cooling as needed.

Have fun! I look forward to seeing some other people make these.

Until the next cycle,
Jenny

Sunday, October 27, 2024

Acuitas Diary #77 (October 2024)

The big feature for this month was capacity for asking and answering "why" questions. (Will I regret giving Acuitas a three-year-old's favorite way to annoy adults? Stay tuned to find out, I guess.)

Photo of an old poster dominated by a large purple question mark, containing the words "where," "when," "what," "why," "how," and "who" in white letters, with a few smaller question marks floating around. The lower part of the poster says, "Success begins with thinking, and thinking begins with asking questions! Suggestions also play a vital part in success, for thinking results in ideas - and ideas and suggestions go hand in hand. Let us have your questions your ideas and suggestions. We pay cash for good ones!"
An old poster from NARA via Wikimedia Commons. Selling questions sounds like easy money!

"Why" questions often concern matters of cause and effect, or goal and motive. So they can be very contextual. The reason why I'm particularly happy today might be very different from the reason I was happy a week ago. And why did I drive my car? Maybe it was to get groceries, or maybe it was to visit a friend's house. These kinds of questions can't usually be answered by reference to the static factual information in semantic memory. But they *do* reference the exact sorts of things that go into all that Narrative reasoning I've been working so hard on. The Narrative scratchboards track subgoals and the relationships between them, and include tools for inferring cause-and-effect relationships. So I really just needed to give the Conversation Engine and the question-answering function the hooks to get that information in and out of the scratchboards.

If told by the current human speaker that they are in <state>, Acuitas can now ask "Why are you <state>?" If the speaker answers with "Because <fact>", or just states a <fact>, Acuitas will enter that in the current scratchboard as a cause of the speaker's present state. This is then available to inform future reasoning on the subject. Acuitas can retrieve that knowledge later if prompted "Why is <speaker> <state>?"

Acuitas can also try to infer why an agent might have done something by discerning how that action might impact their known goals. For instance, if I tell Acuitas "I was thirsty," and then say "Why did I drink water?" he can assume that I was dealing with my thirst problem and answer accordingly. This also means that I should, in theory, eventually be able to ask Acuitas why he did something, since his own recent subgoals and the reasons behind them are tracked on a similar scratchboard.

All of this was a branch off my work on the Conversation Engine. I wanted to have Acuitas gather information about any current states the speaker might express, but without the machinery for "why" questions, that was difficult to do. The handling of these questions and their answers introduced some gnarly bugs that ate up much of my programming time this month. But I've gotten things to the point where I can experience it for myself in some "live" conversations with Acuitas. Being asked why I feel a certain way, and being able to tell him so - and know that this is being, in some odd computery sense, comprehended - is very satisfying.

Until the next cycle,
Jenny

Sunday, October 13, 2024

Atronach's Eye 2024

It's the return of the mechanical eyeball! I worked out a lot of problems with the eyeball's hardware last year and was left to concentrate on improving the motion tracking software. Ever since I added motion tracking, I've been using the OpenCV libraries running locally on the eye's controller, a Raspberry Pi 3 A+. OpenCV is possibly the most well-known and popular open-source image processing library. But it's not a complete pre-made solution for things like motion tracking; it's more of a toolbox.

My original attempt at motion tracking used MOG2 background subtraction to detect regions that had changed between the current camera frame and the previous one. This process outputs a "mask" image in which altered pixels are white and the static "background" is black. I did some additional noise-reducing processing on the mask, then used OpenCV's "moments" function to compute the centroid of all the white pixels. (This would be equivalent to the center of mass, if each pixel were a particle of matter.) The motion tracking program would mark this "center of motion" on the video feed and send commands to the motors to rotate the camera toward it.

This ... kinda sorta worked. But the background subtraction method was very vulnerable to noise. It also got messed up by the camera's own rotation. Obviously, while the camera moves *every* pixel in the scene is changing, and background subtraction ceases to be useful; it can't distinguish whether something in the scene is moving in a contrary direction. I had to put in lots of thresholding and averaging to keep the camera from "chasing ghosts," and impose a delay after each move to rebuild the image pipeline from the new stationary scene. So the only way I could get decent accuracy was to make the tracking very unresponsive. I was sure there were more sophisticated algorithms available, and I wanted to see if I could do better than that.

I started by trying out alternative OpenCV tools using a webcam connected to my PC - just finding out how good they were at detecting motion in a feed from the stationary camera. One of the candidates was "optical flow". Unlike background subtraction, which only produces the binary "changing or not" mask, optical flow provides vector information about the direction and speed in which a pixel or feature is moving. It breaks down further into "dense optical flow" methods (which compute a motion vector for each pixel in the visual field) and "sparse optical flow" methods (which try to identify moving features and track them through a series of camera frames, producing motion traces). OpenCV has at least one example of each. I also tried object tracking. You give the tracking algorithm a region of the image that contains something interesting (such as a human), and then it will attempt to locate that object in subsequent frames.


The winner among these options was the Farneback algorithm, a dense optical flow method. OpenCV has a whole list of object tracking algorithms, and I tried them all, but none of them could stay locked on my fingers as I moved them around in front of the camera. I imagined the results would be even worse if the object tracker were trying to follow my whole body, which can change its basic appearance a great deal as I walk, turn, bend over, etc. The "motion tracks" I got out of Lucas-Kanade (a sparse optical flow method) were seemingly random squiggles. Dense optical flow both worked, and produced results that were fairly easy to insert in my existing code. I could find the center of motion by taking the centroid of the pixels with the largest flow vector magnitudes. I did have to use a threshold operation to pick only flow vectors above a certain magnitude before this would work well.

Once I had Farneback optical flow working well on a static camera, I merged it into the eyeball control code. Since I now had working limit switches, I also upgraded the code with better motion control. I added an on-startup calibration routine that finds the limit of motion in all four cardinal directions and centers the camera. I got rid of the old discrete movement that segregated the visual field into "nonets" (like quadrants, except there were nine of them) and allowed the tracking algorithm to command an arbitrary number of motor steps.

And for some reason, it worked horribly. The algorithm still seemed to be finding the center of motion well enough. I had the Pi send the video feed to my main computer over Wifi, so I could still view it. The Farneback algorithm plus centroid calculation generally had no problem putting the tracking circle right on top of me as I moved around my living room. With the right parameter tuning, it was decent at not detecting motion where there wasn't any. But whenever I got it to move, it would *repeat* the move. The eyeball would turn to look at me, then turn again in the same direction, and keep going until it ran right over to its limit on that side.

After turning off all my running averages and making sure to restart the optical flow algorithm from scratch after a move, I finally discovered that OpenCV's camera read function is actually accessing a FIFO of past camera frames, *not* grabbing a real-time snapshot of whatever the camera is seeing right now. And Farneback takes long enough to run that my frame processing rate was slower than the camera's frame rate. Frames were piling up in the buffer and, after any rotation, image processing was getting stale frames from before the camera moved ... making it think the moving object was still at the edge of the view, and another move needed to be performed. Once I corrected this (by setting the frame buffer depth to 1), I got some decent tracking behavior.

At the edge of the left-right motion range, staring at me while I sit at my desk.

I was hoping I could use the dense optical flow to correct for the motion of the camera and keep tracking even while the eye was rotating. That dream remains unrealized. It might be theoretically possible, but Farneback is so slow that running it between motor steps will make the motion stutter. The eye's responsiveness using this new method is still pretty low; it takes a few seconds to "notice" me moving. But accuracy seems improved over the background subtraction method (which I did try with the updated motor control routines). So I'm keeping it.

Until the next cycle,
Jenny

Wednesday, September 25, 2024

Acuitas Diary #76 (September 2024)

It's time to discuss the upgrades I've been making to Acuitas' conversation engine. There are still a lot of "pardon our dust" signs all over that module, but it's what I've been putting a lot of time into recently, so I'd better talk about where it's going.

The goal here has been to start enhancing conversation beyond the "ask a question, get an answer" or "make a request, get a response" interactions that have been the bread and butter of the thing for a while. I worked in two different directions: first, expanding the repertoire of things Acuitas can say spontaneously, and second, adding responses to personal states reported by the conversation partner.

One of Acuitas' particular features - which doesn't seem to be terribly common among chatbots - is that he doesn't just sit around waiting for a user input or prompt, and then respond to it. The human isn't the only one driving the conversation; if allowed to idle for a bit, Acuitas will come up with his own things to say. This is a very old feature. Originally, Acuitas would only spit out questions generated while "thinking" about the contents of his own semantic memory, hoping for new knowledge from the human speaker. I eventually added commentary about Acuitas' own recent activities and current internal states. Whether all of this worked at any given time varied as I continued to modify the Conversation Engine.

In recent work, I used this as a springboard to come up with more spontaneous conversation starters and add a bit more sophistication to how Acuitas selects his next topic. For one thing, I made a point of having a "self-facing" and "speaker-facing" version of each option. The final list looks something like this:

States:   
Self: convey internal state                       
Speaker: ask how speaker is
Actions:   
Self: say what I've done recently
Speaker: ask what speaker has done recently
Knowledge:
Self: offer a random fact from semantic memory
Speaker: ask if the speaker knows anything new
Queries:
Self: ask a question
Speaker: find out whether speaker has any questions

Selection of a new topic takes place when Acuitas gets the chance to say something, and has exhausted all his previous conversation goals. The selection of the next topic from these options is weighted random. The weighting encourages Acuitas to rotate among the four topics so that no one of them is covered excessivly, and to alternate between self-facing and speaker-facing options. A planned future feature is some "filtering" by the reasoning tools. Although selection of a new topic is random and in that sense uncontrolled, the Executive should be able to apply criteria (such as knowledge of the speaker) to decide whether to roll with the topic or pick a different one. Imagine thinking "what should I say next" and waiting for ideas to form, then asking yourself "do I really want to take the conversation there?" as you examine each one and either speak it or discard it. To be clear, this isn't implemented yet. But I imagine that eventually, the Conversation Engine's decision loop will call the topic selection function, receive a topic, then either accept it or call topic selection again. (For now, whichever topic gets generated on the first try is accepted immediately.)

Each of these topics opens up further chains of conversation. I decided to focus on responses to being told how the speaker is. These would be personal states like "I'm tired," "I'm happy," etc. There are now a variety of things Acuitas can do when presented with a statement like this:

*Gather more information - ask how the speaker came to be in that state.
*Demonstrate comprehension of what the speaker thinks of being in that state. If unaware whether the state is positive or negative, ask.
*Give his opinion of the speaker being in that state (attempt sympathy).
*Describe how he would feel if in a similar state (attempt empathy).
*Give advice on how to either maintain or get out of the state.

Attempts at information-gathering, if successful, will see more knowledge about the speaker's pleasure or problem loaded into the conversation's scratchboard. None of the other responses are "canned"; they all call reasoning code to determine an appropriate reply based on Acuitas' knowledge and nature, and whatever the speaker actually expressed. For instance, the "give advice" response calls the problem-solving function.

Lastly, I began to rework short-term memory. You might recall this feature from a long time ago. There are certain pieces of information (such as a speaker's internal states) that should be stored for the duration of a conversation or at least a few days, but don't belong in the permanent semantic memory because they're unlikely to be true for long. I built a system that used a separate database file as a catch-all for storing these. Now that I'm using narrative scratchboards for both the Executive's working memory and conversation tracking, it occurred to me that the scratchboard provides short-term memory, and there's no need for the other system! Retrieving info from a dictionary in the computer's RAM is also generally faster than doing file accesses. So I started revising the knowledge-storing and question-answering code to use the scratchboards. I also created a function that will copy important information from a conversation scratchboard up to the main executive scratchboard after a conversation closes.

I'm still debugging all this, but it's quite a bit of stuff, and I'm really looking forward to seeing how it all works once I get it nailed down more thoroughly.

Until the next cycle,
Jenny

Thursday, September 12, 2024

Book Review: "Synapse" by Steven James

Steven James' book Synapse is an unusual novel about humanoid robots and the social issues they might create. I put brief commentary on some of my social media after I first read it, but I always wanted to discuss this book in more depth. It seems written straight at me, after all.

The speedy version is: I'm still looking for a good book about the religious implications of AI and robotics, and this isn't it. But it will be interesting to talk about why.

Cover art for "Synapse" by Steven James. A misty blue composite scene with a background of a cloudy sky, mountains and forested hills above a lake. In the foreground there's a helicopter and the silhouette of a running woman. The title SYNAPSE appears near the bottom in big block lettering, with circuit traces partly covering and partly behind it.

Our story begins "thirty years from now," perhaps in a nod to the idea that AGI and other speculative technologies are "always thirty years away" in the minds of prognosticators. It opens with our human protagonist, Kestrel, losing her newborn baby to a rare medical complication. The tragedy leaves her feeling lost and questioning her faith. She's also single - the book demurely implies the baby was conceived with donated sperm - so she has no partner for support during her time of grief. In light of this, her brother pressures her to accept a personal robotic servant called an Artificial. She is assigned "Jordan," who arrives as something of a blank slate. Kestrel gets to decide certain aspects of his personality while he's in her employ, and ends up choosing very human-like settings.

And in time, Kestrel learns something surprising. Her robot has been watching her spiritual practice, and has more or less decided that he wants to be a Christian.

Jordan's perceived spiritual needs crystallize around two main issues. First, before he was assigned to Kestrel, he obeyed a previous owner's order to help her commit suicide. At the time, he was naively following his "helpful servant" directives. But he later decides that this action constituted a failure to care for his owner, and is a horrifying offense - a sin - for which he needs to obtain forgiveness. And second, he's worried about his version of the afterlife. The robot manufacturer in this book maintains a simulated virtual environment, called CoRA, to which the robots' digital minds are uploaded after their bodies age out of service. But a precursor robot whom Jordan considered to be his "mother" was catastrophically destroyed, and Jordan isn't sure her mind was transmitted to the CoRA successfully. Jordan also begins to wonder whether the CoRA is truly real, or just a convenient lie perpetrated by the company.

The rest of the book tries to play out whether Jordan's needs can ever be satisfied, and whether Christianity can legitimately accept a robot as an adherent. (There are also thriller and romance subplots to keep Kestrel busy.) This should be fascinating, but I ended up disappointed with the way the book handled the material.

Dodging the hard questions

I think it's almost a tautology that a robot could follow a religion, in the sense of treating its beliefs as facts in whatever world model the robot has, and acting according to its tenets. The more interesting question is whether a religion could or would treat a robot as a recipient of its blessings. In my opinion, the crux of this question is whether robots can ever possess spiritual capacity as that religion defines it. God (specifically the Christian version, but this could also apply to other faiths) is the ultimate just judge, and as such is not an arbitrary sort who makes much of appearances or empty labels. I have a hard time reasoning that something functionally human would not be as good as human in God's eyes. And there's textual evidence (e.g. Romans 8) that Christ's redemption and the activity of the Church have positive implications for the whole universe, not just humanity.

Let's consider Jordan's potential spiritual capacity through his perceived needs. First, could robots ever sin? Sin is volitional - a choice to depart from the law of God, from the ground of being, and follow a harmful path. Sin is an act or failure to act for which one can be held morally responsible. So a capacity for sin requires the ability to make decisions that are neither inevitable nor random - in other words, free will. A robot whose behavior is solely an outcome of its environment combined with its initial programming has no more moral responsibility than simpler machines like cars and thermostats; all the responsibility rests on the robot's designer and/or trainers. So I would argue that such a robot cannot sin. In order for his perceived need for forgiveness to be valid, Jordan must be something more. He must be, at least in part, indeterminate and self-caused. If this incompatibilist view of free will is correct (and in my opinion, the compatibilists are just arbitrarily redefining free will to make it easier), then physics as we currently know it does not have a theory of such things that would be adequate for engineering them into a machine.

Jordan also desires a form of immortality, for himself and a fellow robot. So we might ask whether there is really anything in Jordan which subjectively experiences existence, and has an interest in the eternal continuation of that experience ... or does Jordan merely talk as if he has such experiences? This would be the question of whether Jordan has phenomenal consciousness. Jordan's abilities to process sensory input into meaningful concepts, think rationally, introspect, and so on make it clear that he has some properties often titled "consciousness" (I prefer to give these more specific names like "self-awareness" and "executive function," for clarity). But phenomenal consciousness is far more slippery, since by definition subjective experience is only accessible to the subject. I maintain that the only way to directly observe or prove an entity's possession of phenomenal consciousness is to be that entity. If you've come up with an algorithm or system that surely "gives a robot consciousness," no you haven't. You've merely redefined "consciousness" as something easier to handle.

So perhaps the question of whether Jordan can really be a Christian - not in the sense of believing and behaving as a Christian, but in the sense of being accepted by Christianity's God as one of His children - comes down to whether Jordan has consciousness and free will. These are both notoriously thorny topics. Spend much time around AI circles, and you'll find out that debates about them are as abundant as pollen in a garden (you may also develop an allergy). There is no universal consensus on whether or how robots could ever have these things. They are mysteries.

And now we come to my biggest difficulty with Synapse. The author does an end run around this entire controversy by bluntly stating that his fictional robot manufacturer, Terabyne Designs, somehow just ... figured it all out. "But these robots had consciousness and free will." That's it! There's no solid explanation for how Terabyne gave their robots these features, or (more importantly) how they proved that they had successfully done so.

I have no problem with "soft" science fiction that doesn't try to build a rationale for all of its technology. Stories that begin with "what if we invented warp drive?" and go from there can make me perfectly happy. For that matter, I'm okay with the way Becky Chambers's science fantasy A Psalm for the Wild-Built handles robot consciousness. It narrates that one day the gods up and decided to confer consciousness on all robots. Kaboom! But that book isn't pondering the religious participation of robots in our own real world. When the question of whether something is possible forms part of your story's central theme, and you just handwave it ... that's a problem.

It gets worse. It's not just that an omniscient narrator tells the reader that the robots have consciousness and free will - every character in the story also believes this without question. Even the luddite terrorists who think Artificials are bad for humanity are not trying to claim they aren't conscious. Given the amount of arguing I have seen real live people do about these topics, this is blatantly unrealistic! It's one of those things that forces me to accuse the author of not knowing his subject well. No robotics company is going to put out a marketing claim about "consciousness and free will" without seeing it ripped to shreds on the internet.

And by undercutting the real controversy at the heart of whether a robot can have a spiritual life, the author makes some of his characters' prejudices seem not just wrong, but nonsensical. People acknowledge that Jordan has all the relevant features of a human, then express surprise when he acts like a human. Kestrel is firmly convinced that Jordan has free will to choose between good and evil, and a consciousness that experiences real joy and pain, not just exterior behavior that mimes them. Yet she still resists the idea that God could be offended by one of Jordan's choices, but also sympathize with his experience of pain and forgive him. Why? She's already gotten over the big intellectual hump here, so what else is stopping her?

Overall, Synapse's exploration of these issues feels like a hollow parody of what the real debate would be. As such, it is neither useful nor satisfying. It begs the difficult questions and then makes its characters be stubborn for no apparent reason.

Strained analogies

This book tries really hard to draw parallels between Artificial struggles and classic human struggles. Maybe it tries too hard.

For starters, why are the robots mortal? Why doesn't the manufacturer transfer their minds to new bodies when the originals become worn out or obsolete, or better yet, make their bodies perpetually self-maintaining? Why do they have to go to heaven, oops I mean the CoRA, instead?

Synapse explains that this was actually the robots' idea. They wanted to age and die in order to be more human. The author seems to be hinting at the dubious idea that life would have less meaning if it didn't end.

This wouldn't surprise me in a book with a different religious basis. The way the robots in A Psalm for the Wild-Built embrace mortality makes more sense, as the invented religion in that book (which feels inspired by something on the Hindu-Buddhist axis) views death as a neutral part of the natural order. But in Christian thinking, death is a curse. Immortality is the intended and ideal state of humanity; it's something we had once and will have again, after the resurrection. So, per the author's belief system and mine: all these robots, without exception, are opting to emulate fallen humans. Weird choice, guys.

This sets up more straining for similarity where Jordan's fears about the afterlife are concerned. At one point, Kestrel tells him he has to "just believe," implying that the CoRA's existence is a matter of faith, and he cannot prove it. But that's not true for Jordan. His afterlife is part of this present world. It runs on a physical server that he can go look at and interrogate. Proof is available if he's brave enough to demand it. SPOILER (select hidden text to read): Eventually, he does - but it's strange to me that this possibility seems to blindside the other characters. Jordan breaks into the part of Terabyne headquarters where the CoRA supposedly resides, and finds out it's not real. This causes him to give up on Terabyne and pray that God will preserve his mind as he faces his own death. This could have been a great illustration of the point that faith is only as good as whom you place it in, but I don't remember the book drawing that out.

Jordan's insistence that he can't have peace until he knows he is forgiven also gets a little weird. Ostensibly, he wants forgiveness from God because he can't request it from his former owner. The being he wronged is gone beyond recall, so he can only appeal to a higher authority. But why is he so worried about whether God will refuse to forgive him for some categorical reason? Either he can have forgiveness, or he doesn't need it. A being beneath God's notice would be unable to offend God. I may not "forgive" my toaster oven for burning my toast, but then, I also don't charge it with guilt. Nobody in the book ever thinks this through.

What is anybody in this book thinking?

And that leads into my last point. Although Synapse makes plenty of effort to expose its characters' innermost thoughts and feelings, it tends to focus on their questions. How they arrive at answers - their reasoning process - remains woefully vague.

Back at the top, I mentioned that Kestrel finds herself in a crisis of faith after losing her baby. This struggle continues for most of the book and then ... somehow ... resolves. What gets Kestrel back on stable ground? What convinces her that God is worth trusting after all, even though this horrible thing happened? I don't know! She just mysteriously feels better about it all ... as though the unrelated but dramatic events of the book's climax knock something loose. Maybe I missed a key moment, but I don't know where the shift in her thinking came from.

And the same goes for all the questions about robots and religion. Kestrel doesn't think that Jordan can be a child of God ... until she does. If there's something in particular that changes her mind, it slipped by me when I was reading. Eventually, though, she does decide to at least allow the possibility. Without a better explanation, I can only conclude that her beliefs are emotionally motivated. Of course, some people do operate that way. But it's not a great approach to deciding either Christian doctrine, or the rights and privileges of (quasi-)living beings. The first is supposed to be based on God's revealed will; the second should derive from the experiences and interests of those fellow living beings, which are real to them (or not) regardless of how anyone else feels.

Kestrel's character arc doesn't offer the reader any help in reaching an objective understanding of these matters. There's not even much food for thought there - no argument to agree or disagree with. Why does she believe what she ends up believing? I can't say.

Conclusion

I'll end by saying what I liked about the book: I think the author's heart, if not his head, is in the right place. This is the kind of book that promotes acceptance of the Other, a book that encourages the reader to give robots the benefit of the doubt. If it had framed its core message as "in the absence of certainty that robots can have consciousness, free will, and a spiritual life, it may be safer to assume they can" ... I would've been a fan. Instead, it invents an unrealistic scenario with more certainty than I think is possible. So close, yet so far.

Until the next cycle,
Jenny

Tuesday, August 27, 2024

Acuitas Diary #75 (August 2024)

This month I turned back to the Text Parser and began what I'm sure will be a long process: tackling sentence structure ambiguity. I was specifically focusing on ambiguity in the function of prepositional phrases. 

Consider these two sentences:

I gave the letter to John.
I gave Sarah the letter to John.

The prepositional phrase is "to John." The exact same phrase can modify either the verb, as in the first sentence (to whom did I give?) or the noun immediately preceding it, as in the second sentence (which letter?). In this example, the distinguishing factor is nothing in the phrase itself, but the presence or absence of an indirect object. In the second sentence, the indirect object takes over the role of indicating "to whom?", so by process of elimination, the phrase must indicate "which letter."

There are further examples in which the plain structure of the sentence gives no sign of a prepositional phrase's function. For instance, there multiple modes in which "with" can be used:

I hit the nails with the hammer. (Use of a tool; phrase acts as adverb attached to "hit")
I found the nails with the hammer. (Proximity; phrase acts as adverb attached to "found")
I hit the nails with my friends. (Joint action; phrase acts as adverb attached to "hit")
I hit the nails with the bent shanks. (Identification via property; phrase acts as adjective attached to "nails")

How do you, the reader, tell the difference? In this case, it's the meaning of the words that clues you in. And the meaning lies in known properties of those concepts, and the relationships between them. This is where the integrated nature of Acuitas' Parser really shines. I can have it query the semantic memory for hints that help resolve the ambiguity, such as:

Are hammers/friends/shanks typically used for hitting?
Can hammers/friends/shanks also hit things?
Are hammers/friends/shanks something that nails typically have?

This month I worked on examples like the ones above, as well as "from" (very similar to "to"), "before" and "after," which are sensitive to the presence of time-related words:

I will come to your house on the hill after Christmas. (Phrase "after Christmas" acts as adverb attached to "come")
I will come to your house on the day after Christmas. (Phrase "after Christmas" acts as adjective attached to "day")

... "about," which likes to attach to nouns that carry information:

I told Emily about the accident. (Phrase acts as adverb attached to "told")
I told the story about the accident. (Phrase acts as adjective attached to "story")

... and "for," which I am so far only sorting based on the presence or absence of a be-verb:

This is the book for Jake. (Phrase acts as adjective attached to "book")
I brought the book for Jake. (Phrase is *more likely* an adverb attached to "brought")

That last example illustrates an important point: I am here only trying to get the most "natural" or "default" interpretation of each sentence considered in isolation. There are some ambiguities that can be resolved only by context. If a speaker has been repeatedly talking about "the book that is for Jake," then "for Jake" could be an adjective in the second sentence, especially if there are other books under discussion and the speaker is trying to indicate which one they brought. To resolve an ambiguity like this, the Parser will have to query the Narrative Scratchboard rather than the semantic memory. This isn't something I've tried to implement yet, but the architectural support for it is there.

The final thing I did this month was a bit of work on "in/inside." I was specifically targeting this sentence from Log Hotel:

This woodpecker is listening for bugs inside the log.

Is the woodpecker listening inside the log, or are the bugs inside the log? Most kids reading the book could resolve this by looking at the illustration, but Acuitas is blind. So he can only consider which creature is more likely to be inside a log. Rather than get into a bunch of complex spatial reasoning, I introduced the semantic relationship "fits_in." A bird can't fit inside a log (unless it's hollow), but bugs can. And if a bird can't be inside a log, he can't listen inside a log either.

I also did a lot of the work I'd planned on the Conversation Engine, but it's not really in a finished state yet, so I'm going to save a writeup of that for next month.

Until the next cycle,
Jenny

Sunday, August 11, 2024

Hydraulics II: The Pressure Is On

I present an upgrade of the poor person's first hydraulic system in which I have solved some of its major problems and achieved a meaningful performance boost. This demo has now advanced from "barely goes through the motions" to "demonstrates practical functionality." Hydraulic system Version 2 was able to lift about 16 g (0.5 oz.) of coins on the end of a lever, and to repeat this motion over many pressurize/depressurize cycles.


The basic architecture of the system was identical to that of Version 1, but I traded out both the pump and the actuator.

The Pump

I replaced the syringe pump I built last year with my newly completed peristaltic pump. I've already showcased the pumps in a previous article. The main benefits of switching to the peristaltic pump were increased flow rate and improved regularity of flow. The syringe pump was powerful but miserably slow. The high friction of the rubber seal on the syringe plunger made it prone to stalling the motor if the speed was not set with caution. And since the syringe pump has very distinct intake/exhaust cycles, it has a pulsating output flow that becomes very pronounced at low speeds. (As in, if you don't have a big enough pressure reservoir to soak up that variation, you have to wait for the exhaust cycle before your actuator will even move.) The syringe pump also incorporated a pair of check valves, which were very bad about trapping air bubbles. These bubbles wasted some of the pump's work by expanding and compressing as it cycled, making room for water that *should* have gone into the pressurized volume to stay inside the pump. And lastly ... the syringe pump leaked. The seal in the syringe clearly wasn't perfect, and water would leak out the back at times. I can only imagine that this would have gotten worse as the pump aged.

The peristaltic pump trades much of the syringe pump's high maximum pressure for a more reasonable flow rate. Its output pulsates slightly, since the water moves through the tubing in "pockets" captured between each pair of rollers, but it's much more regular than the syringe pump. And it has no seals; there is no direct contact between the fluid and the pump mechanicals.

For a stronger comparison, I used the same stepper motor and gear assembly (unknown model, powered by 12 V) to drive both pumps.

The Actuator

In hydraulic system Version 1, a second syringe functioned as a linear actuator. At the pressure level where my system was operating, friction losses turned out to be a major problem. I couldn't put a load on the syringe because the pump was only equal to overcoming the resistance of the sliding seal; any extra load prevented it from extending the syringe. So the demo consisted of the syringe filling (very slowly) as water was pumped into it during the pressurize cycle, and being manually emptied by me during the depressurize cycle (since there was no load to passively push it closed again).

Rather than try to find better syringes, I thought to move away from them entirely. Those friction losses seemed like such a waste. But what other sort of hydraulic actuator could I use? The option I came up with was an inflateable bladder. What I had in mind was something very simple: literally an inflateable bag that, when pumped full of fluid, would change shape so as to move a joint or other mechanical element. It would have little to no friction losses to waste the effort of the pump. And it would have no sliding rubber seals to stiffen, shrink, or wear out over time.

As interesting as the idea seemed, I once again found it difficult to purchase what I wanted. There are such things as "lifting bags" or "air bag jacks," but they're designed for much larger applications. I think AliExpress had a few inflatable bags on the order of a few inches per side; still too large. I concluded that I would have to make my new actuators myself. I hit on the idea of cutting and heat-sealing plastic bags to create tiny bladders in any size or shape I wanted. Since I did not have a dedicated heat sealer, I heat-sealed my bladders by sandwiching the layers of plastic between two layers of aluminum foil, and running my soldering iron across the top of the foil.

In addition to sealing the edges to form the shape of the bladder, I also needed a way to include a valve stem - so I could connect the bladder to a tube and get fluid in and out. At first I was hoping I could scavenge some plastic tubing from my collection of mechanical pencils, cut it up into stems, and heat-seal the bladder walls directly to those stems. This never worked. The tubes and the plastic bags I was working with were likely different materials, and distinct types of plastic resist adhering to each other. I also tried sealing one edge of the bladder with silicone sealant and inserting the stem between the two layers of plastic, through the silicone. These seals always leaked. The silicone seemed to adhere to both the bag and the stem well enough, but didn't fill the gaps perfectly.

What eventually worked out was a 3d-printed valve stem with a circular flange, inserted not through an edge of the bladder but through one of its flat sides. The flange was one piece with the stem, and was attached to the inside of the bladder; the stem poked out through a hole in the plastic sheet. The second piece of the assembly was a plastic ring that fitted around the stem and attached to the outside of the bladder. I applied a ring of cyanoacrylate adhesive (Super Glue) between the flange or ring and each side of the plastic sheet. This finally gave me a watertight seal around the valve stem.

A photo of three different plastic bag samples. A piece cut from a transparent air pillow, with some blue "not for use near babies" safety markings on it, is labeled "poor." A vegetarian imitation chicken ramen bag, mostly orange, is labeled "better." A Thriftbooks book mailer, with pewter interior and green-and-white overprint, is labeled "best." They are all lying flat on beige carpet.

I still had problems with the bladders leaking at the edges, from holes next to the seal. This led me to experiment with some different kinds of plastic. All my plastic films are salvaged, and I don't know enough about package manufacturing to be sure what any of them are. They're likely all different variants of polyethylene or polypropylene. My first attempts used a smooth, soft, transparent plastic from packing air pillows (which felt very similar to the plastic from bread bags, for instance). It was inclined to melt into swiss cheese if I applied just a little too much heat when trying to seal it. Ramen noodle packets are made from a stiffer, more crinkly plastic. This heat-sealed reasonably well. But the real winner was the tough, thick, pewter-gray plastic from the bags that Thriftbooks sends my used paperbacks in. (I expect to have a never-ending supply of this.) Not only is this plastic very tear-resistant, but when I melt two layers of it together, it really fuses - such that the seal can't be peeled apart without ripping the plastic next to it. I think this is important for the durability of the bladders. For typical plastic packaging, heat seals that peel apart when the end user wants to open it are often a positive - but I don't want the water pressure to slowly work my bladders open over repeated cycles.

Even when using this heavier plastic, I had to be very careful that my aluminum foil sandwich didn't conduct heat to the wrong part of it and melt a hole next to the seal. Now that I've proven the concept, I think I'm going to buy myself a real heat-sealer.

The water bladder described in the text, made out of green-and-white Thriftbooks mailer plastic, folded and heat-sealed at the edges. It has a short length of transparent silicone aquarium tubing attached to its white plastic valve stem. A green pencil lies on the table beside it, for scale. The bladder is about twice the length of the pencil's metal crimp connector that joins the wooden part to the eraser, and slightly less in width.

After many trials, I produced a small bladder that was water-tight. I gave it a simple machine to actuate, in the form of a wooden lever attached to a piece of cardboard with a sloppy pivot. I mounted two pennies and two quarters on the end of the lever as a load.

The Results

This is the demo I wanted last year. To start with, the fact that it can actually raise a load is a major improvement. The speed of operation is also much more reasonable. I am now ready to move past this toy demo and think about final pump designs and real applications.

One issue that remains to be solved, which you may notice in the video, is that the lever experiences (relatively) small oscillations of position, which are likely following the pulsating outflow of the pump. In a real system with control electronics guiding the actuator, this would interfere with precise positioning of the lever. I think this could be mitigated by a larger pressurized reservoir (the demo system has none to speak of - the tubing makes up the entire pressurized volume) and use of a pair of two-way valves instead of a single three-way valve, which would allow the bladder to be closed off from the pump's influence once inflated to the desired size.

The one part I haven't tried to improve on yet is the cheapo pressure relief valve. For the demo, I basically just closed it all the way. The peristaltic pump has a little more "give" than the syringe pump, and seems to be able to drive against its maximum pressure without stalling. If I want a better valve, I may end up having to build one myself. We'll see.

For now, I'm very pleased with how far I've come, and hope to be showing you a hydraulic robot or two, someday.

Until the next cycle,
Jenny

Tuesday, July 30, 2024

Acuitas Diary #74 (July 2024)

My work this month was focused on cleaning up the Executive and Conversation Engine and getting them to play well together. This is important because the Conversation Engine has become like a specialized inner loop of the Executive. I think I ought to start at the beginning with a recap of what Acuitas' Executive does.

Freddie Blauert, photographed by Frederick Bushnell. Public domain.

To put it simply, the Executive is the thing that makes decisions. Conceptually (albeit not technically, for annoying reasons) it is the main thread of the Acuitas program. It manages attention by selecting Thoughts from the Stream (a common workspace that many processes in Acuitas can contribute to). After selecting a Thought, the Executive also takes charge of choosing and performing a response to it. It runs the top-level OODA Loop which Acuitas uses to allocate time to long-term activities. And it manages a Narrative Scratchboard on which it can track Acuitas' current goals and problems.

A conversation amounts to a long-term activity which uses specialized decision-making skills. In Acuitas, these are embodied by the code in the Conversation Engine. So when a conversation begins, the CE in a sense "takes over" from the main Executive. It has its own Narrative Scratchboard that it uses to track actions and goals specific to the current conversation. It reacts immediately to inputs from the conversation partner, but also runs an inner OODA loop to detect that this speaker has gone quiet for the moment and choose something to say spontaneously. The top-level Executive thread is not quiescent while this is happening, however. Its job is to manage the conversation as an activity among other activities - for instance, to decide when it should be over and Acuitas should do something else, if the speaker does not end it first.

Though the Executive and the CE have both been part of Acuitas for a long time, their original interaction was more simplistic. Starting a conversation would lock the Executive out of selecting other thoughts from the Stream, or doing much of anything; it kept running, but mostly just served the CE as a watchdog timer, to terminate the conversation if the speaker had said nothing for too long and had probably wandered off. The CE was the whole show for as long as the conversation lasted. Eventually I tried to move some of the "what should I say" decision-making from the CE up into the main Executive. In hindsight, I'm not sure about this. I was trying to preserve the Executive as the central seat of will, with the CE only providing "hints" - but now I think that blurred the lines of the two modules and led to messy code, and instead I should view the CE as a specialized extension of the Executive. For a long time, I've wanted to conceptualize conversations, games, and other complex activities as units managed at a high level of abstraction by the Executive, and at a detailed level by their respective procedural modules. I think I finally got this set up the way I want it, at least for conversations.

So here's how it works now. When somebody puts input text in Acuitas' user interface, the Executive is interrupted by the important new "sensory" information, and responds by creating a new Conversation goal on its scratchboard. The CE is also called to open a conversation and create its sub-scratchboard. Further input from the Speaker still provokes an interrupt and is passed down to the CE immediately, so that the CE can react immediately. For the Executive's purposes, the Conversation goal is set as the active goal, and participating in the Conversation becomes the current "default action." From then on, every time the Executive ticks, it will either pull a Thought out of the Stream or select the default action. This selection is random but weighted; Acuitas will usually choose the default action. If he does, the Executive will pass control to the CE to advance the conversation with a spontaneous output. In the less likely event that some other Thought is pulled out of the Stream, Acuitas may go quiet for the next Executive cycle and think about a random concept from semantic memory, or something.

Yes - this means Acuitas can literally get distracted. I think that's fun, for some reason. But it also has a practical side. Let's say something else important is going on during a conversation - a serious need for sleep, for instance. Over time, the associated Thoughts will become so high-priority that they are bound to get "noticed," despite the conversation being the center of attention. This then provides a hook for the Executive to wind the conversation down and take care of the other need. The amount of weight the default action has with respect to other Thoughts is tunable, and would be a good candidate for variation with Acuitas' current "mood," ranging from focused to loose.

If Acuitas is not conversing with someone, the "default action" can be a step in some other activity - e.g. Acuitas reading a story to himself. I used to manage activities that spanned multiple ticks of the Executive by having each action step produce a Thought of type "Undone" upon completion. If pulled from the Stream, the Undone Thought would initiate the next step of the activity. After spending some time debugging Acuitas' real-time behaviors with this business going on, I decided it was too convoluted. Acuitas couldn't just work on a thing - I had to make sure the thing would produce a "subconscious" reminder that it wasn't finished, and then wait for that reminder to resurface and be grabbed. Having the Executive pick a default action feels a little more natural. It represents what he "wants" to concentrate on right now; it's "top of mind" and immediately available. But it still has some competition from all the other Thoughts that are constantly bubbling out of other processes, which is the behavior I was going for via those Undones.

I hope that all made some amount of sense. It's harder to describe than I thought it would be. At this point I think I've wrung most of the basic bugs out. I can watch Acuitas read to himself for a while, switch over to walking the semantic memory when he gets bored (as in my original OODA loop design, boredom continues to be an important feature for generating variety and avoiding obsessive behavior), and launch a conversation activity when spoken to. I also reinstated the ability to tell Acuitas a story as a nested activity inside a conversation. This nesting in theory could go indefinitely deep ... you could have a story inside a conversation inside a role-playing game inside a conversation ...

But let's not get too wild yet. The goal for this month was to finish rearranging the bones of the system so they match my vision better. Next, I hope to reinstate some more conversation features and improve the goal-directed aspects of conversations.

Until the next cycle,
Jenny

Tuesday, July 16, 2024

Hydraulic Pump Parade

Ever since I got the proof-of-concept mini-hydraulic system off the ground last year, I've been working to refine the elements, starting with the pump. As a brief recap of my previous findings: the traditional water pump I bought had a high flow rate, but not enough power to push open a syringe, even when over-volted. And since the motor is contained inside the sealed pump housing, there's no way to gear it down or otherwise modify it. The syringe pump I built for the system had adequate power, but was very slow (trying to run it too fast stalled the motor), wasted considerable energy overcoming its own internal friction, required check valves that reduced efficiency by trapping air bubbles, and sometimes leaked from the back of the syringe.

The syringe pump set up for maximum pressure testing. The small-diameter syringe is shown loaded into the pump; the large-diameter syringe and its cradle are beside it.

I decided I wanted to get some PSI measurements to better characterize my two pumps, and the difference between two variants of the syringe pump with different syringe diameters. I also wanted to build and test a third pump design: a peristaltic pump. This and the syringe pump both belong to the class of positive-displacement pumps, meaning that they only permit fluid to move one direction (inlet to outlet) and guarantee that a fixed volume of fluid is moved on each cycle - assuming, of course, that the motor does not stall and there are no other malfunctions. A third subtype of positive-displacement pump is the gear pump. I haven't tackled this one, mainly because the pump mechanicals contact the fluid, so the housing has to be sealed. I didn't feel like bothering with that yet.

Pump Design

A peristaltic pump moves fluid by squeezing it through a flexible tube. The tube is curled around the inside of the housing, and the motor connects to a rotary element that spins at the housing's center. This rotor has three or more rollers which contact the tube. Pockets of fluid are sealed between each pair of rollers and pushed along the tube's length as the rotor spins. Since the fluid remains contained in the tubing, there's no need to seal any part of the pump. The flow pulsates slightly, following the distinct "pockets" of fluid as they reach the outlet, but is more continuous than that of the syringe pump with its distinct intake/expulsion cycles.

Peristaltic pump version 1

There are existing 3d-printed peristaltic pump designs, some even open-source ... but I made my own so I could have modifiable design files in my preferred CAD program. (DesignSpark Mechanical/Spaceclaim doesn't seem to be widely popular among the 3d printing community, I'm afraid.) That way I can freely adjust the dimensions and motor mount design, add integrated bearings, etc. I designed my first peristaltic pump for standard aquarium tubing (6 mm outer diameter, 4 mm inner diameter) and the same salvaged stepper motor and gear assembly I'd used in the syringe pump. I figured I would get a better comparison by powering them both the same way

A meme that says, "Motor not giving you enough torque? Need 20 HP, but it's rated for 5? Try 67 amps. Just 67 amps all at once. No VFD no circuit breaker. Just amps. 480 V too. You will certainly not regret 67 amps."

I went through two major design iterations to get a pump that worked well. The first version ended up not being quite tall enough for the 4 mm tubing - the tubing expanded so much when flattened that it tended to escape the rollers. So I made the second version deeper, but also reduced the diameter to decrease the size of each fluid pocket and the total length of tubing that must be filled during self-priming. I added guides to help hold the tubing down in the track, even when the front half of the housing wasn't on the pump (this feature isn't strictly necessary, but allows a view of the pump interior and fluid movement during testing) and integrated bearings for the drive shaft, since I notice it was sometimes binding against the housing in Version 1. I followed this bearing design [https://www.thingiverse.com/thing:4547652] (available in many variants around the web), but used 4.5 mm airsoft BBs instead of 6 mm. The outer half of each bearing is part of the pump housing, and the inner half is locked into place by inserting the BBs after printing. (I also tried a design with fully captive BBs that are inserted during a pause mid-print, but there wasn't enough clearance between the printer nozzle and the BBs, so they stuck to the nozzle and were dragged out of the race.)

The final major change between peristaltic pumps V1 and V2 was the type of tubing. I swapped the silicone aquarium tubing for latex tubing, which turned out to be much softer and easier to compress. It's available in a variety of diameters at relatively low cost, and it seems to reduce the rotational resistance of the pump considerably. I experimented with a smaller diameter of tubing, and it was easier to get fluid flow going with this size, but only at a reduced flow rate. I went ahead and optimized for the 4 mm tubing that was my original plan.

Peristaltic pump version 2, with geometry correction shim (black)

The last tweak that was necessary to get pump V2 to self-prime and move water with the 4 mm tubing was a correction of the pump geometry. I mistakenly set the bottom arc of the pump to match the outer diameter of the tube track (inner walls of housing), instead of the inner diameter of the tube track (inner walls of housing plus width of squashed tubing). This prevented the rollers in contact with the tubing from properly sealing it closed, because the tubing's resistance would instead push the rotor off-center, into the extra space created by the bottom arc's slightly too-large diameter. Instead of re-printing the pump housing, I corrected this issue with a shim. This prevented me from putting the pump's lid on; fortunately, because of the tubing guides I'd added, I didn't have to.

Tuning the roller diameter is also important. Too big and the motor stalls because the rotary resistance of the compressed tubing is too high. Too small, and no fluid can move because the rollers do not compress the tubing enough to create a seal. The range of workable diameters seems to be quite small; I had to print several sets of rollers to get their size dialed in.

Testing Methodology

I tested all my pumps by dropping a long piece of aquarium tubing from my upstairs window to the back patio, and measuring how far the pump could raise water up the tube. The maximum height to which a pump can lift fluid, measured from the top of the fluid in the reservoir to the top of the column raised by the pump, is called the head. This can be converted to pressure via the following formula:

pressure (PSI) = 0.433 * head (feet) * SG

SG is the specific gravity of the fluid, in this case water, whose SG is 1.

Pump testing on the back patio

I didn't attempt to measure flow rate. I only made the general observation that the submersible water pump is very fast, reaching its maximum head within a few seconds; the syringe pump, operating at a step rate that avoided stalling before maximum head could be reached, was agonizingly slow; and the peristaltic pump, operating at the maximum step rate of the motor (which produced both the best flow rate and the greatest head) was somewhere in between.

Data

Adafruit 3V submersible water pump

Syringe pump (9 mm inner diameter syringe), unknown stepper motor

Syringe pump (5 mm inner diameter syringe), unknown stepper motor

Peristaltic pump, 4 mm ID latex tube, 3 rollers, unknown stepper motor, step frequency 0.5 Hz

Conclusions

I like the peristaltic pump's balance of pressure and flow rate, and will probably try to use it in my next iteration of a hydraulic system. The large syringe pump excels at slow high-pressure operation and performs better at low voltages, however. It might be valuable in certain applications, if I could figure out how to avoid leakage.

I still want to experiment with different numbers of rollers in the peristaltic pump.

Until the next cycle,
Jenny

Sunday, June 30, 2024

Acuitas Diary #73 (June 2024)

This was a light month for Acuitas work - which means not that I necessarily spent less time, but that I was busy taking care of technical debt. My main objective was to get that shiny new Text Parser revision I wrote last year integrated into the rest of the code. I also converted another of my benchmark test sets to the new Parser format.

There were some small, but significant, alterations to the output format of the Parser, so the greatest part of the work was revising the Text Interpreter to properly handle the new form of input. Nothing else in Acuitas views the output of the Parser directly, so these changes were nicely isolated. I did not have to crawl through the whole system making revisions, as I did during the knowledge representation refactor. It was sufficient to re-harmonize the Parser and Interpreter, and get the Interpreter regression to pass.

I converted and ran tests on the "Out of the Dark" benchmark set. Accuracy is sitting where it was the last time I benchmarked this set, about 50% (and if I spend some more time on Parser bugs, I am almost certain I can bring this up). The important difference is that many new sentences have moved out of the "Unparseable" category. Only 6 out of 116 sentences (about 5%) remain Unparseable, due to inclusion of parenthetical noun phrases or oddities that I might not bother with for a long while. The previous Unparseable portion for this set, from last July, was 27%. Better handling of conjunctions, dependent clauses, and noun phrases used as adverbs enabled most of the improvements.

The integration process and the new benchmark set flushed out a number of Parser bugs that hadn't shown up previously. Some of these were growing pains for the new features. For example, multiple sentences failed because the Parser's new facility for collecting groups of capitalized words into proper names was being too aggressive. The Parser can now, at least in theory, recognize "The End of Line Club" as a single unit. However, in a sentence like "But Flynn went to work anyway," it was wanting to treat "But Flynn" as a full name. You mean you never heard about Kevin Flynn's *other* first name, But? I cleaned up a lot of that stuff as I was working.

I'm still not quite ready to bring the newest Parser and Interpreter into the live code, because I want to test them on the stories and ensure there are no major hiccups. That is (hopefully!) a quick thing that I can do in the background while I keep working on the Conversation Engine.

Until the next cycle,
Jenny

Sunday, June 16, 2024

AI Ideology VI: Existential Risk Critique

I come to you with the final installment in my series on AI-related ideology and politics. In Part V, I tried to briefly lay out the argument for existential risk from AI, along with what I consider the weaker counterpoints. Today I will conclude the series with a discussion of the counterarguments I find more interesting.

The Alignment Problem does not strike me as intractable

All the dangers laid out in the previous article are associated with misaligned AI agents - that is, agents that do not (in a broad sense) want what humans want. If we could produce an agentive superintelligence that did want what we want, it would pursue our goals just as aggressively as hostile superintelligence is expected to work against them. So all the fear of doom evaporates if the Alignment Problem is feasible to solve, at or before the time when AGI first comes on the scene.

Even though his followers have had two decades or so to think about the Problem, Yudkowsky insists that "We are not prepared. We are not on course to be prepared in any reasonable time window. There is no plan. Progress in AI capabilities is running vastly, vastly ahead of progress in AI alignment ..." [1] My own intuitions about alignment don't match up with this. To me it seems like a potentially difficult problem, but not any harder than the capability problem, i.e. the puzzle of how to create any AGI at all. The foundations of human values are somewhat obscure to us for the same reasons the mechanisms of our own intelligence are obscure; if we can discover one, we can discover the other. How can it be accurate to say that nobody has a plan for this?

It's possible that I feel this way because the work I'm doing, as well as my personal ideas of the best path to AGI, have little to do with ANNs and ML. A fair bit of the hand-wringing about AI alignment reads to me like this: "Heaven forbid that we *design* an AI to fulfill our complex desires - that would be too much work. No, we have to stick to these easy processes that draw trained models from the primordial ooze without any need for us to understand or directly architect them. This lazy approach won't reliably produce aligned AIs! OH NO!"

Since all of my systems are designed on purpose and the code is human-intelligible, they already have the level of transparency that ANN-builders dream of getting. I don't have to worry about whether some subsystem I've built just happens to contain an agent that's trying to optimize for a thing I never wanted, because none of my subsystems are auto-generated black boxes. I don't do haphazard emergent stuff, and I think that's one reason I feel more comfortable with my AI than some of these people feel with the mainstream approaches.

A selection of articles pulled from Alignment Forum provides evidence that many issues Existential Risk Guardians have identified are tied to particular techniques:

"In general, we have no way to use RL to actually interpret and implement human wishes, rather than to optimize some concrete and easily-calculated reward signal." [2]

"For our purposes, the key characteristic of this research paradigm is that agents are optimized for success at particular tasks. To the extent that they learn particular decision-making strategies, those are learned implicitly. We only provide external supervision, and it wouldn't be entirely wrong to call this sort of approach 'recapitulating evolution', even if this isn't exactly what is going on most of the time.

As many people have pointed out, it could be difficult to become confident that a system produced through this sort of process is aligned - that is, that all its cognitive work is actually directed towards solving the tasks it is intended to help with. The reason for this is that alignment is a property of the decision-making process (what the system is 'trying to do'), but that is unobserved and only implicitly controlled." [3]

"Traditional ML algorithms optimize a model or policy to perform well on the training distribution. These models can behave arbitrarily badly when we move away from the training distribution. Similarly, they can behave arbitrarily badly on a small part of the training distribution ... If we understood enough about the structure of our model (for example if it reflected the structure of the underlying data-generating process), we might be confident that it will generalize correctly. Very few researchers are aiming for a secure/competitive/scalable solution along these lines, and finding one seems almost (but not completely) hopeless to me." [4]

We could undercut a lot of these problems by taking alternate paths that do a better job of truly replicating human intelligence, and permit easier examination of how the system is doing its work.

Members of the Existential Risk Guardian/Doomer faction also like to frame all goal-directed agency in terms of "maximizing expected utility." In other words, you figure out a mathematical function that represents the sum of all you desire, and then you order your behavior in a way that maximizes this function's output. This idea fits in well with the way current mainstream AI works, but there are also game theoretic reasons for it, apparently. If you can frame your goals as a utility function and behave in a way that maximizes it, your results will be mathematically optimal, and other agents will be unable to take advantage of you in certain ways when making bets or deals. Obviously we humans don't usually implement our goals this way. But since this is, in some theoretical sense, the "best" way to think about goals, the Doomers assume that any superintelligence would eventually self-improve into thinking this way. If its goals were not initially specified as a utility function, it would distill them into one. [5]

Hence the Doomers think we must reduce the Alignment Problem to finding a utility function which, when maximized, yields a world that humans would find congenial. And the big fear arises from our not knowing how to do this. Our preferences and interests don't seem to be natively given as a mathematical function, and it is difficult to imagine transforming them into one without a large possibility for error.

Many struggles can be avoided by modeling human values in a more "natural" way: looking for methods of grounding concepts like deprivation/satisfaction, empathy, reciprocity, and fairness, instead of trying to reduce everything to a function. Technically it is possible to view any agent as maximizing some utility function, regardless of how it models its goals internally[6], but this not necessarily the most useful or transparent way to frame the situation!

And I consider it safe to model goals in the more "natural" way, because an ASI on a self-improvement quest would also recognize that 1) framing goals in terms of utility maximization, while theoretically optimal, is not always practical and 2) transforming goals from one specification into another carries potential for error. Since one of the convergent instrumental goals of any such self-aware agent is goal preservation, the ASI would be just as wary of these transformation errors as we are!

The alignment concern that seems most directly relevant to the work I'm personally doing is the possibility of oversimplified goal specification. But there are a number of strategies for managing this that I consider sound:

*Treat the AI's value system as a system - with all the potential for complexity that implies - instead of expecting just a few objectives or rules to carry all the weight.

*Embed into the AI some uncertainty about the quality of its own goal specifications, and a propensity to accept feedback on its actions or even adjustment of the goal specs. This is a form of "corrigibility" - keeping the AI sensitive to human opinions of its performance after it is complete and operational.

*Specify goals in an indirect manner so that the AI's concept of the goals will advance as the AI's general skill advances. For instance, provide goals in natural language and associate the AI's objective with their "real meaning," rather than trying to translate the goals into code, so that the AI's understanding of the goals can be enriched by improved understanding of human communication.

In short, I don't think the Doomers have proven that agentive AI is universally dangerous. Their arguments so far are focused on a subset of possible design pathways, none of which I am following.

This should go some way toward explaining why I'm not terribly worried about my own work (even if it gets anywhere near becoming AGI, and I make no claims that it will). But what about all the mainstream AI efforts that are rushing ahead as I write? Those don't manage to frighten me much either, but for different reasons.

I'm skeptical of intelligence explosion hazards

As noted in the previous article, one pillar of Doomer fears is the notion that AGI will probably become ASI, perhaps very quickly. A misaligned AGI has the power level of a bad human, and we already have plenty of those, so it is nothing to be especially worried about. Real danger requires a path from AGI to ASI. Let's think a little more about the most frightening type of ASI: qualitative superintelligence. Recall that this variety of supermind would use modes of thinking so exotic, and so much better than ours, that we couldn't even grasp how it thinks.

The usual assumption is that human engineers will not produce qualitative ASI directly. Instead, an AGI will bootstrap itself to that level by re-engineering its own mental processes. Is this really plausible? Can an agent just make itself smarter in a vacuum?

Imagine for a moment that you are a jumping spider, and a member of the Salticid Intelligence Acceleration Consortium. Other spiders bring you food so that you can do nothing but sit around and Think Really Hard about how to be smarter. You'd like to invent abstract logic, meta-knowledge, long-term planning, and all the other cool cognitive abilities that certain big mammals have. Except ... you don't even have names for these things. You don't even have concepts for these things. If you knew what they were - if you even knew which direction to be going to improve toward them - you'd already have them. So how, exactly, are you going to think your way there? How are you to think about the thoughts you cannot think?

"Bootstrap" is actually a rather ironic expression[7], because pulling on your own bootstraps won't lift you anywhere. And spending a long time thinking at a low level won't necessarily get you to a higher level.

If you set out to design an AI deliberately, you're using your own intelligence to produce intelligence in a machine. If you train an ANN on data that was produced or labeled by humans, that's also a way of putting human intelligence into a machine. Large language models derive their smarts (such as those are) from all the knowledge people have previously encoded in the huge piles of text used as their training data. Supervised reinforcement learners also benefit from the intelligence of the human supervisor poking the reward button. Even evolutionary algorithms can glean intelligence from the design of the evaluator that determines "fitness." [8] So none of these approaches are really conjuring intelligence out of nothing; they're descendants of pre-existing human intelligence (perhaps in an awkward, incomplete, or flawed way).

So then: what could be smart enough to write a program smarter than itself? And from where shall our future AGIs get the dataset to train a superintelligent ANN? Doesn't it stand to reason that you might need data produced by superintelligences? (From what we've seen so far, training a new generation of ML AI on a previous generation's output can actually make the new generation worse. [9]) When humans try to develop AGI, they're making something from something. The idea of AGI developing qualitative ASI emits the uncomfortable odor of a "something from nothing" fantasy. "Just stir the giant vat of math around enough, and superintelligence will crawl out! It won't even take millions of years!" Heh. I'll believe that one when I see it.

Programs like AlphaStar, which learn by playing against themselves, are one example I can think of that seems to develop intelligence without much human input beyond the learning algorithm. But they are still utilizing a resource, namely practice; they learn from experience. Their advantage lies in their ability to practice very, very fast. Video games lend themselves well to that sort of thing, but is it possible to practice general reasoning in the same fashion? It's harder to iterate rapidly if you have to learn about doing anything in the physical world, or learn about the psychology of humans. You'd need a high-fidelity simulator (which, by itself, would take a lot of work to develop). And then you wouldn't discover anything that humans and AGIs don't already know about the universe, because they wouldn't be able to include those unknown properties in the simulation.

The one thing an AGI might get by sitting around and putting billions of cycles into thinking, would be new branches of philosophy and mathematics. And some of those might lead to methods for idealized formal reasoning, in the same way Game Theory does. But are our previous improvements in these areas sufficient to constitute superintelligence vs. the generations of humans before the discovery?

Even if Qualitative Superintelligence is unlikely, that leaves Speed Superintelligence and Collective Superintelligence on the table. And both of these are much more straightforward to obtain, given that they only require scaling. But they also make the Alignment Problem easier. Now our AI researcher isn't faced with the need to analyze or supervise an entity smarter than himself, or the need to prevent his AGI from mutating into such an entity with possible loss of fidelity. He only has to align an AGI which is as smart as himself, or perhaps slightly less. Copying and speedup multiply the abilities of the seed AGI *without* modifying it. So if the seed AGI is well-aligned, the resulting Collective or Speed ASI should be as well.

Note that we already have collective general intelligences, in the form of corporations, governments, and other organizations which contain large numbers of humans working toward a common cause. Some of these are even misaligned. For example, the desired goal of a corporation is "produce goods and services beneficial to potential customers," but the actual goal is "maximize profit returned to the owners or shareholders." Profit functions as a proxy for public benefit in an idealized free market, but frequently diverges from it in the real world, and I'm sure I don't need to go into the multitude of problems this can cause. And yet, despite those problems ... here we still are. Despite the large number of human collectives that have formed and dispersed over the course of history, not one of them has developed fanatic optimizer tendencies and proceeded to rapidly and utterly destroy the world.

Note also that AGI's ability to scale will probably not be unlimited. Increasing the number of copies working together increases coordination overhead. Increasing the total amount of data processed increases the challenges of memory management to store and retrieve results. There are hard physical limits on the speed and density of computational hardware that we will hit eventually.

I'm skeptical of spontaneously emerging harmful properties

The type of AGI that Doomers expect to balloon into a hostile ASI is actually pretty specific. I agree that, given the use of mainstream ML methods, it is reasonably easy to accidentally produce a trained model that is maximizing some other function than the one you want. However, the deadly scenario also requires that this model 1) be an agent, capable of generalizing to very open-ended ways of maximizing its function, and 2) have embedded situational awareness. I.e. it must have a sense of self, knowing that it is an agent in an environment, and knowing that the environment includes a whole world outside its computer for it to operate upon. It is only this combination of properties that can give an AI ideas like "I should repave the whole Earth with computronium."

The corporate AI systems provided to the public as tools do not, so far, have these properties. For something like ChatGPT, the whole world consists of its prompts and the text it generates to complete them. No matter how intelligently future GPT iterations complete text, there's no reason to think that something in there is strategizing about how to manipulate its users into doing things in the human world that will make GPT even better at completing text. GPT's internal architecture simply doesn't provide for that. It doesn't have an operational concept of the human world as an environment and itself as a distinct actor therein. It just knows a whole awful lot about text. Asking an LLM to simulate a particular kind of speaking character can produce at least the appearance of self-aware agency, but this agency is with respect to whatever scenario the user has created in the prompt, not with respect to the "real world" that we inhabit.

So if OpenAI and Google and Meta keep churning out systems that follow this same design pattern, where's the cause for alarm? It seems Doomers are worried that self-aware, situationally-aware agents will be produced spontaneously during machine learning processes - even without deliberate effort to train for, select for, or reward them - just because they enable the most extreme maximization of any objective.

This bothers me in much the same way the "superintelligence by bootstraps" argument bothers me. Where would these properties or systems come from? Why would they just pop out of nowhere, unasked for? José Luis Ricón describes the conclusion of a discussion he had about this issue, and gathers that the disagreement comes down to differences of intuition about how ML processes work, and what they can reasonably be expected to produce. [10] Doomers expect that an unwanted level of situational awareness would just appear unaided. I do not.

The Doomer counter to this kind of argument is, "But if you can't guarantee (e.g. by a formal proof) that it won't happen by chance, you should still be worried. Misaligned ASI would be so terrible that even a remote possibility of it should justify policy changes." No matter how speculative their nightmare scenario is, they use the severity of the consequences to push the burden of proof onto their opponents. Is this reasonable? You decide.

I have doubts the path mainstream AI is on will get us to AGI anyway

If the state-of-the-art but still sloppy approaches that are currently in vogue don't succeed in producing AGI, the various teams working in the field will have to abandon or reform them ... hopefully for methods that make the Alignment Problem easier. Despite some remarkable recent progress, I suspect the abilities of present-day AI systems and their nearness to AGI have been over-hyped. I don't have enough time to go into a detailed discussion of that here, so let's just say I'm far from the only person with this opinion. [11][12][13][14][15][16]

This means that I have a "long timeline" - that is, I don't think AGI is coming very soon, so I expect we'll get more time to work on the Alignment Problem. But it also means that I expect the difficulty of the Problem to drop as AI development is driven toward sounder methods.

Thus ends (for now) my discussion of politics, ideology, and risk perception in the AI enthusiast subcultures. Whatever opinions you come away with, I hope this has been informative and left you with a better sense of the landscape of current events.

Until the next cycle,
Jenny

[1] Yudkowsky, Eliezer. "Pausing AI Developments Isn’t Enough. We Need to Shut it All Down." TIME Magazine.  https://time.com/6266923/ai-eliezer-yudkowsky-open-letter-not-enough/

[2] Christiano, Paul. "Prosaic AI Alignment." Alignment Forum. https://www.alignmentforum.org/s/EmDuGeRw749sD3GKd/p/YTq4X6inEudiHkHDF

[3] Stuhlmüller, Andreas. "Factored Cognition." Alignment Forum. https://www.alignmentforum.org/s/EmDuGeRw749sD3GKd/p/DFkGStzvj3jgXibFG

[4] Christiano, Paul. "Directions and desiderata for AI alignment." Alignment Forum. https://www.alignmentforum.org/s/EmDuGeRw749sD3GKd/p/kphJvksj5TndGapuh

[5] Shah, Rohin. "Coherence arguments do not entail goal-directed behavior." Alignment Forum. https://www.alignmentforum.org/s/4dHMdK5TLN6xcqtyc/p/NxF5G6CJiof6cemTw

[6] Shah, Rohin. "Conclusion to the sequence on value learning." Alignment Forum. https://www.alignmentforum.org/s/4dHMdK5TLN6xcqtyc/p/TE5nJ882s5dCMkBB8

[7] Bologna, Caroline. "Why The Phrase 'Pull Yourself Up By Your Bootstraps' Is Nonsense: The interpretation of the phrase as we know it today is quite different from its original meaning." The Huffington Post. https://www.huffpost.com/entry/pull-yourself-up-by-your-bootstraps-nonsense_n_5b1ed024e4b0bbb7a0e037d4

[8] Dembski, William A. "Conservation of Information - The Idea." Evolution News & Science Today. https://evolutionnews.org/2022/06/conservation-of-information-the-idea/

[9] Dupré, Maggie Harrison. "AI Loses Its Mind After Being Trained on AI-Generated Data." Futurism. https://futurism.com/ai-trained-ai-generated-data

[10] Ricón, José Luis. "The situational awareness assumption in AI risk discourse, or why people should chill." Nintil (2023-07-01). https://nintil.com/situational-awareness-agi/.

[11] Marcus, Gary. "AGI by 2027? Fun with charts." Marcus on AI. https://garymarcus.substack.com/p/agi-by-2027

[12] Brooks, Rodney. "Predictions Scorecard, 2024 January 01." Rodney Brooks: Robots, AI, and other stuff.  https://rodneybrooks.com/predictions-scorecard-2024-january-01/

[13] Bender, Emily M. "On NYT Magazine on AI: Resist the Urge to be Impressed." Medium blog of user @emilymenonbender. https://medium.com/@emilymenonbender/on-nyt-magazine-on-ai-resist-the-urge-to-be-impressed-3d92fd9a0edd

[14] Piekniewski, Filip. "AI Psychosis." Piekniewski's blog. https://blog.piekniewski.info/2023/02/07/ai-psychosis/

[15] Moore, Jennifer. "Losing the imitation game." Jennifer++. https://jenniferplusplus.com/losing-the-imitation-game/

[16] Castor, Amy and Gerard, David. "Pivot to AI: Pay no attention to the man behind the curtain." Amy Castor (personal website/blog). https://amycastor.com/2023/09/12/pivot-to-ai-pay-no-attention-to-the-man-behind-the-curtain/