Skip to content

Commit 5ad33a6

Browse files
committed
add som and update minimax
1 parent 1e46c6e commit 5ad33a6

File tree

4 files changed

+71
-10
lines changed

4 files changed

+71
-10
lines changed

README.md

+8-7
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,11 @@
114114

115115
#### Instance-based Learning and Kernel Machines
116116
* k-Nearest Neighbors (kNN) `k_nearest_neighbors.py`
117-
* Learning Vector Quantization (WIP)
117+
* Learning Vector Quantization
118118
* Support Vector Machine (SVM) `support_vector_machine.py`
119119
* Soft boundary
120120
* SMO algorithm
121121
* Different heuristics for selecting pairs in SMO
122-
* Radial Basis Function Network (WIP)
123122

124123
#### Swarm Intelligence
125124
* Evolutionary Algorithm (EA) `evolutionary_algorithm.py`
@@ -134,6 +133,7 @@
134133
* Monte Carlo tree search `monte_carlo_tree_search.py`
135134
* Upper Confidence Bound 1 applied to trees (UCT)
136135
* Minimax `minimax.py`
136+
* Alpha-Beta Pruning
137137

138138
#### Reinforcement Learning
139139
* Temporal difference learning `temporal_difference.py`
@@ -142,10 +142,11 @@
142142
* CNN Target & Policy Net
143143
* Epsilon-Greedy
144144

145-
#### TODO - Unsupervised Learning
146-
* Clustering
147-
* k-Means / dbscan / spectrum / hierachical / SOM
148-
* Dimension Reduction
149-
* Principal Component Analysis / Linear Discriminant Analysis / mds / tsne
145+
#### Unsupervised Learning
146+
* Clustering (WIP)
147+
* k-Means / dbscan / spectrum / hierachical
148+
* Dimension Reduction (WIP)
149+
* SOM
150+
* Principal Component Analysis / Linear Discriminant Analysis / MDS / t-SNE
150151

151152
Feel free to use the code. Please contact me if you have any question: xiecng [at] gmail.com

deep_belief_network.py

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from restricted_boltzmann_machine import RBM
55

66

7+
# this implementation reused the training of MLP for back propagation
78
class DBN(object):
89

910
def __init__(self, layers, n_labels):

minimax.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def heuristic(self, board, player):
8080
n_size - 1 and board[i] == board[i + n_size + 1])
8181
return (-evals[0] * player + evals[1] * player) / (evals[0] + evals[1] + 1)
8282

83-
def score(self, board, player, depth):
83+
def score(self, board, player, depth, alpha, beta):
8484
board_str = ''.join([str(i) for i in board])
8585
if board_str in self.cache: # cached before
8686
return self.cache[board_str]
@@ -97,9 +97,16 @@ def score(self, board, player, depth):
9797
if board[i] != 0:
9898
continue
9999
board[i] = player
100-
board_scores[i] = -self.score(board, -player, depth + 1)[1]
100+
board_scores[i] = -self.score(board, -player, depth + 1, alpha, beta)[1]
101101
heuristics_used[i] = ''.join([str(i) for i in board]) not in self.cache
102102
board[i] = 0
103+
if(player == -1):
104+
alpha = max(np.max(board_scores), alpha)
105+
else:
106+
beta = max(np.max(board_scores), beta)
107+
# alpha beta pruning will reduce the # returned choice of winning moves
108+
if alpha > -beta or (player == -1 and alpha == 1) or (player == 1 and beta == 1):
109+
break
103110
best_score = np.amax(board_scores)
104111
best_moves = [i for i in range(board.shape[0]) if board_scores[
105112
i] == best_score]
@@ -108,7 +115,7 @@ def score(self, board, player, depth):
108115
return best_moves, best_score
109116

110117
def act(self, board, player):
111-
return np.random.choice(self.score(board, player, 0)[0])
118+
return np.random.choice(self.score(board, player, 0, -2, -2)[0])
112119

113120

114121
def main():

self_organizing_map.py

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
4+
5+
class SOM(object):
6+
7+
def __init__(self):
8+
self.sigma = 1
9+
self.lr = 0.1
10+
self.eps = 0.05
11+
self.n_size = 10
12+
self.iterations = 10
13+
self.neighbors_radius = []
14+
radius = 4
15+
for i in range(-radius, radius+1):
16+
for j in range(-radius, radius+1):
17+
if i * i + j * j <= radius * radius:
18+
self.neighbors_radius.append((i, j))
19+
self.w = None
20+
21+
def get_bmu(self, w, x):
22+
dist = np.square(w - x).sum(axis=2)
23+
index = np.argmin(dist)
24+
return np.array([index // self.n_size, index % self.n_size])
25+
26+
def fit(self, x):
27+
fig, ax = plt.subplots(nrows=2, ncols=5, subplot_kw=dict(xticks=[], yticks=[]))
28+
29+
self.w = np.random.randn(self.n_size, self.n_size, x.shape[1])
30+
sigma_sq = self.sigma * self.sigma
31+
for step in range(self.iterations):
32+
for y in np.random.permutation(x):
33+
i, j = self.get_bmu(self.w, y)
34+
# update w
35+
for di, dj in self.neighbors_radius:
36+
if i + di >= 0 and i + di < self.n_size and j + di >= 0 and j + dj < self.n_size:
37+
self.w[i + di][j + dj] += self.lr * (y - self.w[i + di][j + dj]) * np.exp(-np.square([di, dj]).sum() / 2 / sigma_sq)
38+
self.lr *= np.exp(-step * self.eps)
39+
sigma_sq *= np.exp(-step * self.eps)
40+
ax[step//5][step%5].imshow(self.w.astype(int))
41+
ax[step//5][step%5].title.set_text(step)
42+
plt.show()
43+
return self.w
44+
45+
def main():
46+
som = SOM()
47+
x = np.random.randint(0, 255, (3000, 3))
48+
w = som.fit(x)
49+
50+
51+
if __name__ == "__main__":
52+
main()

0 commit comments

Comments
 (0)