Как определить модель на PyTorch для игрового агента Tic Tac Toe - PullRequest
0 голосов
/ 02 июня 2019

Я пытаюсь написать агента для игры Tic Tac Toe.Я знаю, что есть лучшие (?) Способы решения этой проблемы, такие как Minimax, но просто из любопытства я начал писать модель на PyTorch сегодня.Мне кажется, что я что-то не так делаю в функции пересылки.

Я пытался использовать BCELoss для функции потерь, но не могу заставить ее работать.Я имею в виду только использование результата всей игры в качестве проигрыша, но я не могу связать это с остальной сетью.

class LSTM(nn.Module):
    def __init__(self, input_size, hidden_size, num_layers, bidirectional, dropout_hidden, dropout_output):
        super(LSTM, self).__init__()
        """..."""
        self.lstm = nn.LSTM(input_size, self.hidden_size, num_layers = num_layers, bidirectional = self.bidirectional, dropout = dropout_hidden)
        """..."""

        self.fc = nn.Linear(self.hidden_size * 2 if self.bidirectional else self.hidden_size, board_size)
        """..."""
        self.game_over = 0

    def forward(self, state):
        # state.shape = (1, 1, 9)

        self.hn = torch.zeros(self.num_layers * 2 if self.bidirectional else self.num_layers, 1, self.hidden_size).to(device)
        self.cn = torch.zeros(self.num_layers * 2 if self.bidirectional else self.num_layers, 1, self.hidden_size).to(device)

        while True:
            # plays for the player to the first available slot
            state = play(state.view((-1)), player)
            # checks if the game is over yet
            self.game_over = check_game(state)
            state = state.view((1, 1, -1))

            if self.game_over != 0:
                break

            output, (self.hn, self.cn) = self.lstm(state, (self.hn, self.cn))
            # output.shape = (1, 1, hidden_size * 2 if bidirectional else hidden_size)
            output = self.dropoutlayer(output)
            output = self.fc(output)
            move = torch.zeros((1, 1, 9)) - 999
            # out of the outputs, try to find the highest empty slot output
            for i in range(board_size):
                if state[0, 0, i] == 0:
                    move[0, 0, i] = output[0, 0, i]

            _, pred = move.max(dim=2)
            state[0, 0, pred] = player2
            self.game_over = check_game(state.view((-1)))
            if self.game_over != 0:
                break

        return torch.tensor(1., requires_grad=True).to(device) if self.game_over == player2 else torch.tensor(0., requires_grad=True).to(device)
model = LSTM(board_size, 64, 1, True, 0, 0).to(device)
loss = nn.BCELoss()
optimizer = optim.Adam(model.parameters(), lr=0.003, betas=(0.9, 0.999), eps=1e-08, weight_decay=1e-5, amsgrad=False)
model.train()
for i in range(1000):
    state = torch.FloatTensor([0] * board_size)
    state = state.view((1, 1, -1)).to(device)
    optimizer.zero_grad()
    class_pred = model(state)
    output = loss(class_pred, torch.tensor(1.).to(device))
    output.backward()
    optimizer.step()

Я обычно ожидаю, что модель изучитчтобы выиграть у функции воспроизведения, которую я написал (которую, безусловно, можно улучшить, но для первого прототипа я чувствовал, что все в порядке), но на самом деле она ничего не изучает.Если возможно, я хотел бы изменить его в будущем, чтобы он мог играть против другой копии и учиться таким образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...