Skip to content

Commit 041e5f8

Browse files
authored
Merge latest changes (#3)
* Remove unnecessary goal test in search.py (aimacode#953) Remove unnecessary initial goal test in best_first_graph_search. The loop will catch that case immediately. * Minor Changes in Text (aimacode#955) * Minor text change (aimacode#957) To make it more accurate. * Minor change in text (aimacode#956) To make it more descriptive and accurate. * Added relu Activation (aimacode#960) * added relu activation * added default parameters * Changes in texts (aimacode#959) Added a few new sentences, modified the sentence structure at a few places, and corrected some grammatical errors. * Change PriorityQueue expansion (aimacode#962) `self.heap.append` simply appends to the end of the `self.heap` Since `self.heap` is just a python list. `self.append` calls the append method of the class instance, effectively putting the item in its proper place. * added GSoC 2018 contributors A thank you to contributors from the GSoC 2018 program! * Revamped the notebook (aimacode#963) * Revamped the notebook * A few changes reversed Changed a few things from my original PR after a review from ad71. * Text Changes + Colored Table (aimacode#964) Made a colored table to display dog movement instead. Corrected grammatical errors, improved the sentence structure and corrected any typos found. * Fixed typos (aimacode#970) Typos and minor other text errors removed * Fixed Typos (aimacode#971) Corrected typos + minor other text changes * Update intro.ipynb (aimacode#969) * Added activation functions (aimacode#968) * Updated label_queen_conflicts function (aimacode#967) Shortened it, finding conflicts separately and storing them in different variables has no use later in the notebook; so i believe this looks better.
1 parent 41c818c commit 041e5f8

File tree

10 files changed

+943
-386
lines changed

10 files changed

+943
-386
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ Here is a table of the implemented data structures, the figure, name of the impl
168168

169169
# Acknowledgements
170170

171-
Many thanks for contributions over the years. I got bug reports, corrected code, and other support from Darius Bacon, Phil Ruggera, Peng Shao, Amit Patil, Ted Nienstedt, Jim Martin, Ben Catanzariti, and others. Now that the project is on GitHub, you can see the [contributors](https://github.com/aimacode/aima-python/graphs/contributors) who are doing a great job of actively improving the project. Many thanks to all contributors, especially @darius, @SnShine, @reachtarunhere, @MrDupin, and @Chipe1.
171+
Many thanks for contributions over the years. I got bug reports, corrected code, and other support from Darius Bacon, Phil Ruggera, Peng Shao, Amit Patil, Ted Nienstedt, Jim Martin, Ben Catanzariti, and others. Now that the project is on GitHub, you can see the [contributors](https://github.com/aimacode/aima-python/graphs/contributors) who are doing a great job of actively improving the project. Many thanks to all contributors, especially @darius, @SnShine, @reachtarunhere, @MrDupin, @Chipe1, @ad71 and @MariannaSpyrakou.
172172

173173
<!---Reference Links-->
174174
[agents]:../master/agents.py

agents.ipynb

Lines changed: 284 additions & 95 deletions
Large diffs are not rendered by default.

csp.ipynb

Lines changed: 164 additions & 214 deletions
Large diffs are not rendered by default.

intro.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
"source": [
6363
"From there, the notebook alternates explanations with examples of use. You can run the examples as they are, and you can modify the code cells (or add new cells) and run your own examples. If you have some really good examples to add, you can make a github pull request.\n",
6464
"\n",
65-
"If you want to see the source code of a function, you can open a browser or editor and see it in another window, or from within the notebook you can use the IPython magic function `%psource` (for \"print source\") or the function `psource` from `notebook.py`. Also, if the algorithm has pseudocode, you can read it by calling the `pseudocode` function with input the name of the algorithm."
65+
"If you want to see the source code of a function, you can open a browser or editor and see it in another window, or from within the notebook you can use the IPython magic function `%psource` (for \"print source\") or the function `psource` from `notebook.py`. Also, if the algorithm has pseudocode available, you can read it by calling the `pseudocode` function with the name of the algorithm passed as a parameter."
6666
]
6767
},
6868
{

knowledge_FOIL.ipynb

Lines changed: 39 additions & 26 deletions
Large diffs are not rendered by default.

knowledge_current_best.ipynb

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -38,15 +38,15 @@
3838
"source": [
3939
"## OVERVIEW\n",
4040
"\n",
41-
"Like the [learning module](https://github.com/aimacode/aima-python/blob/master/learning.ipynb), this chapter focuses on methods for generating a model/hypothesis for a domain. Unlike though the learning chapter, here we use prior knowledge to help us learn from new experiences and find a proper hypothesis.\n",
41+
"Like the [learning module](https://github.com/aimacode/aima-python/blob/master/learning.ipynb), this chapter focuses on methods for generating a model/hypothesis for a domain; however, unlike the learning chapter, here we use prior knowledge to help us learn from new experiences and find a proper hypothesis.\n",
4242
"\n",
4343
"### First-Order Logic\n",
4444
"\n",
45-
"Usually knowledge in this field is represented as **first-order logic**, a type of logic that uses variables and quantifiers in logical sentences. Hypotheses are represented by logical sentences with variables, while examples are logical sentences with set values instead of variables. The goal is to assign a value to a special first-order logic predicate, called **goal predicate**, for new examples given a hypothesis. We learn this hypothesis by infering knowledge from some given examples.\n",
45+
"Usually knowledge in this field is represented as **first-order logic**; a type of logic that uses variables and quantifiers in logical sentences. Hypotheses are represented by logical sentences with variables, while examples are logical sentences with set values instead of variables. The goal is to assign a value to a special first-order logic predicate, called **goal predicate**, for new examples given a hypothesis. We learn this hypothesis by infering knowledge from some given examples.\n",
4646
"\n",
4747
"### Representation\n",
4848
"\n",
49-
"In this module, we use dictionaries to represent examples, with keys the attribute names and values the corresponding example values. Examples also have an extra boolean field, 'GOAL', for the goal predicate. A hypothesis is represented as a list of dictionaries. Each dictionary in that list represents a disjunction. Inside these dictionaries/disjunctions we have conjunctions.\n",
49+
"In this module, we use dictionaries to represent examples, with keys being the attribute names and values being the corresponding example values. Examples also have an extra boolean field, 'GOAL', for the goal predicate. A hypothesis is represented as a list of dictionaries. Each dictionary in that list represents a disjunction. Inside these dictionaries/disjunctions we have conjunctions.\n",
5050
"\n",
5151
"For example, say we want to predict if an animal (cat or dog) will take an umbrella given whether or not it rains or the animal wears a coat. The goal value is 'take an umbrella' and is denoted by the key 'GOAL'. An example:\n",
5252
"\n",
@@ -73,15 +73,15 @@
7373
"\n",
7474
"### Overview\n",
7575
"\n",
76-
"In **Current-Best Learning**, we start with a hypothesis and we refine it as we iterate through the examples. For each example, there are three possible outcomes. The example is consistent with the hypothesis, the example is a **false positive** (real value is false but got predicted as true) and **false negative** (real value is true but got predicted as false). Depending on the outcome we refine the hypothesis accordingly:\n",
76+
"In **Current-Best Learning**, we start with a hypothesis and we refine it as we iterate through the examples. For each example, there are three possible outcomes: the example is consistent with the hypothesis, the example is a **false positive** (real value is false but got predicted as true) and the example is a **false negative** (real value is true but got predicted as false). Depending on the outcome we refine the hypothesis accordingly:\n",
7777
"\n",
78-
"* Consistent: We do not change the hypothesis and we move on to the next example.\n",
78+
"* Consistent: We do not change the hypothesis and move on to the next example.\n",
7979
"\n",
8080
"* False Positive: We **specialize** the hypothesis, which means we add a conjunction.\n",
8181
"\n",
8282
"* False Negative: We **generalize** the hypothesis, either by removing a conjunction or a disjunction, or by adding a disjunction.\n",
8383
"\n",
84-
"When specializing and generalizing, we should take care to not create inconsistencies with previous examples. To avoid that caveat, backtracking is needed. Thankfully, there is not just one specialization or generalization, so we have a lot to choose from. We will go through all the specialization/generalizations and we will refine our hypothesis as the first specialization/generalization consistent with all the examples seen up to that point."
84+
"When specializing or generalizing, we should make sure to not create inconsistencies with previous examples. To avoid that caveat, backtracking is needed. Thankfully, there is not just one specialization or generalization, so we have a lot to choose from. We will go through all the specializations/generalizations and we will refine our hypothesis as the first specialization/generalization consistent with all the examples seen up to that point."
8585
]
8686
},
8787
{
@@ -138,7 +138,7 @@
138138
"source": [
139139
"### Implementation\n",
140140
"\n",
141-
"As mentioned previously, examples are dictionaries (with keys the attribute names) and hypotheses are lists of dictionaries (each dictionary is a disjunction). Also, in the hypothesis, we denote the *NOT* operation with an exclamation mark (!).\n",
141+
"As mentioned earlier, examples are dictionaries (with keys being the attribute names) and hypotheses are lists of dictionaries (each dictionary is a disjunction). Also, in the hypothesis, we denote the *NOT* operation with an exclamation mark (!).\n",
142142
"\n",
143143
"We have functions to calculate the list of all specializations/generalizations, to check if an example is consistent/false positive/false negative with a hypothesis. We also have an auxiliary function to add a disjunction (or operation) to a hypothesis, and two other functions to check consistency of all (or just the negative) examples.\n",
144144
"\n",
@@ -148,7 +148,9 @@
148148
{
149149
"cell_type": "code",
150150
"execution_count": 3,
151-
"metadata": {},
151+
"metadata": {
152+
"collapsed": true
153+
},
152154
"outputs": [
153155
{
154156
"data": {
@@ -370,7 +372,7 @@
370372
"\n",
371373
"We will take a look at two examples. The first is a trivial one, while the second is a bit more complicated (you can also find it in the book).\n",
372374
"\n",
373-
"First we have the \"animals taking umbrellas\" example. Here we want to find a hypothesis to predict whether or not an animal will take an umbrella. The attributes are `Species`, `Rain` and `Coat`. The possible values are `[Cat, Dog]`, `[Yes, No]` and `[Yes, No]` respectively. Below we give seven examples (with `GOAL` we denote whether an animal will take an umbrella or not):"
375+
"Earlier, we had the \"animals taking umbrellas\" example. Now we want to find a hypothesis to predict whether or not an animal will take an umbrella. The attributes are `Species`, `Rain` and `Coat`. The possible values are `[Cat, Dog]`, `[Yes, No]` and `[Yes, No]` respectively. Below we give seven examples (with `GOAL` we denote whether an animal will take an umbrella or not):"
374376
]
375377
},
376378
{
@@ -427,7 +429,7 @@
427429
"cell_type": "markdown",
428430
"metadata": {},
429431
"source": [
430-
"We got 5/7 correct. Not terribly bad, but we can do better. Let's run the algorithm and see how that performs."
432+
"We got 5/7 correct. Not terribly bad, but we can do better. Lets now run the algorithm and see how that performs in comparison to our current result. "
431433
]
432434
},
433435
{
@@ -472,7 +474,7 @@
472474
"name": "stdout",
473475
"output_type": "stream",
474476
"text": [
475-
"[{'Rain': '!No', 'Species': 'Cat'}, {'Rain': 'Yes', 'Coat': 'Yes'}, {'Coat': 'Yes', 'Species': 'Cat'}]\n"
477+
"[{'Species': 'Cat', 'Rain': '!No'}, {'Species': 'Dog', 'Coat': 'Yes'}, {'Coat': 'Yes'}]\n"
476478
]
477479
}
478480
],
@@ -563,7 +565,7 @@
563565
"cell_type": "markdown",
564566
"metadata": {},
565567
"source": [
566-
"Say our initial hypothesis is that there should be an alternative option and let's run the algorithm."
568+
"Say our initial hypothesis is that there should be an alternative option and lets run the algorithm."
567569
]
568570
},
569571
{
@@ -613,7 +615,7 @@
613615
"name": "stdout",
614616
"output_type": "stream",
615617
"text": [
616-
"[{'Pat': '!Full', 'Alt': 'Yes'}, {'Hun': 'No', 'Res': 'No', 'Rain': 'No', 'Pat': '!None'}, {'Fri': 'Yes', 'Type': 'Thai', 'Bar': 'No'}, {'Fri': 'No', 'Type': 'Italian', 'Bar': 'Yes', 'Alt': 'No', 'Est': '0-10'}, {'Fri': 'No', 'Bar': 'No', 'Est': '0-10', 'Type': 'Thai', 'Rain': 'Yes', 'Alt': 'No'}, {'Fri': 'Yes', 'Bar': 'Yes', 'Est': '30-60', 'Hun': 'Yes', 'Rain': 'No', 'Alt': 'Yes', 'Price': '$'}]\n"
618+
"[{'Alt': 'Yes', 'Type': '!Thai', 'Hun': '!No', 'Bar': '!Yes'}, {'Alt': 'No', 'Fri': 'No', 'Pat': 'Some', 'Price': '$', 'Type': 'Burger', 'Est': '0-10'}, {'Rain': 'Yes', 'Res': 'No', 'Type': '!Burger'}, {'Alt': 'No', 'Bar': 'Yes', 'Hun': 'Yes', 'Pat': 'Some', 'Price': '$$', 'Rain': 'Yes', 'Res': 'Yes', 'Est': '0-10'}, {'Alt': 'No', 'Bar': 'No', 'Pat': 'Some', 'Price': '$$', 'Est': '0-10'}, {'Alt': 'Yes', 'Hun': 'Yes', 'Pat': 'Full', 'Price': '$', 'Res': 'No', 'Type': 'Burger', 'Est': '30-60'}]\n"
617619
]
618620
}
619621
],
@@ -627,6 +629,13 @@
627629
"source": [
628630
"It might be quite complicated, with many disjunctions if we are unlucky, but it will always be correct, as long as a correct hypothesis exists."
629631
]
632+
},
633+
{
634+
"cell_type": "code",
635+
"execution_count": null,
636+
"metadata": {},
637+
"outputs": [],
638+
"source": []
630639
}
631640
],
632641
"metadata": {
@@ -645,7 +654,7 @@
645654
"name": "python",
646655
"nbconvert_exporter": "python",
647656
"pygments_lexer": "ipython3",
648-
"version": "3.5.3"
657+
"version": "3.6.5"
649658
}
650659
},
651660
"nbformat": 4,

learning.py

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
removeall, unique, product, mode, argmax, argmax_random_tie, isclose, gaussian,
55
dotproduct, vector_add, scalar_vector_product, weighted_sample_with_replacement,
66
weighted_sampler, num_or_str, normalize, clip, sigmoid, print_table,
7-
open_data, sigmoid_derivative, probability, norm, matrix_multiplication
7+
open_data, sigmoid_derivative, probability, norm, matrix_multiplication, relu, relu_derivative,
8+
tanh, tanh_derivative, leaky_relu, leaky_relu_derivative, elu, elu_derivative
89
)
910

