From 206f2cf2592f1ea36d28e1026c5bfb0a6432fbd2 Mon Sep 17 00:00:00 2001 From: InigoGutierrez Date: Wed, 22 Jun 2022 21:31:40 +0200 Subject: Created subclasses for different neural networks. --- imago/engine/keras/convNeuralNetwork.py | 51 ++++++++++++++++++++++++++++++++ imago/engine/keras/denseNeuralNetwork.py | 28 ++++++++++++++++++ imago/engine/keras/keras.py | 8 +++-- imago/engine/keras/neuralNetwork.py | 31 ++++++------------- testKeras.py | 7 +++-- 5 files changed, 98 insertions(+), 27 deletions(-) create mode 100644 imago/engine/keras/convNeuralNetwork.py create mode 100644 imago/engine/keras/denseNeuralNetwork.py diff --git a/imago/engine/keras/convNeuralNetwork.py b/imago/engine/keras/convNeuralNetwork.py new file mode 100644 index 0000000..2534db6 --- /dev/null +++ b/imago/engine/keras/convNeuralNetwork.py @@ -0,0 +1,51 @@ +"""Convolutional neural network.""" + +from tensorflow.keras.models import Sequential +from tensorflow.keras.layers import Conv2D, Conv2DTranspose, Reshape, Dense +from tensorflow.keras.optimizers import Adam + +from imago.engine.keras.neuralNetwork import NeuralNetwork + +defaultModelFile = 'models/imagoConvKerasModel.h5' + +class ConvNeuralNetwork(NeuralNetwork): + + def _initModel(self, boardSize=NeuralNetwork.DEF_BOARD_SIZE): + model = Sequential([ + Conv2D( + filters=32, + kernel_size=(3), + activation='relu', + padding='same', + input_shape=(boardSize,boardSize,1) + ), + Conv2D( + filters=64, + kernel_size=(3), + activation='relu', + padding='same' + ), + #Conv2DTranspose( + # filters=64, + # kernel_size=(3), + # activation='relu', + # padding='same' + #), + Dense( + units=1, + activation='softmax' + ), + Reshape( + (boardSize,boardSize) + ), + ]) + + model.summary() + + model.compile( + optimizer=Adam(learning_rate=0.0001), + loss='categorical_crossentropy', + metrics=['accuracy'] + ) + + return model diff --git a/imago/engine/keras/denseNeuralNetwork.py b/imago/engine/keras/denseNeuralNetwork.py new file mode 100644 index 0000000..ff2efa8 --- /dev/null +++ b/imago/engine/keras/denseNeuralNetwork.py @@ -0,0 +1,28 @@ +"""Dense neural network.""" + +from tensorflow.keras.models import Sequential +from tensorflow.keras.layers import Dense +from tensorflow.keras.optimizers import Adam + +from imago.engine.keras.neuralNetwork import NeuralNetwork + +defaultModelFile = 'models/imagoDenseKerasModel.h5' + +class DenseNeuralNetwork(NeuralNetwork): + + def _initModel(self, boardSize=NeuralNetwork.DEF_BOARD_SIZE): + model = Sequential([ + Dense(units=32, activation='sigmoid', input_shape=(boardSize,boardSize)), + Dense(units=64, activation='relu'), + Dense(units=boardSize, activation='softmax') + ]) + + model.summary() + + model.compile( + optimizer=Adam(learning_rate=0.0001), + loss='categorical_crossentropy', + metrics=['accuracy'] + ) + + return model diff --git a/imago/engine/keras/keras.py b/imago/engine/keras/keras.py index a6aa913..80b6647 100644 --- a/imago/engine/keras/keras.py +++ b/imago/engine/keras/keras.py @@ -3,16 +3,18 @@ from imago.gameLogic.gameMove import GameMove from imago.gameLogic.gameBoard import GameBoard from imago.engine.decisionAlgorithm import DecisionAlgorithm -from imago.engine.keras.neuralNetwork import NeuralNetwork +from imago.engine.keras.denseNeuralNetwork import DenseNeuralNetwork +from imago.engine.keras.convNeuralNetwork import ConvNeuralNetwork -MODEL_FILE = "models/testModel.h5" +MODEL_FILE = "" # Use network's default model file class Keras(DecisionAlgorithm): def __init__(self, move): self.currentMove = move self.boardSize = move.board.getBoardHeight() - self.nn = NeuralNetwork(MODEL_FILE, self.boardSize) + #self.nn = NeuralNetwork(MODEL_FILE, self.boardSize) + self.nn = ConvNeuralNetwork(MODEL_FILE, self.boardSize) def forceNextMove(self, coords): """Selects given move as next move.""" diff --git a/imago/engine/keras/neuralNetwork.py b/imago/engine/keras/neuralNetwork.py index 1ec0efd..a52a3af 100644 --- a/imago/engine/keras/neuralNetwork.py +++ b/imago/engine/keras/neuralNetwork.py @@ -6,18 +6,18 @@ import os.path import numpy from matplotlib import pyplot -from tensorflow.keras.models import Sequential, load_model -from tensorflow.keras.layers import Dense -from tensorflow.keras.optimizers import Adam +from tensorflow.keras.models import load_model from imago.data.enums import Player defaultModelFile = 'models/imagoKerasModel.h5' -DEF_BOARD_SIZE = 9 -PLAYER_ID = 1 -OPPONENT_ID = -1 class NeuralNetwork: + + DEF_BOARD_SIZE = 9 + PLAYER_ID = 1 + OPPONENT_ID = -1 + def __init__(self, modelPath="", boardSize=DEF_BOARD_SIZE): self.boardSize = boardSize self.path = defaultModelFile @@ -29,21 +29,7 @@ class NeuralNetwork: self.model = self._initModel(boardSize) def _initModel(self, boardSize=DEF_BOARD_SIZE): - model = Sequential([ - Dense(units=16, activation='relu', input_shape=(boardSize,boardSize)), - Dense(units=32, activation='relu'), - Dense(units=boardSize, activation='softmax') - ]) - - model.summary() - - model.compile( - optimizer=Adam(learning_rate=0.0001), - loss='categorical_crossentropy', - metrics=['accuracy'] - ) - - return model + raise NotImplementedError("Tried to directly use NeuralNetwork class. Use one of the subclasses instead.") def trainModel(self, games): trainMoves = [] @@ -70,7 +56,8 @@ class NeuralNetwork: if os.path.isfile(modelPath): return load_model(modelPath) else: - raise FileNotFoundError("Keras neural network file not found at %s" % modelPath) + raise FileNotFoundError("Keras neural network model file not found at %s" + % modelPath) def saveModel(self, modelPath=""): if modelPath != "": diff --git a/testKeras.py b/testKeras.py index 3b0b3f5..0f25b21 100755 --- a/testKeras.py +++ b/testKeras.py @@ -6,6 +6,7 @@ import sys from imago.sgfParser.sgf import loadGameTree from imago.engine.keras.neuralNetwork import NeuralNetwork +from imago.engine.keras.convNeuralNetwork import ConvNeuralNetwork def main(): games = [] @@ -15,8 +16,10 @@ def main(): matches = [game.getMainLineOfPlay() for game in games] - modelFile = "models/testModel.h5" - nn = NeuralNetwork(modelFile, 9) + modelFile = "" + boardsize = 9 + nn = NeuralNetwork(modelFile, boardsize) + #nn = ConvNeuralNetwork(modelFile, boardsize) nn.trainModel(matches) nn.saveModel() -- cgit v1.2.1