Tutorial 1: Setting Up & Using the ACS
Neste primeiro tutorial será realizado um programa tipo “Hello World” o qual somente utilizará a arquitetura ACS com uma rede neural tipo backpropagation e o sistema RER (Rule Extraction and Refinement) para extrair regras baseadas no aprendizado.
O objetivo é que o agente aprenda o seguinte:
Se alguém diz “hello” ou “goodbye” para mim,
então devo responder com “hello” ou “goodbye” respetivamente.
Ao final da tarefa a anterior afirmação deverá ser representada como uma regra no nivel superior da ASC.
O agente não vai ter mais informação alem das entradas e as saidas, não vai ter conhecimento a-priori da dinamica da tarefa.
O primeiro passo é adicionar o programa “Simple Hello World” ao projeto após realizar esto, é necessária a inclução do seguinte código para lograr usar as clases e funções do framework.
using Clarion;
using Clarion.Framework;
Os namespaces Clarion e Clarion.Framework são a localização principal da maioria das classes que serão utilizadas quando se trabalha com um agente baseado em Clarion.
É necessário declarar a classe que realizará a tarefa:
public class SimpleHelloWorld
Esta classe contem todo o código para o entorno de simulação, inclui a inicialização do mundo, do agente e dos mecanismos que permitem ao agente iteragir com o mundo. Todo o programa é realizado numa única função: a função Main().
As primeiras linhas dentro da função Main() são:
//Initialize the task
Console.WriteLine("Initializing the Simple Hello World Task");
int CorrectCounter = 0;
int NumberTrials = 10000;
int progress = 0;
World.LoggingLevel = TraceLevel.Warning;
TextWriter orig = Console.Out;
StreamWriter sw = File.CreateText("HelloWorldSimple.txt");
As primeiras linhas do código declaram algumas variáveis e configuram alguns aspetos de C#, como por exemplo, que o resultado seja salvado num arquivo chamado HelloWorldSimple.txt
Quando é realizada uma simulação, a primeira coisa que deve ser feita é descrever como se vê o nosso entorno de simulação. Para isso são utilizados os pares de dimensão-valor (dimension-value). Para o nosso exemplo existe uma dimensão chamada “Salutation” e ela possui dois valores: “Hello” e “goodbye”. Os seguintes pares dimensão-valor representam o entorno de simulação para a nossa tarefa, e são escritas em C# como:
DimensionValuePair hi = World.NewDimensionValuePair("Salutation", "Hello");
DimensionValuePair bye = World.NewDimensionValuePair("Salutation", "Goodbye");
Agora vão-se definir as ações externas que o agente tem a possibilidade de realizar, neste caso “Hello” e “goodbye”, representarão as entradas.
ExternalActionChunk sayHi = World.NewExternalActionChunk("Hello");
ExternalActionChunk sayBye = World.NewExternalActionChunk("Goodbye");
Com estos inicializadores o entorno de simulação está, em base, configurado.
Agora é possível iniciar o agente chamado Jhon:
//Initialize the Agent
Agent John = World.NewAgent("John");
Até aqui foi criado um agente “vazio”. Vazio porque até agora o agente não sabe nada do mundo nem a tarefa que deve realizar.
O único objeto funcional que é necessário inicializar, no momento, é uma Implicit Decision Network (IDN), no nível inferior do ACS. Para configurar esta rede, deve-se inicializar uma rede tipo backpropagation. Mais exatamente uma Q-learning backpropagation network simplificada. Esto é realizado no programa com seguintes linhas:
SimplifiedQBPNetwork net = AgentInitializer.InitializeImplicitDecisionNetwork
(John, SimplifiedQBPNetwork.Factory);
Para a nossa tarefa tudo o que a gente precisa é uma rede de decisão implícita ou IDN(implicit decision network), no nível inferior da ACS. Para inicializar o IDN são passados dois itens como argumento do método de inicialização:
- O agente (John neste caso), ao qual a rede será anexada
- Um fator que será usado para gerar a rede que a gente quer
Neste caso o fator que será usado já vem pronto no Clarion e será SimplifiedQBPNetwork.Factory. O fator permitira a criação da SimplifiedQBPNetwork no nível inferior do ACS
O InitializeImplicitDecisionNetwork retorna um componente implícito do tipo que é especificado por factory.
Foi inicializada a rede com SimplifiedQBPNetwork e seu valor de retorno foi atribuído à variável net. Net pode ser considerada como parte do agente John. Ou seja a rede dever ser adicionada ao agente que foi especificado quando foi declarada a rede. O que esto significa é que oma rede pertence a um agente só e não pode ser usado por nenhum outro agente.
Neste ponto, sem embargo, se deve finalizar a inicialização do IDN, rede, usando os pares DV e as ações. Esto dará a o agente John, a habilidade de escolher ações baseado na informação dos sensores que ele recebe desde o mundo.
As quatro linhas de abaixo completam esta tarefa:
net.Input.Add(hi);
net.Input.Add(bye);
net.Output.Add(sayHi);
net.Output.Add(sayBye);
É importante saber que o número de nós na camada intermediara é calculada automaticamente.
Pode-se inicializar com muitas coisas ao agente, quando o processo de configuração dos objetos funcionais acabar o agente deve ser notificado, este processo é chamado de "commiting". E geralmente após de ter feito o commiting não é possível modificar os objetos funcionais. Todos os objetos devem passar pelo processo de commiting após serem inicializados. Committing um objeto funcional torna ele imutável, ou seja que ele não se pode cambiar, fica de só letura.
Agora é possível lhe dizer a Jhon que ele pode utilizar a rede. Para informa ao agente que a inicialização da rede foi completada é chamada a função Commit.
John.Commit(net);
Tweaking Parameters
Uma ultima inicialização que usualmente é feita é o ajuste de parâmetros. Os seguintes parâmetros são ajustados para otimizar a performance do agente:
net.Parameters.LEARNING_RATE = 1;
John.ACS.Parameters.PERFORM_RER_REFINEMENT = false;
Running a Simulation (& Continued Walkthrough)
Em geral, o entorno de simulação precisa de manusear as seguintes comunicações:
- Especificar ao agente a informação sensorial percebida em cada ciclo de percepção-ação (perception-action cycle)
- Capturar e armazenar a ação que é escolhida pelo agente
- Atualizar o estado do mundo (se for necessário) baseado nas ações do agente
- Prever realimentação ao agente com que tão boa ou má foi a sua escolha
- Seguir a performance do agente (Se se quer apresentar um informe no final da tarefa)
Agora que o mundo e o agente foram configurados, é tempo de dar a John um significado para interagir com o mundo. Aqui é onde o código entra em jogo.
//Run the task
Console.WriteLine("Running the Simple Hello World Task");
Console.SetOut(sw);
Random rand = new Random();
SensoryInformation si;
ExternalActionChunk chosen;
for (int i = 0; i < NumberTrials; i++)
{
...
}
Dentro do loop a informação do sensor é obtida para cada ciclo de percepção-açao, a ação escolhida é capturada, a realimentação é dada e a performance do agente é armazenada.
Initializing the Sensory Information
A primeira coisa que é feita em cada iteração é obter a informação sensorial. O seguinte código faz isso:
si = World.NewSensoryInformation(John);
Obtemos informação sensorial do mundo chamando o método NewSensoryInformation e especificando o agente de quem quer-se obter a informação. A informação sensorial não pode ser compartilhada entre agentes.
Um conceito importante é a chamada "internal meta information" do agente, que é o estado de seus abjetivos, o working memory, os drivers etc.
Neste caso a entrada será gerada aleatoriamente. Se o número gerado aleatoriamente é menor do que 0.5 então a entrada é um "Hello", se o número é maior do que 0.5 a entrada é um "Goodbye":
//Randomly choose an input to perceive.
if (rand.NextDouble() < .5)
{
//Say "Hello"
si.Add(hi, hi.MAXIMUM_ACTIVATION);
si.Add(bye, bye.MINIMUM_ACTIVATION);
}
else
{
//Say "Goodbye"
si.Add(hi, hi.MINIMUM_ACTIVATION);
si.Add(bye, bye.MAXIMUM_ACTIVATION);
}
A configuração do sensor de informação adicionando objetos descritivos a ele. Isso é feito utilizando o método Add.
Perceiving and Acting
As seguintes linhas iniciam a percepção do agente da informação dos sensores e recupera a ação do agente
//Perceive the sensory information
John.Perceive(si);
//Choose an action
chosen = John.GetChosenExternalAction(si);
GetChosenExternalAction retorna a ação que John escolheu (dada a informação atual fornecida)
Processing Outcomes and Delivering Feedback
Apos escolher a ação que sera realizada, o seguinte if determina a consequência desa ação, armazena a saída e premia ou pune a John.
//Deliver appropriate feedback to the agent
if (chosen == sayHi)
{
//The agent said "Hello".
if (si[hi] == hi.MAXIMUM_ACTIVATION)
{
//The agent was right.
Trace.WriteLineIf(World.LoggingSwitch.TraceInfo, "Jon was correct");
//Record the agent's success.
CorrectCounter++;
//Give positive feedback.
John.ReceiveFeedback(si, 1.0);
}
else
{
//The agent was wrong.
Trace.WriteLineIf(World.LoggingSwitch.TraceInfo, "Jon was incorrect");
//Give negative feedback.
John.ReceiveFeedback(si, 0.0);
}
}
else
{
//The agent said "Goodbye".
if (si[bye] == bye.MAXIMUM_ACTIVATION)
{
//The agent was right.
Trace.WriteLineIf(World.LoggingSwitch.TraceInfo, "Jon was correct");
//Record the agent's success.
CorrectCounter++;
//Give positive feedback.
John.ReceiveFeedback(si, 1.0);
}
else
{
//The agent was wrong.
Trace.WriteLineIf(World.LoggingSwitch.TraceInfo, "Jon was incorrect");
//Give negative feedback.
John.ReceiveFeedback(si, 0.0);
}
}
Para dar a John a realimentação, tudo o que a gente tem que fazer é chamar ao método ReceiveFeedback. Chamando esse método automaticamente se inicia uma iteração de aprendizagem para John.Uma vez finalizado o processamento dos resultados, existe mais uma coisa que deve ser feita antes da simulação terminar.
Killing an Agent
A ultima coisa que deve ser feita para terminar a simulação é terminar o agente. No nosso exemplo pode-se matar a John chamando linha:
John.Die();
Este comando inicia a terminação de todos os processo internos de John. Embora o agente seja morto a informação interna dele ainda continua para ser acessada e salvada.
A seguinte figura apresenta a saída do programa enquanto é feito o treinamento:
![](/gudwin/sites/faculty.dca.fee.unicamp.br.gudwin/files/users/aluno5/Aula8/im04.png)
A seguinte figura apresenta a saída do programa em forma de uma regra num arquivo de texto
![](/gudwin/sites/faculty.dca.fee.unicamp.br.gudwin/files/users/aluno5/Aula8/im06.png)