Que padrões as redes neurais encontram?

Neste post, quero falar sobre os padrões que as redes neurais podem encontrar. Muitos guias para iniciantes enfocam a técnica de escrever código para redes neurais, enquanto questões de "lógica" (o que podem redes neurais? Quais arquiteturas são mais adequadas para quais tarefas e por quê?) Muitas vezes permanecem à margem. Espero que meu post ajude os iniciantes a entender melhor os recursos das redes neurais. Para fazer isso, tentaremos ver como eles lidam com algumas tarefas do modelo. O código de exemplo será fornecido em python usando a biblioteca keras.

Tarefa 1. Vamos começar com uma simples. Construímos uma rede neural aproximando-se do seno.

import numpy as np import matplotlib import matplotlib.pyplot as plt from keras.models import Sequential from keras.layers import Dense def get_X_y(n): X = np.random.uniform(0, np.pi, n) y = np.sin(X) return X, y n = 40 X, y = get_X_y(n) print("X shape:", X.shape) model = Sequential() model.add(Dense(6, input_dim=1, activation='relu')) model.add(Dense(4, activation='relu')) model.add(Dense(1, activation='sigmoid')) model.compile(loss='mean_squared_error', optimizer='adam', metrics=['mean_squared_error']) model.fit(X, y, epochs=1000, batch_size=4) X_test = np.linspace(start=0, stop=np.pi, num=500) print("X test shape:", X_test.shape) y_test = model.predict(X_test) font = {'weight': 'bold', 'size': 25} matplotlib.rc('font', **font) axes = plt.gca() axes.set_ylim(0, 1) plt.plot(X_test, y_test, c='green', marker='o', markersize=5) plt.title("Sinus approximated by neural network") plt.yticks(np.arange(0, 1, 0.1)) plt.grid() plt.show() 

Temos o seguinte gráfico:



Como você pode ver, a rede neural lidou com sucesso com a tarefa de aproximar uma função simples.

Tarefa 2. Vamos ver como a rede neural lidará com uma tarefa mais complexa. Introduziremos valores x distribuídos uniformemente no intervalo [0, 1], e y será definido aleatoriamente: para x <0,6, y será uma variável aleatória assumindo o valor 0 com uma probabilidade de 0,75 e 1 com uma probabilidade de 0,25 (ou seja, um valor aleatório binomial com p = 0,25). Para x> 0,6, y será uma variável aleatória assumindo o valor 0 com probabilidade 0,3 e o valor 1 com probabilidade 0,7. Como uma função otimizada, tomamos o erro padrão.

 import numpy as np import matplotlib import matplotlib.pyplot as plt from keras.models import Sequential from keras.layers import Dense def get_X_y(n): X = np.random.uniform(0, 1, n) y0 = np.random.binomial(size=n, n=1, p=0.25) y1 = np.random.binomial(size=n, n=1, p=0.7) y = np.where(X < 0.6, y0, y1) return X, y n_inputs = 1 n_hidden1 = 100 n_hidden2 = 50 n_outputs = 1 n = 2000 X, y = get_X_y(n) print("X shape:", X.shape) model = Sequential() model.add(Dense(n_hidden1, input_dim=1, activation='relu')) model.add(Dense(n_hidden2, activation='relu')) model.add(Dense(1, activation='sigmoid')) model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy']) model.fit(X, y, epochs=200, batch_size=100) X_test = np.linspace(start=0, stop=1, num=100) print("X test shape:", X_test.shape) y_test = model.predict(X_test) font = {'weight': 'bold', 'size': 25} matplotlib.rc('font', **font) axes = plt.gca() axes.set_ylim(0, 1) plt.plot(X_test, y_test, c='green', marker='o', markersize=5) plt.title("Binomial distribution approximated by neural network") plt.yticks(np.arange(0, 1, 0.1)) plt.grid() plt.show() 

Obtemos o seguinte gráfico de uma rede neural de função aproximada:



