aboutsummaryrefslogtreecommitdiff
path: root/doc/tex/systemDesign.tex
blob: 3542cb55df6f0e49f30368161ea07b9fad795331 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
\section{System Design}

This section explains the design of the component systems of \program{}, the
algorithms used and how they are to be implemented.

\subsection{Class Diagram}

The full class diagram is shown in \fref{fig:fullClasses}.

\begin{figure}[h]
	\begin{center}
		\makebox[0pt]{\begin{minipage}{1.2\textwidth}
			\includegraphics[width=\textwidth]{diagrams/fullClasses.png}
			\caption{Full class diagram.}
			\label{fig:fullClasses}
		\end{minipage}}
	\end{center}
\end{figure}

The design of each system of the diagram is explained after this section
along with diagrams for each subsystem, since the full class diagram can be
too big to be comfortably analyzed.

\subsection{Game}

\begin{figure}[h]
	\begin{center}
		\includegraphics[width=0.55\textwidth]{diagrams/gameModule.png}
		\caption{Design of the implementation of the game of Go.}
		\label{fig:game}
		A game is represented as a tree of moves.
	\end{center}
\end{figure}

A regular Go match is composed of a list of moves. But since game review and
exploration of variants is an important part of Go learning, \program{} and most
playing and analysis existing programs allow for navigation back and forth
through the board states of a match and for new variants to be created from each
of these board states. Therefore, a match is represented as a tree of moves. The
\texttt{GameMove} class has the information about a specific move and also a
reference to the previous move and to a list of following moves, implementing
this tree structure and allowing for navigating both forward and backwards in
the move history.

The state of the board at any given move must be stored so liberties, captures
count and legality of moves can be addressed, so it is represented with the
\texttt{GameState} class, which holds a reference to the current move.

Moves depend on a representation of the game board to have access to its current
layout and count of captured stones. There are also many logic operations needed
to be performed on the board, such as getting the stones in a group, counting
their liberties or checking if a move is playable. The layout of the board and
these operations are implemented as the \texttt{GameBoard} class.

A game can be started by the executable \texttt{go.py}.

These classes and their relationships can be seen in \fref{fig:game}.

\subsection{Engine}

\begin{figure}[h]
	\begin{center}
		\includegraphics[width=0.8\textwidth]{diagrams/engineModule.png}
		\caption{Design of the \acrshort{gtp} engine.}\label{fig:engine}
	\end{center}
\end{figure}

This will be an implementation of \acrshort{gtp}, that is, the piece of software
which offers the \acrshort{gtp} interface to other applications. It is designed
to be used by a software controller but can also be directly run, mostly for
debugging purposes. Its design is shown in \fref{fig:engine}. The core of the
engine is related with three components, each with a separate responsibility:

\begin{itemize}

	\item The ImagoIO component is the one imported from executables or other
		applications and offers the text interface. It reads and processes input
		and calls corresponding commands from the core of the engine.

	\item The \texttt{GameEngine} contains the logic of the commands available
		from the IO component. It uses a \texttt{GameState} to keep a record of
		the game and uses a \texttt{DecisionAlgorithm} to generate moves.

	\item The \texttt{DecisionAlgorithm} component is responsible of analyzing
		the match and generate moves. The engine core uses it when a decision
		has to be made by the \acrshort{ai}, such as when a move needs to be
		generated by the engine.

\end{itemize}

Two implementations of \texttt{DecisionAlgorithm} have been made: one for the
Monte Carlo Tree Search algorithm (on the \texttt{MCTS} class) and the other for
neural networks (on the \texttt{Keras} class).

The \texttt{Keras} class also makes use of the \texttt{NeuralNetwork} class,
which offers functions for creating, training, saving and using neural network
models. The designs of the network are implemented in the subclasses
\texttt{DenseNeuralNetwork} and \texttt{ConvNeuralNetwork} as examples of dense
and convolutional networks, respectively.

The engine can be started with the executable \texttt{imagocli.py}.

\subsubsection{Monte Carlo Tree Search Explained}

Monte Carlo Tree Search is an algorithm that can be useful for exploring
decision trees. It has a history of use in Go engines, not being able to reach
strong levels of play until it was paired with neural networks by AlphaGo as
explained in the AlphaGo 2016 paper \cite{natureAlphaGo2016}.

