Implementing Artificial Consciousness with ADS

From ADS-AC

Revision as of 19:01, 18 January 2006 by Tkorrovi (Talk | contribs)
Jump to: navigation, search

"We may, from the experience we have had of the train and succession of ideas in our minds, often make, I will not say uncertain conjectures, but sure and well-grounded predictions concerning the ideas we shall be affected with pursuant to a great train of actions, and be enabled to pass a right judgment of what would have appeared to us, in case we were placed in circumstances very different from those we are in at present." -- "A Treatise Concerning the Principles of Human Knowledge" by George Berkeley, 1710.

"Prediction is one of the key functions of consciousness. An organism that cannot predict would have a seriously hampered consciousness." Artificial Neuroconsciousness: An Update by Igor Aleksander, Imperial College, London.

Learning is “A set of philogenetically advanced adaptation processes that critically depend on an evolved sensitivity to subjective experience so as to enable agents to afford flexible control over their actions in complex, unpredictable environments.” Implicit learning and consciousness by Axel Cleeremans, University of Brussels, and Luis Jiménez, University of Santiago.

The results of the experiments of neuroscanning on monkeys suggest that a process, not a state or object activates neurons. This paper is unfortunately no longer available, so about these studies see this link from ScienceDaily, also this article: Brain Anticipates Events To Learn Routines. For such reaction there must be created a model of the process based on the information received through the senses, creating models such way demands a lot of flexibility, and is also useful for making predictions. And awareness is an awareness of processes. So, in the meaning of this project:

Artificial Consciousness is an artificial system, which is able to predict the external events in an unexpected environment.

The prediction is based on the multiple drafts principle of Daniel Dennett, so that the processes which fit in their environment, survive. Because such prediction includes the subject, such system tries to act so that it can predict the results of its behaviour, which enables training of such systems. We can call a system an AC, when the question why such system learns, cannot be explained in lower terms than through the aspects of consciousness, such as awareness of the external processes and prediction.

The only other system, unrestricted enough to be fully self-developing, seems to be cellular automaton. But nobody yet succeeded to train a cellular automaton for anything. To train it, one needs to influence the working pattern with some other pattern. But trying all infinitely developing patterns I know, none of them survived the hit of a single glider to the working area of the pattern. See for example the file 1.lif, under this home page, it's best to run it with the program Life32. The infinitely developing pattern dies pretty soon, after being hit by a single glider. This is not proved, but it may indicate, that any fixed grid is too restrictive. At the same time, the structures in ADS-AC may work for months with a proper training program (like the following one), being started from many different simple start structures. This at least shows, that the ability for survival of absolutely dynamic systems is a lot greater than that of cellular automata. Based on that it seems, that for survival of such structures we need nonlocal connections, and we may need changing nonlocal connections, and absolutely dynamic systems are the only unrestricted system so far, which implements changing nonlocal connections.

The training program (a program which talks to the system instead of you) of such system as ADS, must provide a "toys" for a system; the system must learn itself by playing with them. A training program for training a system to play a game of Nim:

/* Two players begin the game of Nim with 15 beans. */ 
/* They take turns removing at least one, and not more than 3. */
/* The player removing the last bean loses. */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <time.h>
#define MAXNIM 15
#define MAXTAKE 3
static int inactive, nim, n;
static float numofgames, numofwins;
static char *instring;
FILE *f;

void statistics (void)
{
	nim = MAXNIM;
	numofgames++;
	/* Don't do that, unless you have ram disk, the writes are too */
	/* frequent and this may damage your hard disk. */
	/* If we would write to the log file only numbers */
	/* without comments, a 1 MB ram disk should not become full */
	/* during 24 hours without truncating file, and tail -f would work */
	/* much better. But this possibility of having a real time view */
	/* is absolutely necessary for this algorithm, as there is not */
	/* so much to see on the main screen using this training program. */
	/* Writes in every line number of games, number of wins, */
	/* percentage from all games played, and z score. */	
	f = fopen ("z:\\dtnim.txt", "a");
	fprintf (f, "%i  %i  %f  %f\n", 
		(int) numofgames, (int) numofwins, numofwins / numofgames * 100,
		(numofwins - numofgames / 2) / sqrt (numofgames / 4));
	fclose (f);
}

