diff --git a/Network/Network.py b/Network/Network.py index 6e8952e..a5c08c5 100644 --- a/Network/Network.py +++ b/Network/Network.py @@ -1,49 +1,49 @@ import tensorflow as tf from keras import layers -from keras.models import Sequential -from keras.optimizers import Adam -from keras.utils import to_categorical -from keras.preprocessing.image import ImageDataGenerator - # Normalizes the pixel values of an image to the range [0, 1]. - +# Normalizes the pixel values of an image to the range [0, 1]. + + def normalize(image, label): return image / 255, label + + # Set the paths to the folder containing the training data train_data_dir = "Network/Training/" - # Set the number of classes and batch size +# Set the number of classes and batch size num_classes = 3 batch_size = 32 - # Set the image size and input shape +# Set the image size and input shape img_width, img_height = 100, 100 input_shape = (img_width, img_height, 1) - # Load the training and validation data +# Load the training and validation data train_ds = tf.keras.utils.image_dataset_from_directory( - train_data_dir, - validation_split=0.2, - subset="training", - shuffle=True, - seed=123, - image_size=(img_height, img_width), - batch_size=batch_size) + train_data_dir, + validation_split=0.2, + subset="training", + shuffle=True, + seed=123, + image_size=(img_height, img_width), + batch_size=batch_size) val_ds = tf.keras.utils.image_dataset_from_directory( - train_data_dir, - validation_split=0.2, - subset="validation", - shuffle=True, - seed=123, - image_size=(img_height, img_width), - batch_size=batch_size) - # Get the class names + train_data_dir, + validation_split=0.2, + subset="validation", + shuffle=True, + seed=123, + image_size=(img_height, img_width), + batch_size=batch_size) +# Get the class names class_names = train_ds.class_names print(class_names) - # Normalize the training and validation data +# Normalize the training and validation data train_ds = train_ds.map(normalize) val_ds = val_ds.map(normalize) - # Define the model architecture +# Define the model architecture model = tf.keras.Sequential([ - layers.Conv2D(16, 3, padding='same', activation='relu', input_shape=(img_height, img_width, 1)), + layers.Conv2D(16, 3, padding='same', activation='relu', + input_shape=(img_height, img_width, 1)), layers.MaxPooling2D(), layers.Conv2D(32, 3, padding='same', activation='relu'), layers.MaxPooling2D(), @@ -53,16 +53,17 @@ model = tf.keras.Sequential([ layers.Dense(128, activation='relu'), layers.Dense(num_classes, activation='softmax') ]) - # Compile the model +# Compile the model model.compile(optimizer='adam', - loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True), + loss=tf.keras.losses.SparseCategoricalCrossentropy( + from_logits=True), metrics=['accuracy']) - # Print the model summary +# Print the model summary model.summary() - # Train the model -epochs=10 +# Train the model +epochs = 10 model.fit(train_ds, validation_data=val_ds, epochs=epochs) - # Save the trained model -model.save('Network/trained_model.h5') \ No newline at end of file +# Save the trained model +model.save('Network/trained_model.h5') diff --git a/Network/Predictor.py b/Network/Predictor.py new file mode 100644 index 0000000..07e71aa --- /dev/null +++ b/Network/Predictor.py @@ -0,0 +1,46 @@ +import os +import random +from pathlib import Path +import numpy as np +import tensorflow as tf +from tensorflow import keras + + +class Predictor: + def __init__(self): + # Load the trained model + self.model = keras.models.load_model('Network/trained_model.h5') + + # Load the class names + self.class_names = ['table', 'done', 'order'] + + # Path to the folder containing test images + self.test_images_folder = 'Network/Testing/' + + def predict(self, image_path): + # Load and preprocess the test image + test_image = keras.preprocessing.image.load_img( + image_path, target_size=(100, 100)) + test_image = keras.preprocessing.image.img_to_array(test_image) + test_image = np.expand_dims(test_image, axis=0) + test_image = test_image / 255.0 # Normalize the image + + # Reshape the image array to (1, height, width, channels) + test_image = np.reshape(test_image, (1, 100, 100, 3)) + + # Make predictions + predictions = self.model.predict(test_image) + predicted_class_index = np.argmax(predictions[0]) + predicted_class = self.class_names[predicted_class_index] + + print(predicted_class) + return predicted_class + + def random_path_img(self) -> str: + folder_name = random.choice(os.listdir(self.test_images_folder)) + folder_path = os.path.join(self.test_images_folder, folder_name) + filename = "" + while not (filename.endswith('.jpg') or filename.endswith('.jpeg')): + filename = random.choice(os.listdir(folder_path)) + image_path = os.path.join(folder_path, filename) + return image_path diff --git a/Network/TesterRandom.py b/Network/TesterRandom.py index 4101038..97c6a89 100644 --- a/Network/TesterRandom.py +++ b/Network/TesterRandom.py @@ -1,4 +1,5 @@ import os +from pathlib import Path import numpy as np import tensorflow as tf from tensorflow import keras @@ -7,7 +8,7 @@ from tensorflow import keras model = keras.models.load_model('Network/trained_model.h5') # Load the class names -class_names = ['Table', 'Done','Order'] +class_names = ['table', 'done', 'order'] # Path to the folder containing test images test_images_folder = 'Network/Testing/' @@ -19,42 +20,45 @@ for folder_name in os.listdir(test_images_folder): folder_path = os.path.join(test_images_folder, folder_name) if os.path.isdir(folder_path): print('Testing images in folder:', folder_name) - + # True class based on folder name if folder_name == 'Empty': - true_class = 'Table' + true_class = 'table' elif folder_name == 'Food': - true_class = 'Done' + true_class = 'done' elif folder_name == 'People': - true_class = 'Order' - + true_class = 'order' + # Iterate over the files in the subfolder for filename in os.listdir(folder_path): if filename.endswith('.jpg') or filename.endswith('.jpeg'): - i+=1 + i += 1 # Load and preprocess the test image image_path = os.path.join(folder_path, filename) - test_image = keras.preprocessing.image.load_img(image_path, target_size=(100, 100)) + test_image = keras.preprocessing.image.load_img( + image_path, target_size=(100, 100)) test_image = keras.preprocessing.image.img_to_array(test_image) test_image = np.expand_dims(test_image, axis=0) test_image = test_image / 255.0 # Normalize the image - + # Reshape the image array to (1, height, width, channels) - test_image = np.reshape(test_image, (1,100, 100, 3)) - + test_image = np.reshape(test_image, (1, 100, 100, 3)) + # Make predictions predictions = model.predict(test_image) predicted_class_index = np.argmax(predictions[0]) predicted_class = class_names[predicted_class_index] - + direct = 'Network/Results/' - filename = str(i) + predicted_class + '.jpeg' + filename = str(i) + predicted_class + '.jpeg' test_image = np.reshape(test_image, (100, 100, 3)) - tf.keras.preprocessing.image.save_img(direct+filename, test_image) + Path(direct).mkdir(parents=True, exist_ok=True) + tf.keras.preprocessing.image.save_img( + direct+filename, test_image) if predicted_class != true_class: errorcount += 1 print('Image:', filename) print('True class:', true_class) print('Predicted class:', predicted_class) print() -print('Error count: ', errorcount) \ No newline at end of file +print('Error count: ', errorcount) diff --git a/Network/testerVal.py b/Network/testerVal.py index 7af6388..45140c2 100644 --- a/Network/testerVal.py +++ b/Network/testerVal.py @@ -1,4 +1,4 @@ -import os +from pathlib import Path import numpy as np import tensorflow as tf from tensorflow import keras @@ -7,7 +7,7 @@ from tensorflow import keras model = keras.models.load_model('Network/trained_model.h5') # Load the class names -class_names = ['Table', 'Done','Order'] +class_names = ['table', 'done', 'order'] # Load and preprocess the validation dataset data_dir = "Network/Training/" @@ -47,6 +47,7 @@ for i in range(60): direct = 'Network/Results/' filename = predicted_class + str(i) + '.jpeg' + Path(direct).mkdir(parents=True, exist_ok=True) tf.keras.preprocessing.image.save_img(direct+filename, val_images[i]) if predicted_class != true_class: errorcount += 1 @@ -54,4 +55,4 @@ for i in range(60): print('True class:', true_class) print('Predicted class:', predicted_class) print() -print('Error count: ', errorcount) \ No newline at end of file +print('Error count: ', errorcount) diff --git a/README.MD b/README.MD index b75c27a..47e99d4 100644 --- a/README.MD +++ b/README.MD @@ -49,6 +49,6 @@ --- -- [ ] **Sieci neuronowe: wymagania dot. czwartego przyrostu** - - [ ] Należy przygotować zbiór uczący zawierający co najmniej 1000 przykładów dla każdej klasy. - - [ ] Agent powinien wykorzystywać wyuczoną sieć w procesie podejmowania decyzji. +- [x] **Sieci neuronowe: wymagania dot. czwartego przyrostu** + - [x] Należy przygotować zbiór uczący zawierający co najmniej 1000 przykładów dla każdej klasy. + - [x] Agent powinien wykorzystywać wyuczoną sieć w procesie podejmowania decyzji. diff --git a/requirements.txt b/requirements.txt index 513e519..43deeb7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,6 @@ pygame==2.3.0 pandas scikit-learn -graphviz \ No newline at end of file +graphviz +tensorflow +pillow \ No newline at end of file diff --git a/src/obj/Table.py b/src/obj/Table.py index d9938a6..7fb85f3 100644 --- a/src/obj/Table.py +++ b/src/obj/Table.py @@ -1,5 +1,6 @@ import random from src.obj.Object import Object +from Network.Predictor import Predictor class Table(Object): @@ -8,6 +9,7 @@ class Table(Object): self.waiting_time = 0 self.cooking_time = 0 self.is_actual = False + self.p = Predictor() def isActual(self): return self.is_actual @@ -17,7 +19,7 @@ class Table(Object): return self.is_actual = True # here must be neural network choise - new_role = random.choice(["table", "order", "wait", "done"]) + new_role = self.p.predict(self.p.random_path_img()) self.change_role(new_role, current_time) if self.agent_role == "table":