The algorithm assigns a score to each explored node of the game tree based on
how likely the player who makes the corresponding move is to win and updates
this score on each exploration cycle.

The exploration of the tree has 4 steps:

\begin{enumerate}

	\item \textbf{Selection}: The most promising move with at least one
		unexplored children is selected for exploration. Unexplored children are
		viable moves which are not yet part of the tree.

	\item \textbf{Expansion}: An unexplored children of the selected move is
		added to the tree. This children is selected at random.

	\item \textbf{Simulation}: The score of the new move is evaluated by playing
		different matches from it. How this matches are played varies: they can
		be totally random, but here is where AlphaGo introduces one of its
		neural networks so these simulation matches are more valuable.

	\item \textbf{Backpropagation}: The scores of the new move and its previous
		moves up to the root of the tree are updated based on the results of the
		simulation.

\end{enumerate}

The suggested move is the children of the current move with the best score from
the perspective of the player which has to make the move.

The implementation of the algorithm will use the existing \texttt{GameMove}
class from the Game System to access the game logic it needs, such as to get the
available children from a node or to simulate random games.

\subsubsection{Neural Networks Explained}

A neural network is composed of nodes or ``neurons''. Each node contains a value
named weight. During execution the node receives a numeric input, multiplies it
for its weight and applies a function called activation function to the result.

Nodes are organized in layers so that a network contains several layers and each
layer one or more neurons. The input to the network forms the input layer, which
contents are forwarded to the second layer. The second layer applies the weight
and activation function as discussed before in each of its nodes and the result
is forwarded to the next layer, and so on. At the end the last layer, called the
output layer, contains the result of the input evaluation. Each layer can have a
unique activation function for all its nodes and a different strategy of
connecting to the previous and next layers.

Several kinds of layers have been used in this project:

\begin{itemize}

	\item \textbf{Dense layers}, which connects each of its nodes to each of the
		nodes of the previous layers.

	\item \textbf{Convolutional layers}, which process their input by applying a
		filter function to adjacent values. In the case of this project, the
		board is filtered by grouping its vertices in 3x3 squares. The aim of
		these layers is to detect patterns in the input, such as curves, edges
		or more complex shapes, so they are used a lot on image processing. They
		are used in this project because a configuration of the Go board is not
		that different from a two-dimensional image.

	\item \textbf{Max pooling layers}, which process their input in a similar
		way to convolutional layers, but reducing the size of the input by
		keeping the highest value in each of the groups they process. This
		reduction accentuates the patterns detected by convolutional layers and
		helps on the detection of bigger, more complex patterns.

	\item \textbf{Flatten layers}, which just change the shape of the input so
		that all the values are on one dimension.

\end{itemize}

Combinations of these layers have been used to define two neural networks.

First, a network using mainly dense layers as an example of a more general
purpose and baseline design of a network.

Then, a network with convolutional and max pooling layers to compare the
approach used on image processing to the more general one and study its utility
on the analysis of the Go board.

These networks have been implemented on the \texttt{DenseNeuralNetwork} and \\
\texttt{ConvNeuralNetwork} classes, respectively.

The networks have been designed to process boards of size 9x9, which is the
introductory size to the game. It is the easiest both for the hardware to handle
and for the analysis of results while still being big enough to support
meaningful matches.

Both networks have the same design for their input and output.

Their input is a three-dimensional matrix of size 9x9x2 with values either 0 or
1. It represents two views of the board, one with ones as the stones of a player
and the other with ones as the stones of the other player.

Their output is a vector with 82 elements of type float. Classification networks
typically use a vector of probabilities with one element for each class they are
trying to classify. Here the classes are the 81 positions of the 9x9 board and
the pass move, hence 82 total elements. Each element signifies the chance of
playing that move for the input board position, so the element with the highest
value represents the suggested move.

\subsubsection{Dense Neural Network Design}

\begin{listing}[h]
	\inputminted{text}{listings/denseModel.txt}
	\caption{Dense neural network model.}
	\label{code:denseModel}
\end{listing}

