def _format_array_v2(file): # This one actually works :) output = [] try: raw_data = open(file, 'r').read() # reads the data from specified file as string except: log.error('File {} could not be read'.format(file)) return False raw_data = raw_data.replace("[", "") raw_data = raw_data.replace(" ", "") # reduces string to essential characters length = len(raw_data) str_num = "" # Buffer to hold characters for single value for i in range(length): char = raw_data[i] if not char == "," and not char == "]": # If char is .|0|1|2 str_num += char if char == "," or char == "]": # If reached end of number num = float(str_num) output.append(num) str_num = "" # Resets buffer return output
def _predict(input_data): global model global new_model global has_model global has_new_model input_data = np.array(input_data) input_array = [] input_array.append(input_data) input_array = np.array(input_array) # (input_array.shape) if has_new_model: prediction = new_model.predict_on_batch( input_array) # Because I couldn't get model.predict(...) to work else: if has_model: prediction = model.predict_on_batch(input_array) else: log.error("No model found") return False prediction = prediction[0] move = np.argmax(prediction) # returns location of highest array value return prediction
def __get(self): self._url = Url.check(self._url) if self._url is None: return False self._url = self._url + self._path # log.info('正在获取 {}'.format(self._url)) try: return self.__download() except Exception as e: log.error('{} 获取失败! 错误信息: {}'.format(self._url, e.args))
def wrapper(self, count=0, *args, **kwargs): try: return fun(self, *args, **kwargs) except requests.exceptions.ConnectionError: log.error('{} 不存在'.format(self._url)) except Exception as e: if count < retry_num: count += 1 log.info("{}: 第{}次重试".format(self._url, count)) time.sleep(1) return wrapper(self, count, *args, **kwargs) else: raise Exception(e)
def _add_input_layer(): try: global model log.info('Adding input layer') model.add(keras.layers.Flatten(input_shape=(42))) log.info('\tInput layer added\n') return True except: log.error('\tUnknown error in NeuralNetwork._add_input_layer\n') return False
def _create_model(): try: global model log.info('Creating network model') model = Sequential() log.info('\tNetwork model created\n') return True except: log.error('\tUnknown error in NeuralNetwork._create_model\n') return False
def _evaluate_model(): try: log.info('Evaluating model') global model global test_input # Test data doesn't exist, not strictly required global test_output # Unless you want to make 1,000 more data sets accuracy = model.evaluate(test_input, test_output) log.info('\tModel evaluated at {}% loss\n'.format(accuracy)) return True except: log.error('\tUnknown error in NeuralNetwork._evaluate_model\n') return False
def _compile_model(): try: global model log.info('Network compiling') model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) log.info('\tNetwork compiled\n') return True except: log.error('\tUnknown error in NeuralNetwork._compile_model\n') return False
def exportPlay(column): """ Converts play to an array and exports this data to a text file :param column: The players move :return: """ global GatherMove GatherMove = False # Ensures that only plays after exported boards are recorded dataForExport = [] # Prepare a list for the data to be dumped into """ #Intended AI output would be list of probabilities indicating best move #e.g: [0.1, 0.3, 0.5, 0.7, 0.5, 0.2, 0.1] #Would indicate best move to be 4th column """ for i in range(0, 7): if column == i: dataForExport.append( 1.0) #For move at col 2 would result in [0,0,1,0,0,0,0] else: dataForExport.append(0.0) # EXPORTING CODE # if not os.path.isdir("trainingData"): # Verify the desired folder exists, if not, create it log.debug("Training Data folder missing... creating") os.mkdir("trainingData") fileNum = 0 try: while True: # this loop makes sure it wont overwrite an existing file, then writes filename = "trainingData/ExportedMove{}.txt".format(fileNum) if os.path.isfile(filename): fileNum += 1 else: f = open(filename, "w") f.write(str(dataForExport)) f.close() log.info("Exported current state to {}".format(filename)) return True except Exception as e: # Error handling ^-^ log.error("Failed to export game state: {}".format(e)) return False
def _add_output_layer(size): # try: global model log.info('Adding output layer') model.add(keras.layers.Flatten()) # model.add(keras.layers.Dense(size, activation=tf.nn.softmax, output_size=6)) model.add(keras.layers.Dense(size, activation=tf.nn.softmax)) # todo: ValueError: Error when checking target: expected dense_4 to have shape (1,), but got array with shape (6,) log.info('\tOutput layer added\n') return True # except: log.error('\tUnknown error in NeuralNetwork._add_output_layer\n') return False
def _add_hidden_layers(layers, nodes): # try: global model log.info('Adding {} hidden layers'.format(layers)) for _ in range(layers): # model.add(keras.layers.Dense(nodes, activation=tf.nn.relu, output_size=42)) model.add(keras.layers.Dense(nodes, activation=tf.nn.relu)) # model.add(keras.layers.flatten()) log.info('\tHidden layers aadded\n') return True # except: log.error('\tUnknown error in NeuralNetwork._add_hidden_layers\n') return False
def _add_hidden_layers(layers, nodes): try: global model log.info('Adding {} hidden layers'.format(layers)) for _ in range(layers): model.add( keras.layers.Dense(nodes, input_shape=(41, ), activation=tf.nn.relu)) log.info('\tHidden layers aadded\n') return True except: log.error('\tUnknown error in NeuralNetwork._add_hidden_layers\n') return False
def _fit_model(epochs): # try: # global model # global training_input # global training_output # # log.info('Fitting model') # # model.fit(training_input, training_output, epochs=epochs) #Not currently working # # # log.info('\tModel fitted\n') # return True # # except: # log.error('\tUnknown error in NeuralNetwork._fit_model\n') # return False # global model # global training_input # global training_output # # # print(model.summary()) # # log.info('Fitting model') # model.fit(training_input, training_output, epochs=epochs) # Not currently working # # # log.info('\tModel fitted\n') try: log.info('Fitting model') global model model.fit(training_input, training_output, epochs=epochs, batch_size=128) # Trains neural network log.debug("\tModel fitted\n") return True except: log.error("\tFailed to fit model\n") return False
def _load_model(name): try: global model log.info('Loading model "{}"'.format(name)) name = name + '.model' try: new_model = keras.models.load_model(name) log.info('\tLoaded model "{}"\n'.format(name)) return True except: log.error('\tModel "{}" failed to load\n'.format(name)) except: log.error('\tUnknown error in NeuralNetwork._load_model\n') return False
def _drop_piece(playField, row, col, player): """ Places the piece onto the playField :param playField: The play field :param row: The target row :param col: The target column :param player: The player making the move :return: None """ try: log.debug("P{}: Placing piece at [{}][{}]".format(player, row, col)) playField[row][col] = player if GatherMove: # Exports play if board exported exportPlay(col) except Exception as e: log.error("Failed to place piece: {}".format(e)) return False
def _get_data(): try: global training_input global training_output training_input = [] training_output = [] log.info('Fetching training data') number_of_files = int(len(os.listdir('trainingData'))) for file_num in range(0, int(number_of_files / 2)): state_file = 'trainingData/ExportedState{}.txt'.format(file_num) move_file = 'trainingData/ExportedMove{}.txt'.format(file_num) f = open(state_file, "r") data = list(f.read()) # data = np.load(file) data = df._format_array_v2(state_file) data = np.array(data) training_input.append(data) f = open(move_file, "r") data = list(f.read()) # data = np.load(file) data = df._format_array_v2(move_file) data = np.array(data) training_output.append(data) training_input = np.array(training_input) training_output = np.array(training_output) log.info('\tData fetched') log.info('\t\tTraining_input length: {}'.format(len(training_input))) log.info('\t\tTraining_out length: {}\n'.format(len(training_output))) return True except: log.error('\tUnknown error in NeuralNetwork._get_data\n') return False
def _save_model(name): try: global model log.info('Saving model') name = name + '.model' try: model.save(name) log.info('\tModel saved as {}'.format(name)) except: log.error('\tFailed to save model as {}'.format(name)) return False except: log.error('\tUnknown error in NeuralNetwork._save_model\n') return False
def _get_data(): try: global training_input global training_output training_input = [] training_output = [] log.info('Fetching training data') try: number_of_files = int(len(os.listdir('trainingData'))) except: log.error('Directory trainingData does not exist') return False for file_num in range(0, int(number_of_files / 2)): state_file = 'trainingData/ExportedState{}.txt'.format(file_num) move_file = 'trainingData/ExportedMove{}.txt'.format(file_num) state_data = df._format_array_v2(state_file) move_data = df._format_array_v2(move_file) if not state_data: log.error('Failed to load board state data') return False if not move_data: log.error('Failed to load move data') return False state_data = np.array(state_data) move_data = np.array(move_data) training_input.append(state_data) training_output.append(move_data) training_input = np.array(training_input) training_output = np.array(training_output) log.info('\tData fetched') log.info('\t\tTraining_input length: {}\tShape: {}'.format( len(training_input), training_input.shape)) log.info('\t\tTraining_out length: {}\tShape: {}\n'.format( len(training_output), training_output.shape)) return True except: log.error('\tUnknown error in NeuralNetwork._get_data\n') return False
def _get_AI_move(playField): """ Gets the AIs next move :param playField: :return: int of move """ global AI if not AI: log.error( "No AI found" ) # Ensures that an AI exists, does happen earlier as well, just making sure nn._construct("AI") nn._save_model("AI") log.info("AI constructed") AI = True field = _flatten_field(playField) print(np.array(field).shape) moves = nn._predict( field) # Should return array eg: [0.1, 0.1, 0.3, 0.8, 0.4, 0.2, 0.1] best_move = np.argmax( moves) # Returns location of highest val, only first occurrence while not _validate_move(playField, best_move): # Ensures return value is valid moves[best_move] = 0.0 if np.sum(moves) == 0: for i in range(8): if _validate_move( playField, i): # If AI fails, just uses next available slot return i log.error("AI failed to return usable value") return False best_move = np.argmax(moves) log.info("AI selected move at {}".format(best_move)) return best_move
def _compile_model(): try: log.info('Compiling model') global model # log.info('Network compiling') # # # model.compile(optimizer='adam', loss='sparse_categorical_crossentropy', metrics=['accuracy']) # model.compile(optimizer='adam') model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['accuracy']) # trains it using tensoroflow log.info('\tModel compiled\n') return True except: log.error('\tUnknown error in NeuralNetwork._compile_model\n') return False
def flattenAndExport(playfield): """ Flattens the 2D array into a 1D array and exports this data to a text file :param playfield: The game's playfield :return: """ global GatherMove GatherMove = True # The play made at this point to be recorded, for AI target data dataForExport = [] # Prepare a list for the data to be dumped into for row in playfield: for item in row: dataForExport.append( item) # dump each item one by one into this new list # EXPORTING CODE # if not os.path.isdir("trainingData"): # Verify the desired folder exists, if not, create it log.debug("Training Data folder missing... creating") os.mkdir("trainingData") fileNum = 0 try: while True: # this loop makes sure it wont overwrite an existing file, then writes filename = "trainingData/ExportedState{}.txt".format(fileNum) if os.path.isfile(filename): fileNum += 1 else: f = open(filename, "w") f.write(str(dataForExport)) f.close() log.info("Exported current state to {}".format(filename)) return True except Exception as e: # Error handling ^-^ log.error("Failed to export game state: {}".format(e)) return False
def _load_model(name): try: global new_model global has_new_model log.info('Loading model "{}"'.format(name)) name = name + '.model' try: new_model = keras.models.load_model(name) log.info('\tLoaded model "{}"\n'.format(name)) has_new_model = True # keras.plot_model(new_model, to_file='Model.png') # Would be a nice idea return True except: log.error('\tModel "{}" failed to load\n'.format(name)) except: log.error('\tUnknown error in NeuralNetwork._load_model\n') return False
def _add_hidden_layers(layers, nodes): try: global model log.info('Adding {} hidden layers'.format(layers)) # for _ in range(layers): # # model.add(keras.layers.Dense(nodes, activation=tf.nn.relu, output_size=42)) # model.add(keras.layers.Dense(nodes, activation=tf.nn.relu)) # model.add(keras.layers.Dropout(0.01)) # Prevents over-fitting the model while training (memorisation) # # model.add(keras.layers.Flatten()) for _ in range(layers): model.add(Dense(nodes, activation='relu')) model.add(Dropout(0.5)) log.info('\tHidden layers aadded\n') return True except: log.error('\tUnknown error in NeuralNetwork._add_hidden_layers\n') return False
def _add_input_layer(): # try: global model log.info('Adding input layer') # model.add(keras.layers.Flatten(input_shape=(None, 42), output_size=42)) # model.add(keras.layers.Flatten) model.add(keras.layers.Flatten(input_shape=( 1000, 41, ))) # model.add(keras.layers.Input( shape=(1000, 41, ))) # model.add(keras.layers.Flatten(input_dim=41)) log.info('\tInput layer added\n') return True # except: log.error('\tUnknown error in NeuralNetwork._add_input_layer\n') return False
def _add_output_layer(size): try: log.info('Adding output layer') global model # log.info('Adding output layer') # print(model.summary()) # model.add(keras.layers.Flatten()) # todo: Currently cuts off here # # todo: Flatten layer expecten min_ndim=3, got ndim=2 # # # model.add(keras.layers.Dense(size, activation=tf.nn.softmax, output_size=6)) # model.add(keras.layers.Dense(size, activation=tf.nn.softmax)) # # todo: ValueError: Error when checking target: expected dense_4 to have shape (1,), but got array with shape (6,) Sorted? model.add(Dense(size, activation='sigmoid')) # output layer log.info('\tOutput layer added\n') return True except: log.error('\tUnknown error in NeuralNetwork._add_output_layer\n') return False
def _add_input_layer(): # try: global model log.info('Adding input layer') # # model.add(keras.layers.Flatten(input_shape=(None, 42), output_size=42)) # # # model.add(keras.layers.Flatten) # model.add(keras.layers.Flatten(input_shape=(1000, 41, 1))) # # model.add(keras.layers.Input( shape=(1000, 41, ))) # # model.add(keras.layers.Flatten(input_dim=41)) model.add(Dense( 32, activation='relu', input_shape=(42, ))) # relu activiation layer, better perfomance. model.add(Dropout(0.5)) log.info('\tInput layer added\n') return True # except: log.error('\tUnknown error in NeuralNetwork._add_input_layer\n') return False
def _game_loop(playField): """ The main game loop :param playField: the play field :return: """ global TestMode global DataGatherMode global AIMode global AI global turn global hueHSV log.info("Game Loop started") turn = 1 while True: # BIG SCARY EVENT LOOP! for event in pygame.event.get(): # poll pygame for events if event.type == pygame.QUIT: # Allow game to quit _quit() if not TestMode: if event.type == pygame.MOUSEMOTION: # User moved the mouse, so move their piece after their cursor for A E S T H E T I C S pygame.draw.rect( screen, (0, 0, 0), (0, 0, width, 100) ) # hide the last frame of motion, turn this off for some really trippy stuff posx = event.pos[0] # get the location of the cursor if posx < ( COLUMN_COUNT * 100 ) - 25 and posx > 25: # messy way of clamping the location above the game columns if turn % 2 == 0: # determine whos turn it is, and make the piece that colour pygame.draw.circle(screen, (206, 22, 48), (posx, 50), int(radius)) else: pygame.draw.circle(screen, (255, 201, 23), (posx, 50), int(radius)) pygame.display.update() # refresh the screen if event.type == pygame.MOUSEBUTTONDOWN or turn % 2 == 0 and AIMode: # click = drop piece if turn % 2 == 0 and AIMode: col = _input(playField, turn, pos=[0, 0]) else: col = _input( playField, turn, event.pos ) # determine what column the user clicked above if col is not None: # None = the user didnt click in a valid location, so we ignore it row = _get_next_open_row( playField, col) # determine what row we should place a piece if row != -1: _drop_piece(playField, row, col, turn % 2 + 1) # drop said piece if _winning_move(playField, turn % 2 + 1): # check if a player has won log.info( "Win condition met for player {}".format( turn % 2 + 1)) renderer(playField) print("Player {} is the Winner in {} turns!". format(turn % 2 + 1, turn)) if not TestMode: pygame.display.update() end_screen(turn % 2 + 1, turn) pygame.time.wait( 2000 ) # wait for a bit to allow the player to B A S K in their glory quit() return # exit the game loop and quit return else: log.info("Unable to place piece on column " + str(col)) turn -= 1 renderer(playField) pygame.display.update() turn += 1 if event.type == pygame.KEYDOWN: # Bit of code for Mark, because he asked for the game to export its current state if event.key == pygame.K_F6 and turn % 2 == 1: # Check if the user pressed F6 then export log.debug("Exporting current game state...") flattenAndExport(playField) if event.key == pygame.K_t: TestMode = not TestMode renderer(playField) pygame.display.flip() log.debug("Test Mode set to {}".format(TestMode)) start_game() if event.key == pygame.K_d: DataGatherMode = not DataGatherMode log.debug( "Data Gather mode set to {}".format(DataGatherMode)) if event.key == pygame.K_a: AIMode = not AIMode if AIMode and (not AI): try: # AI = keras.models.load_model('AI.model') # If first time AI toggles, imports the NN nn._construct("AI") # nn._save_model("AI") AI = True log.info("Neural Network model loaded") except: log.error("Failed to load Neural Network model") AIMode = False # Ensures not trying to get info from absent AI log.debug("AI mode set to {}".format(AIMode)) if TestMode: col = _input(playField, turn, 1) if col is not None: # None = the user didnt click in a valid location, so we ignore it row = _get_next_open_row( playField, col) # determine what row we should place a piece if row != -1: _drop_piece(playField, row, col, turn % 2 + 1) # drop said piece if _winning_move(playField, turn % 2 + 1): # check if a player has won log.info( "Win condition met for player {}".format(turn % 2 + 1)) renderer(playField) hueHSV = hueHSV + 1 pygame.display.update() print("Player {} is the Winner in {} turns!".format( turn % 2 + 1, turn)) pygame.time.wait(10) return turn += 1 unique, counts = np.unique(playField, return_counts=True) dictionary = dict(zip(unique, counts)) try: if dictionary[0] == 0: return except KeyError: log.warning("Playfield full, restarting...") renderer(playField) pygame.display.update() return except ValueError: pass