Como você pode ver, a rede neural se aproximava da expectativa matemática de nossa variável aleatória y. Portanto, redes neurais podem (em princípio) aproximar os valores médios de variáveis ​​aleatórias que dependem dos parâmetros. Por exemplo, podemos esperar que eles resolvam o seguinte problema: pessoas com renda de até US $ 1.000 são, em média, infelizes e pessoas com renda acima de US $ 1.000 são, em média, felizes; é preciso aprender a prever o "nível de felicidade", dependendo da renda. A rede neural será capaz de encontrar a dependência do nível médio de felicidade em relação à renda, apesar do fato de que, entre as pessoas com qualquer nível de renda, são felizes e infelizes.

Problema 3. Agora nos voltamos para a previsão de sequências. Consideraremos seqüências de 0 e 1 dadas pela seguinte regra: 10 membros - equiprobably 0 ou 1, e o décimo primeiro igual a 1 se o termo anterior for 0 e igualmente provável 0 ou 1 se o termo anterior 1. Geraremos essas sequências de comprimento 11 (entrada 10) membros da sequência e um, o último, prevemos) e treiná-los em nossa rede neural recorrente. E após o treinamento, vamos verificar como ela lida com a previsão de novas sequências (também o comprimento 11).

 import numpy as np from keras.models import Sequential from keras.layers import LSTM, Dense def get_X_y(m, n): X = np.random.binomial(size=(m,n), n=1, p=0.5) y0 = np.ones(m) y1 = np.random.binomial(size=m, n=1, p=0.5) y = np.where(X[:, n-1]==0, y0, y1) X = np.reshape(X, (X.shape[0], X.shape[1], 1)) return X, y model = Sequential() model.add(LSTM(units=50)) model.add(Dense(units=1)) model.compile(optimizer = 'adam', loss = 'mean_squared_error') X_train, y_train = get_X_y(1000, 10) model.fit(X_train, y_train, epochs = 20, batch_size = 32) m_test = 12 n_test = 10 X_test, y_test = get_X_y(m_test, n_test) y_predicted = model.predict(X_test) for i in range(m_test): print("x_last=", X_test[i, n_test-1, 0], "y_predicted=", y_predicted[i, 0]) 

Vamos ver quais previsões nossa rede neural fornece sobre as seqüências testadas (seus resultados serão diferentes, pois aqui a aleatoriedade está presente tanto na escolha das sequências quanto no treinamento da rede neural).

Número de sequênciaPenúltimo membro da sequênciaValor previsto
10 00,96
20 00,95
30 00,97
40 00,96
50 00,96
610,45
70 00,94
810,50
90 00,96
1010,42
1110,44
120 00,92


Como você pode ver, se o penúltimo membro da sequência for 0, a rede neural prediz um valor próximo a 1 e, se for 1, então um valor próximo a 0,5. Isso está próximo da previsão ideal. Um exemplo semelhante de "vida" poderia ser assim: "se eu for ao cinema hoje, amanhã amanhã vou almoçar em um restaurante; se vou ao teatro hoje, amanhã almoçarei em qualquer lugar. " Como vimos, uma rede neural pode capturar padrões desse tipo e prever uma ida a um restaurante indo ao cinema (e indo ao cinema para prever "algo intermediário").

Tarefa 4. Nós complicamos a tarefa da rede neural. Seja tudo como no exemplo anterior, apenas o décimo primeiro membro da sequência será determinado não pelo anterior, mas pelo segundo membro da sequência (pela mesma regra). Não forneceremos o código aqui, pois ele praticamente não difere do anterior. Meu experimento mostrou que a rede neural ainda encontra um padrão, mas por mais tempo (eu tive que usar 100 épocas em vez de 20 para treinamento).
Assim, as redes neurais podem (novamente, em princípio, esclarecer) capturar dependências razoavelmente de longo prazo (em nosso "exemplo de vida", elas podem capturar padrões como "hoje vou a um restaurante se estivesse em um filme há uma semana").

