载入中...
搜索中...
未找到
Learning.h
浏览该文件的文档.
1#pragma once
2
3#include "agent/Agent.h"
4
5#include <algorithm>
6#include <cmath>
7#include <limits>
8#include <numeric>
9
11
12// SplitMix64: local streams, with specified integer-to-double conversion.
14class Random {
15public:
17 explicit Random(std::uint64_t seed) : state_(seed) {}
19 double unit() {
20 auto z = (state_ += 0x9e3779b97f4a7c15ULL);
21 z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9ULL;
22 z = (z ^ (z >> 27)) * 0x94d049bb133111ebULL;
24 return double((z ^ (z >> 31)) >> 11) * 0x1.0p-53;
25 }
27 std::size_t index(std::size_t count) { return std::size_t(unit() * double(count)); }
28
29private:
30 std::uint64_t state_;
31};
32
34inline std::size_t weightCount(std::size_t inputs, std::size_t hidden, std::size_t actions) {
35 return hidden * (inputs + 1) + hidden * (hidden + 1) + actions * (hidden + 1);
36}
37
39inline std::vector<double> layer(const std::vector<double>& x, const Policy& p, std::size_t offset, std::size_t outputs,
40 bool activate) {
42 std::vector<double> y(outputs);
43 for (std::size_t j = 0; j < outputs; ++j) {
44 const auto start = offset + j * (x.size() + 1);
45 double sum = p.weights[start + x.size()];
46 for (std::size_t i = 0; i < x.size(); ++i) sum += x[i] * p.weights[start + i];
47 y[j] = activate ? std::tanh(sum) : sum;
48 }
49 return y;
50}
51
53inline std::vector<double> softmax(std::vector<double> logits, const Observation& o) {
54 double maximum = -std::numeric_limits<double>::infinity();
55 for (auto a : o.legalActions) maximum = std::max(maximum, logits[a]);
57 std::vector<double> probabilities(logits.size());
58 double total = 0;
59 for (auto a : o.legalActions) total += probabilities[a] = std::exp(logits[a] - maximum);
60 for (auto a : o.legalActions) probabilities[a] /= total;
61 return probabilities;
62}
63
65inline std::vector<double> forward(const Policy& p, const Observation& o) {
67 std::vector<double> x(o.features.begin(), o.features.end());
68 auto h1 = layer(x, p, 0, p.hiddenWidth, true);
69 const auto second = p.hiddenWidth * (p.featureCount + 1);
70 auto h2 = layer(h1, p, second, p.hiddenWidth, true);
71 const auto third = second + p.hiddenWidth * (p.hiddenWidth + 1);
73 return softmax(layer(h2, p, third, p.actionCount, false), o);
74}
75
77inline Policy makePolicy(const Config& c) {
78 Policy p;
79 p.featureCount = c.featureCount;
80 p.actionCount = c.actionCount;
81 p.hiddenWidth = c.hiddenWidth;
82 p.weights.resize(weightCount(c.featureCount, c.hiddenWidth, c.actionCount));
84 Random random(c.learningSeed);
85 for (auto& w : p.weights) w = (random.unit() * 2 - 1) / std::sqrt(double(c.hiddenWidth));
86 return p;
87}
88
90inline void train(Policy& p, const Observation& o, std::uint32_t action, double rate) {
92 std::vector<double> x(o.features.begin(), o.features.end());
93 auto h1 = layer(x, p, 0, p.hiddenWidth, true);
94 const auto second = p.hiddenWidth * (p.featureCount + 1);
95 auto h2 = layer(h1, p, second, p.hiddenWidth, true);
96 const auto third = second + p.hiddenWidth * (p.hiddenWidth + 1);
97 auto d3 = softmax(layer(h2, p, third, p.actionCount, false), o);
98 d3[action] -= 1;
100 std::vector<double> d2(p.hiddenWidth), d1(p.hiddenWidth);
101 for (std::size_t i = 0; i < p.hiddenWidth; ++i) {
102 for (std::size_t j = 0; j < p.actionCount; ++j) d2[i] += d3[j] * p.weights[third + j * (p.hiddenWidth + 1) + i];
103 d2[i] *= 1 - h2[i] * h2[i];
104 }
105 for (std::size_t i = 0; i < p.hiddenWidth; ++i) {
106 for (std::size_t j = 0; j < p.hiddenWidth; ++j)
107 d1[i] += d2[j] * p.weights[second + j * (p.hiddenWidth + 1) + i];
108 d1[i] *= 1 - h1[i] * h1[i];
109 }
110 auto update = [&](std::size_t offset, const auto& inputs, const auto& gradient) {
111 for (std::size_t j = 0; j < gradient.size(); ++j) {
112 auto start = offset + j * (inputs.size() + 1);
113 for (std::size_t i = 0; i < inputs.size(); ++i)
114 p.weights[start + i] -= rate * std::clamp(gradient[j] * inputs[i], -1.0, 1.0);
115 p.weights[start + inputs.size()] -= rate * std::clamp(gradient[j], -1.0, 1.0);
116 }
117 };
119 update(third, h2, d3);
121 update(second, h1, d2);
123 update(0, x, d1);
124}
125
126} // namespace eve::agent::detail
Duration start
float w
Definition AnimClip.cpp:738
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
float z
Definition AnimClip.cpp:738
glm::vec4 p[6]
float maximum[3]
int inputs
Definition GridGraph.cpp:23
std::int32_t second
std::int32_t c
size_t offset
MeleePoint3 a
Definition MeleeHit.cpp:40
TileLayer * layer
std::string action
Definition PlayHost.cpp:117
std::vector< ActionSpec > actions
Definition PlayHost.cpp:126
std::uint32_t seed
Definition PointSet.cpp:807
std::uint16_t third
std::uint32_t count
Battle::Random random
Random public API.
Definition Learning.h:14
Random(std::uint64_t seed)
Constructs a Random.
Definition Learning.h:17
std::size_t index(std::size_t count)
Index.
Definition Learning.h:27
Policy makePolicy(const Config &c)
Make policy.
Definition Learning.h:77
void train(Policy &p, const Observation &o, std::uint32_t action, double rate)
Train.
Definition Learning.h:90
std::vector< double > forward(const Policy &p, const Observation &o)
Forward.
Definition Learning.h:65
std::vector< double > softmax(std::vector< double > logits, const Observation &o)
Softmax.
Definition Learning.h:53
std::size_t weightCount(std::size_t inputs, std::size_t hidden, std::size_t actions)
Weight count.
Definition Learning.h:34
Bounded search configuration; seed streams for environment, search and learning are separate.
Definition Agent.h:53
Owning state projection; action IDs index a fixed domain action catalogue.
Definition Agent.h:16
std::vector< std::uint32_t > legalActions
Definition Agent.h:18
std::vector< float > features
Definition Agent.h:17
Owning version-1 portable network weights; import validates the entire value before use.
Definition Agent.h:99
std::uint32_t featureCount
Definition Agent.h:102