This commit is contained in:
soybby 2020-06-15 00:36:53 +02:00
parent c8afe48b63
commit 47f6311d71
2 changed files with 508 additions and 0 deletions

30
final-evaluation.md Normal file
View File

@ -0,0 +1,30 @@
Waiter project - Tao-Sen Chang, Weronika Skowronska, Martyna Druminska
The main objective of our program is to help the customer with their
order, serve meals and pick up dirty plates. Since the program emulates
real life circumstances, where the waiter should work efficiently, we
used reinforcement learning to train the agent to arrive at the tables
as fast as possible by taking note of the tables coordinates. If the
plates happen to be empty, meaning that they probably have not ordered
yet, the program renders a couple questions to determine if the customer
would like a vegan menu or not. We used the decision tree learning
algorithm, to make the best recommendation to the customer. Every 10
plates visited, the program asks the user whether they would like to
exit the program or not. At beginning of our project, we use
reinforcement learning to get the shortest route for our agent to
traversal specific tables. Reinforcement learning is how software agent
ought to take actions in an environment in order to maximize the notion
of cumulative reward. The agent makes a sequence of decisions, and
learns to perform the best actions every step. After tons of training
loops, the agent could get the optimal strategy which might collect
maximal reward. In the case of our program, the “maximal reward”, would
be to find the minimum distance to the customer, which in turn would
save time and effort. Next, we used decision trees to make a prediction
on whether the person would like a vegan menu or not, based on the
“customers” appearance. The decision tree algorithm learns off of a
dataset with a diverse set of variables to make the best prediction. The
program generates a flow-like structure that represents the decisions,
where each node is a “test” on an attribute. The decision tree finishes
when there are only leaf nodes left. In conclusion, we managed to create
a program that runs efficiently and cohesively to satisfy the needs of
the customer.

478
waiter1406.py Normal file
View File