\begin{figure}[h]
	\begin{center}
		\includegraphics[width=0.7\textwidth]{img/models/denseModel.png}
		\caption{Dense neural network model.}
		\label{fig:denseNN}
	\end{center}
\end{figure}

This network first uses two dense layers with 81 nodes each. This number has
been selected so each node can have as input each of the vertices of the board.
A flatten layer acts then to make the output one-dimensional, and a final dense
layer provides the vector containing the likelihood of each possible move.

The design of this network is shown in \lref{code:denseModel} and
\fref{fig:denseNN} as provided by Keras' summary and plot\_model functions
respectively.

\subsubsection{Convolutional Neural Network Design}

\begin{listing}[h]
	\inputminted{text}{listings/convModel.txt}
	\caption{Convolutional neural network model.}
	\label{code:convModel}
\end{listing}

\begin{figure}[h]
	\begin{center}
		\includegraphics[width=0.7\textwidth]{img/models/convModel.png}
		\caption{Convolutional neural network model.}
		\label{fig:convNN}
	\end{center}
\end{figure}

This network uses two pairs of convolutional and max pooling layers with the aim
of being trained to recognize patterns on the board. A flatten layer acts then
to make the output one-dimensional, and a final dense layer provides the vector
containing the likelihood of each possible move.

The design of this network is shown in \lref{code:convModel} and
\fref{fig:convNN} as provided by Keras' summary and plot\_model functions
respectively.

\subsection{Training}

\begin{figure}[h]
	\begin{center}
		\includegraphics[width=\textwidth]{diagrams/trainingModule.png}
		\caption{Components of the \acrshort{sgf} file parsing module.}
		\label{fig:trainingModule}
		Components not showing a capital C are not classes, as in they not
		follow the object-oriented paradigm and do not implement any classes,
		only functions.
	\end{center}
\end{figure}

Neural networks can be powerful machine learning algorithms, but they have to be
trained first so they can provide meaningful results. For a Go \acrshort{ai} it
makes sense to have its algorithms trained on Go games. There exists a common
text format to store Go games: \acrshort{sgf}. If the system is able to process
\acrshort{sgf} files, it can provide the games stored on them to the neural
networks for training. And so the need for an \acrshort{sgf} parser arises.

To parse \acrshort{sgf} files a lexer and parser have been implemented using PLY
\cite{ply}. The result of the parsing is an \acrfull{ast} reflecting the
contents of the text input, each node with zero or more properties, and with the
ability to convert themselves and their corresponding subtree into a
\texttt{GameMove} tree. This is done for the root node, since from the
\acrshort{sgf} specification there are some properties only usable in the root
node, like those which specify general game information and properties such as
rank of players or \gls{komi}.

Here follows an explanation of the role and motivation before each component of
the Training module to show how these previous concerns have been addressed and
solved. These components are shown in \fref{fig:trainingModule}.

\begin{itemize}

	\item \textbf{\texttt{\acrshort{sgf}}}: Provides a high-level method to convert a path to a \acrshort{sgf}
		file to a \texttt{GameMove} tree.

	\item \textbf{\texttt{sgfyacc}}: The implementation of a \acrshort{sgf} parser using PLY. Takes
		the tokens generated by \texttt{sgflex} and creates an \texttt{ASTNode}
		tree from them.

	\item \textbf{\texttt{sgflex}}: The implementation of a \acrshort{sgf} lexer using
		PLY.\@ Takes text input and generates the tokens of the \acrshort{sgf}
		language from them.

	\item \textbf{\texttt{ASTNode}}: The AST resulting from the parsing of a
		\acrshort{sgf} file. Has a method to convert it to a tree of
		\texttt{GameMove} and so obtain the contents of the \acrshort{sgf} in
		the internal representation used by the project's systems.

	\item \textbf{\texttt{Property}}: The representation of a property of an
		\texttt{ASTNode} tree. Each property is made of a name and one or more
		values and this class helps handling this specific situation.

The training can be started with the executable \texttt{train.py}.

\end{itemize}

%\subsection{Modules}
%
%One module to store the state of the game and the game tree. One module to parse
%moves. One module to read and write \acrshort{sgf} files. Modules are shown in
%\fref{fig:modules}.
%
%\begin{figure}[h]
%	\begin{center}
%		\includegraphics[width=\textwidth]{diagrams/modules.png}
%		\caption{Modules.}\label{fig:modules}
%	\end{center}
%\end{figure}

