Влияние инициализации случайного веса на простую нейронную сеть

#python #machine-learning #neural-network

#python #машинное обучение #нейронная сеть

Вопрос:

Я следую книге, в которой есть следующий код:

 
import numpy as np

np.random.seed(1)

streetlights = np.array([[1, 0, 1], [0, 1, 1], [0, 0, 1], [1, 1, 1]])

walk_vs_stop = np.array([[1, 1, 0, 0]]).T


def relu(x):
    return (x > 0) * x


def relu2deriv(output):
    return output > 0


alpha = 0.2
hidden_layer_size = 4

# random weights from the first layer to the second
weights_0_1 = 2*np.random.random((3, hidden_layer_size)) -1
# random weights from the second layer to the output
weights_1_2 = 2*np.random.random((hidden_layer_size, 1)) -1


for iteration in range(60):
    layer_2_error = 0
    for i in range(len(streetlights)):
        layer_0 = streetlights[i : i   1]
        layer_1 = relu(np.dot(layer_0, weights_0_1))
        layer_2 = relu(np.dot(layer_1, weights_1_2))

        layer_2_error  = np.sum((layer_2 - walk_vs_stop[i : i   1])) ** 2

        layer_2_delta = layer_2 - walk_vs_stop[i : i   1]
        layer_1_delta = layer_2_delta.dot(weights_1_2.T) * relu2deriv(layer_1)

        weights_1_2 -= alpha * layer_1.T.dot(layer_2_delta)
        weights_0_1 -= alpha * layer_0.T.dot(layer_1_delta)

    if iteration % 10 == 9:
        print(f"Error: {layer_2_error}")

  

Какие результаты:

 # Error: 0.6342311598444467
# Error: 0.35838407676317513
# Error: 0.0830183113303298
# Error: 0.006467054957103705
# Error: 0.0003292669000750734
# Error: 1.5055622665134859e-05
  

Я все понимаю, но эта часть не объяснена, и я не уверен, почему так оно и есть:

 weights_0_1 = 2*np.random.random((3, hidden_layer_size)) -1
weights_1_2 = 2*np.random.random((hidden_layer_size, 1)) -1
  

Я не понимаю:

  1. Почему существует 2* целая матрица и почему существует -1
  2. Если я изменю 2 3 свою ошибку, она станет значительно ниже # Error: 5.616513576418916e-13
  3. Я попытался изменить значение 2 на многие другие числа вместе с изменением -1 на многие другие числа, которые я получаю # Error: 2.0 большую часть времени, или Error это намного хуже, чем комбинация 3 и -1 .

Кажется, я не могу понять взаимосвязь и цель умножения случайных весов на число и последующего вычитания числа.

PS Идея сети состоит в том, чтобы понимать схему уличного освещения, когда люди должны идти и когда они должны остановиться, в зависимости от того, какая комбинация огней streetlight включена / выключена.

Ответ №1:

Существует множество способов инициализации нейронной сети, и это актуальная тема исследований, поскольку это может оказать большое влияние на производительность и время обучения. Некоторые эмпирические правила :

  • избегайте наличия только одного значения для всех весов, так как все они будут обновлять одно и то же
  • избегайте слишком больших весов, которые могут сделать ваш градиент слишком высоким
  • избегайте слишком малых весов, которые могут привести к исчезновению градиента

В вашем случае цель состоит в том, чтобы просто иметь что-то между [-1;1] :

  1. np.random.random дает вам значение с плавающей точкой в [0;1]
  2. умножение на 2 дает вам что-то в [0;2]
  3. вычесть 1 дает вам число в [-1;1]

Комментарии:

1. Я думаю, что в вашем конкретном случае это просто работает лучше, это просто шум.

Ответ №2:

2*np.random.random((3, 4)) -1 это способ генерировать 3*4=12 случайное число из равномерного распределения полуоткрытого интервала [-1, 1) , т.е. Включая -1 , но исключая 1 .

Это эквивалентно более читаемому коду

 np.random.uniform(-1, 1, (3, 4))