#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
Я не понимаю:
- Почему существует
2*
целая матрица и почему существует-1
- Если я изменю
2
3
свою ошибку, она станет значительно ниже# Error: 5.616513576418916e-13
- Я попытался изменить значение
2
на многие другие числа вместе с изменением-1
на многие другие числа, которые я получаю# Error: 2.0
большую часть времени, илиError
это намного хуже, чем комбинация3
и-1
.
Кажется, я не могу понять взаимосвязь и цель умножения случайных весов на число и последующего вычитания числа.
PS Идея сети состоит в том, чтобы понимать схему уличного освещения, когда люди должны идти и когда они должны остановиться, в зависимости от того, какая комбинация огней streetlight
включена / выключена.
Ответ №1:
Существует множество способов инициализации нейронной сети, и это актуальная тема исследований, поскольку это может оказать большое влияние на производительность и время обучения. Некоторые эмпирические правила :
- избегайте наличия только одного значения для всех весов, так как все они будут обновлять одно и то же
- избегайте слишком больших весов, которые могут сделать ваш градиент слишком высоким
- избегайте слишком малых весов, которые могут привести к исчезновению градиента
В вашем случае цель состоит в том, чтобы просто иметь что-то между [-1;1] :
- np.random.random дает вам значение с плавающей точкой в [0;1]
- умножение на 2 дает вам что-то в [0;2]
- вычесть 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))