\subsection{Technical Testing Plan Specification}

This section lists and explains the exact testing plan.

\subsubsection{Unitary Testing}

Tests for the Python code will be developed using the unittest
\cite{python_unittest} testing framework. It has been chosen by virtue of being
thoroughly documented and widely used.

The coverage of unit testing will be checked with Coverage.py
\cite{python_coverage}, which can by itself run the unittest tests and generate
coverage reports based on the results.

\subsubsection{Integration Testing}

\vspace{\interclassSpace}

\begin{tabular}{p{0.4\linewidth}p{0.5\linewidth}}
	\toprule
	\multicolumn{2}{c}{\textbf{Engine and Game modules}} \\
	\midrule
	\textbf{Test} & \textbf{Expected behaviour} \\
	\midrule
	The GTP interface of the engine is used to play a match & The module handles
	the game and can show its state. \\
	\bottomrule
\end{tabular}

\vspace{\interclassSpace}

\begin{tabular}{p{0.4\linewidth}p{0.5\linewidth}}
	\toprule
	\multicolumn{2}{c}{\textbf{Training and Engine module}} \\
	\midrule
	\textbf{Test} & \textbf{Expected behaviour} \\
	\midrule
	The training process is started & The training uses the network defined on
	the Engine module. \\
	\bottomrule
\end{tabular}

\subsubsection{System Testing}

These are the tests to check the correct working of the system as a whole. The
tests are grouped by the interface they are run against.

\vspace{\interclassSpace}

\begin{tabular}{p{0.4\linewidth}p{0.5\linewidth}}
	\toprule
	\multicolumn{2}{c}{\textbf{Game interface}} \\
	\midrule
	\textbf{Test} & \textbf{Expected behaviour} \\
	\midrule
	Play a game of Go with no engine & The game can be played until the end. \\
	\midrule
	Provide a wrong move & The interface shows it is wrong and the game
	continues without a change of state. \\
	\midrule
	Close the game & The interface closes. \\
	\bottomrule
\end{tabular}

\vspace{\interclassSpace}

\begin{tabular}{p{0.4\linewidth}p{0.5\linewidth}}
	\toprule
	\multicolumn{2}{c}{\textbf{Engine interface}} \\
	\midrule
	\textbf{Test} & \textbf{Expected behaviour} \\
	\midrule
	Ask for the available commands & The interface outputs the available
	commands. \\
	\midrule
	Provide a move & The state of the engine updates with the new move. \\
	\midrule
	Ask for a move & The engine suggests a move without changing the state of
	the current game. \\
	\bottomrule
\end{tabular}

\vspace{\interclassSpace}

\begin{tabular}{p{0.4\linewidth}p{0.5\linewidth}}
	\toprule
	\multicolumn{2}{c}{\textbf{Training interface}} \\
	\midrule
	\textbf{Test} & \textbf{Expected behaviour} \\
	\midrule
	Provide some games to train on & A neural network model is created. \\
	\midrule
	Start the training without providing games & An error message is shown and
	the execution terminated. \\
	\bottomrule
\end{tabular}

\subsubsection{Usability Testing}

Two different human users will be exposed to the interfaces of the project and
asked to answer a questionary about their experience. The aim of this process is
to identify and address any problems end users could have when using the
system.

As the training of the neural networks is part of the preparation of the system,
its usability will not be tested for end users.

These are the questions provided to the testers.

\begin{itemize}

	\item Playing a game against a human:
		\begin{itemize}
			\item Were you able to start the interface?
			\item How hard to understand was the interface of the game?
		\end{itemize}

	\item Playing a game against the engine:
		\begin{itemize}
			\item Were you able to start the interface?
			\item How hard to understand was the interface of the game?
			\item How strong did you find the engine?
		\end{itemize}

	\item Playing a game against the interface through a third-party \acrshort{gui}:
		\begin{itemize}
			\item Were you able to start the interface?
			\item Did you find any problems when setting up the engine?
		\end{itemize}

\end{itemize}