# representation of the bins myAnn = ANN( (2, 20, 10, 10, NUM_BINS), activation_ids=(Activation_Type.IDENTITY, Activation_Type.SIGMOID, Activation_Type.SIGMOID, Activation_Type.SIGMOID, Activation_Type.SIGMOID)) RUNS_PER_IMAGE = 25 ALPHA = 0.05 rms_levels = [] percent_correct_levels = [] for j in range(24 * RUNS_PER_IMAGE): num_correct = 0 for i in range(len(train_inp)): myAnn.predict(train_inp[i]) myAnn.backpropagate(train_outp[i], ALPHA) for i in range(len(validate_inp)): result = myAnn.predict(validate_inp[i]) if np.argmax(validate_outp[i]) == np.argmax(result): num_correct += 1 percent_correct = num_correct / len(validate_inp) * 100 if j % RUNS_PER_IMAGE == 0: output = [] for i in range(len(train_inp)): output.append(myAnn.predict(train_inp[i])) st.draw_sample(image, train_inp, output, x_offset=int(100 * j / RUNS_PER_IMAGE) % 600, y_offset=100 + 100 * int( (100 * j / RUNS_PER_IMAGE) / 600))
class TrigTester: def __init__(self): """ creating an ANN for identifying the sin of an angle. Since we'll be taking in values in the range of -2π, +2π, and outputting values from -1, 1, we're using the identity activation function for our input and output layers, saving the sigmoid for the hidden layers. """ self.myANN = ANN(layer_sizes=(1,10,10,1), activation_ids=(Activation_Type.IDENTITY, Activation_Type.LEAKY_RELU, Activation_Type.LEAKY_RELU, Activation_Type.IDENTITY)) def generate_sin_data(self, N:int, noise:float=0 )-> np.ndarray: """ Generates a set of N number pairs: (ø,sinø), with a random bit of noise in the sin result. :param N: the number of pairs requested :param noise: a bit of random noise added to the output sine. Default is zero noise. :return: a N x 2 numpy array of theta and sin(theta) + random noise, if any. """ result = [] for i in range (N): x = random.random()*4*math.pi -2*math.pi y = math.sin(x)+noise*(random.random()-0.5) result.append((x,y)) return np.array(result) def run_training(self,train_data:np.ndarray): """ Trains the ANN with one cycle of the given data set. :param train_data: an N x 2 set of input, output values :return: None """ for i in range(train_data.shape[0]): self.myANN.predict(np.array(train_data[i][0])) expected = np.array((train_data[i][1],)) self.myANN.backpropagate(expected,alpha=0.0005) def perform_N_training_iterations(self,N:int,train_data:np.ndarray): """ Convenience function to perform N cycles of run_training() :param N: Number of passes through the training data :param train_data: an N x 2 set of input, output values :return: None """ for i in range(N): # print(f"Training cycle: {i}") self.run_training(train_data) def rate_performance(self, data_set_to_test:np.ndarray): """ does a prediction for the input of the given data and compares it to the given output data, calculating the RMSE (root mean squared error) :param data_set_to_test: an M x 2 set of input, output values :return: the RMSE for this data set, a float. Ideally, this will be zero. """ sum_squared_error = 0 for i in range(data_set_to_test.shape[0]): xx = data_set_to_test[i][0] yy = self.myANN.predict(np.array((xx))) sum_squared_error += math.pow(yy[0] - data_set_to_test[i][1], 2) rms = math.sqrt(sum_squared_error)/(len(data_set_to_test) - 1) return rms def get_predictions(self,input_data:np.ndarray)->List[float]: """ gets the list of predicted values from the ANN on the input portion of the given data :param input_data: a set of M x 2 input, output values (output is ignored). :return: a list of corresponding output values. """ output = np.zeros((input_data.shape[0])) for i in range(len(input_data)): output[i]=self.myANN.predict(input_data[i][0]) return output