У вас есть две сети параллельно. Вы можете увидеть это в прямом методе:
state
-> policy1
-> policy2
-> logits
state
-> value1
-> value2
-> value
policy1
, policy2
, value1
и value2
- это 4 разных и независимых полностью связанных (линейных) слоя. Метод nn.Linear
создает новый слой нейронов при каждом вызове.
Редактируйте для получения более подробной информации:
В вашем коде вы определяете класс doubleNetwork
, метод __init__
будет вызываться при создании объекта этого класса
Итак, эта строка:
my_network = doubleNetwork(10,15)
вызывает метод __init__
и создает новый объект doubleNetwork. Newtork будет иметь 4 атрибута value1, value1, policy1, policy2, которые являются полностью связанными слоями.
строка:
self.policy1 = nn.Linear(input_dim, 256)
Создайте новый линейный объект, который является полностью связным слоем, когда эта линия выполняется, веса для слоев инициализируются.
forward
метод сети определяет, что добавляется при вызове сетевого объекта. Например, с такой строкой:
output1, output2 = my_network(input)
Код, записанный в форварде, является функцией, применяемой к входу. Здесь входные данные, которые являются состоянием, передаются на двух уровнях политики в одну сторону, а затем передаются на два уровня значений. И тогда оба выхода возвращаются. Таким образом, сеть в форме вилки с одним входом и 2 выходами.
В этом коде это одна сеть, но поскольку два выхода зависят только от входа и независимы друг от друга, мы могли бы определить их в две отдельные сети с одинаковым результатом. Смотрите код для примера:
class SingleNetwork(nn.Module):
def __init__(self, input_dim, output_dim):
super(doubleNetwork, self).__init__()
self.layer1 = nn.Linear(input_dim, 256)
self.layer2 = nn.Linear(256, output_dim)
def forward(self, state):
output = F.relu(self.layer1(state))
output = self.layer2(output)
return output
my_network1 = singleNetwork(10,15)
my_network2 = singleNetwork(10,1)
затем:
output1 = my_network1(input)
output2 = my_network2(input)
Будет эквивалентно
output1, output2 = my_network(input)