<jupyter_start><jupyter_text>TRAINING DATA<jupyter_code>#torch.cuda.get_device_name(device)
trainloader = DataLoader(dataset, batch_size=1,
                        shuffle=True, num_workers=0) 
#num_workers = 0 doesn't use GPU. GPU seems to be a lot slower than CPU,.
#data set is prob too big or my laptop nvidia GPU is just trash

optimizer = optim.Adam(net.parameters(), lr = 0.0009) #lr = 0.001
criterion = nn.MSELoss() 

for epoch in range(3):  # loop over the dataset multiple times

    running_loss = 0.0
    for i, data in enumerate(trainloader):
        # get the inputs; data is a list of [inputs, labels]
        inputs = data['position'].reshape(1, 513).float()#.cuda()
        labels = data['eval'].float()#.cuda()

        # zero the parameter gradients
        optimizer.zero_grad()

        # forward + backward + optimize
        outputs = net(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

        # print statistics
        running_loss += loss.item()
        if i % 400 == 399:    # print every 2000 mini-batches
            print('[%d, %5d] loss: %.3f' %
                  (epoch + 1, i + 1, running_loss / 400))
            running_loss = 0.0

print('Finished Training')
def compare_eval():
    board = generate_rand_board()
    #print(convert_board(board))
    torch_board = torch.from_numpy(convert_board(board).reshape(1, 513)).float()
    net_eval = net(torch_board)
    sf_eval = stockfish_evaluation(board)
    print(f"NN: {net_eval} Stockfish: {sf_eval/100}")
    
for _ in range(5):
    compare_eval()
# Choosing Best Move with Minimax
def nn_prediction(position: chess.Board):
    board_rep = convert_board(position)
    torch_board = torch.from_numpy(board_rep.reshape(1, 513)).float()
    return net(torch_board)

# Minimax implementation 
def minimax(position, depth, maximizingPlayer, alpha = -1e9, beta = 1e9):
    #print(depth)
    if depth == 0 or position.is_game_over():
        return nn_prediction(position)
        
    if maximizingPlayer:
        value = -np.Inf
        for move in position.legal_moves:
            position.push(move)
            value = max(value, minimax(position, depth-1, False, alpha, beta))
            position.pop()
            alpha = max(alpha, value)
            if beta <= alpha:
                break
        return value
    else:
        value = np.Inf
        for move in position.legal_moves:
            position.push(move)
            value = min(value, minimax(position, depth-1, True, alpha, beta))
            position.pop()
            beta = min(beta, value)
            if beta <= alpha:
                break
        return value
def find_best_move(position, depth):
    
  best_evaluation = -np.Inf

  for move in position.legal_moves:
    position.push(move)
    nn_eval = minimax(position, depth - 1, False, -np.Inf, np.Inf)
    position.pop()
    
    if nn_eval > best_evaluation:
      best_evaluation = nn_eval
      best_move = move
  
  return best_move
def play_game():
    board = chess.Board()
    board.push_san("e4")
    board.push_san("e5")    
    while not board.is_game_over():   
        nn_move = find_best_move(board,4) 
        
        board.push(nn_move)
        print(board)
        print(nn_move)
        moved = False
        while not moved:
            try:
                sqr = input('your move')
                if sqr == 'q' or sqr == 'quit':
                    return
                first_letter = sqr[0]
                if (first_letter == 'n' or 
                        first_letter == 'b' or 
                        first_letter == 'r' or
                        first_letter == 'q' or
                        first_letter == 'k'):
                    sqr = first_letter.upper() + sqr[1:]
                board.push_san(sqr)
                moved = True
            except:
                moved = False

play_game()
# memoization ? transposition of positions<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10593860090588827, 'fraction_numerical': 0.015853044791142426, 'mean_word_length': 2.0251141552511416, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '1', 'dir': 'jupyter-structured-clean-dedup', 'id': '211978', 'license': 'MIT', 'n_tokens_mistral': 1270, 'n_tokens_neox': 1197, 'n_words': 308, 'path': 'chess_nn.ipynb', 'repo_name': 'matthewyu01/chess-ai', 'size': '3974'}