From 58915cc59905d6f63d581f6a358581d75010d6d1 Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Fri, 25 Nov 2016 14:08:41 -0800 Subject: [PATCH 1/9] Add @mojones ANN strategy --- axelrod/strategies/_strategies.py | 4 +- axelrod/strategies/ann.py | 300 ++++++++++++++++++++++++++++++ 2 files changed, 303 insertions(+), 1 deletion(-) create mode 100644 axelrod/strategies/ann.py diff --git a/axelrod/strategies/_strategies.py b/axelrod/strategies/_strategies.py index 32bd21546..830d4433e 100644 --- a/axelrod/strategies/_strategies.py +++ b/axelrod/strategies/_strategies.py @@ -2,6 +2,7 @@ from .alternator import Alternator from .adaptive import Adaptive +from .ann import EvolvedANN from .apavlov import APavlov2006, APavlov2011 from .appeaser import Appeaser from .averagecopier import AverageCopier, NiceAverageCopier @@ -105,6 +106,8 @@ EasyGo, Eatherley, EventualCycleHunter, + EvolvedANN, + EvolvedLookerUp, Feld, FirmButFair, FoolMeForever, @@ -150,7 +153,6 @@ LimitedRetaliate, LimitedRetaliate2, LimitedRetaliate3, - EvolvedLookerUp, MathConstantHunter, NaiveProber, MindBender, diff --git a/axelrod/strategies/ann.py b/axelrod/strategies/ann.py new file mode 100644 index 000000000..e16c9bb3e --- /dev/null +++ b/axelrod/strategies/ann.py @@ -0,0 +1,300 @@ +from axelrod import Actions, Player, init_args + +C, D = Actions.C, Actions.D + + +class ANN(Player): + name = 'ANN' + classifier = { + 'memory_depth': 1, # actually variable + 'stochastic': True, + 'inspects_source': False, + 'makes_use_of': set(), + 'manipulates_source': False, + 'manipulates_state': False + } + + def activate(self, inputs): + # calculate values of hidden nodes + hidden_values = [] + for i in range(self.hidden_layer_size): + hidden_node_value = 0 + bias_weight = self.bias_weights[i] + hidden_node_value += bias_weight + for j in range(self.input_values): + weight = self.input_to_hidden_layer_weights[i][j] + hidden_node_value += inputs[j] * weight + + # ReLU activation function + hidden_node_value = max(hidden_node_value, 0) + + hidden_values.append(hidden_node_value) + + # calculate output value + output_value = 0 + for i in range(self.hidden_layer_size): + output_value += hidden_values[i] * \ + self.hidden_to_output_layer_weights[i] + + return output_value + + @init_args + def __init__( + self, + input_to_hidden_layer_weights=[], + hidden_to_output_layer_weights=[], + bias_weights=[] + ): + + Player.__init__(self) + self.input_to_hidden_layer_weights = input_to_hidden_layer_weights + self.hidden_to_output_layer_weights = hidden_to_output_layer_weights + self.bias_weights = bias_weights + + self.input_values = len(input_to_hidden_layer_weights[0]) + self.hidden_layer_size = len(hidden_to_output_layer_weights) + + # self.init_args = (input_to_hidden_layer_weights, + # hidden_to_output_layer_weights, + # bias_weights) + + def strategy(self, opponent): + # action2input = {'C': 1, 'D': -1} + + if len(opponent.history) == 0: + opponent_first_c = 0 + opponent_first_d = 0 + + opponent_second_c = 0 + opponent_second_d = 0 + + my_previous_c = 0 + my_previous_d = 0 + + my_previous2_c = 0 + my_previous2_d = 0 + + opponent_previous_c = 0 + opponent_previous_d = 0 + + opponent_previous2_c = 0 + opponent_previous2_d = 0 + + elif len(opponent.history) == 1: + opponent_first_c = 1 if opponent.history[0] == 'C' else 0 + opponent_first_d = 1 if opponent.history[0] == 'D' else 0 + + opponent_second_c = 0 + opponent_second_d = 0 + + my_previous_c = 1 if self.history[-1] == 'C' else 0 + my_previous_d = 0 if self.history[-1] == 'D' else 0 + + my_previous2_c = 0 + my_previous2_d = 0 + + opponent_previous_c = 1 if opponent.history[-1] == 'C' else 0 + opponent_previous_d = 1 if opponent.history[-1] == 'D' else 0 + + opponent_previous2_c = 0 + opponent_previous2_d = 0 + + else: + opponent_first_c = 1 if opponent.history[0] == 'C' else 0 + opponent_first_d = 1 if opponent.history[0] == 'D' else 0 + + opponent_second_c = 1 if opponent.history[1] == 'C' else 0 + opponent_second_d = 1 if opponent.history[1] == 'D' else 0 + + my_previous_c = 1 if self.history[-1] == 'C' else 0 + my_previous_d = 0 if self.history[-1] == 'D' else 0 + + my_previous2_c = 1 if self.history[-2] == 'C' else 0 + my_previous2_d = 1 if self.history[-2] == 'D' else 0 + + opponent_previous_c = 1 if opponent.history[-1] == 'C' else 0 + opponent_previous_d = 1 if opponent.history[-1] == 'D' else 0 + + opponent_previous2_c = 1 if opponent.history[-2] == 'C' else 0 + opponent_previous2_d = 1 if opponent.history[-2] == 'D' else 0 + + turns_remaining = self.match_attributes['length'] - len(self.history) + + total_opponent_c = opponent.history.count('C') + total_opponent_d = opponent.history.count('D') + + total_self_c = self.history.count('C') + total_self_d = self.history.count('D') + + output = self.activate([ + opponent_first_c, + opponent_first_d, + + opponent_second_c, + opponent_second_d, + + my_previous_c, + my_previous_d, + + my_previous2_c, + my_previous2_d, + + opponent_previous_c, + opponent_previous_d, + + opponent_previous2_c, + opponent_previous2_d, + + total_opponent_c, + total_opponent_d, + + total_self_c, + total_self_d, + + turns_remaining + + ]) + # if output > random.uniform(-1, 1): + if output > 0: + return 'C' + else: + return 'D' + + +def split_weights(weights, input_values, hidden_layer_size): + number_of_input_to_hidden_weights = input_values * hidden_layer_size + # number_of_hidden_bias_weights = hidden_layer_size + number_of_hidden_to_output_weights = hidden_layer_size + + input2hidden = [] + for i in range(0, number_of_input_to_hidden_weights, input_values): + input2hidden.append(weights[i:i + input_values]) + + hidden2output = weights[ + number_of_input_to_hidden_weights:number_of_input_to_hidden_weights + number_of_hidden_to_output_weights] + bias = weights[ + number_of_input_to_hidden_weights + number_of_hidden_to_output_weights:] + + return (input2hidden, hidden2output, bias) + + +class EvolvedANN(ANN): + name = "EvolvedANN" + + @init_args + def __init__(self): + input_values = 17 + hidden_layer_size = 10 + + test_weights = [0.19789658035994948, -5575.476236516673, + 0.1028948855131803, 0.7421752484224489, + -16.286246197005298, 11708.007255945553, + 0.01400184611448853, -33.39126355009626, + -12.755203414662356, -32.92388754142929, + 197.3517717772447, 108262.87038790248, + -0.1084768512582505, 85.20738888799768, + 723.9537664890132, -2.59453614458083, + 0.5599936275978272, 7.89217571665664, + -48014.821440080384, -1.364025168184463, + -1.062138244222801, 11153713.883580556, + -59.58314524751318, 51278.916519524784, + 3196.528224457722, -4635.771421694692, + -129.93354968926164, -0.7927383528469051, + 98.47779304649353, -81.19056440190543, + 29.53082483602472, -48.16562780387682, + 49.40755170297665, 288.3295763937912, + -68.38780651250116, -167.64039570334904, + -0.1576073061122998, 160.6846658333963, + 34.55451693336857, -0.08213997499783675, + -4.802560347075611, -1.4042000430302104, + -0.9832145174590058, + 0.008705149387813573, 14.041842191255089, + 0.05395665905821821, + -0.13856885306885558, 5.311455433711278, + -5.835498171845142, + 0.00010294700612334848, + 26.42528200366623, 33.690839945794785, + 7.931017950666591, + -0.00037662122944226125, + 59.295075951374606, -0.15888507169191035, + 3.670332254391659, 789.6230735057893, + -0.7367125124436135, -198.44119280589902, + 537.9939493545736, -287.54344903637207, + 1759.5455359353778, -18.48997020629342, + -8426184.81603275, -82.36805426730088, + 1144.1032034358543, 15635.402592538396, + 3095.643889329041, 2332.107673930774, + -0.5601648316602144, 101.98300711150003, + -7387.135294747112, -4241.004613717573, + 3.06175607282536e-05, + -35122.894421260884, -38591.45572476855, + -0.16081285130591272, -29608.73087879185, + 122.47563639056185, 6.381946054740736, + -0.8978628581801188, 17658.47647781355, + -0.011719257684286711, + 0.10734295104044986, -378.35448968529494, + 225.06912279045062, -351.12326495980847, + -1.927322672845826, + 0.0014584395475859544, + -8.629826916169318, 22.43281153854352, + 87.10895591188721, -0.22253937914423294, + -233.06796470563208, -620.4917481128365, + -1.8253699204909606, + -0.0030318160426064467, + -77.25818476745101, -2057.311059352977, + 3.764204074005541, -47.47629147374066, + 233.16096124330778, -160721.96744375565, + -278292.9688140893, -2.093640525920404, + -142886.66171202937, 53.64449245132945, + 12.5162147724691, -207.75462390139955, + 132167.659160016, 21.197418541051732, + 83979.45623573882, -49.47558832987566, + 0.05242625398046057, -842.1484416713075, + -0.1581049310461208, 2359.2124343564096, + 1170.5147830681053, -847999.9145843558, + -0.8053911061885284, -5363.722820739466, + 171.58433274294117, -724.7468082647013, + 2500359.853524033, 1595.3955511798079, + -4.254009123616706, -171.12968391407912, + -32.30624102753424, -558.412338112568, + -234.29754199019308, -18768.34057250429, + 8338.792126484348, -0.18593140210730602, + -7.758804964874875, 0.39736677884665267, + 547.0567585452197, 1.1969366369973133, + 0.4861465741177498, -51.19319208716985, + 12.775051406025534, -0.09185362260212569, + 22.08417300332754, -5090.013231748707, + -0.814394991797045, 1.1534025840023847, + 8.390439959276764, -0.02227253403481858, + 0.14162040507921927, + -0.011508263843203926, + 0.22372493104861083, 0.7754713610627112, + 0.1044033140236981, -4.377055307648915, + -41.898221495326574, -18656.755601828827, + -134.56719406539244, -2405.8148785743474, + 16864.049985157206, -0.5124682025216784, + 14521.069005125159, -10.740782200739309, + 18756.807715014013, -1723.9353962656946, + 87029.99828299093, + 5.7383786020894195e-05, + 4762.960401619296, 0.7331769713238158, + -308.5673034493341, 85.29725765515369, + 0.4268843538235295, -0.17788805472511407, + -1.1727033611646802, 7578.6822604990175, + 0.5124673187864222, 0.1595627909684813, + -145.93742731401096, -2954.234440189563, + 0.009672881359732015, 106.4646644917487, + -0.050606976105730346, + 2.3904047264403596, -4.987645640997455, + -43.22984692765006, -36.177108409134966, + -0.3812547430698569, -2959.4921368963633, + -1.8635802741029985, + 0.020513128847167047, + -0.9179124323385958] + + (i2h, h2o, bias) = split_weights( + test_weights, + input_values, + hidden_layer_size + ) + ANN.__init__(self, i2h, h2o, bias) From ff6bc7d892bcf16b374ddd7747277679387bc27c Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Fri, 25 Nov 2016 14:34:58 -0800 Subject: [PATCH 2/9] Source @mojones' gist --- axelrod/strategies/ann.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/axelrod/strategies/ann.py b/axelrod/strategies/ann.py index e16c9bb3e..bef49d9de 100644 --- a/axelrod/strategies/ann.py +++ b/axelrod/strategies/ann.py @@ -2,6 +2,8 @@ C, D = Actions.C, Actions.D +# Source: https://gist.github.com/mojones/550b32c46a8169bb3cd89d917b73111a#file-ann-strategy-test-L60 +# Original Author: Martin Jones, @mojones class ANN(Player): name = 'ANN' From 6c16832aa52947ad0aea140394392f33e2564616 Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Fri, 25 Nov 2016 14:39:51 -0800 Subject: [PATCH 3/9] Comments for ANN, mostly --- axelrod/strategies/ann.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/axelrod/strategies/ann.py b/axelrod/strategies/ann.py index bef49d9de..da2bb5627 100644 --- a/axelrod/strategies/ann.py +++ b/axelrod/strategies/ann.py @@ -8,8 +8,8 @@ class ANN(Player): name = 'ANN' classifier = { - 'memory_depth': 1, # actually variable - 'stochastic': True, + 'memory_depth': float('inf'), + 'stochastic': False, 'inspects_source': False, 'makes_use_of': set(), 'manipulates_source': False, @@ -17,6 +17,7 @@ class ANN(Player): } def activate(self, inputs): + """Compute the output of the neural network.""" # calculate values of hidden nodes hidden_values = [] for i in range(self.hidden_layer_size): @@ -56,13 +57,8 @@ def __init__( self.input_values = len(input_to_hidden_layer_weights[0]) self.hidden_layer_size = len(hidden_to_output_layer_weights) - # self.init_args = (input_to_hidden_layer_weights, - # hidden_to_output_layer_weights, - # bias_weights) - def strategy(self, opponent): - # action2input = {'C': 1, 'D': -1} - + # Compute features for Neural Network if len(opponent.history) == 0: opponent_first_c = 0 opponent_first_d = 0 @@ -156,14 +152,15 @@ def strategy(self, opponent): turns_remaining ]) - # if output > random.uniform(-1, 1): if output > 0: - return 'C' + return C else: - return 'D' + return D def split_weights(weights, input_values, hidden_layer_size): + """Splits the input vector into the the NN bias weights and layer + parameters.""" number_of_input_to_hidden_weights = input_values * hidden_layer_size # number_of_hidden_bias_weights = hidden_layer_size number_of_hidden_to_output_weights = hidden_layer_size @@ -179,7 +176,6 @@ def split_weights(weights, input_values, hidden_layer_size): return (input2hidden, hidden2output, bias) - class EvolvedANN(ANN): name = "EvolvedANN" From 817760adaed378ded1d2a9bcfab787ad69750284 Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Mon, 28 Nov 2016 08:14:27 -0800 Subject: [PATCH 4/9] Fix broken test by adding classifier to ANN --- axelrod/strategies/ann.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/axelrod/strategies/ann.py b/axelrod/strategies/ann.py index da2bb5627..d5f0fcd6c 100644 --- a/axelrod/strategies/ann.py +++ b/axelrod/strategies/ann.py @@ -13,7 +13,8 @@ class ANN(Player): 'inspects_source': False, 'makes_use_of': set(), 'manipulates_source': False, - 'manipulates_state': False + 'manipulates_state': False, + 'long_run_time': False } def activate(self, inputs): From cbfd20cd8fc38f6380cd6a421f53e73a3ccb2d86 Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Mon, 28 Nov 2016 08:28:21 -0800 Subject: [PATCH 5/9] Cleanup of ANN and classified ANN as using tournament length --- axelrod/strategies/ann.py | 238 +++++++++++++------------------------- 1 file changed, 79 insertions(+), 159 deletions(-) diff --git a/axelrod/strategies/ann.py b/axelrod/strategies/ann.py index d5f0fcd6c..0a06036e0 100644 --- a/axelrod/strategies/ann.py +++ b/axelrod/strategies/ann.py @@ -19,7 +19,7 @@ class ANN(Player): def activate(self, inputs): """Compute the output of the neural network.""" - # calculate values of hidden nodes + # Calculate values of hidden nodes hidden_values = [] for i in range(self.hidden_layer_size): hidden_node_value = 0 @@ -34,7 +34,7 @@ def activate(self, inputs): hidden_values.append(hidden_node_value) - # calculate output value + # Calculate output value output_value = 0 for i in range(self.hidden_layer_size): output_value += hidden_values[i] * \ @@ -60,98 +60,74 @@ def __init__( def strategy(self, opponent): # Compute features for Neural Network + # These are True/False 0/1 if len(opponent.history) == 0: opponent_first_c = 0 opponent_first_d = 0 - opponent_second_c = 0 opponent_second_d = 0 - my_previous_c = 0 my_previous_d = 0 - my_previous2_c = 0 my_previous2_d = 0 - opponent_previous_c = 0 opponent_previous_d = 0 - opponent_previous2_c = 0 opponent_previous2_d = 0 elif len(opponent.history) == 1: - opponent_first_c = 1 if opponent.history[0] == 'C' else 0 - opponent_first_d = 1 if opponent.history[0] == 'D' else 0 - + opponent_first_c = 1 if opponent.history[0] == C else 0 + opponent_first_d = 1 if opponent.history[0] == D else 0 opponent_second_c = 0 opponent_second_d = 0 - - my_previous_c = 1 if self.history[-1] == 'C' else 0 - my_previous_d = 0 if self.history[-1] == 'D' else 0 - + my_previous_c = 1 if self.history[-1] == C else 0 + my_previous_d = 0 if self.history[-1] == D else 0 my_previous2_c = 0 my_previous2_d = 0 - - opponent_previous_c = 1 if opponent.history[-1] == 'C' else 0 - opponent_previous_d = 1 if opponent.history[-1] == 'D' else 0 - + opponent_previous_c = 1 if opponent.history[-1] == C else 0 + opponent_previous_d = 1 if opponent.history[-1] == D else 0 opponent_previous2_c = 0 opponent_previous2_d = 0 else: - opponent_first_c = 1 if opponent.history[0] == 'C' else 0 - opponent_first_d = 1 if opponent.history[0] == 'D' else 0 - - opponent_second_c = 1 if opponent.history[1] == 'C' else 0 - opponent_second_d = 1 if opponent.history[1] == 'D' else 0 - - my_previous_c = 1 if self.history[-1] == 'C' else 0 - my_previous_d = 0 if self.history[-1] == 'D' else 0 - - my_previous2_c = 1 if self.history[-2] == 'C' else 0 - my_previous2_d = 1 if self.history[-2] == 'D' else 0 - - opponent_previous_c = 1 if opponent.history[-1] == 'C' else 0 - opponent_previous_d = 1 if opponent.history[-1] == 'D' else 0 - - opponent_previous2_c = 1 if opponent.history[-2] == 'C' else 0 - opponent_previous2_d = 1 if opponent.history[-2] == 'D' else 0 - + opponent_first_c = 1 if opponent.history[0] == C else 0 + opponent_first_d = 1 if opponent.history[0] == D else 0 + opponent_second_c = 1 if opponent.history[1] == C else 0 + opponent_second_d = 1 if opponent.history[1] == D else 0 + my_previous_c = 1 if self.history[-1] == C else 0 + my_previous_d = 0 if self.history[-1] == D else 0 + my_previous2_c = 1 if self.history[-2] == C else 0 + my_previous2_d = 1 if self.history[-2] == D else 0 + opponent_previous_c = 1 if opponent.history[-1] == C else 0 + opponent_previous_d = 1 if opponent.history[-1] == D else 0 + opponent_previous2_c = 1 if opponent.history[-2] == C else 0 + opponent_previous2_d = 1 if opponent.history[-2] == D else 0 + + # Remaining Features turns_remaining = self.match_attributes['length'] - len(self.history) - - total_opponent_c = opponent.history.count('C') - total_opponent_d = opponent.history.count('D') - - total_self_c = self.history.count('C') - total_self_d = self.history.count('D') + total_opponent_c = opponent.history.count(C) + total_opponent_d = opponent.history.count(D) + total_self_c = self.history.count(C) + total_self_d = self.history.count(D) output = self.activate([ opponent_first_c, opponent_first_d, - opponent_second_c, opponent_second_d, - my_previous_c, my_previous_d, - my_previous2_c, my_previous2_d, - opponent_previous_c, opponent_previous_d, - opponent_previous2_c, opponent_previous2_d, - total_opponent_c, total_opponent_d, - total_self_c, total_self_d, - turns_remaining - ]) if output > 0: return C @@ -163,7 +139,6 @@ def split_weights(weights, input_values, hidden_layer_size): """Splits the input vector into the the NN bias weights and layer parameters.""" number_of_input_to_hidden_weights = input_values * hidden_layer_size - # number_of_hidden_bias_weights = hidden_layer_size number_of_hidden_to_output_weights = hidden_layer_size input2hidden = [] @@ -172,124 +147,69 @@ def split_weights(weights, input_values, hidden_layer_size): hidden2output = weights[ number_of_input_to_hidden_weights:number_of_input_to_hidden_weights + number_of_hidden_to_output_weights] - bias = weights[ - number_of_input_to_hidden_weights + number_of_hidden_to_output_weights:] + bias = weights[number_of_input_to_hidden_weights + number_of_hidden_to_output_weights:] return (input2hidden, hidden2output, bias) + class EvolvedANN(ANN): name = "EvolvedANN" + self.classifier['makes_use_of'] = set(['length']) + @init_args def __init__(self): input_values = 17 hidden_layer_size = 10 - test_weights = [0.19789658035994948, -5575.476236516673, - 0.1028948855131803, 0.7421752484224489, - -16.286246197005298, 11708.007255945553, - 0.01400184611448853, -33.39126355009626, - -12.755203414662356, -32.92388754142929, - 197.3517717772447, 108262.87038790248, - -0.1084768512582505, 85.20738888799768, - 723.9537664890132, -2.59453614458083, - 0.5599936275978272, 7.89217571665664, - -48014.821440080384, -1.364025168184463, - -1.062138244222801, 11153713.883580556, - -59.58314524751318, 51278.916519524784, - 3196.528224457722, -4635.771421694692, - -129.93354968926164, -0.7927383528469051, - 98.47779304649353, -81.19056440190543, - 29.53082483602472, -48.16562780387682, - 49.40755170297665, 288.3295763937912, - -68.38780651250116, -167.64039570334904, - -0.1576073061122998, 160.6846658333963, - 34.55451693336857, -0.08213997499783675, - -4.802560347075611, -1.4042000430302104, - -0.9832145174590058, - 0.008705149387813573, 14.041842191255089, - 0.05395665905821821, - -0.13856885306885558, 5.311455433711278, - -5.835498171845142, - 0.00010294700612334848, - 26.42528200366623, 33.690839945794785, - 7.931017950666591, - -0.00037662122944226125, - 59.295075951374606, -0.15888507169191035, - 3.670332254391659, 789.6230735057893, - -0.7367125124436135, -198.44119280589902, - 537.9939493545736, -287.54344903637207, - 1759.5455359353778, -18.48997020629342, - -8426184.81603275, -82.36805426730088, - 1144.1032034358543, 15635.402592538396, - 3095.643889329041, 2332.107673930774, - -0.5601648316602144, 101.98300711150003, - -7387.135294747112, -4241.004613717573, - 3.06175607282536e-05, - -35122.894421260884, -38591.45572476855, - -0.16081285130591272, -29608.73087879185, - 122.47563639056185, 6.381946054740736, - -0.8978628581801188, 17658.47647781355, - -0.011719257684286711, - 0.10734295104044986, -378.35448968529494, - 225.06912279045062, -351.12326495980847, - -1.927322672845826, - 0.0014584395475859544, - -8.629826916169318, 22.43281153854352, - 87.10895591188721, -0.22253937914423294, - -233.06796470563208, -620.4917481128365, - -1.8253699204909606, - -0.0030318160426064467, - -77.25818476745101, -2057.311059352977, - 3.764204074005541, -47.47629147374066, - 233.16096124330778, -160721.96744375565, - -278292.9688140893, -2.093640525920404, - -142886.66171202937, 53.64449245132945, - 12.5162147724691, -207.75462390139955, - 132167.659160016, 21.197418541051732, - 83979.45623573882, -49.47558832987566, - 0.05242625398046057, -842.1484416713075, - -0.1581049310461208, 2359.2124343564096, - 1170.5147830681053, -847999.9145843558, - -0.8053911061885284, -5363.722820739466, - 171.58433274294117, -724.7468082647013, - 2500359.853524033, 1595.3955511798079, - -4.254009123616706, -171.12968391407912, - -32.30624102753424, -558.412338112568, - -234.29754199019308, -18768.34057250429, - 8338.792126484348, -0.18593140210730602, - -7.758804964874875, 0.39736677884665267, - 547.0567585452197, 1.1969366369973133, - 0.4861465741177498, -51.19319208716985, - 12.775051406025534, -0.09185362260212569, - 22.08417300332754, -5090.013231748707, - -0.814394991797045, 1.1534025840023847, - 8.390439959276764, -0.02227253403481858, - 0.14162040507921927, - -0.011508263843203926, - 0.22372493104861083, 0.7754713610627112, - 0.1044033140236981, -4.377055307648915, - -41.898221495326574, -18656.755601828827, - -134.56719406539244, -2405.8148785743474, - 16864.049985157206, -0.5124682025216784, - 14521.069005125159, -10.740782200739309, - 18756.807715014013, -1723.9353962656946, - 87029.99828299093, - 5.7383786020894195e-05, - 4762.960401619296, 0.7331769713238158, - -308.5673034493341, 85.29725765515369, - 0.4268843538235295, -0.17788805472511407, - -1.1727033611646802, 7578.6822604990175, - 0.5124673187864222, 0.1595627909684813, - -145.93742731401096, -2954.234440189563, - 0.009672881359732015, 106.4646644917487, - -0.050606976105730346, - 2.3904047264403596, -4.987645640997455, - -43.22984692765006, -36.177108409134966, - -0.3812547430698569, -2959.4921368963633, - -1.8635802741029985, - 0.020513128847167047, - -0.9179124323385958] + test_weights = [0.19789658035994948, -5575.476236516673, 0.1028948855131803, 0.7421752484224489, + -16.286246197005298, 11708.007255945553, 0.01400184611448853, -33.39126355009626, + -12.755203414662356, -32.92388754142929, 197.3517717772447, 108262.87038790248, + -0.1084768512582505, 85.20738888799768, 723.9537664890132, -2.59453614458083, + 0.5599936275978272, 7.89217571665664, -48014.821440080384, -1.364025168184463, + -1.062138244222801, 11153713.883580556, -59.58314524751318, 51278.916519524784, + 3196.528224457722, -4635.771421694692, -129.93354968926164, -0.7927383528469051, + 98.47779304649353, -81.19056440190543, 29.53082483602472, -48.16562780387682, + 49.40755170297665, 288.3295763937912, -68.38780651250116, -167.64039570334904, + -0.1576073061122998, 160.6846658333963, 34.55451693336857, -0.08213997499783675, + -4.802560347075611, -1.4042000430302104, -0.9832145174590058, 0.008705149387813573, + 14.041842191255089, 0.05395665905821821, -0.13856885306885558, 5.311455433711278, + -5.835498171845142, 0.00010294700612334848, 26.42528200366623, 33.690839945794785, + 7.931017950666591, -0.00037662122944226125, 59.295075951374606, -0.15888507169191035, + 3.670332254391659, 789.6230735057893, -0.7367125124436135, -198.44119280589902, + 537.9939493545736, -287.54344903637207, 1759.5455359353778, -18.48997020629342, + -8426184.81603275, -82.36805426730088, 1144.1032034358543, 15635.402592538396, + 3095.643889329041, 2332.107673930774, -0.5601648316602144, 101.98300711150003, + -7387.135294747112, -4241.004613717573, 3.06175607282536e-05, -35122.894421260884, + -38591.45572476855, -0.16081285130591272, -29608.73087879185, 122.47563639056185, + 6.381946054740736, -0.8978628581801188, 17658.47647781355, -0.011719257684286711, + 0.10734295104044986, -378.35448968529494, 225.06912279045062, -351.12326495980847, + -1.927322672845826, 0.0014584395475859544, -8.629826916169318, 22.43281153854352, + 87.10895591188721, -0.22253937914423294, -233.06796470563208, -620.4917481128365, + -1.8253699204909606,-0.0030318160426064467, -77.25818476745101, -2057.311059352977, + 3.764204074005541, -47.47629147374066, 233.16096124330778, -160721.96744375565, + -278292.9688140893, -2.093640525920404, -142886.66171202937, 53.64449245132945, + 12.5162147724691, -207.75462390139955, 132167.659160016, 21.197418541051732, + 83979.45623573882, -49.47558832987566, 0.05242625398046057, -842.1484416713075, + -0.1581049310461208, 2359.2124343564096, 1170.5147830681053, -847999.9145843558, + -0.8053911061885284, -5363.722820739466, 171.58433274294117, -724.7468082647013, + 2500359.853524033, 1595.3955511798079, -4.254009123616706, -171.12968391407912, + -32.30624102753424, -558.412338112568, -234.29754199019308, -18768.34057250429, + 8338.792126484348, -0.18593140210730602, -7.758804964874875, 0.39736677884665267, + 547.0567585452197, 1.1969366369973133, 0.4861465741177498, -51.19319208716985, + 12.775051406025534, -0.09185362260212569, 22.08417300332754, -5090.013231748707, + -0.814394991797045, 1.1534025840023847, 8.390439959276764, -0.02227253403481858, + 0.14162040507921927, -0.011508263843203926, 0.22372493104861083, 0.7754713610627112, + 0.1044033140236981, -4.377055307648915, -41.898221495326574, -18656.755601828827, + -134.56719406539244, -2405.8148785743474, 16864.049985157206, -0.5124682025216784, + 14521.069005125159, -10.740782200739309, 18756.807715014013, -1723.9353962656946, + 87029.99828299093, 5.7383786020894195e-05, 4762.960401619296, 0.7331769713238158, + -308.5673034493341, 85.29725765515369, 0.4268843538235295, -0.17788805472511407, + -1.1727033611646802, 7578.6822604990175, 0.5124673187864222, 0.1595627909684813, + -145.93742731401096, -2954.234440189563, 0.009672881359732015, 106.4646644917487, + -0.050606976105730346, 2.3904047264403596, -4.987645640997455, -43.22984692765006, + -36.177108409134966, -0.3812547430698569, -2959.4921368963633, -1.8635802741029985, + 0.020513128847167047, -0.9179124323385958] (i2h, h2o, bias) = split_weights( test_weights, From 70e85c10ecd67d84d782878a446c02adde58ba8b Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Mon, 28 Nov 2016 08:31:58 -0800 Subject: [PATCH 6/9] Move classifier modification in ANN to __init__ --- axelrod/strategies/ann.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/axelrod/strategies/ann.py b/axelrod/strategies/ann.py index 0a06036e0..689dd554b 100644 --- a/axelrod/strategies/ann.py +++ b/axelrod/strategies/ann.py @@ -155,10 +155,11 @@ def split_weights(weights, input_values, hidden_layer_size): class EvolvedANN(ANN): name = "EvolvedANN" - self.classifier['makes_use_of'] = set(['length']) + @init_args def __init__(self): + self.classifier['makes_use_of'] = set(['length']) input_values = 17 hidden_layer_size = 10 From 0ed2db50dd0e3bd9f622680ae95f57186e7d06aa Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Mon, 28 Nov 2016 08:37:56 -0800 Subject: [PATCH 7/9] Fix doc test --- docs/tutorials/advanced/classification_of_strategies.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/tutorials/advanced/classification_of_strategies.rst b/docs/tutorials/advanced/classification_of_strategies.rst index cad2ebe73..607f98b3e 100644 --- a/docs/tutorials/advanced/classification_of_strategies.rst +++ b/docs/tutorials/advanced/classification_of_strategies.rst @@ -81,7 +81,7 @@ length of each match of the tournament:: ... } >>> strategies = axl.filtered_strategies(filterset) >>> len(strategies) - 5 + 6 Note that in the filterset dictionary, the value for the 'makes_use_of' key must be a list. Here is how we might identify the number of strategies that use From 22caaeab062ab689ebcb0bab9790688f68b50086 Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Mon, 28 Nov 2016 20:15:42 -0800 Subject: [PATCH 8/9] Basic tests and some more cleanup for EvolvedANN --- axelrod/strategies/ann.py | 48 ++++++++++++++++++---------------- axelrod/tests/unit/test_ann.py | 32 +++++++++++++++++++++++ 2 files changed, 57 insertions(+), 23 deletions(-) create mode 100644 axelrod/tests/unit/test_ann.py diff --git a/axelrod/strategies/ann.py b/axelrod/strategies/ann.py index 689dd554b..aa24fae13 100644 --- a/axelrod/strategies/ann.py +++ b/axelrod/strategies/ann.py @@ -1,11 +1,32 @@ +# Source: https://gist.github.com/mojones/550b32c46a8169bb3cd89d917b73111a#file-ann-strategy-test-L60 +# Original Author: Martin Jones, @mojones + from axelrod import Actions, Player, init_args C, D = Actions.C, Actions.D -# Source: https://gist.github.com/mojones/550b32c46a8169bb3cd89d917b73111a#file-ann-strategy-test-L60 -# Original Author: Martin Jones, @mojones + +def split_weights(weights, input_values, hidden_layer_size): + """Splits the input vector into the the NN bias weights and layer + parameters.""" + number_of_input_to_hidden_weights = input_values * hidden_layer_size + number_of_hidden_to_output_weights = hidden_layer_size + + input2hidden = [] + for i in range(0, number_of_input_to_hidden_weights, input_values): + input2hidden.append(weights[i:i + input_values]) + + start = number_of_input_to_hidden_weights + end = number_of_input_to_hidden_weights + number_of_hidden_to_output_weights + + hidden2output = weights[start: end] + bias = weights[end:] + + return (input2hidden, hidden2output, bias) + class ANN(Player): + """A single layer neural network based strategy.""" name = 'ANN' classifier = { 'memory_depth': float('inf'), @@ -135,28 +156,9 @@ def strategy(self, opponent): return D -def split_weights(weights, input_values, hidden_layer_size): - """Splits the input vector into the the NN bias weights and layer - parameters.""" - number_of_input_to_hidden_weights = input_values * hidden_layer_size - number_of_hidden_to_output_weights = hidden_layer_size - - input2hidden = [] - for i in range(0, number_of_input_to_hidden_weights, input_values): - input2hidden.append(weights[i:i + input_values]) - - hidden2output = weights[ - number_of_input_to_hidden_weights:number_of_input_to_hidden_weights + number_of_hidden_to_output_weights] - bias = weights[number_of_input_to_hidden_weights + number_of_hidden_to_output_weights:] - - return (input2hidden, hidden2output, bias) - - class EvolvedANN(ANN): name = "EvolvedANN" - - @init_args def __init__(self): self.classifier['makes_use_of'] = set(['length']) @@ -182,8 +184,8 @@ def __init__(self): -8426184.81603275, -82.36805426730088, 1144.1032034358543, 15635.402592538396, 3095.643889329041, 2332.107673930774, -0.5601648316602144, 101.98300711150003, -7387.135294747112, -4241.004613717573, 3.06175607282536e-05, -35122.894421260884, - -38591.45572476855, -0.16081285130591272, -29608.73087879185, 122.47563639056185, - 6.381946054740736, -0.8978628581801188, 17658.47647781355, -0.011719257684286711, + -38591.45572476855, -0.16081285130591272, -29608.73087879185, 122.47563639056185, + 6.381946054740736, -0.8978628581801188, 17658.47647781355, -0.011719257684286711, 0.10734295104044986, -378.35448968529494, 225.06912279045062, -351.12326495980847, -1.927322672845826, 0.0014584395475859544, -8.629826916169318, 22.43281153854352, 87.10895591188721, -0.22253937914423294, -233.06796470563208, -620.4917481128365, diff --git a/axelrod/tests/unit/test_ann.py b/axelrod/tests/unit/test_ann.py new file mode 100644 index 000000000..43147df12 --- /dev/null +++ b/axelrod/tests/unit/test_ann.py @@ -0,0 +1,32 @@ +"""Test for the Adaptive strategy.""" + +import axelrod + +from .test_player import TestHeadsUp, TestPlayer + +C, D = axelrod.Actions.C, axelrod.Actions.D + + +class TestEvolvedANN(TestPlayer): + + name = "EvolvedANN" + player = axelrod.EvolvedANN + expected_classifier = { + 'memory_depth': float('inf'), + 'stochastic': False, + 'makes_use_of': set(["length"]), + 'long_run_time': False, + 'inspects_source': False, + 'manipulates_source': False, + 'manipulates_state': False + } + + def test_strategy(self): + # Test initial play sequence + self.first_play_test(C) + + +class TestEvolvedANNvsCooperator(TestHeadsUp): + def test_rounds(self): + self.versus_test(axelrod.EvolvedANN(), axelrod.Cooperator(), + [C, D, D, C, D], [C] * 5) From 0c103dfd5967ca196a293045765591e2538faa0d Mon Sep 17 00:00:00 2001 From: Marc Harper Date: Tue, 29 Nov 2016 07:42:22 -0800 Subject: [PATCH 9/9] Changes re: review --- axelrod/strategies/ann.py | 12 ++++++++++-- axelrod/tests/unit/test_ann.py | 11 +++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/axelrod/strategies/ann.py b/axelrod/strategies/ann.py index aa24fae13..3eddc61a3 100644 --- a/axelrod/strategies/ann.py +++ b/axelrod/strategies/ann.py @@ -157,6 +157,14 @@ def strategy(self, opponent): class EvolvedANN(ANN): + """ + A strategy based on a pre-trained neural network. + + Names: + + - EvolvedANN: : Original name by Martin Jones. + """ + name = "EvolvedANN" @init_args @@ -165,7 +173,7 @@ def __init__(self): input_values = 17 hidden_layer_size = 10 - test_weights = [0.19789658035994948, -5575.476236516673, 0.1028948855131803, 0.7421752484224489, + weights = [0.19789658035994948, -5575.476236516673, 0.1028948855131803, 0.7421752484224489, -16.286246197005298, 11708.007255945553, 0.01400184611448853, -33.39126355009626, -12.755203414662356, -32.92388754142929, 197.3517717772447, 108262.87038790248, -0.1084768512582505, 85.20738888799768, 723.9537664890132, -2.59453614458083, @@ -215,7 +223,7 @@ def __init__(self): 0.020513128847167047, -0.9179124323385958] (i2h, h2o, bias) = split_weights( - test_weights, + weights, input_values, hidden_layer_size ) diff --git a/axelrod/tests/unit/test_ann.py b/axelrod/tests/unit/test_ann.py index 43147df12..ec780ad61 100644 --- a/axelrod/tests/unit/test_ann.py +++ b/axelrod/tests/unit/test_ann.py @@ -30,3 +30,14 @@ class TestEvolvedANNvsCooperator(TestHeadsUp): def test_rounds(self): self.versus_test(axelrod.EvolvedANN(), axelrod.Cooperator(), [C, D, D, C, D], [C] * 5) + + +class TestEvolvedANNvsDefector(TestHeadsUp): + def test_rounds(self): + self.versus_test(axelrod.EvolvedANN(), axelrod.Defector(), + [C, D, D, D, D], [D] * 5) + +class TestEvolvedANNvsTFT(TestHeadsUp): + def test_rounds(self): + self.versus_test(axelrod.EvolvedANN(), axelrod.TitForTat(), + [C, D, D, C, C], [C, C, D, D, C] * 5)