1011
import copy
@@ -652,7 +653,7 @@ def predict(example):
652653

653654

654655
def NeuralNetLearner(dataset, hidden_layer_sizes=None,
655-
learning_rate=0.01, epochs=100):
656+
learning_rate=0.01, epochs=100, activation = sigmoid):
656657
"""Layered feed-forward network.
657658
hidden_layer_sizes: List of number of hidden units per hidden layer
658659
learning_rate: Learning rate of gradient descent
@@ -664,9 +665,9 @@ def NeuralNetLearner(dataset, hidden_layer_sizes=None,
664665
o_units = len(dataset.values[dataset.target])
665666

666667
# construct a network
667-
raw_net = network(i_units, hidden_layer_sizes, o_units)
668+
raw_net = network(i_units, hidden_layer_sizes, o_units, activation)
668669
learned_net = BackPropagationLearner(dataset, raw_net,
669-
learning_rate, epochs)
670+
learning_rate, epochs, activation)
670671

671672
def predict(example):
672673
# Input nodes
@@ -695,7 +696,7 @@ def random_weights(min_value, max_value, num_weights):
695696
return [random.uniform(min_value, max_value) for _ in range(num_weights)]
696697

697698

698-
def BackPropagationLearner(dataset, net, learning_rate, epochs):
699+
def BackPropagationLearner(dataset, net, learning_rate, epochs, activation=sigmoid):
699700
"""[Figure 18.23] The back-propagation algorithm for multilayer networks"""
700701
# Initialise weights
701702
for layer in net:
@@ -743,8 +744,18 @@ def BackPropagationLearner(dataset, net, learning_rate, epochs):
743744
# Error for the MSE cost function
744745
err = [t_val[i] - o_nodes[i].value for i in range(o_units)]
745746

746-
# The activation function used is the sigmoid function
747-
delta[-1] = [sigmoid_derivative(o_nodes[i].value) * err[i] for i in range(o_units)]
747+
# The activation function used is relu or sigmoid function
748+
if node.activation == sigmoid:
749+
delta[-1] = [sigmoid_derivative(o_nodes[i].value) * err[i] for i in range(o_units)]
750+
elif node.activation == relu:
751+
delta[-1] = [relu_derivative(o_nodes[i].value) * err[i] for i in range(o_units)]
752+
elif node.activation == tanh:
753+
delta[-1] = [tanh_derivative(o_nodes[i].value) * err[i] for i in range(o_units)]
754+
elif node.activation == elu:
755+
delta[-1] = [elu_derivative(o_nodes[i].value) * err[i] for i in range(o_units)]
756+
else:
757+
delta[-1] = [leaky_relu_derivative(o_nodes[i].value) * err[i] for i in range(o_units)]
758+
748759

749760
# Backward pass
750761
h_layers = n_layers - 2
@@ -756,7 +767,20 @@ def BackPropagationLearner(dataset, net, learning_rate, epochs):
756767
# weights from each ith layer node to each i + 1th layer node
757768
w = [[node.weights[k] for node in nx_layer] for k in range(h_units)]
758769

759-
delta[i] = [sigmoid_derivative(layer[j].value) * dotproduct(w[j], delta[i+1])
770+
if activation == sigmoid:
771+
delta[i] = [sigmoid_derivative(layer[j].value) * dotproduct(w[j], delta[i+1])
772+
for j in range(h_units)]
773+
elif activation == relu:
774+
delta[i] = [relu_derivative(layer[j].value) * dotproduct(w[j], delta[i+1])
775+
for j in range(h_units)]
776+
elif activation == tanh:
777+
delta[i] = [tanh_derivative(layer[j].value) * dotproduct(w[j], delta[i+1])
778+
for j in range(h_units)]
779+
elif activation == elu:
780+
delta[i] = [elu_derivative(layer[j].value) * dotproduct(w[j], delta[i+1])
781+
for j in range(h_units)]
782+
else:
783+
delta[i] = [leaky_relu_derivative(layer[j].value) * dotproduct(w[j], delta[i+1])
760784
for j in range(h_units)]
761785

762786
# Update weights
@@ -800,14 +824,14 @@ class NNUnit:
800824
weights: Weights to incoming connections
801825
"""
802826

803-
def __init__(self, weights=None, inputs=None):
827+
def __init__(self, activation=sigmoid, weights=None, inputs=None):
804828
self.weights = weights or []
805829
self.inputs = inputs or []
806830
self.value = None
807-
self.activation = sigmoid
831+
self.activation = activation
808832

809833

810-
def network(input_units, hidden_layer_sizes, output_units):
834+
def network(input_units, hidden_layer_sizes, output_units, activation=sigmoid):
811835
"""Create Directed Acyclic Network of given number layers.
812836
hidden_layers_sizes : List number of neuron units in each hidden layer
813837
excluding input and output layers
@@ -818,7 +842,7 @@ def network(input_units, hidden_layer_sizes, output_units):
818842
else:
819843
layers_sizes = [input_units] + [output_units]
820844

821-
net = [[NNUnit() for n in range(size)]
845+
net = [[NNUnit(activation) for n in range(size)]
822846
for size in layers_sizes]
823847
n_layers = len(net)
824848

0 commit comments

Comments
 (0)