From 03d74b5aeee0e7b1495d604c054488df11688c87 Mon Sep 17 00:00:00 2001 From: s452730 <93314764+s452730@users.noreply.github.com> Date: Thu, 8 Sep 2022 02:03:01 +0200 Subject: [PATCH] dataset, neural network --- main.py | 14 +++++++++ neural.py | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++ trash.xlsx | Bin 13674 -> 14347 bytes 3 files changed, 99 insertions(+) create mode 100644 neural.py diff --git a/main.py b/main.py index 89be88e..d0c4593 100644 --- a/main.py +++ b/main.py @@ -1,12 +1,16 @@ # from collections import deque from queue import PriorityQueue +import matplotlib.pyplot as plt + +from neural import * from path_algorithms.a_star import a_star # from path_algorithms.bfs import bfs from rubbish import * from tree import evaluate_values, trash_selection from truck import Truck from surface import * +from PIL import Image from genetic import genetic RESOLUTION = 900 @@ -53,6 +57,9 @@ for i in range(15): rubbish_list.append(Rubbish(screen, j * 60, i * 60)) path = [] +X,y = create_training_data() +model = learn_neural_network(X,y) + gen = [(truck.y / 60, truck.x / 60)] fl = 0 length = [] @@ -118,6 +125,13 @@ while True: # the decision that takes what to do with the garbage if not path and order: + + number = np.random.randint(2077) + path_img = "images/bbb" + img = Image.open(path_img+'/'+str(number)+'.jpg') + img.show() + prediction = predict(model,path_img+'/'+str(number)+'.jpg') + result(prediction) data = rubbish_list[order[0]].data_for_decision_tree() print(f'----------\n' f'Characteristics of the garbage we met:\n' diff --git a/neural.py b/neural.py new file mode 100644 index 0000000..814d00d --- /dev/null +++ b/neural.py @@ -0,0 +1,85 @@ +import math +import os +import cv2 +import matplotlib.pyplot as plt +import numpy as np +from keras.layers import Conv2D, MaxPooling2D +from keras.layers import Dense, Activation, Flatten +from keras.models import Sequential +from tqdm import tqdm + +def create_training_data(): + DATADIR = "images" + CATEGORIES = ["plastic", "other"] + IMG_SIZE = 100 + training_data = [] + for category in CATEGORIES: + path = os.path.join(DATADIR, category) + class_num = CATEGORIES.index(category) # 0 - plastic, 1 - other + for img in tqdm(os.listdir(path)): + try: + img_array = cv2.imread(os.path.join(path, img), cv2.IMREAD_GRAYSCALE) + new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE)) + training_data.append([new_array, class_num]) + except Exception as e: + pass + + X = [] + y = [] + + for features, label in training_data: + X.append(features) + y.append(label) + + X = np.array(X).reshape(-1, IMG_SIZE, IMG_SIZE, 1) + y = np.array(y) + + print("Training data created!") + return X,y + +def learn_neural_network(X,y): + X = X/255.0 + + model = Sequential() + + model.add(Conv2D(64, (3, 3), input_shape=X.shape[1:])) + model.add(Activation('relu')) + model.add(MaxPooling2D(pool_size=(2, 2))) + + model.add(Conv2D(64, (3, 3))) + model.add(Activation('relu')) + model.add(MaxPooling2D(pool_size=(2, 2))) + + model.add(Flatten()) + + model.add(Dense(64)) + + model.add(Dense(1)) + model.add(Activation('sigmoid')) + + model.compile(loss='binary_crossentropy', + optimizer='adam', + metrics=['accuracy']) + + model.fit(X, y, batch_size=1, epochs=1, validation_batch_size=0.1) + + return model + +def prepare_img(filepath): + IMG_SIZE = 100 + img_array = cv2.imread(filepath, cv2.IMREAD_GRAYSCALE) + new_array = cv2.resize(img_array, (IMG_SIZE, IMG_SIZE)) + return new_array.reshape(-1, IMG_SIZE, IMG_SIZE, 1) / 255 + +def predict(model, filepath): + return model.predict([prepare_img(filepath)]) + +def result(prediction): + if prediction[0][0] >= 0.65: + print(prediction) + print(math.ceil(prediction[0][0])) + print('No plastic') + elif prediction[0][0] < 0.65: + print(prediction) + print(math.floor(prediction[0][0])) + print("Plastic") diff --git a/trash.xlsx b/trash.xlsx index c138e308097c1ee9aa44559491769e4e6d1366c9..b91e5afb31fdeb962f64b6dc9f5b882578b49293 100644 GIT binary patch delta 10428 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 delta 9716 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 yix5dLzsLID