def fit_stoch(X, y, alpha, w, epochs=500, epsilon=1.0e-5): """ Stochastic gradient descent :param X: :param y: :param alpha: :param w: :param epochs: :param epsilon: :return: """ global logs, logs_stoch logs = [] logs_stoch = [] random.seed(0) idx = list(range(len(X))) for epoch in range(epochs): random.shuffle(idx) for i in idx: y_hat = predict([X[i]], w)[0] loss = y[i] - y_hat gradient = vector.mul(loss, X[i]) w = vector.add(w, vector.mul(alpha, gradient)) logs_stoch += (w, alpha, sse(X, y, w)) if vector.norm(gradient) < epsilon: print('Gradient', vector.norm(gradient)) break logs += (w, alpha, sse(X, y, w)) print("Epoch", epoch) return w
def solve_collision(self, b1, b2): # Changes the direction of non-static moving bodies, and separates overlapping bodies def penetration(normal, movable_body, fixed_body): if normal.x < -0.0001: return abs(movable_body.rect.right() - fixed_body.rect.left()) elif normal.x > 0.0001: return abs(fixed_body.rect.right() - movable_body.rect.left()) if normal.y < -0.0001: return abs(fixed_body.rect.top() - movable_body.rect.bottom()) else: return abs(movable_body.rect.top() - fixed_body.rect.bottom()) if b1.is_static and not (b2.is_static): normal = self.calculate_normal(b2, b1) pen_distance = penetration(normal, b2, b1) b2.rect.position = vector.sum(b2.rect.position, vector.mul(normal, pen_distance)) b2.direction = vector.reflect(normal, b2.direction) return normal elif not (b1.is_static) and b2.is_static: normal = self.calculate_normal(b1, b2) pen_distance = penetration(normal, b1, b2) b1.rect.position = vector.sum(b1.rect.position, vector.mul(normal, pen_distance)) b1.direction = vector.reflect(normal, b1.direction) return normal elif not (b1.is_static) and not (b2.is_static): normal = self.calculate_normal(b1, b2) normal_inv = vector.minus(normal) pen_distance = penetration(normal, b1, b2) b1.rect.set_pos(vector.sum(b1.rect.position, vector.mul(normal, 0.5 * pen_distance))) b1.direction = vector.reflect(normal, b1.direction) b2.rect.position = vector.sum(b2.rect.position, vector.mul(normal_inv, 0.5 * pen_distance)) b2.direction = vector.reflect(normal_inv, b2.get_direction()) return normal
def stoch_descent(X, y, alpha, w): """ Stochastic gradient descent :param X: :param y: :param alpha: :param w: :return: """ global logs, logs_stoch logs = [] logs_stoch = [] random.seed(0) idx = list(range(len(X))) for epoch in range(1000): random.shuffle(idx) w_old = w for i in idx: loss = y[i] - vector.dot(X[i], w) gradient = vector.mul(loss, X[i]) w = vector.add(w, vector.mul(alpha, gradient)) logs_stoch += (w, alpha, sse(X, y, w)) if vector.norm(vector.sub(w, w_old)) / vector.norm(w) < 1.0e-5: break logs += (w, alpha, sse(X, y, w)) print("Epoch", epoch) return w
def __backward(self, dout): dbeta = dout.sum(axis=0) dgammax = dout dgamma = ve.sum(ve.mul(self.xhat, dgammax), axis=0) dxhat = dgammax * self.gamma divar = ve.sum(ve.mul(dxhat, self.xmu), axis=0) dxmu1 = dxhat * self.ivar dsqrtvar = divar * (1 / (self.sqrtvar**2)) * (-1) dvar = (1 / ve.sqrt(self.var + 10e-7)) * dsqrtvar * 0.5 dsq = ve.arange([ 1 for i in range(reduce(lambda x, y: x * y, dout.get_demension())) ]).reshape(dout.get_demension()) * (dvar / dout.get_demension()[1]) dxmu2 = ve.mul(self.xmu, dsq) * 2 dx1 = dxmu1 + dxmu2 dmu = ve.sum(dxmu1 + dxmu2, axis=0) * (-1) dx2 = ve.arange([ 1 for i in range(reduce(lambda x, y: x * y, dout.get_demension())) ]).reshape(dout.get_demension()) * (dmu / dout.get_demension()[1]) dx = dx1 + dx2 return dx
def train(self, training_input): wrong_predictions = 0 for input, label in zip([item[1:] for item in training_input], [item[0] for item in training_input]): prediction = self.predict(input) if prediction != label: wrong_predictions += 1 if label == 0 and prediction == 1: self.weights[1:] = vector.sub(self.weights[1:], vector.mul(self.learning_rate, input)) self.weights[0] -= self.learning_rate if label == 1 and prediction == 0: self.weights[1:] = vector.add(vector.mul(self.learning_rate, input), self.weights[1:]) self.weights[0] += self.learning_rate
def update(self, step_time): def change_dir_vel(entities, direction, velocity): for entity in entities: entity.body.direction = direction entity.body.set_velocity(velocity) if (self.moving_left or self.moving_right): if self.moving_left: change_dir_vel(self.paddles, Vector2(-1, 0), PADDLE_VELOCITY) if self.game_status == GameLayer.INITIALIZATION: change_dir_vel(self.balls, Vector2(-1, 0), PADDLE_VELOCITY) else: change_dir_vel(self.paddles, Vector2(1, 0), PADDLE_VELOCITY) if self.game_status == GameLayer.INITIALIZATION: change_dir_vel(self.balls, Vector2(1, 0), PADDLE_VELOCITY) else: change_dir_vel(self.paddles, ZERO2, magnitude(ZERO2)) if self.game_status == GameLayer.INITIALIZATION: change_dir_vel(self.balls, ZERO2, magnitude(ZERO2)) if self.push_balls and self.game_status == GameLayer.INITIALIZATION: for ball in self.balls: if ball.body.is_static: ball.body.is_static = False v = Vector2(BALL_VELOCITY_X, BALL_VELOCITY_Y) change_dir_vel(self.balls, normalize(v), magnitude(v)) self.push_balls = False self.game_status = GameLayer.GAME_LOOP # Remove bricks that have been destroyed free_brick_list = [] for brick in self.bricks: if brick.health_points == 0: self.unregister_entity(brick) free_brick_list.append(brick) self.bricks = [b for b in self.bricks if free_brick_list.count(b) == 0] for paddle in self.paddles: # Integrate paddle paddle.body.rect.position = sum( paddle.body.rect.position, mul(paddle.body.direction, paddle.body.velocity * step_time)) # Relocate paddle position to a valid position range paddle.body.rect.position.x = utils.clamp( paddle.body.rect.position.x, 0, WINDOW_WIDTH - PADDLE_WIDTH) paddle.body.rect.position.y = WINDOW_HEIGHT - PADDLE_HEIGHT - PADDLE_LINE_SPACING for ball in self.balls: if ball.body.is_static: pos_r = Vector2((PADDLE_WIDTH - BALL_WIDTH) * 0.5, -BALL_HEIGHT) ball.body.rect.position = sum( self.paddles[0].body.rect.position, pos_r)
def walls(self, width, height): """ Return all the walls which can be used for drawing the maze. """ maze_width, maze_height = len(self.grid[0]), len(self.grid) scalex, scaley = width / maze_width, height / maze_height scale = min(scalex, scaley) centerx = (width - scale * (maze_width - 1)) / 2 centery = (height - scale * (maze_height - 1)) / 2 center = (centerx, centery) walls = [] # Draw all the horizontal going walls. for y in range(maze_height): lines = ''.join(map(str, self.grid[y])).split(str(EMPTY)) offset = 0 for line in lines: if len(line) > 1: start = add(center, mul((offset, y), scale)) end = add(center, mul(((offset + len(line)-1), y), scale)) walls.append(Wall(start, end)) offset += len(line) + 1 else: offset += 2 # Draw all the vertical going walls. grid_transposed = [list(x) for x in zip(*self.grid)] for x in range(maze_width): lines = ''.join(map(str, grid_transposed[x])).split(str(EMPTY)) offset = 0 for line in lines: if len(line) > 1: start = add(center, mul((x, offset), scale)) end = add(center, mul((x, (offset + len(line)-1)), scale)) walls.append(Wall(start, end)) offset += len(line) + 1 else: offset += 2 return walls
def move(self, move, walls): angle_offset = 0 if move == MOVE_EAST or move == MOVE_WEST: angle_offset = 90 if move == MOVE_WEST else -90 elif move == MOVE_SOUTH: angle_offset = -180 move_vector = atov(self.angle + 30 + angle_offset) newpos = add(self.pos, mul(move_vector, Player.AMPLIFIER_MOVE)) if not intersect_segments(Line(self.pos, newpos), walls): self.pos = newpos for ray in self.rays: ray.update(newpos)
def update(self, step_time): def change_dir_vel(entities, direction, velocity): for entity in entities: entity.body.direction = direction entity.body.set_velocity(velocity) if(self.moving_left or self.moving_right): if self.moving_left: change_dir_vel(self.paddles, Vector2(-1,0), PADDLE_VELOCITY) if self.game_status == GameLayer.INITIALIZATION: change_dir_vel(self.balls, Vector2(-1,0), PADDLE_VELOCITY) else: change_dir_vel(self.paddles, Vector2(1,0), PADDLE_VELOCITY) if self.game_status == GameLayer.INITIALIZATION: change_dir_vel(self.balls, Vector2(1,0), PADDLE_VELOCITY) else: change_dir_vel(self.paddles, ZERO2, magnitude(ZERO2)) if self.game_status == GameLayer.INITIALIZATION: change_dir_vel(self.balls, ZERO2, magnitude(ZERO2)) if self.push_balls and self.game_status == GameLayer.INITIALIZATION: for ball in self.balls: if ball.body.is_static: ball.body.is_static = False v = Vector2(BALL_VELOCITY_X, BALL_VELOCITY_Y) change_dir_vel(self.balls, normalize(v), magnitude(v)) self.push_balls = False self.game_status = GameLayer.GAME_LOOP # Remove bricks that have been destroyed free_brick_list = [] for brick in self.bricks: if brick.health_points == 0: self.unregister_entity(brick) free_brick_list.append(brick) self.bricks = [ b for b in self.bricks if free_brick_list.count(b) == 0 ] for paddle in self.paddles: # Integrate paddle paddle.body.rect.position = sum(paddle.body.rect.position, mul(paddle.body.direction, paddle.body.velocity * step_time)) # Relocate paddle position to a valid position range paddle.body.rect.position.x = utils.clamp(paddle.body.rect.position.x, 0, WINDOW_WIDTH - PADDLE_WIDTH) paddle.body.rect.position.y = WINDOW_HEIGHT - PADDLE_HEIGHT - PADDLE_LINE_SPACING for ball in self.balls: if ball.body.is_static: pos_r = Vector2((PADDLE_WIDTH - BALL_WIDTH) * 0.5, - BALL_HEIGHT) ball.body.rect.position = sum(self.paddles[0].body.rect.position, pos_r)
def batch_descent(X, y, alpha, w): global logs logs = [] alpha /= len(X) for epoch in range(1, 1000): loss = vector.sub(y, vector.mul_mat_vec(X, w)) gradient = vector.mul_mat_vec(vector.transpose(X), loss) w_old = w w = vector.add(w, vector.mul(alpha, gradient)) logs += (w, alpha, sse(X, y, w)) if vector.norm(vector.sub(w, w_old)) / vector.norm(w) < 1.0e-5: break print("Epoch", epoch) return w
def batch_descent(X, y, alpha, w): """ Batch gradient descent :param X: :param y: :param alpha: :param w: :return: """ global logs logs = [] alpha /= len(X) for epoch in range(1, 1000): loss = vector.sub(y, vector.mul_mat_vec(X, w)) gradient = vector.mul_mat_vec(vector.transpose(X), loss) w_old = w w = vector.add(w, vector.mul(alpha, gradient)) logs += (w, alpha, sse(X, y, w)) if vector.norm(vector.sub(w, w_old)) / vector.norm(w) < 1.0e-5: break print("Epoch", epoch) return w
def fit_batch(X, y, alpha, w, epochs=500, epsilon=1.0e-5): """ Batch gradient descent :param X: :param y: :param alpha: :param w: :param epochs: :param epsilon: :return: """ global logs logs = [] alpha /= len(X) for epoch in range(epochs): y_hat = predict(X, w) loss = vector.sub(y, y_hat) gradient = vector.mul_mat_vec(vector.transpose(X), loss) w = vector.add(w, vector.mul(alpha, gradient)) logs += (w, alpha, sse(X, y, w)) if vector.norm(gradient) < epsilon: break print("Epoch", epoch) return w
def __init__(self, size): self.walls = generate(10, 10).walls(*size) self.player = Player(mul(size, 0.4), size[0])
def mul(P, Q): w1, v1 = P w2, v2 = Q return (w1*w2 - _v.dot(v1, v2),_v.sum(_v.mul(w1, v2), _v.mul(w2, v1), _v.cross(v1, v2)))
def draw(self, surface, color='black', width=1): towards = add(self.p1, mul(sub(self.p2, self.p1), Ray.AMPLIFIER_DRAW)) pygame.draw.line(surface, pygame.Color(color), self.p1, towards, width)
def integrate(self, elapsed_time): if not (self.is_static): self.rect.position = vector.sum( self.rect.position, vector.mul(self.direction, self.velocity * elapsed_time) )