Vídeo Aulas de Técnicas de Programação

Bom, este será um quick-post:

Basicamente, eu estou abrindo um mini-curso de técnicas de programação. A idéia são pequenas aulas, de 10 a 15 minutos, falando sobre Orientação a Objetos, Testes Automatizados, Programação Funcional, Closures, Tipagem, e mais um monte de coisas que seria legal todo programador saber (mas que infelizmente, nunca vemos na faculdade).

A página oficial das vídeo-aulas é: http://snipurl.com/programacao. Os vídeos estão hospedados no YouTube, na URL: http://snipurl.com/programacao-videos. Não vou duplicar o conteúdo que já está na página, mas já adiantando, as vídeo-aulas são principalmente para quem já sabe algo de programação, mas tem dúvidas ainda em como aplicar os conceitos, como montar um sistema, etc.

Sugestões, como sempre, são bem-vindas. Bons estudos!

Publicado em Quick Post, Vídeo Aulas | 1 Comentário

Redes Neurais – Parte 3

Ok, vamos finalmente para a terceira parte sobre Redes Neurais (e também, aonde será apresentado o código completo de uma rede neural em Ruby). Este post será sobre treinamento de redes neurais, especificamente sobre o treinamento dos pesos que saem dos neurônios de entrada e vão para os neurônios ocultos da rede. Antes de mais nada, vamos relembrar nosso desenho da rede neural:

Neural

Já vimos no post anterior que para achar o valor que MAXIMIZA a função de custo, usamos o métoodo chamado de “gradiente”. O método “gradiente” usa derivadas parciais, e como vamos achar o valor de um peso que sai do neurônio de entrada para o neurônio da camada oculta, precisamos calcular a derivada parcial da função de custo em relação a um destes pesos. Vamos usar o “peso_a1_b2″ para este exemplo.

Antes de mais nada, vamos relembrar todas as contas que fazemos para nossa rede neural. Para tal, eu vou usar a notação “peso_ax_by” para indicar o peso que sai do neurônio “ax” e vai para o neurônio “by”. Note que NÃO EXISTE “peso_a1_b1″, porque o neurônio “b1″ é o “bias”, logo o valor dele é sempre “1″ (e não faria sentido calcular um valor se ele vai descartá-lo e usar “1″, no fim das contas). Sabemos que o valor de um neurônio oculto é a soma de todos os valores dos neurônios de entrada (multiplicados por seus devidos pesos) e aplicadas uma “função de ativação” (que no nosso caso, é a “Tangente Hiperbólica”). Eu vou chamar de “b_sem_ativacao_x” o valor desta soma dos neurônios de entrada, ANTES de se aplicar a função de ativação. Logo, nossas contas são:

b\_antes\_ativacao\_2 = a1 * peso\_a1\_b2 + a2 * peso\_a2\_b2 + a3 * peso\_a3\_b2 \\  b\_antes\_ativacao\_3 = a1 * peso\_a1\_b3 + a2 * peso\_a2\_b3 + a3 * peso\_a3\_b3 \\  b\_antes\_ativacao\_4 = a1 * peso\_a1\_b4 + a2 * peso\_a2\_b4 + a3 * peso\_a3\_b4 \\  \\  b2 = tanh(b\_antes\_ativacao\_2) \\  b3 = tanh(b\_antes\_ativacao\_3) \\  b4 = tanh(b\_antes\_ativacao\_4) \\  \\  c1 = b1 * peso\_b1\_c1 + b2 * peso\_b2\_c1 + b3 * peso\_b3\_c1 + b4 * peso\_b4\_c1 \\  c2 = b1 * peso\_b1\_c2 + b2 * peso\_b2\_c2 + b3 * peso\_b3\_c2 + b4 * peso\_b4\_c2 \\  \\  custo = \frac{1}{2 * N} * \sum\limits_{n=1}^N \sum\limits_{i=1}^2 (ci(do\ exemplo\ n) - yi(do\ exemplo\ n)) ^ 2
Continuar lendo

