Путаница в отношении реализации производной softmax в Numpy - PullRequest
0 голосов
/ 12 апреля 2020

Я учусь, как реализовать классификатор нейронной сети с нуля, используя Numpy и набор данных Iris Flowers. Я использую функцию кросс-энтропийной потери. Набор данных можно найти здесь . Используемая мной нейронная сеть имеет следующую архитектуру:

  • Входной слой имеет 4 единицы, поскольку имеется 4 независимых переменных
  • 1-й скрытый слой имеет 5 единиц с активацией tanh (x)
  • 2-й скрытый слой имеет 4 единицы с активацией tanh (x)
  • Последний (выходной) слой имеет 3 единицы для обозначения трех результирующих классов (Versicolor, Setosa & Virginica), которые имеют softmax активация

И соответствующие матрицы весов и смещений имеют следующие функции и размеры

  • матрица весов w1 измерения 5 в 4, которая отображает входные данные в первый скрытый слой
  • единица смещения b0, размера 5 на 100, которая добавляет смещение к первому скрытому слою
  • матрица весов w2 измерения 4 на 5, который отображает первый скрытый слой на второй скрытый слой
  • Блок смещения b1 измерения 4 в 100, который добавляет значения смещения ко второму скрытому слою
  • весовая матрица w3 измерения 3 в 4, которая отображает второй скрытый слой к выходному слою
  • Единица смещения b2 измерения 3 в 100, которая добавляет значения смещения к выходному слою

Следующий код получает данные, один горячий кодирует вывод и инициализирует матрицы весов и смещений

import numpy as np
import pandas as pd

data = pd.read_csv('iris.csv')
def softmax(x):
    """Compute softmax values for each sets of scores in x."""
    e_x = np.exp(x - np.max(x))
    return e_x / e_x.sum(axis=0)

### One hot encoding
output_vector = {

    'setosa':[1,0,0],
    'veriscolor':[0,1,0],
    'virginica':[0,0,1]
}
vector_df = pd.DataFrame.from_dict(output_vector)
vector_df = vector_df.transpose()
vector_df['Species'] = vector_df.index
vector_df.reset_index(inplace=True)
vector_df.drop('index',axis=1,inplace=True)
data = pd.merge(data,vector_df)
data = data.drop('Unnamed: 0',axis=1)
X = data[['SepalLength','SepalWidth','PetalLength','PetalWidth']].values
y = data[[0,1,2]].values
X = X.T
y = y.T
np.random.seed(42)
w1 = np.random.rand(5,4)
b0 = np.ones((5,100))
w2 = np.random.rand(4,5)
b1 = np.ones((4,100))
w3 = np.random.rand(3,4)
b2 = np.ones((3,100))
alpha = 0.1
loss = []

. После настройки входов прямой проход выполняется следующим образом:

x1 = np.tanh(w1@X+b0)
x2 = np.tanh(w2@x1+b1)
x3 = softmax(w3@x2+b2)

, где x1 - первый скрытый слой, x2 - это второй скрытый слой, а x3 - выходной слой.

После того, как прямой переход сделан, нам нужно вычислить градиенты функции кросс-энтропийной потери относительно весов, используя обратное распространение. Это включает в себя расчет ошибок для каждого слоя, как показано на следующем снимке экрана, взятом из здесь

enter image description here

Код, который я

delta_3 = (x3-y)/100 ### Need to multiply this with derivative of softmax

delta_2 = np.multiply(w3.T@delta_3,1-np.power(x2,2))

delta_1 = np.multiply(w2.T@delta_2,1-np.power(x1,2))

## Weight Update
## Learning Rate

w1 = w1 - (alpha*delta_1@X.T)
b0 = b0 - (alpha*delta_1)
w2 = w2 - (alpha*delta_2@x1.T)
b1 = b1 - (alpha*delta_2)
w3 = w3 - (alpha*delta_3@x2.T)
b2 = b2 - (alpha*delta_3)

Производные функции tanh (x) кажутся прямыми, иначе 1-tanh (x) 2 . Но я застрял с производными от softmax продукции.

Давайте рассмотрим пример одного выхода [0.1,0.2,0.7].

import numpy as np
output = np.array([0.1,0.2,0.7]).reshape(3,1)
e = np.ones((3,1))
diff = np.multiply(output@e.T,(np.eye(3) - e@output.T))
print(diff)

array([[ 0.09, -0.02, -0.07],
       [-0.02,  0.16, -0.14],
       [-0.07, -0.14,  0.21]])

Результирующий дифференциал будет представлять собой матрицу 3 на 3. Учитывая это, как мы можем расширить это до выходного вектора от 3 до 100 (вместо одного выхода, 100 выходов)? Это потому, что для вычисления термина delta_3 нам нужен дифференциальный член, который имеет размеры от 3 до 100 (из-за продукта Адамара). Есть ли какое-то скручивание / усреднение?

Заранее спасибо!

...