Тестирование нейронной сети PyTorch после написания симулятора естественного отбора.
Я второй день пытаюсь провернуть один тест: собрать одну и ту же сетку своей моделью nn_module (мною написанный класс) и с помощью библиотеки PyTorch. Посмотрим, как получится. Пока свел их, чтобы они имели одинаковую структуру. Теперь эти входы надо задать вручную и сравнить выходы.
Зачем? А хз. Просто хочется предсказуемости в результатах, и в том, что я делаю. Да и проверить свой класс нейронной сети, написанный уже фиг знает когда, без нормальных знаний, наощупь.
Что касается собственно отбора, загвоздка с вращением существ, возможно и не должна разрешаться как-то математически, как с sin(): данная конфигурация отбора не вынуждает существ бесконечно адаптироваться, достаточно выживать на каком-то уровне, когда основная массу существ все-таки дает потомство, тогда отбор фактически останавливается. Такая у меня гипотеза. Они бегают, находят хоть немного пищи, достаточно чтобы дожить до размножения.
Ну, поглядим, надо расширять функционал наблюдения за существами, чтобы увидеть ситуацию в деталях.
В общем, возвращаясь к тесту, вот в это надо попасть:
('linear_relu_stack.0.weight', Parameter containing:
tensor([[-0.3258, -0.0829],
[-0.2872, 0.4691],
[-0.5582, -0.3260]], requires_grad=True))
('linear_relu_stack.0.bias', Parameter containing:
tensor([-0.1997, -0.4252, 0.0667], requires_grad=True)) <--- Это видимо биасы для нейронов указанного выше слоя
('linear_relu_stack.2.weight', Parameter containing:
tensor([[-0.5702, 0.5214, -0.4904],
[ 0.4457, 0.0961, -0.1875]], requires_grad=True))
('linear_relu_stack.2.bias', Parameter containing:
tensor([0.3568, 0.0900], requires_grad=True)) <--- Это видимо биасы для нейронов указанного выше слоя
('linear_relu_stack.4.weight', Parameter containing:
tensor([[0.5713, 0.0773]], requires_grad=True))
('linear_relu_stack.4.bias', Parameter containing:
tensor([-0.2230], requires_grad=True)) <--- Это видимо биасы для нейронов указанного выше слоя
Выход вроде этот:
tensor([[0.5306]], grad_fn=<SigmoidBackward0>)
А получилось: 0.532279745246279
Хм.. даже неясно как это трактовать. Проще всего поменять входы, посмотреть как будет реагировать выход.
Болван,
nn1._inputs = [0.01, 0.95]
nn1.calc()
было "inputs = .."
, вместо "nn1._inputs = .."
Соответственно, сетка стартовала с нулевыми инпутами. Поправил, и…
[0.1, 0.5] 0.5306 0.5305758657475955
[0.01, 0.05] 0.5285 0.5285213320457128
[0.91, 0.95] 0.5343 0.5343439532365446
[0.99, 0.01] 0.5310 0.5309853972119467
[0.01, 0.99] 0.5323 0.5323244660220846
Странно, что входы так мало влияют на выходы. Многовато слоёв? Оставим один скрытый слой и 1 нейрон на выходе.
[0.01, 0.99] 0.4053 0.40633567109426694
[0.1, 0.5] 0.3966 0.3975956529132423
[0.01, 0.05] 0.3897 0.3907299083682923
Так, непонятно. Такая точность в предыдущем эксперименте, и такие промахи в этом. Ага, ошибся в одном из весов. 0.1045 вместо 0.1802. Еще раз проверим.
[0.01, 0.05] 0.3897 0.3896808115540953
[0.1, 0.5] 0.3966 0.3965604421661039
[0.01, 0.99] 0.4053 0.4053252099378104
Ладно, думаю, этому можно верить. Что мы имеем? Ну, ура, потому что мой класс nn_module, который считает полносвязную сетку прямого распространения правильно, в точности также, как
self.linear_relu_stack = nn.Sequential(
nn.Linear(2, 3, bias=True),
nn.Sigmoid(),
nn.Linear(3, 2),
nn.Sigmoid(),
nn.Linear(2, 1),
nn.Sigmoid(),
)
Давно хотел подобный эксперимент провести. Теперь можно заменить мой класс на конструкцию из pytorch и получить что-то аналогичное (они будут вести себя также странно и крутиться? Или что-то поменяется?). А потом можно поиграть со разными конфигурациями сетей. LSTM, я ползу к тебе.
Еще, как побочная информация, заметил, что у трехслойных сетей, выход как-то слабо коррелирует с входом, по крайней мере, в сравнении с двуслойными сетями. Ну, или по крайней мере, можно поразмышлять об этом явлении.