Publicado em Algoritmos | Marcado com , , , , , , | Deixe um comentário

Redes Neurais – Parte 2

No post anterior, vimos como montar a estrutura de uma rede neural. Neste post, veremos como fazer o treinamento dos pesos, para que a rede generalize nossos exemplos de teste e seja capaz de classificar exemplos que ainda não foram vistos. Num primeiro momento, vamos relembrar o desenho de uma rede neural:

Neural

Para facilitar, deixei um nome para cada neurônio (nota: provavelmente vocês não vão encontrar essa forma de nomear os neurônios em lugar algum-eu coloquei essa nomenclatura mais para facilitar o post do que para ser uma abordagem matemática mesmo). Os neurônios “a1″ e “b1″ são “bias”, conforme vimos no post anterior, e os neurônios “c1″ e “c2″ são os neurônios de saída. Note que este desenho de rede neural não representa nossa rede neural, pois nossa rede neural precisaria de 5 neurônios de entrada e 3 de saída. Bom, conforme vimos no post anterior, num primeiro momento os pesos sinápticos (as linhas ligando os neurônios, representadas pelas matrizes “input_weights” e “hidden_weights” no post anterior) são aleatórios, o que significa que a rede possuirá comportamento aleatório. A partir deste ponto, temos que alterar os pesos para tentar chegar num resultado melhor da rede. Para tal, precisamos de uma função que nos mostre quão bom é a solução atual: uma “função de custo”.
Continuar lendo

Publicado em Algoritmos | Marcado com , , , , , , , | 3 Comentários

Redes Neurais For Dummies

Ultimamente, muito tem-se falado sobre “machine learning” e redes neurais, então resolvi tentar trazer à luz alguns conceitos que eu tenho aprendido e que tem pouca (ou nenhuma) informação fácil na internet. A primeira coisa a se pensar é que todo o conceito de Redes Neurais, SVM, e outras técnicas de Machine Learning são áreas da matemática, portanto tudo o que for processado numa Rede Neural tem que, de alguma forma, ser convertido para números (o que não é exatamente um problema na maioria dos casos).

As redes neurais podem ser usadas para prever determinados valores, mas são principalmente usadas no processo de classificação de algo (por exemplo, eu tenho um conjunto de sintomas e quero classificar esse conjunto em uma doença conhecida) ou clusterização/agrupamento de valores (da mesma forma, eu tenho um conjunto de características de um país e quero separá-lo em conjuntos). Existem vários modelos de redes neurais, e neste primeiro post vou falar da rede perceptron. Este post está dividido em duas partes, a primeira (este post) será a montagem de uma rede neural, e a segunda, será sobre o treinamento da rede.

Neural
Continuar lendo

Publicado em Algoritmos | Marcado com , , , , , | Deixe um comentário

Usando a Tipagem de Scala para Validar Parâmetros

Bom, primeiramente, muita coisa aconteceu por isso a falta de postagens, mas espero que daqui pra frente seja possível postar mais coisas interessantes.

Esses dias, estou tentando encapsular um código Java em um código Scala, basicamente, um código de matrizes, multiplicação de matrizes, etc, e será este o exemplo que usarei neste post. Para os que não lembram de matrizes, as operações sobre matrizes devem seguir uma determinada regra, por exemplo, adição de matrizes só podem ser efetuadas quando as duas matrizes possuem mesmo número de elementos:

