diff --git a/Andrzej_Preibisz.md b/Andrzej_Preibisz.md old mode 100644 new mode 100755 diff --git a/Drzewo.png b/Drzewo.png old mode 100644 new mode 100755 diff --git a/Jakub Damiński.md b/Jakub Damiński.md new file mode 100644 index 0000000..53cdb7c --- /dev/null +++ b/Jakub Damiński.md @@ -0,0 +1,15 @@ +## Podprojekt: algorytm genetyczny +### Jakub Damiński + +#### Opis problemu +Metodą uczenia, którą postanowiłem zaimplementować w projekcie był algorytm genetyczny. Zastosowalem go, by znaleźć najszybszą ścieżkę, którą może podążyć wózek widłowy pomiędzy paczkami, by przejechać w sumie jak najkrótszy dystans. + +#### Metoda +Pierwszym krokiem jest zbudowanie grafu z wagami w którym wierzchołkami są paczki, regały na które te paczki mają trafić oraz punkt startowy wózka, a wagi krawędzi to odległości między nimi. Ponieważ środowisko opiera się na 2-wymiarowej powierzchni, gdzie nie ma odizolowanych pól jest to graf pełny. Graf zapisany jest w 2-wymiarowej tablicy. + +Ponieważ wózek musi odwiedzić wszystkie paczki każde rozwiązanie tego problemu będzie permutacja zbioru tych paczek, przedstawiający, które paczki po kolei powinien wózek odwiedzić. Wartościowość takiego rozwiązania jest weryfikowana poprzez zsumowanie odległości jakie wózek musi przebyć do paczki oraz od paczki do jej wyznaczonego regału. + +Wykorzystując algorytm genetyczny sprawimy, że spośród losowych permotacji zaczną wyłaniać się tej najbardziej efektywne, czyli te o najkrótszej ścieżce. + +#### Zasada działania +... diff --git a/Readme.md b/Readme.md old mode 100644 new mode 100755 diff --git a/Test_Results.png b/Test_Results.png old mode 100644 new mode 100755 diff --git a/agent.py b/agent.py old mode 100644 new mode 100755 index 1474bed..49b6e64 --- a/agent.py +++ b/agent.py @@ -1,11 +1,17 @@ +from pandas.tests.io.json.test_ujson import numpy + from warehouse import Coordinates, Tile, Pack from queue import PriorityQueue -from math import sqrt +from math import sqrt, ceil from attributes import TURN_LEFT_DIRECTIONS, TURN_RIGHT_DIRECTIONS, PackStatus import pygame import sys import pdb +import numpy as np from package_location_classifier.classifier import PackageLocationClassifier +from genetic_route import genetic_trace_route +from siec import imgSkan, imageClass +from keras.models import Sequential class Node: def __init__(self, coord_x, coord_y, package=None, is_rack=False): @@ -16,9 +22,11 @@ class Node: self.is_rack = is_rack self.g_cost = 0 self.h_cost = 0 + self.graph_map = None + def __eq__(self, other): if isinstance(other, Node): - return self.x == other.x and self.y == self.y + return self.x == other.x and self.y == other.y return False def __lt__(self, other): @@ -27,50 +35,61 @@ class Node: def __repr__(self): return "Node:{}x{}".format(self.x, self.y) + class Agent: def __init__(self, start_x, start_y, assigned_warehouse, radius=5): self.x = start_x self.y = start_y self.radius = radius self.warehouse = assigned_warehouse + self.graph_map = np.zeros(((self.warehouse.no_of_packages * 2) + 1, (self.warehouse.no_of_packages * 2) + 1)) self.is_loaded = False self.transported_package = None self.direction = "up" - self.dest = Node(1, 1) self.closed = list() self.open = PriorityQueue() self.path = list() self.location_classifier = PackageLocationClassifier() self.check_packages_locations() + self.route = [] + self.destination = None def check_packages_locations(self): for pack in self.warehouse.packages: if pack.lays_on_field.category.name in self.warehouse.storage_types: can_place = self.location_classifier.check_if_can_place(pack, pack.lays_on_field) - pack.status = PackStatus.STORED if (can_place and pack.lays_on_field.capacity >= 0) else PackStatus.STORED_BAD_LOCATION + pack.status = PackStatus.STORED if ( + can_place and pack.lays_on_field.capacity >= 0) else PackStatus.STORED_BAD_LOCATION - - def find_path(self): + def find_path(self, *args, **kwargs): self.closed = [] self.path = [] self.open = PriorityQueue() - packages_to_go = [p for p in self.warehouse.packages if p.status != PackStatus.STORED] - if not packages_to_go and not self.transported_package: - return - if self.is_loaded: - rack = self.find_nearest_rack_for(self.transported_package) - self.dest = Node(rack.x_position, rack.y_position, is_rack=True) + if len(args) != 0: + if len(args) == 1: + start_node = Node(self.x, self.y) + else: + start_node = args[1] + self.destination = args[0] else: - package = self.find_nearest_package() - self.dest = Node(package.lays_on_field.x_position, package.lays_on_field.y_position, package=package) + packages_to_go = [p for p in self.warehouse.packages if p.status != PackStatus.STORED] + if not packages_to_go and not self.transported_package: + return + if self.is_loaded: + print(self.transported_package) + rack = self.find_nearest_rack_for(self.transported_package) + self.destination = Node(rack.x_position, rack.y_position, is_rack=True) + else: + package = self.find_package() + self.destination = Node(package.lays_on_field.x_position, package.lays_on_field.y_position, package=package) - start_node = Node(self.x, self.y) + start_node = Node(self.x, self.y) self.open.put((0, start_node)) while self.open: _, current_node = self.open.get() self.closed.append(current_node) - if current_node.x == self.dest.x and current_node.y == self.dest.y: + if current_node.x == self.destination.x and current_node.y == self.destination.y: while current_node.x != start_node.x or current_node.y != start_node.y: self.path.append(current_node) current_node = current_node.parent @@ -86,7 +105,7 @@ class Agent: neighbour.parent = current_node else: neighbour.g_cost = cost - neighbour.h_cost = self.heuristic(neighbour, self.dest) + neighbour.h_cost = self.heuristic(neighbour, self.destination) neighbour.parent = current_node self.open.put((neighbour.g_cost, neighbour)) return False @@ -103,10 +122,10 @@ class Agent: diff_x = pow(goal.x - start.x, 2) diff_y = pow(goal.y - start.y, 2) additional_cost = 0 - return round(sqrt(diff_x + diff_y), 3) + float(10*additional_cost) - + return round(sqrt(diff_x + diff_y), 3) + float(10 * additional_cost) + def check_if_open(self, node: Node): - return (node.x, node.y) in [(n.x, n.y) for (_,n) in self.open.queue] + return (node.x, node.y) in [(n.x, n.y) for (_, n) in self.open.queue] def check_if_closed(self, node: Node): return (node.x, node.y) in [(n.x, n.y) for n in self.closed] @@ -122,81 +141,79 @@ class Agent: if self.check_if_can_move(Coordinates(node.x, node.y - 1)): neighbours.append(Node(node.x, node.y - 1)) return neighbours - + def move(self): - dest_coords = (self.dest.x, self.dest.y) - if not self.path: - if not self.find_path(): - return - else: - next = self.path.pop() - star_dir = self.direction - if self.x > next.x and not self.direction == 'left': - if self.direction == 'down': - self.turn_right() - else: - self.turn_left() - elif self.x < next.x and not self.direction == 'right': - if self.direction == 'down': - self.turn_left() - else: - self.turn_right() - elif self.y > next.y and not self.direction == 'up': - if self.direction == 'left': - self.turn_right() - else: - self.turn_left() - elif self.y < next.y and not self.direction == 'down': - if self.direction == 'right': - self.turn_right() - else: - self.turn_left() - - if (next.x, next.y) == dest_coords: - if self.dest.package: - self.pick_up_package(self.dest.package) - return - elif self.dest.is_rack: - self.unload_package(self.dest) - return - - if star_dir == self.direction: - self.x = next.x - self.y = next.y + if len(self.path) == 0: + self.find_path() + next_coord = self.path.pop() + star_dir = self.direction + if self.x > next_coord.x and not self.direction == 'left': + if self.direction == 'down': + self.turn_right() else: - self.path.append(next) + self.turn_left() + elif self.x < next_coord.x and not self.direction == 'right': + if self.direction == 'down': + self.turn_left() + else: + self.turn_right() + elif self.y > next_coord.y and not self.direction == 'up': + if self.direction == 'left': + self.turn_right() + else: + self.turn_left() + elif self.y < next_coord.y and not self.direction == 'down': + if self.direction == 'right': + self.turn_right() + else: + self.turn_left() + if Node(next_coord.x, next_coord.y) == self.destination or Node(self.x, self.y) == self.destination: + if self.destination.package: + self.pick_up_package(self.destination.package) + return + elif self.destination.is_rack: + self.unload_package(self.destination) + return + + if star_dir == self.direction: + self.x = next_coord.x + self.y = next_coord.y + else: + self.path.append(next_coord) self.closed = [] - + def check_if_can_move(self, next_coords: Coordinates): tile_on_map = 0 <= next_coords.x < self.warehouse.width and 0 <= next_coords.y < self.warehouse.height tile_passable = True if not tile_on_map: return False next_tile = self.warehouse.tiles[next_coords.x][next_coords.y] - if (next_coords.x, next_coords.y) != (self.dest.x, self.dest.y): + if (next_coords.x, next_coords.y) != (self.destination.x, self.destination.y): tile_passable = isinstance(next_tile, Tile) and next_tile.category.passable return tile_passable - def find_nearest_package(self): - packages_costs = [] - start_node = Node(self.x, self.y) - if not self.warehouse.packages: - return None - for package in self.warehouse.packages: - if package.status == PackStatus.STORED: - continue - new_node = Node(package.lays_on_field.x_position, package.lays_on_field.y_position) - cost = self.heuristic(start_node, new_node) - if cost > 0: - packages_costs.append((package, cost)) - if not packages_costs: - return - # pygame.quit() - # sys.exit() - - package = min(packages_costs, key=lambda l: l[1])[0] - return package + def find_package(self): + if len(self.route) == 0: + pygame.quit() + sys.exit() + pack_id = self.route[0] + self.route = self.route[1:] + print("Next package ID:") + print(pack_id) + dst_package = None + for pack in self.warehouse.packages: + if pack.id + 1 == pack_id: + dst_package = pack + break + if dst_package is not None: + return dst_package + + nmodel = Sequential() + imageClass(nmodel) + nmodel.load_weights('model_weights.h5') + imgSkan() + def rack_heuristics(self, start, goal, can_place): heur_can_place = not can_place diff_x = pow(goal.x - start.x, 2) @@ -210,8 +227,8 @@ class Agent: if package.category == "freezed": storage = "Fridge" start_node = Node(self.x, self.y) - quarter_x = int(self.warehouse.width/4) + expand_box - quarter_y = int(self.warehouse.height/4) + expand_box + quarter_x = int(self.warehouse.width / 4) + expand_box + quarter_y = int(self.warehouse.height / 4) + expand_box start_quarter_x = self.x - quarter_x if self.x - quarter_x > 0 else 0 end_quarter_x = self.x + quarter_x if self.x + quarter_x < self.warehouse.width else self.warehouse.width - 1 start_quarter_y = self.y - quarter_y if self.y - quarter_y > 0 else 0 @@ -227,17 +244,17 @@ class Agent: if cost > 0: racks_costs.append((rack, cost)) - rack = self.find_nearest_rack_for(package, expand_box + 1) if not racks_costs else min(racks_costs, key=lambda l: l[1])[0] + rack = self.find_nearest_rack_for(package, expand_box + 1) if not racks_costs else \ + min(racks_costs, key=lambda l: l[1])[0] return rack - def pick_up_package(self, pack): self.warehouse.packages.remove(pack) self.is_loaded = True if pack.lays_on_field.category.name in ['Rack', 'Fridge']: pack.lays_on_field.capacity += pack.size - self.dest.package = None + self.destination.package = None pack.lays_on_field = None self.transported_package = pack @@ -250,4 +267,27 @@ class Agent: pack.lays_on_field.capacity -= pack.size pack.status = PackStatus.STORED self.warehouse.packages.append(pack) - # print(tile.air_temperature, tile.humidity) + + # print(tile.air_temperature, tile.humidity) + + def create_graph_map(self): + for package1 in self.warehouse.packages: + rack = self.find_nearest_rack_for(package1) + for package2 in self.warehouse.packages: + self.find_path(Node(package2.x, package2.y), Node(rack.x_position, rack.y_position)) + self.graph_map[package2.id + 1][package1.id + ceil((len(self.warehouse.packages) / 2)) + 1] = len(self.path) + self.graph_map[package1.id + ceil((len(self.warehouse.packages) / 2)) + 1][package2.id + 1] = len(self.path) + if package1 == package2: + continue + self.find_path(Node(package1.x, package1.y), Node(package2.x, package2.y)) + self.graph_map[package1.id + 1][package2.id + 1] = len(self.path) + self.find_path(Node(package1.x, package1.y)) + self.graph_map[package1.id + 1][0] = len(self.path) + self.graph_map[0][package1.id + 1] = len(self.path) + + def trace_route(self): + for packs in self.warehouse.packages: + print(packs.id) + self.route = genetic_trace_route(self.graph_map, len(self.warehouse.packages)) + print("best route") + print(self.route) diff --git a/attributes.py b/attributes.py old mode 100644 new mode 100755 diff --git a/cyfra.png b/cyfra.png new file mode 100644 index 0000000..35db652 Binary files /dev/null and b/cyfra.png differ diff --git a/environment.md b/environment.md old mode 100644 new mode 100755 diff --git a/forklift_loaded.png b/forklift_loaded.png new file mode 100755 index 0000000..91848c1 Binary files /dev/null and b/forklift_loaded.png differ diff --git a/genetic_algorithm.md b/genetic_algorithm.md old mode 100644 new mode 100755 diff --git a/genetic_algorithm.py b/genetic_algorithm.py old mode 100644 new mode 100755 diff --git a/genetic_route.py b/genetic_route.py new file mode 100755 index 0000000..ab7f580 --- /dev/null +++ b/genetic_route.py @@ -0,0 +1,98 @@ +import numpy as np +from random import randrange, random +from math import floor +import copy + +num_of_surviving = 6 +num_of_couples = 8 +mutation_probability = 0.07 +max_population = 20 +iterations = 50 + +# creates new random solution to add to population +def create_new_route(points): + route = np.random.permutation(points) + route = [x + 1 for x in route] + return route + +# creates initian population +def create_population(points): + population = [] + for i in range(max_population): + population.append(create_new_route(points)) + return population + +# gives score to a solution based on lenght +def score_route(graph_map, route): + score = graph_map[0][route[0]] + for i in range(len(route) - 2): + rack = len(route) + route[0] + score = score + graph_map[rack][route[i + 1]] + score = score + graph_map[route[i + 1]][route[i + 2]] + return score + +# scores every solution in population +def score_all(graph_map, population): + scores = [] + for i in range(len(population)): + tmp = [i, score_route(graph_map, population[i])] + scores.append(tmp) + return scores + +# designed to create new population by mixing steps between most succesfull solutions +def crossover(a, b): + new_a = copy.deepcopy(a) + new_b = copy.deepcopy(b) + for i in range(floor(len(a) / 2)): + rel = randrange(len(a)) + tmp_a = new_a[rel] + tmp_b = new_b[rel] + if tmp_a == tmp_b: + continue + new_a[new_a.index(tmp_b)] = tmp_a + new_b[new_b.index(tmp_a)] = tmp_b + new_a[rel] = tmp_b + new_b[rel] = tmp_a + return new_a, new_b + +# adds randomness to newly created solutions +def mutate(route): + new_route = copy.deepcopy(route) + for i in range(len(route) - 1): + if random() < mutation_probability: + tmp = new_route[i] + new_route[i] = new_route[i + 1] + new_route[i + 1] = tmp + return new_route + +# main function that iterate population until the best solutions emerge +def genetic_trace_route(graph_map, packages): + population = create_population(packages) + for i in range(iterations): + new_population = [] + scores = score_all(graph_map, population) + scores.sort(key=lambda x: x[1]) +# breeding + for j in range(0, num_of_couples, 2): + a, b = crossover(population[scores[j][0]], population[scores[j+1][0]]) + new_population.append(a) + new_population.append(b) +# mutations + for j in range(len(new_population)): + mutate(new_population[j]) +# survival + for j in range(0, num_of_surviving): + new_population.append(population[scores[j][0]]) + # random new + for j in range(max_population - (num_of_surviving + num_of_couples)): + new_population.append(create_new_route(packages)) + population.clear() + population = copy.deepcopy(new_population) + scores = score_all(graph_map, population) + scores.sort(key=lambda x: x[1]) + print("Best route of all population in iteration " + str(i + 1)) + print(scores[0][1]) + + scores = score_all(graph_map, population) + scores.sort(key=lambda x: x[1]) + return population[scores[0][0]] diff --git a/main.py b/main.py old mode 100644 new mode 100755 index 30f455a..a6e1b41 --- a/main.py +++ b/main.py @@ -26,6 +26,7 @@ class MainGameFrame: pygame.display.set_caption("Smart ForkLift") agent_radius = int(TILE_WIDTH/2) self.agent_tex = pygame.image.load('forklift.png') + self.agent_tex2 = pygame.image.load('forklift_loaded.png') self.font = pygame.font.Font('freesansbold.ttf', 16) self.warehouse_map = warehouse.Warehouse(20, 20, 150, 10) starting_x, starting_y = self.set_starting_agent_position() @@ -41,6 +42,9 @@ class MainGameFrame: print("wagi paczek: ",packs_sizes) print("pojemności regałów: ",racks_capacities) gen_alg(packs_sizes, racks_capacities, number_of_generations, generation_size, mutation_prob, amount_of_promotion, self.agent.location_classifier) + self.agent.create_graph_map() + self.agent.trace_route() + self.agent.find_path() def run(self): while True: @@ -101,9 +105,16 @@ class MainGameFrame: if cell.category.name in self.warehouse_map.storage_types: text_surface = self.font.render(str(cell.capacity), True, (0, 0, 0)) self.display.blit(text_surface, ((cell.x_position * TILE_WIDTH) + 6, (cell.y_position * TILE_HEIGHT) + 6)) + for package in self.warehouse_map.packages: + if package.status == PackStatus.LOOSE: + text_surface = self.font.render(str(package.id + 1), True, (0, 0, 0)) + self.display.blit(text_surface, ((package.lays_on_field.x_position * TILE_WIDTH) + 6, (package.lays_on_field.y_position * TILE_HEIGHT) + 6)) def draw_agent(self): - rotated = pygame.transform.rotate(self.agent_tex, DIRECTION_ANGLES.get(self.agent.direction)) + if self.agent.is_loaded: + rotated = pygame.transform.rotate(self.agent_tex2, DIRECTION_ANGLES.get(self.agent.direction)) + else: + rotated = pygame.transform.rotate(self.agent_tex, DIRECTION_ANGLES.get(self.agent.direction)) self.display.blit(rotated, (self.agent.x*TILE_WIDTH, self.agent.y*TILE_WIDTH)) def set_starting_agent_position(self): diff --git a/model_weights.h5 b/model_weights.h5 new file mode 100644 index 0000000..1ce4b6b Binary files /dev/null and b/model_weights.h5 differ diff --git a/products_types.py b/products_types.py old mode 100644 new mode 100755 diff --git a/route_planning.md b/route_planning.md old mode 100644 new mode 100755 diff --git a/siec.py b/siec.py new file mode 100644 index 0000000..94a401b --- /dev/null +++ b/siec.py @@ -0,0 +1,45 @@ +import numpy +from keras.datasets import mnist +from keras.layers import Conv2D, MaxPooling2D +from keras.layers import Dense, Dropout, Flatten +from keras.models import Sequential +from keras.utils import np_utils +from keras_preprocessing.image import load_img, img_to_array + + +img_rows, img_cols = 28, 28 +input_shape = (img_rows, img_cols, 1) + +producent = [] +def imageClass(model): + model.add(Conv2D(75, kernel_size=(5, 5), + activation='relu', + input_shape=input_shape)) + model.add(MaxPooling2D(pool_size=(2, 2))) + model.add(Dropout(0.2)) + model.add(Conv2D(100, (5, 5), activation='relu')) + model.add(MaxPooling2D(pool_size=(2, 2))) + model.add(Dropout(0.2)) + model.add(Flatten()) + model.add(Dense(500, activation='relu')) + model.add(Dropout(0.5)) + model.add(Dense(10, activation='softmax')) + + model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"]) + +nmodel = Sequential() +imageClass(nmodel) +nmodel.load_weights('model_weights.h5') + +def imgSkan(): + img_width, img_height = 28, 28 + new_image = load_img('cyfra.png', target_size=(img_width, img_height), color_mode = "grayscale") + new_image = img_to_array(new_image) + new_image = new_image.reshape((1,) + new_image.shape) + + prediction = nmodel.predict(new_image) + prediction = numpy.argmax(prediction) + print("Producent:", prediction) + producent.append(prediction) + +imgSkan() \ No newline at end of file diff --git a/sieci.md b/sieci.md old mode 100644 new mode 100755 index 5445256..13fff58 --- a/sieci.md +++ b/sieci.md @@ -1,89 +1,86 @@ -# Temat podptojektu: -Stworzenie sieci neuronowej, która rozpoznaje odręcznie napisaną na paczce liczbę, która oznacza producenta paczki. - -# Uczenie modelu -## Dane wejściowe: -### Pakiet Keras MNIST: -- dwa pliki: - - Plik z obrazkami - - Plik z poprawnymi odpowiedziami -### Format obrazków: -- rozmiar 28x28 -- odcienie szarości (0-biały, 255- czarny) -- obrazki w postaci binarnej są zapisane w jeden plik -## Praca z pakietem: -1. Zdefiniowano dane treningowe: tensory wejściowe i tensory wartości docelowych. -2. Zdefiniowano warstwy sieci (lub modelu) przypisującej dane wejściowe do docelowych wartości. -3. Skonfigurowano proces uczenia, wybierając funkcję straty, optymalizator i monitorowane metryki. -4. Wykonano iteracje procesu uczenia na danych treningowych, wywołując metodę -fit() zdefiniowanego modelu - -# Proces uczenia --ustawiam seed, aby powtarzać wyniki --pobieram dane -- konwertuję wymiary obrazu -- normalizuję dane -- konwertuję etykiety w kategorie -## Inicjalizuję sieć neuronową (sieć sekwencyjna). - model = Sequential() - model.add(Conv2D(75, kernel_size=(5, 5), - activation='relu', - input_shape=input_shape)) - model.add(MaxPooling2D(pool_size=(2, 2))) - model.add(Dropout(0.2)) - model.add(Conv2D(100, (5, 5), activation='relu')) - model.add(MaxPooling2D(pool_size=(2, 2))) - model.add(Dropout(0.2)) - model.add(Flatten()) - model.add(Dense(500, activation='relu')) - model.add(Dropout(0.5)) - model.add(Dense(10, activation='softmax')) -### Dołączam kolejno warstwy: -- Conv2D - mnoży obrazek przez macierz 2x2 -- activation='relu' - zeruje negatywne wyniki (funkcja aktuwacji) -- MaxPooling2D - zmienia rozdzielczość zdjęcia -- Droupout - ogranicza nadmierne dopasowanie -- Flatten - spłaszcza macierz do wektora -- Dense(10) - decyduje o przynależności zdjęcia do kategorii (cyfry od 0 do 9) -Activation='soft-max' - zwraca rozkład prawdopodobieństwa 10 różnych klas - -## Kompilacja modelu: - model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"]) -Funkcja straty - "catecorical_crossentropy" -Optymalizator - "Adam" -Monitorowanie dokładności - "accuracy" - -## Trenowanie modelu: - model.fit(X_train, Y_train, batch_size=200, epochs=10, validation_split=0.2, verbose=1) -trenuję model za pomocą funkcji fit() -### Pokazuję dokładność pracy na testowanych rannych - scores = model.evaluate(X_test, Y_test, verbose=0) - print("Dokadnosc na testowanych dannych: %.2f%%" % (scores[1]*100)) - -# Integracja z projektem -Tworzę model i ładuję wagi nauczonego modelu. - - image_cl = Sequential() - ImageClass(image_cl) - image_cl.load_weights('model_weights.h5') - -Po podniesieniu paczki odpalana jest funkcja imgSkan(), która z czytuje ręcznie napisaną cyfrę i wpisuje nr producenta paczki. - - def imgSkan(): - img = files.upload() - !ls - img_path = '2.png' - img = image.load_img(img_path, target_size=(28, 28), color_mode = "grayscale") - plt.imshow(img.convert('RGBA')) - plt.show() - x = image.img_to_array(img) - x = np.expand_dims(x, axis=0) - x = 255 - x - x /= 255 - prediction = model.predict(x) - prediction = np.argmax(prediction) - print("Cyfra:", prediction) - - - - +# Temat podptojektu: +Stworzenie sieci neuronowej, która rozpoznaje odręcznie napisaną na paczce liczbę, która oznacza producenta paczki. + +# Uczenie modelu +## Dane wejściowe: +### Pakiet Keras MNIST: +- dwa pliki: + - Plik z obrazkami + - Plik z poprawnymi odpowiedziami +### Format obrazków: +- rozmiar 28x28 +- odcienie szarości (0-biały, 255- czarny) +- obrazki w postaci binarnej są zapisane w jeden plik +## Praca z pakietem: +1. Zdefiniowano dane treningowe: tensory wejściowe i tensory wartości docelowych. +2. Zdefiniowano warstwy sieci (lub modelu) przypisującej dane wejściowe do docelowych wartości. +3. Skonfigurowano proces uczenia, wybierając funkcję straty, optymalizator i monitorowane metryki. +4. Wykonano iteracje procesu uczenia na danych treningowych, wywołując metodę +fit() zdefiniowanego modelu + +# Proces uczenia +-ustawiam seed, aby powtarzać wyniki +-pobieram dane +- konwertuję wymiary obrazu +- normalizuję dane +- konwertuję etykiety w kategorie +## Inicjalizuję sieć neuronową (sieć sekwencyjna). + model = Sequential() + model.add(Conv2D(75, kernel_size=(5, 5), + activation='relu', + input_shape=input_shape)) + model.add(MaxPooling2D(pool_size=(2, 2))) + model.add(Dropout(0.2)) + model.add(Conv2D(100, (5, 5), activation='relu')) + model.add(MaxPooling2D(pool_size=(2, 2))) + model.add(Dropout(0.2)) + model.add(Flatten()) + model.add(Dense(500, activation='relu')) + model.add(Dropout(0.5)) + model.add(Dense(10, activation='softmax')) + +### Dołączam kolejno warstwy: +- Conv2D - mnoży obrazek przez macierz 2x2 +- activation='relu' - zeruje negatywne wyniki (funkcja aktuwacji) +- MaxPooling2D - zmienia rozdzielczość zdjęcia +- Droupout - ogranicza nadmierne dopasowanie +- Flatten - spłaszcza macierz do wektora +- Dense(10) - decyduje o przynależności zdjęcia do kategorii (cyfry od 0 do 9) +Activation='soft-max' - zwraca rozkład prawdopodobieństwa 10 różnych klas + +## Kompilacja modelu: + model.compile(loss="categorical_crossentropy", optimizer="adam", metrics=["accuracy"]) +Funkcja straty - "catecorical_crossentropy" +Optymalizator - "Adam" +Monitorowanie dokładności - "accuracy" + +## Trenowanie modelu: + model.fit(X_train, Y_train, batch_size=200, epochs=10, validation_split=0.2, verbose=1) +trenuję model za pomocą funkcji fit() +### Pokazuję dokładność pracy na testowanych rannych + scores = model.evaluate(X_test, Y_test, verbose=0) + print("Dokadnosc na testowanych dannych: %.2f%%" % (scores[1]*100)) + +# Integracja z projektem +Tworzę model i ładuję wagi nauczonego modelu. + + nmodel = Sequential() + imageClass(nmodel) + nmodel.load_weights('model_weights.h5') + +Po podniesieniu paczki odpalana jest funkcja imgSkan(), która z czytuje ręcznie napisaną cyfrę i wpisuje nr producenta paczki. + + def imgSkan(): + img_width, img_height = 28, 28 + new_image = load_img('cyfra.png', target_size=(img_width, img_height), color_mode = "grayscale") + new_image = img_to_array(new_image) + new_image = new_image.reshape((1,) + new_image.shape) + + prediction = nmodel.predict(new_image) + prediction = numpy.argmax(prediction) + print("Producent:", prediction) + producent.append(prediction) + + + + diff --git a/sieci_n.py b/sieci_n.py old mode 100644 new mode 100755 index fd45034..412e6cc --- a/sieci_n.py +++ b/sieci_n.py @@ -1,14 +1,9 @@ -import numpy as np +import numpy from keras.datasets import mnist from keras.models import Sequential from keras.layers import Dense, Dropout, Flatten from keras.layers import Conv2D, MaxPooling2D from keras.utils import np_utils -from keras.preprocessing import image -from matplotlib import pyplot as plt -import matplotlib.pyplot as plt -# %matplotlib inline -from google.colab import files numpy.random.seed(42) @@ -52,4 +47,5 @@ model.fit(X_train, Y_train, batch_size=200, epochs=10, validation_split=0.2, ver scores = model.evaluate(X_test, Y_test, verbose=0) print("Dokadnosc na testowanych dannych: %.2f%%" % (scores[1]*100)) + model.save_weights('model_weights.h5') \ No newline at end of file diff --git a/srodowisko_agenta.png b/srodowisko_agenta.png old mode 100644 new mode 100755 diff --git a/warehouse.py b/warehouse.py old mode 100644 new mode 100755 index 1e50857..2bbb6a7 --- a/warehouse.py +++ b/warehouse.py @@ -242,6 +242,9 @@ class Warehouse: package_field = self.tiles[pack_x][pack_y] new_package = Pack(lays_on_field=package_field) new_package.size = new_package_size + new_package.id = i + new_package.x = pack_x + new_package.y = pack_y if package_field.category.name in self.storage_types: package_field.capacity -= new_package.size packages.append(new_package)