Алгоритм стохастического градиентного спуска не работает должным образом (Python)Python

Программы на Python
Anonymous
Алгоритм стохастического градиентного спуска не работает должным образом (Python)

Сообщение Anonymous »

Мне нужно написать SGD-Perceptron для распознавания цифр в соответствии с этими рекомендациями:
  • Выбрана база данных MNIST с 60 000 обучающими выборками.
  • Получить случайный вектор, вычислить net (взвешенную сумму) и найти y_j = f(net_j), где f(x) — функция активации. Также w_0j – это веса смещения (веса смещения), x0 = 1
  • Найти ε = 0,5 * sum((d_j-y_j) ** 2), где d — желаемый вектор (я думаю, нулевой вектор с 1 напротив желаемой цифры), созданный из выбора (

    Код: Выделить всё

    y_train). Я также думаю, что ε
    называется функцией потерь.
  • Если ε < ε_threshold, разорвите цикл.
  • Отрегулируйте веса: w_ij += -η * δ_j * x_i, δ_j = -(d_j-y_j) ∙ f'(net_j), где η — скорость обучения, ∙ оператор, как я думаю, является внутренним продуктом.
  • Повторяйте шаги 2–5, пока цикл не разорвется.
проблема в том, что персептрон не запоминает значения η, ε_threshold и offset (случайное начальное смещение веса), которые я установил. У меня есть похожие результаты после каждого вектора, например:
Желаемая цифра из y_train: 3 (индекс 3 в следующих массивах)

Взвешенная цифра для каждый j: [-2,39 -2,21 -2,254 -2,49 -2,41 -2,16 -2,17 -2,37 -2,35 -2,32]

Вектор ошибки (желаемый-y_pred): [-0,083 -0,098 -0,095 0,924 -0,082 -0,102 -0,101 -0,085 -0,086 -0,088]
Это означает, что весовые точки на всех выходах одинаково вероятны, хотя вектор ошибок пытается их правильно настроить. .
Я использую сигмовидную () функция активации с производной σ(x)*(1-σ(x)).
Вот мой код:

Код: Выделить всё

import random
import numpy as np
from keras.datasets import mnist
from scipy.misc import derivative

(X_train, y_train), (X_test, y_test) = mnist.load_data()

# Normalize data
X_train = X_train / 255.0
X_test = X_test / 255.0

# Constants from data
X_vector_len = 28*28
y_vector_len = 10

# Learning parameters
learning_rate = 0.05
offset = 0.03  # Random initial weight offset
e_threshold = 0.01

def activation_function(x):
return 1 / (1 + np.exp(-x))

def acivation_derivative(x):
return activation_function(x) * (1 - activation_function(x))

def train(X_train, y_train):
# Weight initialization
weights = np.random.rand(X_vector_len, y_vector_len) * offset * 2 - offset
bias = np.random.rand(y_vector_len) * offset * 2 - offset

epochs = 0
while True:
# Getting X and D vectors
s = random.randrange(len(X_train))
sample = np.append(X_train[s], [])
desired = np.zeros(y_vector_len, dtype=np.float64)
desired[y_train[s]] = 1

net = np.dot(sample, weights) + bias  # Weighted sum
y_pred = activation_function(net)
e_vec = desired - y_pred
e = sum(e_vec ** 2) / 2  # Error ε for current vector

if e < e_threshold:
break

gradient = -e_vec.dot(acivation_derivative(net))
for j in range(y_vector_len):
for i in range(X_vector_len):
weights[i, j] -= learning_rate * gradient * float(sample[i])
bias[j] -= learning_rate * gradient
epochs += 1
return weights, bias, epochs

def test(X_test, y_test, weights, bias):
correct_predictions = 0
for j, text in enumerate(y_test):
sample = np.append(X_train[j], [])
net = np.dot(sample, weights) + bias
print(f"Test {j+1}: Desired {text}, prediction: {net.argmax()} ({net})")
if text == net.argmax():
correct_predictions += 1
return correct_predictions / len(X_test)

if __name__ == "__main__":
weights, bias, epochs = train(X_train, y_train)
print(f"Model trained for {epochs} epochs")

accuracy = test(X_test, y_test, weights, bias)
print(f"Accuracy for test selection: {accuracy * 100:.2f}%")
Поиск ошибок в формулах и чтение некоторых реализаций и математической теории SGD мне не помогли. У меня больше вопросов только потому, что реализации разные:
  • Почему нейронная сеть не обучается, несмотря на то, что вектор ошибок содержит правильные коэффициенты (положительные для желаемых, отрицательные для других цифр)
  • Градиент δ — это число, поскольку оно является внутренним произведением, что такое δ_j ? Если мне следует использовать δ как δ_j, не смешает ли это веса? Значение error_j = d_j - y_j определенно должно влиять на определенные выходные данные. Я пытался использовать как δ, так и δ_j = -(d_j-y_j) * f'(net_j) (обычный продукт) с одинаковыми результатами.
  • Сигмоидальная функция имеет диапазон значений = (0, 1), что приводит к значениям вектора ошибок либо 1-σ(x), либо 0-σ(x ), другими словами, (-1, 1). Прав ли я, что вектор ошибок — это один из коэффициентов весов, и он должен быть положительным, если результат правильный, и наоборот, в то время как другие коэффициенты всегда неотрицательны? А как тогда другие функции активации, например. f(x) = x, f(x) = arctg(x) с другим диапазоном значений работают?
  • Я использовал функцию единичного шага в качестве функции активации в другом алгоритме, применима ли она для SGD?
  • Могу ли я использовать функции numpy как-то корректировать веса? Мне нужно умножить все значения w_ij на x_i в строках.


Подробнее здесь: https://stackoverflow.com/questions/785 ... rly-python

Вернуться в «Python»