Tem havido alguns desenvolvimentos notáveis recentemente no mundo da inteligência artificial, desde o progresso altamente divulgado com carros sem motorista até as máquinas que agora fazer imitações de Chopin ou apenas seja realmente bom em videogames .
Qual das opções a seguir não é uma ferramenta ou técnica típica usada em design responsivo?
No centro desses avanços estão algumas ferramentas que ajudam a derivar o aprendizado profundo e outros modelos de aprendizado de máquina, principalmente Torch, Caffe e Theano. No entanto, como o Google Brain se tornou open source em novembro de 2015 com seu próprio estrutura , TensorFlow, vimos a popularidade desta biblioteca de software disparar para ser o estrutura aprendizagem profunda mais popular.
Por que isso aconteceu? As razões incluem a grande quantidade de suporte e documentação disponível, sua preparação para produção, a facilidade de distribuição de cálculos em uma variedade de dispositivos e uma excelente ferramenta de visualização: TensorBoard .
Por fim, o TensorFlow consegue combinar um conjunto abrangente e flexível de recursos técnicos com grande facilidade de uso.
Neste artigo, você obterá uma compreensão da mecânica dessa ferramenta usando-a para resolver um problema numérico geral bem diferente do que o aprendizado de máquina normalmente envolve, antes de apresentar seus usos no aprendizado profundo com uma implementação de rede neural simples.
Presume-se um conhecimento básico dos métodos de aprendizado de máquina. Se você precisar se atualizar, verifique este publicação .
Como vamos demonstrar a API Python, uma compreensão do Numpy também é benéfica.
Para configurar o TensorFlow, siga as instruções encontradas Aqui .
Se você estiver usando o Windows, deve observar que, no momento em que redigiu este documento, deve estar usando Python 3.4+, não 2.7.
Então, quando estiver pronto, você deverá ser capaz de importar a biblioteca com:
import tensorflow as tf
A construção de programas TensorFlow geralmente consiste em duas etapas principais, a primeira delas é construir um gráfico computacional que descreverá os cálculos que você deseja realizar, mas não os realizará de fato ou terá qualquer valor.
Como em qualquer gráfico, temos nós e arestas. As arestas representam tensores, um tensor que representa uma matriz n-dimensional. Por exemplo, um tensor com dimensão (ou classificação, na linguagem do TensorFlow) 0 é um escalar, a classificação 1 é um vetor, a classificação 2 é uma matriz e assim por diante.
Os nós representam operações que produzem tensores de saída e tomam tensores como entradas, se necessário. Essas operações incluem adições (tf.add
), multiplicações de matrizes (tf.matmul
), bem como a criação de constantes (tf.constant
).
Portanto, vamos combinar alguns deles em nosso primeiro gráfico.
a = tf.constant([2.5, 2]) b = tf.constant([3, 6], dtype=tf.float32) total = tf.add(a, b)
Aqui, criamos três operações, duas delas para criar arrays 1-d constantes.
s corporação tributada como c corporation
Os tipos de dados são inferidos do argumento de valor transmitido ou você pode denotá-los com o argumento dtype
. Se eu não tivesse feito isso com b
, então um int32
teria sido inferido e um erro dado como tf.add
Eu teria tentado definir uma adição em dois tipos diferentes.
O gráfico está definido, mas para fazer os cálculos sobre ele (ou qualquer parte dele), devemos instalar uma sessão do TensorFlow.
sess = tf.Session()
Como alternativa, se estivermos executando uma sessão em um console interativo, como IPython, usamos:
sess = tf.InteractiveSession()
O run
no objeto de sessão é uma forma de avaliar um Tensor.
Portanto, para avaliar o cálculo de adição definido acima, passamos 'total', o Tensor a ser removido, que representa a saída do op tf.add
.
print(sess.run(total)) # [ 5.5 8. ]
Neste ponto, apresentamos a variável TensorFlow. Onde as constantes são uma parte fixa da definição do gráfico, as variáveis podem ser atualizadas. O construtor da classe requer um valor inicial, mas as variáveis requerem uma operação para inicializá-las explicitamente antes que outras operações sejam executadas nelas.
As variáveis mantêm o estado do gráfico em uma determinada sessão, portanto, devemos observar o que acontece com várias sessões usando o mesmo gráfico para entender melhor as variáveis.
# Crea una variable con un valor inicial de 1 some_var = tf.Variable(1) # Crea una op para ejecutar inicializadores de variables init_op = tf.global_variables_initializer() # Crea una op para reemplazar el valor mantenido por some_var a 3 assign_op = some_var.assign(3) # Instala dos instancias de una sesión sess1 = tf.Session() sess2 = tf.Session() # Inicializa variables en ambas sesiones sess1.run(init_op) sess2.run(init_op) print(sess1.run(some_var)) # Salidas 1 # Cambia some_var en sesión1 sess1.run(assign_op) print(sess1.run(some_var)) # Salidas 3 print(sess2.run(some_var)) # Salidas 1 # Cierra Sesiones sess1.close() sess2.close()
Instalamos o gráfico e duas sessões.
Depois de executar a inicialização em ambas as sessões (se não executarmos isso e depois avaliarmos a variável, encontraremos um erro), apenas executamos a operação de atribuição em uma sessão. Como você pode ver, o valor da variável persiste, mas não em todas as sessões.
Outro conceito importante do TensorFlow é o espaço reservado. Enquanto as variáveis mantêm o estado, os marcadores de posição são usados para definir quais entradas o gráfico pode esperar e seu tipo de dados (e opcionalmente sua forma). Podemos inserir dados no gráfico por meio desses marcadores de posição quando executamos o cálculo.
O gráfico do TensorFlow está começando a se parecer com as redes neurais que queremos treinar, mas antes disso, vamos usar os conceitos para resolver um problema de número comum no mundo financeiro.
Suponha que desejamos encontrar y
em uma equação como esta:
para um v
dado (com a constante C
e P
).
Esta é uma fórmula para calcular o rendimento até o vencimento (y
) em um título com valor de mercado v
, principal P
e cupom C
pagos semestralmente, mas com fluxos de caixa descontados em composição contínua.
Basicamente, temos que resolver uma equação como essa com tentativa e erro e escolheremos o método da bissecção para focar em nosso valor final para y
.
Primeiro, vamos modelar esse problema como um gráfico do TensorFlow.
C
e P
elas são constantes fixas e fazem parte da definição de nosso gráfico. Queremos um processo que refina os limites inferior e superior de y
. Portanto, esses limites (denotados como 'a' e 'b') são bons candidatos para as variáveis que devem ser modificadas após cada suposição de 'y' (que é considerada o ponto médio de 'a' e 'b').
# Especifica los valores que generarán nuestras operaciones constantes C = tf.constant(5.0) P = tf.constant(100.0) # Especificamos los valores iniciales que serán nuestros límites inferior y superior cuando se inicialicen. # Obviamente, el éxito final de este algoritmo depende de puntos de partida decentes a = tf.Variable(-10.0) b = tf.Variable(10.0) # Esperamos que se inserte un número flotante en la gráfica v_target = tf.placeholder('float') # Recuerda que las siguientes operaciones son definiciones, # ninguna se lleva a cabo hasta que se evalúa una operación en una sesión! y = (a+b)/2 v_guess = C*tf.exp(-0.5*y) + C*tf.exp(-y) + C*tf.exp(-1.5*y) + (C + P)*tf.exp(-2*y) # Operaciones para establecer valores temporales (a_ y b_) destinado a ser los próximos valores de a y b. # ej. si la conjetura resulta en una v mayor que la v objetivo, # estableceremos a_ como el valor actual de y a_ = tf.where(v_guess > v_target, y, a) b_ = tf.where(v_guess Portanto, agora temos uma lista de operações e variáveis, qualquer uma das quais pode ser avaliada em relação a uma sessão específica. Algumas dessas operações dependem de outras operações sendo executadas, portanto, a execução, por exemplo, v_guess
irá disparar uma reação em cadeia para outros tensores, como C
e P
, são avaliados primeiro.
Algumas dessas operações dependem de um espaço reservado para o qual um valor deve ser especificado, então como podemos realmente alimentar esse valor?
Isso é feito usando o argumento feed_dict
na função run
.
Se você deseja avaliar a_
, inserimos o valor de nosso marcador v_target
, assim:
sess.run(a_, feed_dict={v_target: 100})
Dando como resultado 0,0.
Conecte um v_target
de 130 e obtemos -10,0.
É a nossa operação de 'etapa' que realmente requer que todas as outras operações sejam realizadas como um pré-requisito e realmente executa o gráfico inteiro. É também uma operação que realmente altera o estado real em nossa sessão. Portanto, quanto mais executamos a etapa, mais empurramos incrementalmente nossas variáveis a
e b
em direção ao valor real de y
.
Então, digamos que nosso valor para v
em nossa equação é igual a 95. Vamos configurar uma sessão e rodar nosso gráfico 100 vezes.
# Configurar una sesión e inicializar variables sess = tf.Session() tf.global_variables_initializer().run() # Ejecuta la operación de paso (y, por lo tanto, toda la gráfica) 100 veces para i en el rango (100): sess.run(step, feed_dict={v_target:95})
Se avaliarmos o tensor y
agora, obtemos algo como uma resposta desejável
design de comunicação visual vs design gráfico
print(sess.run(y)) # 0.125163
Redes neurais
Agora que entendemos a mecânica do TensorFlow, podemos combinar isso com algumas operações adicionais de aprendizado de máquina integradas ao TensorFlow para treinar uma rede neural simples.
Aqui, gostaríamos de classificar os pontos de dados em um sistema de coordenadas 2d, dependendo se eles caem em uma região particular em um círculo de raio 0,5 centrado na origem.
Claro, isso pode ser verificado de forma concreta simplesmente procurando por um determinado ponto (a,b)
sim a^2 + b^2 <0.5
, mas para os fins deste experimento de aprendizado de máquina, em vez disso, gostaríamos de executar um conjunto de treinamento: uma série de pontos aleatórios e se eles caem ou não em nossa região prevista. Aqui está uma maneira de criar isso:
import numpy as np NO_OF_RANDOM_POINTS = 100 CIRCLE_RADIUS = 0.5 random_spots = np.random.rand(NO_OF_RANDOM_POINTS, 2) * 2 - 1 is_inside_circle = (np.power(random_spots[:,0],2) + np.power(random_spots[:,1],2) Vamos criar uma rede neural com as seguintes características:
- Consiste em uma camada de entrada com dois nós, na qual alimentamos nossa série de vetores bidimensionais contidos em 'random_spots'. Isso será representado por um marcador aguardando os dados de treinamento.
- A camada de saída também terá dois nós, então precisamos alimentar nossa série de rótulos de treinamento ('is_inside_circle') em um espaço reservado para um escalar e então converter esses valores em um vetor quente bidimensional.
- Teremos uma camada oculta consistindo de três nós, portanto, precisaremos usar variáveis para nossas matrizes de peso e vetores de polarização, pois esses são os valores que precisam ser refinados durante o treinamento.
INPUT_LAYER_SIZE = 2 HIDDEN_LAYER_SIZE = 3 OUTPUT_LAYER_SIZE = 2 # Los valores iniciales para los pesos y los sesgos se dibujan aleatoria y uniformemente a partir de [-1, 1] # Por ejemplo, W1 es una matriz de forma 2x3 W1 = tf.Variable(tf.random_uniform([INPUT_LAYER_SIZE, HIDDEN_LAYER_SIZE], -1, 1)) b1 = tf.Variable(tf.random_uniform([HIDDEN_LAYER_SIZE], -1, 1)) W2 = tf.Variable(tf.random_uniform([HIDDEN_LAYER_SIZE, OUTPUT_LAYER_SIZE], -1, 1)) b2 = tf.Variable(tf.random_uniform([OUTPUT_LAYER_SIZE], -1, 1)) # Especificando que el marcador de posición X puede esperar una matriz de 2 columnas (pero cualquier cantidad de filas) # representando lugares aleatorios X = tf.placeholder(tf.float32, [None, INPUT_LAYER_SIZE]) # El marcador de posición Y puede esperar números enteros que representen si el punto correspondiente está en el círculo # o no (sin forma específica) Y = tf.placeholder(tf.uint8) # Una op para convertir a un único vector caliente onehot_output = tf.one_hot(Y, OUTPUT_LAYER_SIZE)
Para completar a definição do nosso gráfico, definimos algumas operações que nos ajudarão a treinar as variáveis para chegar a um classificador melhor. Isso inclui cálculos de matriz, funções de ativação e otimizador.
LEARNING_RATE = 0.01 # Op para ejecutar un cálculo de matriz X*W1 + b1 hidden_layer = tf.add(tf.matmul(X, W1), b1) # Utiliza la función de activación sigmoidea en el resultado activated_hidden_layer = tf.sigmoid(hidden_layer) # Aplica los siguientes pesos y sesgo (W2, b2) a la capa oculta y luego aplica la función softmax # para obtener nuestra capa de salida (cada vector sumando 1) output_layer = tf.nn.softmax(tf.add(tf.matmul(activated_hidden_layer, W2), b2)) # Calcula la entropía cruzada para nuestra función de pérdida loss = -tf.reduce_sum(onehot_output * tf.log(output_layer)) # Utiliza el optimizador de descenso de gradiente a la velocidad de aprendizaje especificada para minimizar el valor dado por el tensor de pérdida train_step = tf.train.GradientDescentOptimizer(LEARNING_RATE).minimize(loss)
Depois de configurar nosso gráfico, é hora de configurar uma sessão e executar o “passe de trem” (que também executa as operações de pré-requisito). Algumas dessas operações usam marcadores de posição, portanto, os valores devem ser fornecidos. Esta etapa de treinamento representa uma época em nosso algoritmo de aprendizado e, como tal, está vinculada ao número de épocas que queremos executar. Podemos executar outras partes do gráfico, como o tensor de 'perda' para fins informativos.
EPOCH_COUNT = 1000 sess = tf.Session() tf.global_variables_initializer().run() para i en rango(EPOCH_COUNT): if i%100 == 0: print('Loss after %d runs: %f' % (i, sess.run(loss, feed_dict={X: random_spots, Y: is_inside_circle}))) sess.run(train_step, feed_dict={X: random_spots, Y: is_inside_circle}) print('Final loss after %d runs: %f' % (i, sess.run(loss, feed_dict={X: random_spots, Y: is_inside_circle})))
Depois de treinar o algoritmo, podemos alimentar um ponto e obter a saída da rede neural como esta:
a regra gestalt de pragnanz sugere que o sistema visual
sess.run(output_layer, feed_dict={X: [[1, 1]]}) # Hopefully something close to [1, 0] sess.run(output_layer, feed_dict={X: [[0, 0]]}) # Hopefully something close to [0, 1]
Podemos classificar o ponto como fora do círculo se o primeiro membro do vetor de saída for maior que 0,5, caso contrário, dentro. Ao executar o tensor output_layer
Para muitos pontos, podemos ter uma ideia de como o aluno visualiza a região que contém os pontos classificados positivamente. Vale a pena testar o tamanho do conjunto de treinamento, a taxa de aprendizagem e outros parâmetros para ver o quão perto podemos chegar do círculo que pretendíamos.

Conjunto de treinamento: 100 pontos
Taxa de aprendizagem: 0,01
Vezes: 1000

Conjunto de treinamento: 1000 pontos
Taxa de aprendizagem: 0,01
Vezes: 1000

Conjunto de treinamento: 1000 pontos
Taxa de aprendizagem: 0,01
Vezes: 10.000

Conjunto de treinamento: 1000 pontos
Taxa de aprendizagem: 0,0001
Vezes: 10.000
Para terminar
Esta é uma boa lição de que um aumento no conjunto de treinamento, ou a quantidade de tempo não é garantia para um bom aluno, a taxa de aprendizagem deve ser ajustada adequadamente.
Felizmente, essas demonstrações deram a você uma boa ideia dos princípios básicos do TensorFlow e fornecem uma base sólida para a implementação de técnicas mais complexas.
Não cobrimos conceitos como o Tensorboard ou o treinamento de nossos modelos em GPUs, mas eles são bem abordados no Documentação do TensorFlow . Várias receitas podem ser encontradas na documentação que podem ajudá-lo a se familiarizar com as empolgantes tarefas de aprendizado profundo usando esta estrutura poderosa.