@ -0,0 +1,478 @@
#### MD #######
import pandas as pd
import pygame
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score
from sklearn.metrics import confusion_matrix
from pygame.locals import *
import numpy as np
import matplotlib.pyplot as plt
from sklearn import tree
import random
from textpygame import get_key, ask, display_box
###### /MD ######
import math
import pickle
########################
### WS ###
########################
# For CNN:
import keras
from keras.preprocessing import image
from keras.models import Sequential
from keras.layers import Convolution2D
from keras.layers import MaxPooling2D
from keras.layers import Flatten
from keras.layers import Dense
#initializing:
cnn_model = Sequential()
#Convolution:
cnn_model.add(Convolution2D(32, (3, 3), input_shape =(256, 256, 3), activation = "relu"))
#Pooling:
cnn_model.add(MaxPooling2D(pool_size = (2,2)))
# Adding a second convolutional layer
cnn_model.add(Convolution2D(32, 3, 3, activation = 'relu'))
cnn_model.add(MaxPooling2D(pool_size = (2, 2)))
#Flattening:
cnn_model.add(Flatten())
#Fully connected layers::
cnn_model.add(Dense(units = 128, activation = "relu"))
cnn_model.add(Dense(units = 3, activation = "softmax"))
# loading weigjts:
cnn_model.load_weights('s444523/best_model_weights2.h5')
#Making CNN:
cnn_model.compile(optimizer = "adam", loss = "categorical_crossentropy", metrics = ["accuracy"])
########################
### /WS ###
########################
#### MD#####
#read csv file
dataset= pd.read_csv("veganism.csv")
#create a new dataset
newdataset = pd.DataFrame(dataset, columns=['ethnicity', 'gender', 'appearence', 'vegan'])
# creating instance of labelencoder
labelencoder = LabelEncoder()
# Assigning numerical values and storing in another column
newdataset['ethnicity_no'] = labelencoder.fit_transform(newdataset['ethnicity'])
newdataset['gender_no']= labelencoder.fit_transform(newdataset['gender'])
newdataset['appearence_no']= labelencoder.fit_transform(newdataset['appearence'])
# for x values drop unimportant columns, axis=1 specifies that we want the columns not rows
Y=newdataset['vegan']
X=newdataset.drop(newdataset.columns[0:4], axis=1)
#test 14% of the data
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.15)
classifier = DecisionTreeClassifier()
classifier.fit(X_train, Y_train)
y_pred = classifier.predict(X_test)
fn=['ethnicity','gender','appearence']
cn=['yes', 'no']
# Setting dpi = 300 to make image clearer than default (for the decision tree visualisation)
fig, axes = plt.subplots(nrows = 1,ncols = 1,figsize = (4,4), dpi=300)
tree.plot_tree(classifier,
feature_names = fn,
class_names=cn,
filled = True);
fig.savefig('imagenamenew.png')
class Customer:
def __init__(self, coordinate_i, coordinate_j):
self.coordinate_i = coordinate_i
self.coordinate_j = coordinate_j
change_value(coordinate_i, coordinate_j,1 , 4)
class CustomerPlace:
def __init__(self, coordinate_i, coordinate_j):
self.coordinate_i = coordinate_i
self.coordinate_j = coordinate_j
change_value(coordinate_i, coordinate_j,1 , 5)
###### /MD #######
# Colors:
# Define some colors
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
BLUE = (0, 0, 240)
YELLOW = (255, 255, 0)
#Width and Height of each square:
WIDTH = 20
HEIGHT = 20
#Margin:
MARGIN = 5
grid = [[0 for x in range(16)] for y in range(16)]
def change_value(i, j, width, n):
for r in range (i, i+width):
for c in range (j, j+width):
grid[r][c] = n
class Table:
def __init__(self, coordinate_i, coordinate_j):
self.coordinate_i = coordinate_i
self.coordinate_j = coordinate_j
change_value(coordinate_i, coordinate_j, 2, 1)
def get_destination_coor(self):
return [self.coordinate_i+2, self.coordinate_j+2]
########################
### WS ###
########################
# The finction "state of meal" chooses a photo of a plate at the given table.
def state_of_meal(self):
## !!!!!!###
num = np.random.randint(67, 100)
## !!!!!!###
if num<=67:
img_name = 'plates/{}.png'.format(num)
else:
img_name = 'plates/{}.jpg'.format(num)
return img_name
# The function "change state" changes the value of the state variable.
# It informs, whether the client are waiting for the waiter to make an order
# (0 - empty plates) are eating (2 - full plates) or are waiting for the
# waiter to get a recipt (1 - dirty plates)
def change_state(self, st):
self.state = st
########################
### /WS ###
########################
class Kitchen:
def __init__(self, coordinate_i, coordinate_j):
self.coordinate_i = coordinate_i
self.coordinate_j = coordinate_j
change_value(coordinate_i, coordinate_j, 3, 2)
class Agent:
def __init__(self,orig_coordinate_i, orig_coordinate_j):
self.orig_coordinate_i = orig_coordinate_i
self.orig_coordinate_j = orig_coordinate_j
self.state = np.array([orig_coordinate_i,orig_coordinate_j])
change_value(orig_coordinate_j, orig_coordinate_j, 1, 3)
self.state_update(orig_coordinate_i, orig_coordinate_j)
def state_update(self, c1, c2):
self.state[0] = c1
self.state[1] = c2
def leave(self):
change_value(self.state[0], self.state[1], 1, 0)
def move_to(self, nextPos):
self.leave()
nextPos_x, nextPos_y = nextPos
self.state_update(nextPos_x, nextPos_y)
change_value(self.state[0], self.state[1], 1, 3)
########################
### WS ###
########################
#The function "define_table" serches for the apropriate table in the
# table_dict (to enable the usage of class attributes and methods)
def define_table(self, t_num):
t_num = 'table{}'.format(t_num)
t_num = table_dict[t_num]
return t_num
# The function "check_plates" uses the pretrained CNN model to classify
# the plate on the table as empty(0), full(2) or dirty(1)
def check_plates(self, table_number):
table = self.define_table(table_number)
plate = table.state_of_meal()
plate= image.load_img(plate, target_size = (256, 256))
plate = image.img_to_array(plate)
#plate = plate.reshape((256, 256))
plate = np.expand_dims(plate, axis = 0)
result = cnn_model.predict(plate)[0]
print(result)
if result[1] == 1:
result[1] = 0
x = int(input("Excuse me, have You done eating? 1=Yes, 2 = No \n"))
result[x] = 1
for i, x in enumerate(result):
if result[i] == 1:
table.change_state(i)
return i
########################
### /WS ###
########################
def check_done():
for event in pygame.event.get(): # Checking for the event
if event.type == pygame.QUIT: # If the program is closed:
return True # To exit the loop
def draw_grid():
for row in range(16): # Drawing the grid
for column in range(16):
color = WHITE
if grid[row][column] == 1:
color = GREEN
if grid[row][column] == 2:
color = RED
if grid[row][column] == 3:
color = BLUE
pygame.draw.rect(screen,
color,
[(MARGIN + WIDTH) * column + MARGIN,
(MARGIN + HEIGHT) * row + MARGIN,
WIDTH,
HEIGHT])
## default positions of the agent:
x = 12
y = 12
agent = Agent(x, y)
table1 = Table(2, 2)
table2 = Table (2,7)
table3 = Table(2, 12)
table4 = Table(7, 2)
table5 = Table(7, 7)
table6 = Table(7, 12)
table7 = Table(12, 2)
table8 = Table(12, 7)
################### WS #####################
# I added the dict to loop through tables.
table_dict = {"table1":table1, "table2":table2, "table3":table3,"table4":table4,
"table5":table5,"table6":table6,"table7":table7,"table8":table8
}
################### WS #####################
pygame.init()
####MD ####
'''
# create a font object.
# 1st parameter is the font file
# which is present in pygame.
# 2nd parameter is size of the font
font = pygame.font.Font('freesansbold.ttf', 14)
X = 400
Y = 400
# create a text suface object,
# on which text is drawn on it.
text = font.render('waiter: hello, let me help you with your order.', True, WHITE, BLACK)
userText=font.render('user: ', True, BLUE, BLACK)
# create a rectangular object for the
# text surface object
textRect = text.get_rect()
inputRect = userText.get_rect()
# set the center of the rectangular object.
textRect.center= (200, 340)
inputRect.center=(200,370)
'''
#### /MD ####
#class Kitchen:
kitchen = Kitchen(13, 13)
WINDOW_SIZE = [405, 405]
screen = pygame.display.set_mode(WINDOW_SIZE)
pygame.display.set_caption("Waiter_Grid3")
done = False
clock = pygame.time.Clock()
with open('res_targets_4-1.data', 'rb') as filehandle:
# read the data as binary data stream
trained_route = pickle.load(filehandle)
destination = (4, 14)
trained_route.append(destination)
table_targets = [(9, 4),(4, 4),(4, 9),(4, 14)]
destination_tables = []
###### MD /########3
x=[2,7,12]
y=[2,7]
random_customer_seat_x=random.choice(x)
random_customer_seat_y=random.choice(y)
print(random_customer_seat_x,random_customer_seat_y)
seat=Customer(random_customer_seat_x,random_customer_seat_y)
next_to=CustomerPlace(random_customer_seat_x,random_customer_seat_y-1)
WINDOW_SIZE = [405, 405]
screen = pygame.display.set_mode(WINDOW_SIZE)
pygame.display.set_caption("Waiter_Grid3")
done = False
print(random_customer_seat_x,random_customer_seat_y-1)
clock = pygame.time.Clock()
#updating the drawing
def updateDraw():
x = agent.state[0]
y = agent.state[1]
screen.fill(BLACK) # Background color
for row in range(16): # Drawing the grid
for column in range(16):
color = WHITE
if grid[row][column] == 1:
color = GREEN
if grid[row][column] == 2:
color = RED
if grid[row][column] == 3:
color = BLUE
if grid[row][column] == 4:
color = MAGENTA
surface = pygame.draw.rect(screen,
color,
[(MARGIN + WIDTH) * column + MARGIN,
(MARGIN + HEIGHT) * row + MARGIN,
WIDTH,
HEIGHT])
def customer():
screen.blit(text, textRect)
ethnicity3 = input("Excuse me, What's you're ethnicity? <black>, <asian>, <white>\n")
gender3= input("Excuse me, What's you're gender? <male>, <female>, <other> \n")
appearence3=input("Excuse me, What's you're appearance? <hippie>, <other> \n")
if (ethnicity3 =="black"):
ethnicity3 = 1
elif ethnicity3 == "asian":
ethnicity3 = 0
else:
ethnicity3 = 2
if gender3 == "male":
gender3 = 0
else:
gender3 = 1
if appearence3 == "hippie":
appearence3= 0
else:
appearence3 = 1
prediction = classifier.predict([[ethnicity3, gender3, appearence3]])
#pygame.quit()
if prediction == [0]:
print("You're probably not vegan. Would you like a regular menu?")
else:
print("It seems like you're vegan. Would you like a vegan menu?")
#exit()
###### /MD ###
# -------- Main Program Loop -----------
exit_counter = 0
while not done:
screen.fill(BLACK) # Background color
draw_grid()
done = check_done()
new_route = trained_route[:]
for value in table_dict.values():
destination_tables.append(value.get_destination_coor())
num_of_table = 1
while len(new_route) != 0:
# move to next grid
agent.move_to(new_route[0])
# update the grid
pygame.time.delay(150)
screen.fill(BLACK)
draw_grid()
# Drawing the grid
clock.tick(100) # Limit to 60 frames per second
pygame.display.flip() # Updating the screen
# get current grid coordinate
x = agent.state[0]
y = agent.state[1]
# if reached the table, ask to collect the plates
if [x, y] in destination_tables:
########################
### WS ###
########################
#pygame.time.delay(100)
print("I'm at a table no. {}".format(num_of_table))
## Checking at what state are the plates:
state_of_table = agent.check_plates(num_of_table)
num_of_table +=1
if state_of_table == 0:
customer()
# Early stopping (after 10 rounds)
exit_counter += 1
print("exit_counter", exit_counter)
if exit_counter == 10:
play_again = 1
play_again = int(input("Exit? 0=No, 1=Yes \n"))
if play_again:
pygame.quit()
else:
exit_counter = 0
########################
### /WS ###
########################
destination_tables = destination_tables[1:]
new_route = new_route[1:]
# After each fool loop, we can quit the program:.
pygame.quit()