umie sie uczyc
This commit is contained in:
		
							parent
							
								
									62fbec9b44
								
							
						
					
					
						commit
						3d83bb3f8f
					
				
							
								
								
									
										1000
									
								
								data/sin.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1000
									
								
								data/sin.dat
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1000
									
								
								data/wig20.dat
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1000
									
								
								data/wig20.dat
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										17
									
								
								decider.h
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								decider.h
									
									
									
									
									
								
							| @ -6,6 +6,7 @@ | ||||
| #include <iterator> | ||||
| #include <iostream> | ||||
| 
 | ||||
| 
 | ||||
| class decider { | ||||
| public: | ||||
|     double   start_money; | ||||
| @ -37,6 +38,8 @@ template <int p, int m, int s, int ...layers> | ||||
| class neural_decider : public decider, macd_decider { | ||||
| public: | ||||
|     using network_t = network<double, p+m+s+2, layers..., 2>; | ||||
|     using self_t    = neural_decider<p, m, s, layers...>; | ||||
| 
 | ||||
|     network_t network; | ||||
| 
 | ||||
|     double   start_money; | ||||
| @ -61,13 +64,23 @@ public: | ||||
|         return abs(buy - sell) <= .5 ? 0 : amount * start_stock / 10; | ||||
|     } | ||||
| 
 | ||||
|     virtual void reset() | ||||
|     virtual void reset() override | ||||
|     { | ||||
|         this->reset(); | ||||
|         macd_decider::reset(); | ||||
|     } | ||||
| 
 | ||||
|     virtual ~neural_decider() { } | ||||
| 
 | ||||
|     self_t combine(self_t smth, typename network_t::combiner_t combiner = [](const double& a, const double& b) { return .35*a + .65*b; }) | ||||
|     { | ||||
|         self_t result; | ||||
| 
 | ||||
|         result.network = network.combine(smth.network, combiner); | ||||
|         result.start_money = start_money; | ||||
|         result.start_stock = start_stock; | ||||
| 
 | ||||
|         return result; | ||||
|     } | ||||
| private: | ||||
|     typename network_t::input prepare(double money, unsigned stock) | ||||
|     { | ||||
|  | ||||
							
								
								
									
										11
									
								
								network.h
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								network.h
									
									
									
									
									
								
							| @ -101,7 +101,7 @@ public: | ||||
|     } | ||||
| 
 | ||||
|     self combine(self& rhs, combiner_t weight_combiner, combiner_t bias_combiner) { | ||||
|         self result; | ||||
|         self result(normalizer); | ||||
|         result.template get<0>() = get<0>().combine(rhs.template get<0>(), weight_combiner, bias_combiner); | ||||
| 
 | ||||
|         return result; | ||||
| @ -159,13 +159,18 @@ public: | ||||
|     } | ||||
|      | ||||
|     self combine(self& rhs, typename base::combiner_t weight_combiner, typename base::combiner_t bias_combiner) { | ||||
|         self result; | ||||
|         self result(normalizer); | ||||
| 
 | ||||
|         result.template get<0>() = get<0>().combine(rhs.template get<0>(), weight_combiner, bias_combiner); | ||||
|         result.subnetwork = subnetwork.combine(rhs.subnetwork); | ||||
|         result.subnetwork = subnetwork.combine(rhs.subnetwork, weight_combiner, bias_combiner); | ||||
| 
 | ||||
|         return result; | ||||
|     } | ||||
| 
 | ||||
|     self combine(self& rhs, typename base::combiner_t combiner) | ||||
|     { | ||||
|         return combine(rhs, combiner, combiner); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
| #endif | ||||
|  | ||||
							
								
								
									
										169
									
								
								trainer.h
									
									
									
									
									
								
							
							
						
						
									
										169
									
								
								trainer.h
									
									
									
									
									
								
							| @ -1,7 +1,10 @@ | ||||
| #include <vector> | ||||
| #include <random> | ||||
| #include <ctime> | ||||
| #include <functional> | ||||
| #include <iostream> | ||||
| #include <algorithm> | ||||
| #include <memory> | ||||
| 
 | ||||
| template<class T> | ||||
| struct trained { | ||||
| @ -10,23 +13,35 @@ struct trained { | ||||
|      | ||||
|     double   monies; | ||||
|     unsigned stock; | ||||
|     double   wealth; | ||||
|     | ||||
|     double   result; | ||||
|     void recalculate(double price) | ||||
|     { | ||||
|         wealth = monies + stock*price; | ||||
|     } | ||||
| 
 | ||||
|     double score; | ||||
| }; | ||||
| 
 | ||||
| template <class T> | ||||
| class trainer { | ||||
|     std::vector< trained<T>* > trainees; | ||||
|     std::vector<std::shared_ptr<trained<T>>> trainees; | ||||
|     std::function<T()> factory; | ||||
| 
 | ||||
|     unsigned int id; | ||||
| 
 | ||||
|     std::default_random_engine random_engine; | ||||
|     std::size_t n; | ||||
| 
 | ||||
| public: | ||||
|     double money; | ||||
|     unsigned stock; | ||||
| 
 | ||||
|     std::function<double(std::shared_ptr<trained<T>> x)> q; | ||||
| 
 | ||||
|     trainer(double money, unsigned stock, std::size_t n, std::function<T()> factory)  | ||||
|         : factory(factory), id(0), money(money), stock(stock) | ||||
|         : factory(factory), id(0), money(money), stock(stock), n(n), | ||||
|         q([](std::shared_ptr<trained<T>> x){ return x->wealth; }), random_engine(std::time(0)) | ||||
|     { | ||||
|         add(n); | ||||
|     } | ||||
| @ -34,12 +49,7 @@ public: | ||||
|     void add(std::size_t n, std::function<T()> factory) | ||||
|     { | ||||
|         for(std::size_t i = 0; i < n; i++) { | ||||
|             trained<T> *trainee = new trained<T>(); | ||||
|             trainee->id = ++id; | ||||
|             trainee->result = 0.0; | ||||
|             trainee->decider = factory(); | ||||
| 
 | ||||
|             trainees.push_back(trainee); | ||||
|             add(factory()); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @ -48,22 +58,17 @@ public: | ||||
|         add(n, factory); | ||||
|     } | ||||
| 
 | ||||
|     void test(std::istream& input) | ||||
|     void add(const T& decider) | ||||
|     { | ||||
|         for (auto trainee : trainees) { | ||||
|             trainee->monies = money; | ||||
|             trainee->stock  = stock; | ||||
|         auto trainee = std::make_shared<trained<T>>(); | ||||
|         trainee->id = ++id; | ||||
|         trainee->decider = decider; | ||||
| 
 | ||||
|             trainee->decider.start_money = money; | ||||
|             trainee->decider.start_stock = stock; | ||||
|         trainees.push_back(trainee); | ||||
|     } | ||||
| 
 | ||||
|         double price, start; | ||||
|         input >> price; | ||||
|         start = price*stock + money; | ||||
| 
 | ||||
|         do { | ||||
|             for (auto trainee : trainees) { | ||||
|     int train(std::shared_ptr<trained<T>> trainee, double price) | ||||
|     { | ||||
|         auto decision   = trainee->decider.decide(price, trainee->monies, trainee->stock); | ||||
|         auto current    = price*trainee->stock + trainee->monies; | ||||
|         auto max_credit = std::max(current * 0.05, -1e4); | ||||
| @ -79,6 +84,29 @@ public: | ||||
| 
 | ||||
|         trainee->stock  += decision; | ||||
|         trainee->monies -= price*decision; | ||||
|         trainee->recalculate(price); | ||||
| 
 | ||||
|         return decision; | ||||
|     } | ||||
| 
 | ||||
|     void test(std::istream& input) | ||||
|     { | ||||
|         for (auto trainee : trainees) { | ||||
|             trainee->monies = money; | ||||
|             trainee->stock  = stock; | ||||
| 
 | ||||
|             trainee->decider.start_money = money; | ||||
|             trainee->decider.start_stock = stock; | ||||
|             trainee->decider.reset(); | ||||
|         } | ||||
| 
 | ||||
|         double price, start; | ||||
|         input >> price; | ||||
|         start = price*stock + money; | ||||
| 
 | ||||
|         do { | ||||
|             for (auto trainee : trainees) { | ||||
|                 train(trainee, price); | ||||
|             } | ||||
|         } while (input >> price); | ||||
| 
 | ||||
| @ -87,13 +115,102 @@ public: | ||||
|         std::cout << "HODL: " << hodl << " START: " << start << std::endl; | ||||
|         std::cout << "-----------------------" << std::endl; | ||||
| 
 | ||||
|         std::sort(trainees.begin(), trainees.end(), [=](trained<T> *a, trained<T> *b){ | ||||
|             return (a->monies + a->stock * price) > (b->monies + b->stock * price); | ||||
|         }); | ||||
|         normalize(); | ||||
| 
 | ||||
|         for (auto trainee : trainees) { | ||||
|             auto earned = trainee->monies + trainee->stock * price; | ||||
|             std::cout << "#" << trainee->id << ": " << earned << " [" << earned - hodl << "] " << trainee->stock << " akcji, " << trainee->monies << " gelda w banku. " << std::endl;  | ||||
|             std::cout  | ||||
|                 << "#" << trainee->id << ": " << trainee->wealth  | ||||
|                 << " [" << trainee->wealth - hodl << "] (" << trainee->score << ") " | ||||
|                 << trainee->stock << " akcji, "  | ||||
|                 << trainee->monies << " gelda w banku. " << std::endl;  | ||||
|         } | ||||
| 
 | ||||
|         filter(); | ||||
|         breed(); | ||||
|     } | ||||
| 
 | ||||
|     void normalize() | ||||
|     { | ||||
|         std::sort(trainees.begin(), trainees.end(), [=](std::shared_ptr<trained<T>> a, std::shared_ptr<trained<T>> b){ | ||||
|             return q(a) > q(b); | ||||
|         }); | ||||
| 
 | ||||
|         auto high = q(*trainees.begin()); | ||||
|         auto low  = q(*(trainees.end() - 1)); | ||||
| 
 | ||||
|         // best = 1, worst = 0
 | ||||
|         for (auto t : trainees) { | ||||
|             t->score = (q(t) - low) / (high - low); | ||||
|         }; | ||||
|     } | ||||
| 
 | ||||
|     void filter() | ||||
|     { | ||||
|         /* static std::exponential_distribution<double> distribution(0.50); */ | ||||
| 
 | ||||
|         /* auto random = [=](){ return 1. - std::clamp(0., distribution(random_engine), 2.)/2.1; }; */ | ||||
|         /* auto iterator = std::remove_if(trainees.begin(), trainees.end(), [=](std::shared_ptr<trained<T>> t) { */ | ||||
|         /*     return random() > t->score; */ | ||||
|         /* }); */ | ||||
| 
 | ||||
|         trainees.erase(trainees.begin() + 49, trainees.end()); | ||||
| 
 | ||||
|         std::cout << "Przy życiu pozostają: "; | ||||
|         for (auto trainee : trainees) { | ||||
|             std::cout << "#" << trainee->id << " "; | ||||
|         } | ||||
|         std::cout << std::endl; | ||||
|     } | ||||
| 
 | ||||
|     void breed() | ||||
|     {    | ||||
|         std::size_t diff = n - trainees.size(); | ||||
|         std::cout << "---------------------------------------" << std::endl; | ||||
|         std::cout << "W populacji brakuje " << diff << " sieci, aktualnie " << trainees.size() << "." << std::endl; | ||||
| 
 | ||||
|         std::vector<double> probability; | ||||
|         for (auto t : trainees) { | ||||
|             probability.push_back(t->score); | ||||
|         } | ||||
| 
 | ||||
|         std::discrete_distribution<unsigned> distribution(probability.begin(), probability.end()); | ||||
|         std::exponential_distribution<double> exponential(1.5); | ||||
|          | ||||
|         auto combiner = [=](const double& a, const double& b){ | ||||
|             auto mutation = (rand() % 2 ? -1 : 1) * exponential(random_engine); | ||||
| 
 | ||||
|             if (exponential(random_engine) < 1) { | ||||
|                 return .6 * a + .4 * b + mutation;  | ||||
|             } | ||||
| 
 | ||||
|             return (rand() % 2 ? a : b) + mutation; | ||||
|         }; | ||||
| 
 | ||||
|         unsigned first, second; | ||||
|         for (int i = 0; i < diff; i++) { | ||||
|             first = distribution(random_engine); | ||||
|             do { second = distribution(random_engine); } while (first == second); | ||||
| 
 | ||||
|             auto combined = trainees[first]->decider.combine(trainees[second]->decider, combiner); | ||||
|             std::cout << "Łączenie #" << trainees[first]->id << " z #" << trainees[second]->id << " dało #" << (id+1) << std::endl; | ||||
|             add(combined); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     void see_best(std::istream& stream) | ||||
|     { | ||||
|         std::shared_ptr<trained<T>> trainee = this->trainees[0]; | ||||
| 
 | ||||
|         std::cout << "price,decision" << std::endl; | ||||
|         double price; | ||||
|          | ||||
|         trainee->monies = money; | ||||
|         trainee->stock  = stock; | ||||
| 
 | ||||
|         trainee->decider.reset(); | ||||
|         while (stream >> price) { | ||||
|             int decision = train(trainee, price); | ||||
|             std::cout << price << "," << decision << std::endl; | ||||
|         } | ||||
|     } | ||||
| }; | ||||
|  | ||||
							
								
								
									
										48
									
								
								wtf.cpp
									
									
									
									
									
								
							
							
						
						
									
										48
									
								
								wtf.cpp
									
									
									
									
									
								
							| @ -5,6 +5,7 @@ | ||||
| #include <random> | ||||
| #include <ctime>  | ||||
| #include <algorithm> | ||||
| #include <fstream> | ||||
| #include <vector> | ||||
| 
 | ||||
| #include "argh.h" | ||||
| @ -13,40 +14,69 @@ | ||||
| #include "decider.h" | ||||
| #include "trainer.h" | ||||
| 
 | ||||
| using current_decider = neural_decider<24, 12, 12, 32, 16>; | ||||
| 
 | ||||
| int main(int argc, char* argv[]) | ||||
| { | ||||
|     argh::parser args; | ||||
|     args.add_params({"-m", "--money"}); | ||||
|     args.add_params({"-s", "--stock"}); | ||||
|     args.add_params({"-p", "--population"}); | ||||
|     args.add_params({"-n", "--iterations"}); | ||||
| 
 | ||||
|     args.parse(argc, argv); | ||||
| 
 | ||||
|     double   money; | ||||
|     unsigned stock, population; | ||||
|     unsigned stock, population, iterations; | ||||
|     std::string input_file; | ||||
| 
 | ||||
|     args({ "m", "money" }, 1000.)   >> money; | ||||
|     args({ "s", "stock" }, 1000)    >> stock; | ||||
|     args({ "p", "population" }, 25) >> population; | ||||
|     args({ "n", "iterations" }, 4)  >> iterations; | ||||
|     args(1) >> input_file; | ||||
| 
 | ||||
|     std::uniform_real_distribution<double> distribution(-1.0, 1.0); | ||||
|     std::default_random_engine random_engine; | ||||
|     random_engine.seed(std::time(0)); | ||||
|     std::uniform_real_distribution<double> distribution(-2.0, 2.0); | ||||
|     std::uniform_real_distribution<double> bias_distribution(-16.0, 16.0); | ||||
| 
 | ||||
|     std::function<double(const int&, const int&)> randomizer = [&](const int& i, const int& j) -> double { | ||||
|     std::random_device rd; | ||||
| 
 | ||||
|     //
 | ||||
|     // Engines 
 | ||||
|     //
 | ||||
|     std::mt19937 random_engine(rd()); | ||||
| 
 | ||||
|     std::function<double(const int&, const int&)> randomizer = [&](const int&, const int&) -> double { | ||||
|         return distribution(random_engine); | ||||
|     }; | ||||
| 
 | ||||
|     std::function<double(const int&, const int&)> bias_randomizer = [&](const int&, const int&) -> double { | ||||
|         return distribution(random_engine); | ||||
|     }; | ||||
| 
 | ||||
|     std::function<double(const double&)> normalizer = [](const double& result) -> double { return erf(result); }; | ||||
| 
 | ||||
|     using current_decider = neural_decider<24, 12, 12, 32, 16>; | ||||
| 
 | ||||
|     std::function<current_decider ()> factory = [&]() -> current_decider { | ||||
|         current_decider decider(normalizer); | ||||
|         decider.network.fill(randomizer); | ||||
|         decider.network.fill(randomizer, bias_randomizer); | ||||
| 
 | ||||
|         return decider; | ||||
|     }; | ||||
| 
 | ||||
|     trainer<current_decider> train(money, stock, population, factory); | ||||
|     train.test(std::cin); | ||||
|   | ||||
|     std::fstream input; | ||||
|     input.open(input_file); | ||||
| 
 | ||||
|     for (int i = 0; i < iterations; i++) { | ||||
|         input.clear(); | ||||
|         input.seekg(0); | ||||
| 
 | ||||
|         train.test(input); | ||||
|     } | ||||
| 
 | ||||
|     input.clear(); | ||||
|     input.seekg(0); | ||||
| 
 | ||||
|     train.see_best(input); | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user