首先提供一些背景信息。
我正在进行一个非常雄心勃勃的项目,制作一个能够在一定水平上玩国际象棋的神经网络。我可能不会成功,但主要是为了学习如何处理这种机器学习问题。
我决定使用遗传算法来训练网络,以便在不同的神经网络通过几局象棋对弈后微调权重。
每个神经元使用双曲正切函数(-1, 1)来对处理后的数据进行归一化,但在数据进入网络之前并未进行归一化处理。
我从Giraffe象棋引擎中获得了一些灵感,特别是关于输入的部分。
输入将大致如下所示:
第一层:
-
剩余白方兵的数量(0-8)
-
剩余黑方兵的数量(0-8)
-
剩余白方马的数量(0-2)
-
剩余黑方马的数量(0-2)
…
第二层与第一层处于同一级别:
- 兵1的位置(可能使用两个值,x[0-7]和y[0-7])
- 兵2的位置
…
- 后1的位置
- 后2的位置
…
第三层,与前两层处于同一级别。数据将在下一层抽象之后才进行“交互”。
- 兵1攻击的棋子价值(约在0-12范围内)
- 兵2攻击的棋子价值
…
- 象1攻击的棋子价值
你应该明白我的意思了。
如果你还不明白,这里有一个非常粗糙的Paint图示来说明我的意思:
问题是:我在神经网络读取数据之前是否应该对输入数据进行归一化处理?
我觉得压缩数据可能不是一个好主意,但我实在没有足够的专业知识来做出决定性的判断。
我希望这里有人能在这个问题上给我一些启发,如果你认为我应该归一化数据,我希望你能建议一些方法来实现这一点。
谢谢!
回答:
你不需要在网络内部对任何东西进行归一化处理。机器学习的重点是训练权重和偏置以学习一个非线性函数,在你的例子中,它将是静态的象棋评估。因此,你的第二条归一化的蓝色垂直条(靠近最终输出)是多余的。
注意: 隐藏层
比 抽象层
更合适的术语,所以我会使用它来代替。
在隐藏层之前的其他归一化处理是可选的,但推荐使用。它还取决于我们讨论的是什么样的输入。
Giraffe论文在第18页写道:
“每个槽位有归一化的x坐标,归一化的y坐标…”
象棋有64个格子,如果不进行归一化,范围将是[0,1,….63]。这是非常离散的,范围也比其他输入高得多(稍后会详细讨论)。将它们归一化为更易管理且与其他输入可比的范围是有意义的。论文没有说明具体如何进行归一化,但我看不出为什么[0…1]范围不适用。对棋盘格(或坐标)进行归一化是有意义的。
其他输入,比如棋盘上是否有后,是真还是假,因此不需要归一化。例如,Giraffe论文在第18页写道:
…棋子是否存在或不存在…
显然,你不需要对其进行归一化处理。
对你的问题的回答
- 如果你的棋子数量层像Giraffe那样表示,你不需要进行归一化处理。但如果你更喜欢在[0..8]范围内使用离散表示(因为象棋中可能有9个后),你可能需要进行归一化处理。
- 如果你的棋子位置层使用棋盘格表示,你应该像Giraffe那样进行归一化处理。
- Giraffe没有对
棋子攻击防御层
进行归一化处理,可能是因为它以每个格子的最低价值攻击者和防御者
来表示信息。不幸的是,论文没有明确说明这是如何完成的。你的实现可能需要进行归一化处理,因此请使用你的常识。
在没有先验假设哪些特征对模型更相关的情况下,你应该将它们归一化为可比较的尺度。
已编辑
让我回答你的评论。归一化不是正确的术语,你谈论的是激活函数(https://en.wikipedia.org/wiki/Activation_function)。归一化和激活函数不是同一回事。