之前一直觉得神经网络很神奇,直到今天我才第一次体验它。神经网络的好处是,研究一个黑箱的输入和输出关系条件,只需要提供一定量输入和输出数据,不需要把黑箱打开研究,数据量越多,神经网络的输出值就越准确。

使用神经网络非常方便,在Python开源社区,有许多的神经网络实现,在此由衷感谢开源社区的每一位贡献者🙇。训练一个神经网络并不复杂,有时只需设定参数和数据集。下面,我将介绍如何使用神经网络来训练弹弹堂游戏对战策略。

在弹弹堂对战中,攻击目标的必要条件是准确把握风力、距离、角度和力度。在互联网上可以找到对战逻辑源码,本文不详细展开,只留下链接给读者自行探索:SkelletonX/DDTank4.1 - 20231023ddtank · Pypi - 20231023。于是,假设你已经实现了下面这个计算力度的函数:

def operate_calculate_strength(angle: int, wind: int, dx: int, dy: int) -> int

我们用它生成 100000 组准确数据,保存到 bp03.xlsx:

from pandas import DataFrame

import math
import numpy as np

COUNT = 100000

angle = np.random.randint(0, 90, COUNT)
wind = np.around(np.random.random(COUNT) * np.random.choice(np.array([-1, 1]), COUNT) * 4, 1)
dx = np.random.randint(0, 20, COUNT)
dy = np.random.randint(-10, 10, COUNT)
force = np.array([operate_calculate_strength(angle[i], wind[i], dx[i], dy[i]) for i in range(COUNT)])
force = np.around(force, 0)

df1 = DataFrame({"angle": angle, "wind": wind, "dx": dx, "dy": dy, "force": force})
df1.to_excel("bp03.xlsx")

同样,生成 1000 组测试数据,但保存到 bp03_test.xlsx。下面,使用生成的 100000 组数据进行训练,神经网络选用 sklearn.neural_network 的 MLPRegressor,神经网络设定为两层 64x32,最大迭代次数设定为 500,求解器设定为 adam,使用 joblib 将网络保存方便以后使用,注意这里我还对数据进行了筛选:

import pandas as pd
from sklearn.neural_network import MLPRegressor
import joblib

pd03 = pd.read_excel("bp03.xlsx")
pd03 = pd03[pd03["force"] != 100]

user_input = pd03[["angle", "wind", "dx", "dy"]].to_numpy()
output = pd03["force"].to_numpy()

mlp = MLPRegressor(hidden_layer_sizes=(64, 32), max_iter=500, solver="adam")
mlp.fit(user_input, output)

joblib.dump(mlp, "bp03.pk1")

接下来,就是使用神经网络测试数据,本文认为力度相差在 2 以内便认为基本击中目标:

import pandas as pd
import joblib
import numpy

pd03 = pd.read_excel("bp03_test.xlsx")
pd03 = pd03[pd03["force"] < 100]

user_input = pd03[["angle", "wind", "dx", "dy"]].to_numpy()
output = pd03["force"].to_numpy()

mlp = joblib.load("bp03.pk1")
result = mlp.predict(user_input)
error = numpy.abs((output - result))

print(numpy.average(error))
print(numpy.sum(error < 2) / numpy.sum(error >= 0))

得到如下输出:

1.5551639423831543
0.8106267029972752

结果非常可观,平均力度误差是 1.55(/100),准确攻击目标的频率是 81%。

下面,我将测试数据集大小对结果的影响:

from sklearn.neural_network import MLPRegressor
import pandas as pd
import numpy

pd03 = pd.read_excel("bp03.xlsx")
pd03 = pd03[pd03["force"] != 100]

user_input = pd03[["angle", "wind", "dx", "dy"]].to_numpy()
output = pd03["force"].to_numpy()

from pandas import DataFrame

result = {"count": [], "average": [], "success": []}

for i in [10, 50, 100, 500, 1000, 5000, 10000, 50000]:
    mlp = MLPRegressor(hidden_layer_sizes=(64, 32), max_iter=500, solver="adam")
    mlp.fit(user_input[0:i], output[0:i])

    force = mlp.predict(user_input)
    error = numpy.abs((output - force))

    result["count"].append(i)
    result["average"].append(numpy.average(error))
    result["success"].append(numpy.sum(error < 2) / numpy.sum(error >= 0))

df = DataFrame(result)
print(df)

结果如下:

数据集大小平均误差成功预测率
1014.2098860.174658
5010.3277420.241196
1009.4757450.220924
5007.5542220.295324
10007.0496730.338776
50003.9074370.47686
100002.6605910.599222
500002.0485460.725905

总的来说,数据集越大,成功预测率也越高,但是这种规律只有在数据集量级相差较大时呈现。感兴趣的读者可以自己去试试吧!

最后修改:2024 年 03 月 02 日
如果觉得我的文章对你有用,请随意赞赏