char *teach (char *outchar, unsigned int noc, 
	unsigned long *oldbegin, unsigned long *newbegin, 
	unsigned long *freebegin, unsigned long *freelength)
{
	unsigned long *p;
	p = oldbegin, p = newbegin, p = freebegin, p = freelength, p = p;
	strcpy (instring, "");
	if (noc == 1)
	{
		if (inactive)
		{
			inactive--;
			return instring;
		}
		if (outchar [0] < 'A' || outchar [0] >= 'A' + MAXTAKE)
			return instring;
		nim = nim - outchar [0] + 'A' - 1; /* ADS move */
		if (nim <= 0) /* ADS loses */
		{
			statistics ();
			inactive = 10;
			return instring;
		}
		if (nim == 1) /* ADS won */
		{
			numofwins++;
			statistics ();
			return instring;
		}
		n = rand () % MAXTAKE + 1;
		nim = nim - n; /* other player move */
		if (nim <= 0) /* ADS won */
		{
			numofwins++;
			statistics ();
			return instring;
		}
		if (nim == 1) /* ADS loses */
		{
			statistics ();
			inactive = 10;
			return instring;
		}
		strcpy (instring, " ");
		instring [0] = 'A' + n - 1;
	}
	return instring;
}

void attach (unsigned long *sknot)
{
	unsigned long *p = sknot;
	p = p;
	nim = MAXNIM;
	numofgames = numofwins = 0;
	srand (time (NULL));
	instring = (char *) malloc (FILENAME_MAX);
}

void detach (void)
{
	/* f = fopen ("dtnim.txt", "a"); */
	/* fprintf (f, "games %i  wins %i  percentage %f\n", (int) numofgames, 
		(int) numofwins, numofwins / numofgames * 100); */
	/* fclose (f); */
	free (instring);
}

One example of the log file generated by the program with this training algorithm is in Test Example. There z score (for significant result we need z score more than 2, see Calculating the Z Score, use gawk or such to calculate z score from the log file) was three times more than two in the first hundred games, but this would not happen in every attempt, and the number of such games is a bit too small for that to be very convincing. This is rather an example of the method of testing such system. This was also one of the first times when I tried an algorithm without using space as a confirmation of winning, think using space that way was wrong. I started training from nim15-0.str, which was saved after not more than a second running distart3.str (download both from the main page here). Press c to start distart3.str, it takes some 10 attempts for it to start to work.

It's not exactly clear whether system size 65000 is enough or 200000 would be necessary for better results, also whether decay like in the test included in the distribution, would be necessary, but it cannot start with much larger size than 65000. There are certainly many ways to make the program also several times faster, or working better so that it would learn faster, but there was no time for that yet, as in this stage the aim is only to test the existing program. I'm indeed also sorry that the program is written in windows api, and not gtk, so that it will not work in linux. This should be done in the future, the problem was that at the time I started writing the gui, gtk was not yet ported to windows. Some things, like not using arrays of structures, may seem strange, but many things are only because of speed, it certainly depends on compiler, but often calculating the location of the structure element takes more time than accessing data directly by pointer.

The example here does not react to 10 outputs after losing the game, based on the results this tends to work as negative sign, ie the system used to expect some letters as a response to its output, not getting a response would be contrary to what it predicts, and therefore a negative sign. But this would happen only when it has learned enough to predict response. It is inevitable that training it from the very beginning is not so easy, it so much depends on occasion, in some rare occasion we may also get a system which will not work at all.

It's very likely that the principle of award/punishment comes from the same general principle of prediction mentioned above, ie something easily predictable for some time would be awarding for the system, and something not predictable for some time would be punishment. The exact theory of training such way likely should be figured out, in more complicated training it should also be considered that the award/punishment may depend on how much the system has learned. Such principle is universal, in that training programs for training theoretically anything can be made such way, whenever the mechanism of the system is capable of prediction in an unexpected environment. The lack of any pre-programmed award, punishment or criterion in such systems may make the training more complicated, as there would be more things to consider, but this is necessary for maximum generality, as any rules of award, punishment or criterion would restrict the system, so that it cannot be quite general enough for most of the tasks any more.

The previous (first) test the system passed only shows that the system is able to learn (predict a reply). Such environment is unexpected for a system, which starts from only a few lines connected together. The z score for that test was not calculated, but it must be very high, as it does that most of the time.

There are currently no known bugs.

di32bin.exe is a windows self-extractor of DI 3.2 binary, but don't use it, as it contains a known bug. ads014.zip contains sources of ads version 0.1.4, which at present is the same as DI version 3.2, but with no known bugs. The compiler used was the latest version 3.1.0-1 of open source c/c++ compiler MinGW. The sources are also in cvs repository, in spite that it shows 0 commits and 0 adds on the project page, this is because SourceForge doesn't at present update the cvs statistics, because of the known issue mentioned on the statistics page.

At present, all binaries, including dtnim.dll, and nim.str, are under the url of this site. The binaries are not included in the distribution, because without a compiler it is not possible to create training programs, so it's better to have a compiler anyway. The programs written for mingw should also compile well in visual c and other compilers, as mingw is more standard, but one should know how to create projects or makefiles for compiling the program and dll-s, for the other compilers.