
























































Estude fácil! Tem muito documento disponível na Docsity
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
Prepare-se para as provas
Estude fácil! Tem muito documento disponível na Docsity
Prepare-se para as provas com trabalhos de outros alunos como você, aqui na Docsity
Encontra documentos específicos para os exames da tua universidade
Prepare-se com as videoaulas e exercícios resolvidos criados a partir da grade da sua Universidade
Responda perguntas de provas passadas e avalie sua preparação.
Ganhe pontos para baixar
Ganhe pontos ajudando outros esrudantes ou compre um plano Premium
REVISTA DE PROGRAMAÇÃO QUE FALA SOBRE A TECNOLOGIA DE DESENVOLVIMENTO DE SISTEMAS
Tipologia: Manuais, Projetos, Pesquisas
1 / 64
Esta página não é visível na pré-visualização
Não perca as partes importantes!

























































Apesar de possivelmente controverso o título deste editorial, não é para controvérsias o meu objectivo, na sua escrita. A verdade é que possivelmente muitos dos leitores, se identificam como “geeks”! Como pessoas curiosas, dedicadas, ávidas de conhecimento, dispostas a caminhar as outras milhas, mesmo na adversidade! Pessoas extraordinárias! Com este Verão já em curso, quente, até por vezes demasiado quente, sonolento e complexo, entre o calor, a praia, montes de festivais, livros e notícias que dão vontade de não as ver, muitas vezes me lembro da música, que serve de título a esta edição! “Os geeks herdarão a terra”! No passado mês de Junho, tive a oportunidade de ver como um conjunto de geeks (developers, makers, arquitectos, engenheiros, gente das mais diversas áreas), começou a organizar-se numa rede social, para usar os seus conhecimentos e talentos, para fazer tentar fazer a diferença que ´”nós geeks” podemos fazer, para mudar o mundo fazendo-o um pouco melhor! Esta edição, gostava de a dedicar a todos os que fazem diferença, não ficando a ver “o tempo passar”, mas se inquietam todos os dias, para fazer a diferença nas mais diversas áreas , nos mais diversos sectores, nas mais diversas situações! Aqueles que independentemente de tudo, decidem estar inquietos e fazer algo! A todos esses, dedico-vos a revista e deixo-vos o muito obrigado por serem inquietos! Pois como tive oportunidade de ler, “Muda uma vida, muda o Mundo”, obrigado por mudarem o Mundo!
Até à próxima edição, boas leituras! António Santos
A revista PROGRAMAR é um projecto voluntário sem fins lucrativos. Todos os artigos são da responsabilidade dos autores, não podendo a revista ou a comunidade ser responsável por alguma imprecisão ou erro. Para qualquer dúvida ou esclarecimento poderá sempre contactar-nos.
Investigadores de Cibersegurança expuseram novas vulnerabilidades passíveis de exploração por ransomware. Desde robôs com que trabalhamos lado a lado até turbinas de parques eólicos estão sob risco de possíveis ataques. Segun- do a notícia avançada pelo Fiancial Times, na conferência de cibersegurança Black Hat, foram reveladas falhas recentes que demonstram a possibilidade de usar a fraca segurança dos sistemas de controlo industriais.
Estes investigadores expuseram estas falhas para que as empresas as pudessem solucionar. Eles alertam para o facto de software malicioso ou ransomware poderá afetar grave- mente as empresas.
Foram descobertas também graves falhas em parques eóli- cos , como por exemplo a falta de encriptação de mensagens, a utilização de passwords default e a não separação de redes, de forma a que, uma vez que alguém com más intenções entrasse no sistema, poderia controlar até todo um parque.
Recentemente pudemos testemunhar as notícias dos estra- gos e transtornos causados pelo famoso Wannacry. Mas a vulnerabilidade na segurança pode ter outras repercussões.
Ao invés de ser exigido o pagamento de um resgate, pode acontecer que ao explorar essas vulnerabilidades, a própria produção de um produto seja afetada, danificando não so- mente a produção e o aspeto financeiro da empresa em ques- tão mas também a sua reputação.
Teve lugar no Laboratório de Robótica e Equipamentos Inteligentes do Instituto Politécnico de Castelo Branco (IPCB), a 13ª edição consecutiva do estágio “Construir Robôs Inteligentes”. Este evento contou com o apoio da Ciência Viva.
Este ano participaram doze alunos do 10º ao 12º ano de Escolas Secundárias de Lisboa, Setúbal, Pombal, Porto, Sabugal, Fundão e Castelo Branco.
De acordo com a notícia avançada pelo Diário Digital Cas- telo Branco, este estágio pretendeu introduzir a robótica aos alunos, abordando diversos conceitos desde a mecâni- ca, eletrónica e programação, necessários à construção e desenvolvimento de robôs. Os alunos puderam construir robôs inteligentes, capazes de se moverem autonomamen- te e de serem comandados via remota através do telemó- vel.
Iniciaram a semana com a parte de componente mecânica e eletrónica sob o acompanhamento do Professor Paulo Gonçalves e pelos investigadores Bernardo Lourenço, Jo- ão Mendes, Megann Doudy, Paulo Amaral e Rodrigo Ber- nardo. Seguidamente passaram à construção da platafor- ma robótica, respetivos testes e programação, tendo utili- zado o Arduino. Isto constituiu uma nova experiência, bem como a programação do smartphone Android para funcio- nar como comando remoto do robô construído.
Segundo apresentado no DDCB, os alunos avaliaram esta iniciativa como sendo um sucesso: “Convívio, construção do robô e o trabalho em equipa na realização das ativida- des”; “Gostei de montar e de programar os robots e de conhecer novos amigos!”; “A Programação em Arduino, e os efeitos dos códigos no movimento do robô”; “Alguma dificuldade na ligação de fios”; “Apenas uma semana de estágio é pouco. Construir robôs requer muito trabalho, espírito de equipa, perseverança e método.”
Fontes: Diário Digital Castelo Branco, Ciência Viva
Imagem: DDCB
Jovens de Castelo Branco
constroem robôs inteligentes
Raspberry Pi Alexa
Tal como pode ser visto na figura anterior será apresentada a aplicação com as opções numeradas, que permitem efectuar uma série de configurações base necessárias. Apenas nos focaremos nas configurações base necessárias, uma vez que as restantes saem do âmbito deste artigo.
FileSystem” e confirmamos a acção. Será apresentada uma mensagem a indicar que esta acção apenas terá efeito após o reinício do sistema, no entanto podemos prosseguir.
será alterar a password do utilizador “pi”. Para tal seleccionamos a segunda opção “Change user password” e alteramos a password.
português o passo seguinte será recorrer à opção 4 “Internacionalization Options” e será alterado o keyboard layout, para português.
Options), para activar a opção de ligação por SSL, uma vez que não será muito prático ter de andar sempre a ligar e desligar teclados, para o que possamos precisar. Dentro das opções avançadas, seleccionamos “ssh” e de seguida “enable”.
Feitos estes procedimentos, é hora de reiniciar o raspberry, recorrendo ao comando seguinte:
Uma vez reiniciado o sistema, podemos finalmente avançar para a instalação do AlexaPi, que nos permitirá usar o serviço Alexa da Amazon. Mas antes disso, falta-nos apenas um pormenor. É necessário registar o dispositivo na amazon, para que possamos usar o Alexa Voice Service. Caso já tenhamos uma conta developer na amazon, podemos avançar alguns passos, caso contrário o passo seguinte será mesmo o de registar-se na amazon em https://goo.gl/FHmvHf. O processo de registo é simples e intuitivo, pelo que não será detalhado neste artigo. Seguindo para o registo do dispositivo, uma vez feito o login em https://developer.amazon.com, selecionamos a opção “ALEXA” no menu, e de seguida “Alexa Voice Service”. De seguida, escolhemos a opção “Register a Product Type” e posteriormentemente “Device”. Neste momento será visível a “Device Type Info”, na tab esquerda.
Tal como é visivel na imagem exemplo, têm de ser preenchidos os campos “ Device Type ID ” e “ Display Name ”. Convém usar algum nome que seja simples de associar ao que realmente é, mas isso não é de todo difícil. Agora passa- se ao item seguinte, o “Security Profile”. Neste item, clica-se em “ Create a new profile ”, de seguida escolhe-se um “ Security Profile Name ” e “ Security Profile Description ” e clica-se no botão “ next ” para dar continuidade”.
RASPBERRY PI ALEXA
$ sudo shutdown –r now
Na tab “ web settings ” clicamos em “ edit ”, para alterar o conteudo e em “ Allowed Origins ” escrevemos “ http:// localhost:5050 ” e “http://10.0.0.100:5050”, onde o endereço ip, deve ser substituído pelo ip local do nosso raspberry pi. De igual forma em “Allowed return URL’s” preenchemos com “ http://localhost:5050/code ” e “ http://10.0.0.100 ”, trocando novamente o endereço ip pelo do raspberry pi. São necessários preencher mais alguns dados, mas nada de complicado, conforme se pode observar nas figuras seguintes.
Terminada a parte de configurações na Amazon, hora de inslatar o AlexaPi, no raspberry! Para tal, acedemos por ssh, utilizando um software cliente de ssh a gosto, no meu caso o putty, e uma vez feito o login, começamos! A primeira coisa a fazer, será mesmo instalar o git no raspbian. Para tal recorremos ao seguinte comando na bash:
Com o git instalado, podemos partir para a fase seguinte. Primeiramente deslocamos o cursor para a pasta /opt com o seguinte comando:
Agora vamos clonar o repositório git do projecto AlexaPi, para podermos prosseguir com a instalação.
E executamos o script de instalação do Alexa pi:
Terminada a instalação e antes de se avançar para o arranque do AlexaPi, uma vez que no caso deste artigo foi usado um headset usb, tal como já foi referido, temos de efectuar algumas configurações adicionais, caso contrário o rasbpian irá utilizar os dispositivos audio padrão do raspberry pi. Para tal começamos por desabilitar o PA.
De seguida, temos de editar o ficheiro client.conf que se encontra em /var/lib/AlexaPi/.config/pulse/, e definir o valor “autospawn” para “no”. Para tal recorremos a um editor de texto. Neste caso será usado o nano, mas pode ser usado o que o leitor preferir.
Dentro do ficheiro colocamos o seguinte:
Feito isto, proseguimos para as configurações com o objectivo de executar o PA (Pulse Audio) em modo de todo os sistema (System-wide mode), uma vez que esta é a forma mais segura de utilizar o PA com o AlexaPi. Para tal começamos por executar os seguintes comandos:
Voltamos a editar o ficheiro client.conf que se encontra em / var/lib/AlexaPi/.config/pulse/ e a definir o “ autospawn=no ”. Agora temos de dar permissões de escrita ao ficheiro de log do alexa pi, com o seguinte comando:
De seguida adicionamos o utilizador que vamos usar no raspberry, ou por defeito o utilizador pi e o utilizador alexapi ao grupo de utilizadores pulse-access e o utilizador
RASPBERRY PI ALEXA
$ sudo nano /var/lib/AlexaPi/.config/pulse/ client.conf
$ sudo apt-get install git
$ cd /opt
$ sudo git clone https://github.com/alexa-pi/ AlexaPi.git
$ sudo ./AlexaPi/src/scripts/setup.sh
$ sudo mkdir -p /var/lib/AlexaPi/.config/pulse $ sudo cp /etc/pulse/client.conf /var/lib/ AlexaPi/.config/pulse/
$ sudo chown -R alexapi:alexapi /var/lib/AlexaPi/ $ sudo usermod --home /var/lib/AlexaPi alexapi
$ sudo apt install pulseaudio pavucontrol $ sudo apt remove pavumeter paman padevchooser
$ sudo mkdir -p /var/lib/AlexaPi/.config/pulse $ sudo cp /etc/pulse/client.conf /var/lib/ AlexaPi/.config/pulse/
autospawn = no
O código do programa será o seguinte:
Escrito o código e colocado a correr, temos de criar uma capacidade (skill) para a Alexa. Para isto voltamos à consola da Amazon, selecionamos “Alexa” e depois “Alexa Skill Set”, e por fim “Add a new skill”.
É necessário preencher a grande maioria dos campos, mas como são intuitivos, vamos apenas focar os mais importantes. Em “ Skill Name ”, escrevemos “RPI Control” e em “Invocation name” escrevemos “raspberry pi”. Em “Interaction Model” colocamos o código referente ao esquema pretendido “ intent schema ”.
Em “ Add Slot Type ” dentro de “ Enter Type ” escrevemos “GPIO_Control” e em “Enter Values” escrevemos “on” e “off” e em “uterrance”, os seguintes valores:
RASPBERRY PI ALEXA
"intents": [ { "slots": [ { "name": "status", "type": "GPIO_CONTROL" } ], "intent": "GPIOControlIntent" } ] }
GPIOControlIntent to turn lights {status} GPIOControlIntent to turn {status} the lights
from flask import Flask from flask_ask import Ask, statement, convert_errors import RPi.GPIO as GPIO import logging GPIO.setmode(GPIO.BCM) app = Flask(name) ask = Ask(app, '/') logging.getLogger("flask_ask").setLevel (logging.DEBUG) @ask.intent('GPIOControlIntent', mapping= {'status': 'status'}) def gpio_status(status): if status in ['on','high' ]: GPIO.setup(21, GPIO.IN) state = GPIO.input(21) if (state == True): GPIO.setup(21, GPIO.OUT) GPIO.output(21,GPIO.HIGH) return statement('Lights are already on') else: GPIO.setup(21, GPIO.OUT) GPIO.output(21,GPIO.HIGH) return statement('Turning lights {}'.format (status)) if status in ['off','low' ]: GPIO.setup(21, GPIO.IN) state = GPIO.input(21) print('status of light',state) if (state == False): GPIO.setup(21, GPIO.OUT) GPIO.output(21,GPIO.LOW) return statement('Lights are already off') else: GPIO.setup(21, GPIO.OUT) GPIO.output(21,GPIO.LOW) return statement('Turning lights {}'.format (status)) if name == 'main': port = 5000 #a porta pode ser definida pelo #programador app.run(host='0.0.0.0', port=port)
Agora em configuração seleccionamos “ HTTPS ” como Endpoint do serviço e escolhemmos a região, no nosso caso “ Europe ”. Por fim, na caixa destinada ao url, digitamos o url que foi gerado quando executamos pela primeira vez o ficheiro gpio_control.py. O endereço seve ser algo semelhante a: https://dd3F58A9.ngrok.io.
E para terminar esta parte, em SSL Certificate, escolhemos “My development endpoint is a sub-domain of a domain that has a wildcard certificate from a certificate authority”. E agora testamos no simulador, e vêmos o resultado no raspberry.
Com tudo isto terminado, gravamos e podemos fechar o Amazon developer.
Agora sim, podemos dizer ao micro do raspberry que tem o AlexaPi instalado “Alexa, tell Raspberry Pi to turn light on” e veremos o led acender! Conclusão Apesar do equipamento Amazon Echo não estar ainda disponível em Portugal, a utilização do serviço da amazon não é de todo impossível, ainda que apenas fale e entenda a lingua inglesa. Existem bastantes dispositivos compatíveis com Alexa, como por exemplo os WeMo, que podem ser simulados usando um ESP8266, além de diversos dispositivos compatíveis, disponibilizados por diversos fabricantes, como o caso da Itead. Poderá ser engraçado para o leitor aventurar-se a ligar outros equipamentos utilizando o GPIO do raspberry Pi, ou até quem sabe em lugar de utilizarem o raspberry para instalar a Alexa, utilizar por exemplo um “C.H.I.P.” de menores dimensões e maior eficiência energética. Ao longo deste artigo instalamos e configuramos o AlexaPi e de seguida usamos um outro raspberry pi, para criar um pequeno circuito e adicionar uma skill à Alexa que lhe permitiu acender e apagar um led. Muito mais pode ser feito, mas isso fica ao critério da imaginação do leitor!
RASPBERRY PI ALEXA
Escrito por António C. Santos Programar é criar um novo mundo escrevendo código, cumprindo os mais elementares desígnios da vida, “aprender, ensinar, criar, partilhar, melhorar e seguir”. Formou-se no Instituto Politécnico de Viana do Castelo. Membro da Comunidade Portugal-a-Programar desde Agosto de 2007, é também membro da Sahana Software Foundation, onde é Programador Voluntário desde 2012, actualmente exerce funções de mentor voluntário na plataforma MOOC Coursera. Twitter:@apocsantos
AUTOR
Pseudo-random Number Generators , ou simplesmen- te PRNGs, são algoritmos para geração de números com propriedades semelhantes à dos números aleatórios ( random numbers ). Os PRNGs produzem sequências de números aparentemente independentes, normalmente se- guindo uma distribuição uniforme, com base numa expres- são matemática. São normalmente definidos pelos seguintes aspetos: o seu output é determinístico, periódico e depende de um valor de inicialização, conhecido como seed. Este tipo de algoritmos (os PRNGs) são normalmente mais rápidos que a geração de números realmente aleatórios no /dev/ random ou /dev/urandom (por exemplo, disponíveis numa distribuição Linux), uma vez que o SO usa o input de dados de interfaces de hardware, p.ex., o rato, tráfego de rede da NIC ( Network Interface Controller ), et cetera. Um outro exemplo de um true random number gene- rator é o random.org, onde são usados dados de ruído at- mosférico como input de aleatoriedade.
PRNGs
PRNGs representam peças cruciais dentro do contex- to da simulação computacional, pois permitem criar situa- ções aleatórias pelas quais um evento do mundo real é afe- tado. Assim, uma falha em termos da qualidade de Random- ness pode resultar numa reprodução deficiente do modelo de simulação, levando possivelmente a conclusões falsas ou deficientes. Processamento é sinónimo de tempo, e os PRNGs produzem resultados num espaço temporal consideravel- mente menor em relação a outro tipo de geradores de núme- ros e sequências aleatórias. Um exemplo desse facto é a geração de tráfego de rede, onde a distribuição dos resulta- dos deve ser controlada e seguindo uma distribuição expo- nencial, e não deve ser morosa (i.e., o tempo de processa- mento não pode ser muito elevado). PRNGs são também usados em máquinas de jogos online , jogos de vídeo e aplicações de segurança informáti- ca. No campo de segurança da informação, os PRNGs são muitas vezes a fonte de chaves de criptografia, nonces , hashs ou cifras. Nem todos os PRNGs podem ser usados em todas essas aplicações, uma vez que nem todos cum- prem com exatidão algumas das regras que lhes permite serem a fonte para determinadas implementações criptográ- ficas. Para criptografia são usados um tipo específico de PRNGs conhecidos por CSPRNGs (geradores de número pseudo-aleatório criptograficamente seguros), com proprie- dades que os tornam adequados para esse contexto.
Pseudorandom Number Generators (PRNGs)
Hoje em dia, existem muitos algoritmos para geração de números pseudo-aleatórios com distribuição uniforme, como p.ex., LCG, ISAAC, Mersenne Twister, etc., todos defi- nidos por características próprias:
vem ser independentes uns dos outros);
ro 2 é igual à probabilidade de sair o número 7);
quência novamente com determinados parâmetros iniciais).
De notar que as propriedades acima citadas são difi- cilmente conciliáveis, pelo que a seleção de um gerador con- veniente para uma dada situação pode ser uma tarefa não muito trivial. PRNGs são então funções matemáticas que debitam uma sequência finita de números, isto é, a dada altura a se- quência de números começa a repetir-se. Ao tamanho dessa sequência é chamado período.
O LCG é o PRNG mais popular dentro deste contexto e usado largamente para geração de números pseudo- aleatórios com uma distribuição uniforme. Ele é de fácil im- plementação, tem alta performance computacional e simples de entender. É bastante usado a nível científico. O LCG é um PRNG que gera sequências de inteiros pseudo-aleatórias com base na expressão matemática
Xn = aX (^) n-1 + b mod M
em que a, b e M são números inteiros com determinadas características. Como se pode concluir da definição, cada número da sequência Xn é produzido a partir do seu ante- cessor Xn-r. Alguns destes geradores usam um número pri- mo como M e b igual a 0. O número máximo que o período que estes geradores podem atingir é M e, para que isso aconteça, a e b devem preencher requisitos adicionais. Por exemplo, de uma maneira geral, a-1 deve ser divisível por todos os primos que fatorizam M, e b deve ser coprimo com
java.util.Random gera um número aleatório?
java.util.Random tem um período e repete-se passadas algu- mas iterações ...
M. Se M for uma potência de 2 (muito comum em implementa- ções práticas, já que operações módulo 2 32 ou 2^64 são simples de implementar em máquinas de 32 ou 64 bits), então a-1 deve ser divisível por 4. A escolha dos valores que parametrizam o gerador é crítica para manter uma qualidade mínima dos números gera- dos. Por exemplo, pode verificar-se a partir da seguinte iniciali- zação que o gerador acima descrito (LCG) degenera num gera- dor fraco. a=4 b=2 M= Considere começar com X 1 = 1. A sequência gerada é a seguinte:
= 4 × 1 + 2 mod 8 = 6;
= 4 × 6 + 2 mod 8 = 2;
= 4 × 2 + 2 mod 8 = 2; …
A sequência é dada por: (1, 6, 2, 2, 2, …). Começou a repetir o valor 2 logo a partir do terceiro valor. Para os parâme- tros iniciais definidos anteriormente (incluindo o X1), o período desta sequência é 3. Na verdade, é difícil garantir excelente comportamento para sequências produzidas com um LCG, mas é pelo menos possível garantir que o período máximo (i.e., M) é atingido. Para garantir que o LCG tem um período M, podem ser defini- das algumas regras à cabeça, nomeadamente: b e M têm de ser co-primos, e a-1 tem de ser divisível por todos os factores primos de M. Ter um período completo significa que a sequência co- meça a repetir-se apenas após M, e antes que isso aconteça, a sequência é constituída por todos os valores possíveis módulo M. Para que isso aconteça é importante determinar a melhor parametrização. Se forem considerados agora os seguintes parâmetros de inicialização: a=4 b=3 M=16,as regras impostas acima são satisfeitas, i.e.: M é potência de 2 (16= 2 4 ), a-1=4 e divisível por 4, e 3 e 16 são números co-primos. Neste caso, aplicando as regras definidas, consegue-se que o máximo período para os parâmetros de inicialização com módulo M=16 seja atingido. A sequência produzida, começan- do por X1 = 10, seria: (10, 5, 12, 15, 14, 9, 0, 3, 2, 13, 4, 7, 6, 1, 8, 11, 10, …) Mas se um PRNG não é infinito, qual é o período máxi- mo do LCG? Isto é, quantos números diferentes são possíveis gerar para uma sequência com este algoritmo?
É comum encontrarem-se geradores com o tamanho do período igual a ou múltiplo do tamanho máximo de um registo inteiro no CPU, (e.g., 2 32 , que numericamente é re- presentado pelo valor 4294967296 -- 32 bits de 1’s). A título de exemplo, é possível obter um LCG com um período de 2³² com a seguinte parametrização:
rseed=(rseed 1103515245+12345)&RAND MAX O java.util.Random é um LCG que gera números ale- atórios de 248 bits através do UNIX rand48, usando apenas os primeiros 32 bits como output útil.
O java.util.Random é um LCG que gera números ale- atórios de bits através do UNIX rand48, usando apenas os primeiros 32 bits como output útil. Teste Estatístico ao LCG
Existem baterias de teste preparadas para testar exaustivamente PRNGs, nomeadamente a TestU01. O códi- go acima entregue já possui a implementação do LCG usado no java nesta biblioteca de teste de PRNGs. O resultado da qualidade do LCG é a seguinte para a bateria de testes mais modesta, conhecida por SmallCrush:
PSEUDORANDOM NUMBER GENERATORS (PRNGS)
#include "unif01.h" #include "bbattery.h" #include <stdio.h> #include <time.h> #include <stdlib.h> #include <math.h> #include "ulcg.h" #define norm 2.328306549295728e- unsigned int rseed = 5; double lcg(){ return (rseed=(rseed * 1103515245 + 12345) & RAND_MAX)*norm; } int main (void) { unif01_Gen gen; gen = unif01_CreateExternGen01 ("MyLCG", lcg); / My LCG */ bbattery_SmallCrush (gen); unif01_DeleteExternGen01 (gen); return 0; }
Nesta edição trazemos até vós caros leitores uma abordagem ao algoritmo de backpropagation. Este algoritmo foi desenvolvido nos anos 80 por Ru- melhant, Hinton e Williams e é um dos algoritmos mais conhecidos das redes neuronais. De forma a melhor introduzirmos o tema, uma rede neuronal artificial é inspirada no funcionamento nosso próprio sistema funcional enquanto humanos. Ou seja, é uma rede que aprende a cada experiência vivenciada. Um dos constituintes principais do siste- ma nervoso humano é o neurónio. Esta célula é res- ponsável pela condução dos impulsos nervosos, e comunicam entre si através de sinapses. Por sua vez a sinapse é a região onde dois neurónios entram em contacto entre si, sendo que os impulsos recebidos, por exemplo, pelo neurónio X, são processados pas- sando a informação resultante ao neurónio Y por meio de uma substância neurotransmissora. Sem querer alongar muito este tema biológico, podemos apenas dizer que os neurónios são formados por dendritos (funcionam como terminais de entrada), pelo corpo central (onde ocorre o processamento) e pelos axónios (que por sua vez funcionam como ter- minais de saída). As redes neuronais artificiais são redes com- putacionais que apresentam um modelo matemático inspirado na estrutura neuronal anteriormente apre- sentada e que adquirem conhecimento através de cada experiência processada, simulando assim a in- teligência humana. Este comportamento é possível graças às interacções entre as diversas unidades de processamento que constituem estas redes. Uma vantagem deste tipo de implementação algorítmica é que possui um elevado grau de paralelismo, caracte- rística que lhe proporciona uma elevada rapidez de processamento. Então temos que numa rede neuronal existe três tipos de camadas:
tados à rede;
maior parte do processamento, através das conexões ponderadas que podem ser consideradas como extrato- ras de características;
cluído e apresentado.
O desenvolvimento do algoritmo backpropagation defende que é possível “treinar” as camadas intermédias, resultando no modelo MLP (Multilayer Perceptron), isto é, são redes de múltiplas camadas, formadas por uma camada de entrada, uma ou mais camadas ocultas (intermédias) e uma camada de saída, como pode ser visto na imagem ante- rior. Cada neurónio de uma camada recebe os sinais de to- dos os neurónios da camada anterior e propaga os seus dados de saída a todos os neurónios da camada posterior. Para um melhor enquadramento teórico do leitor, é importante referir que o algoritmo de backpropagation é apenas um dos muitos que podem ser usados num modelo MLP. Existem dois tipos de algoritmos de treino, os supervi- sionados e os não supervisionados. Os algoritmos supervisionados necessitam de um vector de entrada e de um vector de saída (também conhe- cido como vector alvo), ambos são utilizados para o treino da rede neuronal. Quando o vector de entrada é aplicado, a saída é calculada e comparada com o vector alvo correspondente. O erro encontrado é então reassumido pela rede neuronal e os pesos são actualizados de forma a minimizar o erro. Este processo é repetido até que o erro dos vectores seja corre- spondente ao valor pré-definido para cada conjunto. Por sua vez, os algoritmos não supervisionados, não têm um vector alvo para os dados de saída, não tendo assim qualquer comparação para determinar a solução ideia. Neste caso, o algoritmo modifica dos pesos da rede de forma a que os valores de saída sejam consistentes O método backpropagation é um algoritmo supervi- sionado. Correndo o risco de me repetir, mas ajudando a cimentar tudo o que já foi escrito atrás, durante o treino, a rede comporta-se da seguinte forma:
rede. Este processamento flui através da rede, cama- da por camada, até que a resposta seja produzida pela camada de saída.
saída desejada para esse padrão particular. Se esta não estiver correta, o erro é calculado e o mesmo é propagado a partir da camada de saída até a camada de entrada, e os pesos das conexões das unidades das camadas internas vão sendo modificados con- forme o erro é retropropagado (daí o nome do algorit- mo…) Ou seja, este algoritmo tem duas fases distintas (também conhecidas como a fase Forward - em que é definida a saida da rede para um dado padrão de entrada e a fase Backward – em que a diferença entre o resultado desejado e o resultado obtido é utilizada para atualizar os pesos das conexões).
Algoritmo BackPropagation
Um ponto importante nas redes que utilizam este algo- ritmo é que as mesmas utilizam uma variação Delta própria. Esta regra do Delta generalizado implementa um gradiente descencente no quadrado da soma do erro em funções line- ares, o que provoca a que as redes possam ficar sujeitas aos problemas dos minimos locais.
Sem querer levar demasiado este artigo para o lado matemático do algoritmo, é importante deixar ao leitor algumas considerações sobre a “Regra Delta Generalizada”…
dades com uma função de ativação semi-linear, isto é, uma função diferenciável e não decrescente, como por exemplo, a função Sigmoid.
de erro. A este processo de redução gradativa do erro que acompanha a minimização dá-se o nome de con- vergência.
cionalidade no intervalo [0,1], pois este procedimento requer apenas que a mudança no peso seja proporcion- al à meta que queremos atingir.
passos infinitesimais pois quanto maior for a constante
utilizada, maior será a mudança dos pesos, aumen- tando assim velocidade de aprendizagem da rede, o que pode levar à oscilação do modelo na sua super- fície de erro. Uma maneira de aumentar a taxa de aprendizagem sem levar à oscilação da rede é modificando a regra Delta Generalizada de forma a incluir o termo momentum, uma constante que determina o efeito das mudanças que a rede sofreu anteriormente dos pesos na direção atual do mo- vimento no espaço dos pesos.
Mais uma vez, quero recordar que esta é só uma forma de implementação do algoritmo, muitas outras poderiam ser usa- das, como por exemplo esta em linguagem C: http:// courses.cs.washington.edu/courses/cse599/01wi/admin/ Assignments/bpn.html
Desejo a todos os leitores, boas implementações, até à próxi- ma edição!
// adjusts the weight of the out- put neuron, based on its er- ror outputNeuron.error = sigmoid.derivative(outputNeuron.output)
(results[i] - outputNeu- ron.output); outputNeuron.adjustWeights(); // then adjusts the hidden neu- rons' weights, based on their er- rors hiddenNeuron1.error = sigmoid.derivative(hiddenNeuron1.output)
outputNeuron.error * outputNeuron.weights [0]; hiddenNeuron2.error = sigmoid.derivative(hiddenNeuron2.output)
outputNeuron.error * outputNeuron.weights [1]; hiddenNeuron1.adjustWeights(); hiddenNeuron2.adjustWeights(); } if (epoch < 2000) goto Retry; Console.ReadLine(); } } }
// desired results double[] results = { 0, 1, 1, 0 }; // creating the neurons Neuron hiddenNeuron1 = new Neuron(); Neuron hiddenNeuron2 = new Neuron(); Neuron outputNeuron = new Neuron(); // random weights hiddenNeuron1.randomizeWeights(); hiddenNeuron2.randomizeWeights(); outputNeuron.randomizeWeights(); int epoch = 0; Retry: epoch++; for (int i = 0; i < 4; i++) // very //important, do NOT train for only one example { // 1) forward propagation //(calculates output) hiddenNeuron1.inputs = new double[] { inputs[i, 0], inputs[i, 1] }; hiddenNeuron2.inputs = new double[] { inputs[i, 0], inputs[i, 1] }; outputNeuron.inputs = new double[] { hiddenNeuron1.output, hiddenNeuron2.output }; Console.WriteLine("{0} xor {1} = {2}", inputs[i, 0], inputs[i, 1], outputNeuron.output); // 2) back propagation (adjusts weights)
AUTOR
Escrito por Rita Peres Natural de Castelo Branco, licenciou-se em Engenharia Informática pela Universidade da Beira Interior. Membro do P@P desde Janeiro de 2010. Embaixadora das Geek Girls Portugal – Núcleo de Lisboa.
Up-Ciclar a velhinha aparelhagem Hi-Fi