From 7f20764a1d47ebfa871d2b66cfd006c8e23cff4e Mon Sep 17 00:00:00 2001 From: Timotej Lazar Date: Tue, 18 Jul 2017 17:07:49 +0200 Subject: Add project 2017/ev3-controller --- 2017/ev3-controller/data_processing.py | 60 ++++ 2017/ev3-controller/line_follower_Q.py | 80 +++++ 2017/ev3-controller/nn_11_function.py | 86 +++++ 2017/ev3-controller/nn_driver.py | 113 +++++++ 2017/ev3-controller/report.pdf | Bin 0 -> 320583 bytes 2017/ev3-controller/training_data.csv | 570 +++++++++++++++++++++++++++++++++ AUTHORS.md | 12 +- 7 files changed, 919 insertions(+), 2 deletions(-) create mode 100644 2017/ev3-controller/data_processing.py create mode 100644 2017/ev3-controller/line_follower_Q.py create mode 100644 2017/ev3-controller/nn_11_function.py create mode 100644 2017/ev3-controller/nn_driver.py create mode 100644 2017/ev3-controller/report.pdf create mode 100644 2017/ev3-controller/training_data.csv diff --git a/2017/ev3-controller/data_processing.py b/2017/ev3-controller/data_processing.py new file mode 100644 index 0000000..164c8bc --- /dev/null +++ b/2017/ev3-controller/data_processing.py @@ -0,0 +1,60 @@ +import csv +import numpy as np +import random +import collections +#580 +def process(length=5, SEED=1552, data='training_data.csv'): + + set=[] + output=[] + previous_set=[] + input=[] + inputs=[] + + #read the data from file + with open(data, 'r') as csvfile: + csv_reader = csv.reader(csvfile, delimiter=',') + i=0 + for row in csv_reader: + #create one-hot vector + vector=np.zeros((9,), dtype=np.int) + vector[int(row[0])]= vector[int(row[1])+3] = vector[int(row[2])+6] = 1; + + #concatenate the number of vectors defined in "length" + if (i < length): + previous_set.append(vector.tolist()) + else: + for pr in previous_set: + input=np.append(input, pr) + input = np.append(input, vector) + inputs.append(input) + input=[] + previous_set = previous_set[1:]+[vector.tolist()] + i = i + 1 + + + #randomize data + random.seed(SEED) + random.shuffle(inputs) + + #create inputs and outputs + for v in inputs: + set.append(v[:-6]) + output.append(v[-3:]) + + #set the size of training set + training=int(len(output)*0.9) + + #create training and test sets + training_set=set[:training] + training_output=output[:training] + test_set=set[training:] + test_output=output[training:] + return training_set, training_output, test_set, test_output + + +training_x, training_y, test_x, test_y = process() + + + + diff --git a/2017/ev3-controller/line_follower_Q.py b/2017/ev3-controller/line_follower_Q.py new file mode 100644 index 0000000..a1ea427 --- /dev/null +++ b/2017/ev3-controller/line_follower_Q.py @@ -0,0 +1,80 @@ +import numpy as np +from EV3Robot import * +import csv +gamma = 0.8 +alpha = 1. + +robot = Robot() +robot.connect_motor( 'left' ) +robot.connect_motor( 'right' ) +robot.connect_sensor( 'color' ) + +r = np.array([[1, -10, -1], + [-100, 10, -1], + [-100, -10, 100]]).astype("float32") + +#squre the difference + +q = np.random.rand(3,3) + +def update_q(state, next_state, action): + r_sa = r[state, action] #reward acc to state and action + q_sa = q[state, action] # q value acc to state and action + new_q = q_sa + alpha * (r_sa + gamma * max(q[next_state, :]) - q_sa) + q[state, action] = new_q + # renormalize row to be between 0 and 1 + rn = q[state][q[state] > 0] / np.sum(q[state][q[state] > 0]) + q[state][q[state] > 0] = rn + return r[state, action] + +def bgw(isee, follow_color=50, grey_zone=25): + if isee < follow_color - grey_zone: # BLACK + return 0 + elif isee > follow_color + grey_zone: # WHITE + return 1 + else: # move forward if in the grey zone + return 2 + +def get_state(): + isee = robot.color_sensor_measure('reflected_light_intensity') + color = bgw(isee) + return color + +def do_action(action, speed): + if action == 0: + robot.move(0,speed) + elif action == 1: + robot.move(speed, 0) + elif action == 2: + robot.move(speed, speed) + + +def run(speed): + data_file = open('training_data.csv', 'wb') + while(1): + #check the state + state_1 = get_state() + #action taken according to maximum value of q table in color column + action = np.argmax(q,axis=0)[state_1] + # do the action + do_action(action, speed) + state_2 = get_state() + update_q(state_1, state_2, action) + + action2 = np.argmax(q,axis=0)[state_2] + do_action(action2,speed) + state_3 = get_state() + update_q(state_2, state_3, action2) + + collect_data(data_file, state_1, state_2, action2) + + +def collect_data(data_file, prev_state, current_state, action): + writer = csv.writer(data_file, delimiter=',') + writer.writerow([prev_state, current_state, action]) + + + +run(15) + + diff --git a/2017/ev3-controller/nn_11_function.py b/2017/ev3-controller/nn_11_function.py new file mode 100644 index 0000000..677db1b --- /dev/null +++ b/2017/ev3-controller/nn_11_function.py @@ -0,0 +1,86 @@ +import numpy as np +from data_processing import process + +#get the data +training_x, training_y, test_x, test_y = process() +X=np.array(training_x) +y=np.array(training_y) + + +#sigmoid function +def nonlin(x, deriv=False): + if (deriv == True): + return x * (1 - x) + return 1 / (1 + np.exp(-x)) + +#print(X) +#print(y) + +def train(X=X,y=y, descent_rate=0.01, hl1=2): + np.random.seed(1) + + # randomly initialize our weights with mean 0 + syn0 = 2 * np.random.random((len(X[1]), hl1)) - 1 + syn1 = 2 * np.random.random((hl1, len(y[1]))) - 1 + + for j in range(5000): + + # Feed forward through layers 0, 1, and 2 + l0 = X + l1 = nonlin(np.dot(l0, syn0)) + l2 = nonlin(np.dot(l1, syn1)) + + #print(l2) + + # calculate the error in from the target value + l2_error = y - l2 + + if (j % 100) == 0: + print ( "Error:" + str(np.mean(np.abs(l2_error)))) + + # calculate the desired change in weights - bigger if our confidence is higher, use descent rate to control convergence + l2_delta = l2_error * nonlin(l2, deriv=True)*descent_rate + + # how much did each l1 value contribute to the l2 error (according to the weights)? + l1_error = l2_delta.dot(syn1.T) + + # calculate the desired change in weights - bigger if our confidence is higher, use descent rate to control convergence. + l1_delta = l1_error * nonlin(l1, deriv=True)*descent_rate + + #update the weights + syn1 += l1.T.dot(l2_delta) + syn0 += l0.T.dot(l1_delta) + + + return syn0, syn1 + + +def calculate_output(syn0, syn1, l0): + l1 = nonlin(np.dot(l0, syn0)) + l2 = nonlin(np.dot(l1, syn1)) + return l2 + + +#test neural network +l0=test_x +#print(l0) + +#train the neural network +syn0, syn1=train(X, y) +print(syn0) +print(syn1) + +#get the output values based on the trained network +l2 = calculate_output(syn0, syn1, l0) + +#check correctness of nn +correct = np.equal(np.argmax(test_y, 1), np.argmax(l2, 1)) +print(correct) + +accuracy = np.mean(correct.astype(float)) +print(accuracy) + +#Print inputs and predicted outputs +#for i in range(len(l0)): + #print(l0[i]) + #print(l2[i]) \ No newline at end of file diff --git a/2017/ev3-controller/nn_driver.py b/2017/ev3-controller/nn_driver.py new file mode 100644 index 0000000..b03c125 --- /dev/null +++ b/2017/ev3-controller/nn_driver.py @@ -0,0 +1,113 @@ +import numpy as np +from EV3Robot import * + +robot = Robot() +robot.connect_motor( 'left' ) +robot.connect_motor( 'right' ) +robot.connect_sensor( 'color' ) + +#syn0, syn1=train() + +#syn0 = [[-0.05111396, -0.65152816], + #[-0.60031302, -0.42462132], + #[-0.61138226, -0.94931736], + #[-0.54869344, -1.05984886], + #[ 0.01826786, 0.24129794], + #[ 0.14427619, -0.29771331], + #[-0.74305135, 0.076575 ], + #[-0.08188871, -0.31810276], + #[-0.26736444, 0.20061916], + #[-1.58011504, -1.44969247], + #[-0.47182455, 2.43261639], + #[ 2.17045716, -1.52101072]], + +#syn1 = [[ -3.47021005, -61.89030242, 12.78322924], + #[ -2.8108547, 22.64381972, -65.90059129]] + +syn0 = [[-0.22387899, 0.0272135 ], + [-0.53776054, -0.36374634], + [-0.61603734, -0.48518088], + [-0.57052126, -0.56987098], + [ 0.2442093, 0.23051107], + [-0.17470505, 0.42684878], + [-0.53413718, 0.49524244], + [-0.49455046, 0.49381262], + [-0.17848447, 0.17378944], + [-0.84917023, -1.20753232], + [ 2.3610183, 0.48650416], + [-1.5081981, 1.38669447]] + +syn1 = [[ -1.50414787, 17.11258305, -19.87962655], + [ -1.63558919, -16.87799893, 3.60433587]] + +print("get train data",syn0) +print(syn1) + + +def nonlin(x, deriv=False): + if (deriv == True): + return x * (1 - x) + + return 1 / (1 + np.exp(-x)) + +def calculate_output(syn0, syn1, l0): + l1 = nonlin(np.dot(l0, syn0)) + l2 = nonlin(np.dot(l1, syn1)) + return l2 + +def run1(speed): + previous = [] + + while(1): + #check the state + state_1 = get_state() + #action taken according to maximum value of q table in color column + if(previous==[]): + action=1 + + #get action from + # action = np.argmax(q,axis=0)[state_1] + else: + vector=toBinary(previous) + current=[0,0,0] + current[int(state_1)]=1 + input=np.append(vector, current) + + l2 = calculate_output(syn0, syn1, [input]) + + + action=np.argmax(l2) + # do the action + do_action(action, speed) + + state_2=get_state() + previous=[state_1, state_2, action] + +def toBinary(set): + vector = np.zeros((9,), dtype=np.int) + vector[int(set[0])] = vector[int(set[1]) + 3] = vector[int(set[2]) + 6] = 1; + return vector + + +def bgw(isee, follow_color=50, grey_zone=25): + if isee < follow_color - grey_zone: # BLACK + return 0 + elif isee > follow_color + grey_zone: # WHITE + return 1 + else: # move forward if in the grey zone + return 2 + +def get_state(): + isee = robot.color_sensor_measure('reflected_light_intensity') + color = bgw(isee) + return color + +def do_action(action, speed): + if action == 0: + robot.move(0,speed) #left + elif action == 1: + robot.move(speed, 0) #right + elif action == 2: + robot.move(speed, speed) #forward + +run1(40) \ No newline at end of file diff --git a/2017/ev3-controller/report.pdf b/2017/ev3-controller/report.pdf new file mode 100644 index 0000000..0d8703b Binary files /dev/null and b/2017/ev3-controller/report.pdf differ diff --git a/2017/ev3-controller/training_data.csv b/2017/ev3-controller/training_data.csv new file mode 100644 index 0000000..5e6f5af --- /dev/null +++ b/2017/ev3-controller/training_data.csv @@ -0,0 +1,570 @@ +2,2,2 +2,2,2 +2,2,2 +2,2,2 +2,2,2 +2,2,2 +1,1,1 +1,1,1 +1,1,1 +2,2,2 +2,0,0 +0,2,2 +2,2,2 +1,1,1 +1,1,1 +2,2,2 +2,2,2 +2,1,1 +1,1,1 +1,1,1 +2,2,2 +2,2,2 +1,1,1 +1,1,1 +2,2,2 +2,2,2 +2,2,2 +2,2,2 +0,0,0 +0,0,0 +2,2,2 +2,2,2 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +2,2,2 +1,2,2 +2,2,2 +2,0,0 +0,0,0 +2,2,2 +1,1,1 +2,2,2 +0,0,0 +0,0,0 +2,2,2 +2,2,2 +2,2,2 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +2,2,2 +2,2,2 +2,2,2 +1,1,1 +1,1,1 +1,2,2 +2,2,2 +1,1,1 +1,1,1 +1,1,1 +2,2,2 +2,2,2 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +2,2,2 +2,2,2 +2,2,2 +1,1,1 +1,1,1 +1,1,1 +1,2,2 +2,2,2 +2,1,1 +1,1,1 +1,1,1 +1,1,1 +2,2,2 +2,1,1 +1,1,1 +1,1,1 +1,1,1 +2,2,2 +2,2,2 +2,2,2 +2,2,2 +1,1,1 +2,2,2 +0,0,0 +0,2,2 +2,2,2 +2,2,2 +2,2,2 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +2,2,2 +2,0,0 +0,0,0 +1,1,1 +2,0,0 +0,2,2 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +2,2,2 +0,0,0 +2,2,2 +1,1,1 +1,1,1 +1,2,2 +2,2,2 +0,0,0 +2,2,2 +2,2,2 +1,1,1 +2,2,2 +2,2,2 +0,0,0 +0,0,0 +2,2,2 +2,2,2 +0,0,0 +0,0,0 +0,0,0 +0,2,2 +2,2,2 +2,2,2 +0,0,0 +2,2,2 +2,2,2 +2,2,2 +2,2,2 +2,2,2 +2,2,2 +2,1,1 +2,2,2 +2,2,2 +2,2,2 +2,2,2 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,2,2 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +2,2,2 +2,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +2,2,2 +0,0,0 +0,0,0 +0,0,0 +2,1,1 +1,1,1 +1,1,1 +1,1,1 +1,2,2 +2,0,0 +0,0,0 +0,0,0 +0,0,0 +2,1,1 +1,1,1 +1,1,1 +1,1,1 +2,2,2 +0,0,0 +0,0,0 +0,0,0 +2,2,2 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +2,0,0 +0,0,0 +0,0,0 +0,2,2 +2,2,2 +2,2,2 +2,2,2 +2,2,2 +2,2,2 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +2,2,2 +0,0,0 +0,0,0 +2,2,2 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,2,2 +2,2,2 +1,1,1 +1,1,1 +1,1,1 +2,1,1 +1,1,1 +1,2,2 +0,0,0 +0,0,0 +0,0,0 +2,2,2 +1,1,1 +2,2,2 +0,0,0 +0,2,2 +2,2,2 +1,1,1 +2,2,2 +2,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +2,2,2 +0,0,0 +0,2,2 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,2,2 +2,0,0 +0,0,0 +0,0,0 +2,2,2 +1,1,1 +1,2,2 +2,0,0 +0,0,0 +2,2,2 +1,1,1 +1,1,1 +0,0,0 +0,0,0 +2,2,2 +2,2,2 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,2,2 +0,0,0 +0,2,2 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,2,2 +0,0,0 +2,2,2 +2,0,0 +1,1,1 +1,1,1 +1,1,1 +0,0,0 +0,2,2 +1,1,1 +1,1,1 +1,1,1 +1,2,2 +0,0,0 +0,0,0 +2,1,1 +1,1,1 +0,0,0 +0,0,0 +0,0,0 +2,2,2 +2,2,2 +2,2,2 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +2,2,2 +1,1,1 +1,1,1 +2,2,2 +0,0,0 +2,2,2 +1,1,1 +1,1,1 +2,2,2 +2,2,2 +2,1,1 +1,1,1 +1,1,1 +2,2,2 +2,2,2 +1,1,1 +1,1,1 +1,1,1 +2,2,2 +2,2,2 +1,1,1 +1,1,1 +2,2,2 +2,2,2 +2,2,2 +2,2,2 +2,2,2 +2,2,2 +0,0,0 +0,0,0 +2,2,2 +2,2,2 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +2,2,2 +2,2,2 +2,2,2 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +2,2,2 +2,2,2 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +0,0,0 +2,2,2 +2,0,0 +0,0,0 +0,0,0 +2,2,2 +1,1,1 +1,2,2 +2,2,2 +2,1,1 +1,1,1 +1,1,1 +1,1,1 +2,2,2 +1,1,1 +1,1,1 +1,1,1 +1,2,2 +0,0,0 +0,0,0 +2,2,2 +1,1,1 +2,2,2 +2,2,2 +2,2,2 +2,2,2 +1,1,1 +1,1,1 +1,2,2 +2,2,2 +2,1,1 +1,1,1 +1,1,1 +1,1,1 +2,2,2 +2,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,2,2 +2,2,2 +1,1,1 +1,1,1 +1,1,1 +2,2,2 +2,2,2 +2,2,2 +0,0,0 +0,0,0 +2,2,2 +2,2,2 +2,0,0 +0,0,0 +0,2,2 +2,2,2 +2,0,0 +0,0,0 +2,2,2 +2,2,2 +2,2,2 +2,2,2 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,2,2 +2,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 +1,1,1 diff --git a/AUTHORS.md b/AUTHORS.md index 3ed07bd..8737095 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -1,5 +1,13 @@ ## 2017 -# Disprove the existence of free will +# free-will -Project by Tilen Matkovič. Original repository is located at . +Title: Disprove the existence of free will +Author: Tilen Matkovič + +Original repository is located at . + +# ev3-controller + +Title: EV3 robot controller with Q-learning and neural network +Authors: Amra Omanović, Nejka Bolčič, Magda Nowak-Trzos -- cgit v1.2.1