class Matrix(protected val list: List[List[Double]] {
  def +(other: Matrix) = new Matrix(list zip other.list map { case(me, other) =>
    me zip other map { case(e1, e2) => e1 + e2 }
  })
}

Para os que não conhecem tão bem Scala, o código a seguir soma uma matriz com a outra chamando o método zip, que basicamente, de posse de dois objetos que possam ser iterados (tipo um List), combinam seus elementos:

List(1, 2, 3) zip List(4, 5, 6)
=> List( (1, 4), (2, 5), (3, 6) )
List(List(1, 2)) zip List(List(3, 4))
=> List( (List(1, 2), List(3, 4)) )

O “case”, no map (e no foreach, e em qualquer closure) separa os dois elementos. Seria possível separar também com map { e => e._1, e._2 } mas fica um pouco mais feio o código.

Legal, o código acima funciona mas… ele permite somar matrizes de dimensões diferentes. Claramente, isso não é desejado. Podemos fazer o método nos retornar um erro quando tentarmos somar matrizes de dimensões diferentes:

  def +(other: Matrix) = {
    require(list.size == other.list.size, "Number of rows must be the same")
    require(list(0).size == other.list(0).size, "Number of cols must be the same")

    new Matrix(list zip other.list map { case(me, other) =>
      me zip other map { case(e1, e2) => e1 + e2 }
    })
  }

Ou podemos usar a tipagem para isto.
Continuar lendo

Publicado em Scala | Marcado com , , , , | Deixe um comentário

Scala, Traversable, e Implicits

Meu primeiro post bem técnico sobre Scala, vamos ver no que dá (rs).

Bom, primeiro, um pouco de “background”: comecei o fantástico curso de Machine Learning no site coursera.org, e todas as lições que estão no site são em Octave/Matlab. Não conhecia Octave, muito menos Matlab, e quando programei nestas linguagens descobri algumas coisas meio estranhas (bom, eu pelo menos considero estranho que, ao esquecer de colocar um “;” no final de um comando, ele imprima o resultado na tela), além, claro, de não ser possível programar pra Android, por exemplo.

Como estou estudando Scala, e como já consegui fazer Scala rodar no Android de um jeito menos “doloroso” (mais sobre isso em outro post), resolvi fazer os códigos em Scala. Há bibliotecas boas de multiplicação de matrizes em Scala, porém comparadas com as versões Java, elas são BEM mais lentas. Foi aí que pensei: por que não encapsular uma dessas bibliotecas Java em Scala?

Tudo correu bem, até o momento que resolvi que queria que cada matriz funcionasse como um Traversable. Para quem é de Ruby, o Traversable é equivalente ao Enumerable, com algumas coisas a menos e outras a mais. Só para comparar, vamos ver o código dos dois (para simplificar, vou omitir alguns códigos, mas a API é a seguinte: Matrix#rows e Matrix#cols para saber o número de linhas e colunas, Matrix#* multiplica matrizes ou uma matriz com um número. Também, a matriz possui um atributo, “list”, que contém um array de arrays com os elementos internos da matriz).

class Matrix(list: List[List[Double]]) extends Traversable[Double] {
  def cols = 3 //Só pro nossos códigos de exemplo compilarem...
  def foreach[B](function: Double => B) = list.flatten.foreach { e => function(e) }
}
class Matrix
  include Enumerable
  def each(&b)
    list.flatten.each &b
  end
end

Repare que o código é semelhante nas duas linguagens, a diferença básica é que em Ruby não precisamos definir tipos, em Scala precisamos (não que nesse caso faça alguma diferença). Só que temos um caso engraçado tanto em Ruby como em Scala: se queremos um método que, digamos, eleve todos os elementos ao quadrado, elemento por elemento, ao usar “map” para fazer esse processo, ele vai nos retornar, em Ruby, um Array, e em Scala, um Traversable[Double]. E pior, os elementos vão ficar “achatados”. Em ambos, é possível resolver isso fazendo o “each” (ou o “foreach”) retornar uma lista de elementos que está em cada linha, mas ainda assim temos o problema que nosso retorno será semelhante a um “array de arrays”, não uma matriz. O que fazer?

Bom, em Ruby, a gente se ferrou, literalmente. Não temos uma maneira de fazer isso que não envolva sobrescrever o map, e todos os métodos que constrõem uma lista a partir de outra. Em Scala, temos “implicits”, e um conceito “canBuildFrom”.
Continuar lendo

Publicado em Scala | Marcado com , , | Deixe um comentário

Extraindo o Máximo do Android

Bom, estes dias comprei um Android, um Samsung Galaxy S2, e como todo bom usuário de Linux, já fiz algumas modificações no sistema. A coisa que achei mais diferente é a dificuldade de achar informações sobre como fazer as alterações, tal como “root” ou instalações de ROMs customizadas. Então, resolvi postar aqui como fazer estas alterações.

Em primeiro lugar, vale mencionar algumas coisas sobre o Android. Como todo Linux, ele possui um “kernel” separado do sistema. Além disso, o Android é dividido em um sistema base que fica montado em “/system”, e uma área para os dados dos aplicativos (possível de ser escrita pelo usuário) montado em “/sdcard”. No meu caso, ainda, ele possui um cartão SD externo, que fica montado em “/sdcard/external_sd”. Além disso há uma sopa de letras tipo “FactoryFS”, “Modem”, “Secondary Kernel” e outras coisas que eu entendo só por cima.

Para adquirir acesso “root”, há várias formas diferentes. Uma delas consiste em instalar um kernel diferente, mas aí você ganha um triângulo amarelo no seu celular quando você vai iniciá-lo, então todo mundo fica sabendo que você fez uma modificação. A outra, consiste em instalar um sistema de arquivos diferente. Basicamente o processo é fazer um “flash” no celular, com um kernel modificado (no primeiro caso) ou com um sistema modificado (no segundo). Para o Linux, uso o software “heimdall” (http://www.glassechidna.com.au/products/heimdall/). A versão 1.3.2 me deu problemas, então instalei a 1.3.1 e passei ao processo de flash. Eu recomendo o segundo método, pois o triângulo amarelo não fica presente, e basicamente consiste em baixar esta imagem: http://brasildroid.com.br/galaxy-s-ii-i9100-geral/6187-tutorial-root-ics-firmware-claro-tim-vivo-and-unbranded-oi.html. Depois, basta descompactá-la (usando zip ou rar), e você vai ter um arquivo .tar.md5 ou um arquivo .tar. Para descompactar esse arquivo, basta usar “tar -xf arquivo”, e finalmente a imagem está pronta para o processo de flash.

O processo de flash é bem simples, mas antes de fazê-lo, lembre-se de algumas coisas: primeiro, o suporte técnico da Samsung VAI encher o saco se descobrir que você fez uma modificação dessas no celular, e você pode perder a garantia. Segundo, faça o processo, de preferencia, de um notebook, e SEMPRE com o celular com bateria cheia ou quase cheia-não queremos que ausência de energia (tanto do PC como do celular) estraguem o processo todo, certo?

Então, para fazer o flash, basta deixar o celular num modo específico (modo de download) desligando-o e segurando “power+home+abaixar volume”. Ele pedirá uma confirmação, basta confirmar com o “aumentar volume”, e usar o heimdall. Eu rodei-o com o comando:

sudo heimdall flash --primary-boot boot.bin --cache cache.rfs --dbdata dbdata.rfs --factoryfs factoryfs.rfs  --modem modem.bin --param param.lfs --secondary-boot Sbl.bin --kernel zImage

Caso algum problema aconteça, não se desespere-basta tirar a bateria do celular e colocá-la novamente, e de novo deixa o celular em modo de “download” com a sequencia acima.

Enfim, com esse passo, seu celular terá acesso “root” e coisas interessantes podem ser instaladas (rastreadores que ligam automaticamente o GPS, por exemplo, ou o “Scala Installer” que pré-instala Scala no seu android e permite programar em Scala ao invés de Java, sem o processo de build demorado do proguard… mas mais sobre isso num outro post). Mas, se você quer algo mais hardcore, talvez seria interessante testar o CyanogenMod
Continuar lendo

Publicado em Android | Marcado com , , , , , , , | Deixe um comentário