Tarefa 5. Vamos ver como a rede neural usa as informações disponíveis para previsão.
Para fazer isso, realizaremos treinamento em seqüências de comprimento 4. No total, teremos 3 sequências igualmente prováveis ​​diferentes:

0, 0, 1, 1
0, 1, 0, 1
0, 1, 1, 0


Assim, após a combinação inicial de 0, 0, sempre encontramos duas unidades; após a combinação de 0, 1, temos a mesma probabilidade de encontrar 0 ou 1, mas saberemos com certeza o último número. Agora pediremos à nossa rede neural que retorne sequências definindo return_sequences = True. Como as seqüências previstas, tomamos as mesmas seqüências deslocadas em uma etapa e suplementadas por zero à direita. Agora já podemos assumir o que acontecerá: na primeira etapa, a rede neural produzirá um número próximo a 2/3 (já que com uma probabilidade de 2/3, o segundo termo é 1) e, em seguida, para uma combinação de 0, produzirá dois números próximos a unidade, e para 0, 1 primeiro, ele fornecerá um número próximo a 0,5 e, em seguida, fornecerá um número próximo a 0 ou 1, dependendo de termos a sequência 0, 1, 0 ou 0, 1, 1. No final da rede neural sempre produzirá um número próximo a 0. A verificação com o código a seguir mostra que nossas suposições estão corretas.

 import numpy as np from keras.models import Sequential from keras.layers import LSTM, Dense import random def get_X_y(n): X = np.zeros((n, 4)) z = np.array([random.randint(0, 2) for i in range(n)]) X[z == 0, :] = [0, 0, 1, 1] X[z == 1, :] = [0, 1, 0, 1] X[z == 2, :] = [0, 1, 1, 0] y = np.zeros((n, 4)) y[:, :3] = X[:, 1:] X = np.reshape(X, (X.shape[0], X.shape[1], 1)) y = np.reshape(y, (y.shape[0], y.shape[1], 1)) return X, y model = Sequential() model.add(LSTM(units=20, return_sequences=True)) model.add(Dense(units=1)) model.compile(optimizer = 'adam', loss = 'mean_squared_error') X_train, y_train = get_X_y(1000) model.fit(X_train, y_train, epochs = 100, batch_size = 32) X_test = np.zeros((3, 4)) X_test[0, :] = [0, 0, 1, 1] X_test[1, :] = [0, 1, 0, 1] X_test[2, :] = [0, 1, 1, 0] X_test = np.reshape(X_test, (3, 4, 1)) y_predicted = model.predict(X_test) print(y_predicted) 


A partir deste exemplo, vemos que a rede neural pode alterar dinamicamente a previsão, dependendo das informações recebidas. Faríamos o mesmo, tentando prever uma certa sequência: quando as informações disponíveis nos permitem estimar as probabilidades de resultados na próxima etapa, previmos com base nessas informações; mas, quando descobrirmos informações adicionais na próxima etapa, alteramos a previsão dependendo dela.
Então, se vemos que alguém está vindo para nós do escuro, dizemos "essa é uma pessoa, não sabemos com mais detalhes"; quando começamos a distinguir cabelos longos no escuro, dizemos "provavelmente é uma mulher". Mas se depois considerarmos que uma pessoa tem bigode, dizemos que esse provavelmente é um homem (embora com cabelos compridos). Como vimos, uma rede neural age de maneira semelhante, usando a totalidade das informações atualmente disponíveis para previsão.

Então, analisamos exemplos simples de como as redes neurais funcionam e quais padrões eles podem encontrar. Em geral, vimos que as redes neurais geralmente se comportam "razoavelmente", fazendo previsões próximas daquelas que uma pessoa faria. Embora, note-se, para capturar padrões simples, eles precisam de muito mais dados do que pessoas.

Source: https://habr.com/ru/post/pt467895/


All Articles