Beispiel #1
0
        def setLocalTransformMatrix(self, m: np.matrix):
            '''
                Sets the local transform matrix of this bone.
            '''

            self.transformMatrix = np.matrix(m.copy())
            self.markGlobalTransformDirty()
Beispiel #2
0
def svd(m: np.matrix):
    """ Returns the SVD of a matrix.

    Parameters
    ----------
    m: np.matrix
        The matrix to decompose

    Returns
    -------
    np.matrix or None
        The first matrix of the decomposition. This is a 
        orthogonal matrix.
    np.matrix
        The matrix with the singular values in the diagonal.
    np.matrix
        The second matrix of the decomposition. This one is
        also a orthogonal matrix.
    """
    m = np.float64(m.copy())
    _, columns = m.shape
    svdMatrix = m @ m.T
    singValues, uMatrix = symmetricEig(svdMatrix)
    singValues, uMatrix = _sortEig(singValues, uMatrix)
    singValues = np.sqrt(np.abs(singValues))
    vMatrix = m.T @ uMatrix
    for i in range(vMatrix.shape[1]):
        vMatrix[i, :] = vMatrix[i, :] / np.linalg.norm(vMatrix[i, :])
    return uMatrix, singValues[:columns], vMatrix.T
Beispiel #3
0
def funm(dat: numpy.matrix, f) -> numpy.matrix:
    '''Dirty copycat for scipy.linalg.funm'''
    ret = dat.copy()
    for x in numpy.nditer(ret, op_flags=['readwrite']):
        x[...] = f(x)

    return ret
Beispiel #4
0
        def globalToLocalTransformMatrix(self, m: np.matrix) -> np.matrix:
            '''
                Converts the given global transform into a local transform in respect to this bone's parent.
                If this bone has no parent, the given global transform is returned.
            '''

            if self.parent is None:
                return m.copy()

            return m @ np.linalg.inv(self.parent.getGlobalTransformMatrix())
Beispiel #5
0
def matrix_pow(mat: np.matrix, n: int, mod: int):
    # nの2進数表記でビットが立っているところだけ処理すればいい
    mattmp = mat.copy()
    ret = np.matrix(np.eye(2, dtype='int32'))  # 単位元は対角行列
    while n > 0:
        if n & 1:  # ビットが立っているなら処理する
            ret *= mattmp
            ret %= mod
        mattmp = mattmp**2
        n >>= 1  # ビットを処理
    return ret
Beispiel #6
0
def get_next_rnn_matrix(rnn_matrix: np.matrix, distance_matrix: np.matrix,
                        solution_matrix: np.matrix) -> np.matrix:
    global epsilon
    matrix = rnn_matrix.copy()
    for i in range(matrix.shape[0]):
        for j in range(matrix.shape[1]):
            epsilon = (np.sum(solution_matrix[:, i]) +
                       np.sum(solution_matrix[:, j]) - 2)
            matrix[i, j] = matrix[i, j] - iter_step * (eta * epsilon) + (
                lamda * (distance_matrix[i, j] * np.exp(-current_iter / tau)))
    return matrix
Beispiel #7
0
def get_matrix_cost(matrix: np.matrix) -> np.matrix:
    cost_matrix = matrix.copy()
    minimal_column = matrix.min(1)[:np.newaxis]
    minimal_column[minimal_column == np.inf] = 0
    # Subtract minimal value of a row from matrix
    cost_matrix -= minimal_column
    minimal_row = cost_matrix.min(0)
    minimal_row[minimal_row == np.inf] = 0
    # Subtract minimal value of a column from matrix
    cost_matrix -= minimal_row
    return cost_matrix
def remove_rep_clusts(clusterCords: np.matrix) -> np.matrix:
    """
    Remove repeated clusters from a set of clusters.
    """
    removedCords = clusterCords.copy()
    repIndex = list()
    for i in range(removedCords.shape[0]):
        if (removedCords[i, :] in np.delete(removedCords, i, axis=0)):
            removedCords[i, :] = 0
            repIndex.append(i)
    removedCords = np.delete(removedCords, repIndex, axis=0)
    return removedCords
Beispiel #9
0
        def calcGlobalTransformMatrix(
                self, localTransformMatrix: np.matrix) -> np.matrix:
            '''
                Calculates the global transform matrix for the local transform given,
                without setting the stored global transform of this node.
            '''

            if self.parent is None:
                return localTransformMatrix.copy()

            return localTransformMatrix @ self.parent.getGlobalTransformMatrix(
            )
def getRandomSurferRanking(connectionMatrix: matrix, decimals=1, beta: float = 0.85, normZeros: bool = False) -> \
        Tuple[array, array, int, matrix]:
    m = connectionMatrix.copy()
    nodeCount: int = m.shape[0]
    leapProbability: float = divide(1 - beta, nodeCount)
    m = getStochasticMatrix(m, normZeros)
    r: matrix = matrix(repeat(divide(1, nodeCount), nodeCount)).transpose()
    rZero: array = asarray(r).reshape(-1)
    previousR: matrix = zeros(r.shape)
    totalIterations: int = 0
    while not allclose(previousR, r, rtol=1.e-3, atol=1.e-3):
        previousR = r
        r = (beta * m * r) + leapProbability
        totalIterations += 1
    nodeRanking = asarray(r.round(decimals).transpose()).reshape(-1)
    return nodeRanking, rZero, totalIterations, m
def get_matrix_cost(matrix: np.matrix, debug=False) -> tuple:
    matrix_mod = matrix.copy()
    minimal_column = matrix.min(1)[:np.newaxis]
    minimal_column[minimal_column == np.inf] = 0
    cost = np.sum(minimal_column)
    # Subtract minimal value of a row from matrix
    matrix_mod -= minimal_column
    minimal_row = matrix_mod.min(0)
    minimal_row[minimal_row == np.inf] = 0
    cost += np.sum(minimal_row)
    # Subtract minimal value of a column from matrix
    matrix_mod -= minimal_row
    if debug:
        print(f"Minimal column: {minimal_column}")
        print(f"Minimal column cost: {np.sum(minimal_column)}")
        print(f"Minimal row: {minimal_row}")
        print(f"Minimal row cost: {np.sum(minimal_row)}")
    return cost, matrix_mod
Beispiel #12
0
    def draw_pheromones(self,
                        pheromone_matrix: np.matrix,
                        cutoff: float = 0.01,
                        thickness: float = 1.0,
                        node_size: float = 1.0,
                        node_label: bool = False,
                        label: bool = True):
        matrix = pheromone_matrix.copy()
        for i, j in np.ndindex(matrix.shape):
            if matrix[i, j] < cutoff:
                matrix[i, j] = 0
        G = nx.from_numpy_matrix(matrix, create_using=nx.DiGraph())
        weight = nx.get_edge_attributes(G, 'weight')
        node_colors = ["lightblue" for _ in range(matrix.shape[0])]
        labels = {k: f"{v:.2f}" for k, v in weight.items()}
        if node_label:
            node_labels = None
            if label:
                node_labels = {
                    k: f"{np.diag(matrix)[k]:.2f}"
                    for k in range(matrix.shape[0])
                }
            nx.draw_networkx_labels(G, pos=self.graph_pos, labels=node_labels)

        if label:
            nx.draw_networkx_edge_labels(G,
                                         self.graph_pos,
                                         edge_labels=labels,
                                         label_pos=0.3)
        width = [(w['weight']) * thickness / np.max(matrix)
                 for u, v, w in G.edges(data=True)]
        nx.draw_networkx_nodes(
            G,
            pos=self.graph_pos,
            node_color=node_colors,
            node_size=[node_size * 300 * (1 + v) for v in np.diag(matrix)])
        nx.draw_networkx_edges(G,
                               self.graph_pos,
                               width=width,
                               alpha=0.3,
                               connectionstyle='arc3,rad=0.2',
                               arrowstyle="-|>",
                               arraowsize=thickness * 3)
Beispiel #13
0
def householderQR(m: np.matrix):
    """ Returns the matrices of the complete QR decomposition of the matrix.

    Parameters
    ----------
    m: np.matrix
        The matrix to decompose.

    Returns
    -------
    np.matrix:
        The matrix Q of the decomposition. This is an orthonormal matrix.
    np.matrix:
        The matrix R of the decomposition. This is an upper triangular
        matrix.

    Raises
    ------
    InvalidMatrixException
        If the matrix columns is bigger or equals than the number of rows.
    """
    m = np.float64(m.copy())
    rows, columns = m.shape
    if columns > rows:
        raise InvalidMatrixException('Invalid size.')
    rMatrix = np.copy(m)
    qMatrix = np.eye(rows)
    for i in range(columns - (rows == columns)):
        hMatrix = np.eye(rows)
        xVector = rMatrix[i:, i]
        auxVector = xVector / \
            (xVector[0] + np.copysign(np.linalg.norm(xVector), xVector[0]))
        auxVector[0] = 1
        hMatrix[i:, i:] = np.eye(xVector.shape[0])
        hMatrix[i:, i:] -= (2 / np.dot(auxVector, auxVector)) * \
            np.dot(auxVector[:, None], auxVector[None, :])
        qMatrix = qMatrix @ hMatrix
        rMatrix = hMatrix @ rMatrix
    return qMatrix, rMatrix
Beispiel #14
0
def gramSchmidtQR(m: np.matrix):
    """ Returns the matrices of the QR decomposition of the matrix.

    The columns of the matrix should have all its columns linearly independent.

    Parameters
    ----------
    m: np.matrix
        The matrix to decompose.

    Returns
    -------
    np.matrix:
        The matrix Q of the decomposition. This is an orthonormal matrix.    
    np.matrix:
        The matrix R of the decomposition. This is an upper triangular
        matrix.

    Raises
    ------
    InvalidMatrixException
        If the matrix columns is bigger or equals than the number of rows.
    """
    rows, columns = m.shape
    if columns > rows:
        raise InvalidMatrixException('Invalid size.')
    m = np.float64(m.copy())
    rMatrix = np.matlib.zeros((columns, columns))
    qMatrix = np.matlib.zeros((rows, columns))
    for i in range(columns):
        aux = m[:, i]
        for k in range(i):
            rMatrix[k, i] = qMatrix[:, k].T @ m[:, i]
            aux = aux - rMatrix[k, i] * qMatrix[:, k]
        rMatrix[i, i] = np.linalg.norm(aux)
        qMatrix[:, i] = aux / rMatrix[i, i]
    return qMatrix, rMatrix
Beispiel #15
0
def absorb_to_protein(absorb: numpy.matrix) -> numpy.matrix:
    f = _standart_curve()
    #FIXME: 调试中先不调用
    #ret = funm(absorb, f)
    ret = absorb.copy()
    return ret
Beispiel #16
0
class VectorNeuron(object):
    """
    The VectorNeuron class represents a single weight matrix and a corresponding
    transfer function.  

    An input to a VectorNeuron is first multiplied by the weight matrix.  The 
    result is then fed through a transfer function to produce the VectorNeuron's 
    output. 

    The output is either the containing neural network's final output or the input
    to another VectorNeuron.
    """

    __weight_matrix = None
    __weight_matrix_backup = None
    __bias_vector = None
    __delta_w_matrix = None
    __result = None
    __transfer_function = ""
    __mersenne_twister = None

    def __init__(self, left_num_neurons, right_num_neurons, transfer_function):
        """
        Initializes a vectorneuron with a weight matrix of size (left_num_neurons, right_num_neurons), 
        a bias vector of size (right_num_neurons, 1), and a transfer function transfer_function.
        """

        print '>>> Creating VectorNeuron: (%s, %s) %s' % \
        (left_num_neurons, right_num_neurons, transfer_function)

        self.__weight_matrix = Matrix(rand(right_num_neurons, left_num_neurons))
        self.__weight_matrix_backup = self.__weight_matrix.copy()
        self.__bias_vector = Matrix(rand(right_num_neurons, 1))
        self.__delta_w_matrix = Matrix(rand(right_num_neurons, left_num_neurons))
        self.__mersenne_twister = MersenneTwister()
        self.__mersenne_twister.seed(int(1000*time.time()))
        self.__transfer_function = transfer_function

    def neuron_compute(self, input_matrix):
        """Computes the vectorneuron output for input_matrix"""
        self.__result = self.__weight_matrix * input_matrix
        current_value = None
        transfer_function = self.__transfer_function
        row_dim = self.__weight_matrix.shape[0]
        input_col_dim = input_matrix.shape[1]

        for i in range(0,row_dim):
            for j in range(0, input_col_dim):
                current_value = self.__result[i, j]
                self.__result[i, j]= self.__bias_vector[i, 0] + current_value
                cmd = "self.%s(current_value)" % transfer_function
                self.__result[i, j] = eval(cmd)

    def compute_delta_w(self, m, lr):
        """Computes new delta_w matrix"""
        k = 0
        delta_w = None
        delta_w_row_dim = self.__delta_w_matrix.shape[0]
        delta_w_col_dim = self.__delta_w_matrix.shape[1]

        for i in range(0, delta_w_row_dim):
            for j in range(0,delta_w_col_dim):
                k = abs(self.__mersenne_twister.randint(0,math.pow(2,32)) % m)
                if k == 0:
                    delta_w = lr
                elif k == 1:
                    delta_w = -1.0 * lr
                else:
                    delta_w = 0.0
                self.__delta_w_matrix[i, j] = delta_w

    def compute_delta_w_annealing(self, n, m, lr):
        """Computes new delta_w matrix (annealing style)"""
        k = 0
        delta_w = None
        delta_w_row_dim = self.__delta_w_matrix.shape[0]

        for i in range(0,delta_w_row_dim):
            delta_w_matrix_col = self.__delta_w_matrix.shape[1]
            for j in range(0, delta_w_matrix_col):
                k = abs(self.__mersenne_twister.randint(0,math.pow(2,32)) % m)
                if k < n:
                    if k % 2 == 0:
                        if (k == 0):
                            delta_w = lr
                        else:
                            delta_w = lr / k
                    elif k % 2 == 1:
                        delta_w = -1.0 * lr / k
                    else:
                        delta_w = 0.0
                else:
                    delta_w = 0.0
                self.__delta_w_matrix[i, j]  = delta_w

    def logsig(self, x):
        """Returns logsig of a single variable x"""
        return 1.0/(1.0 + exp(-1.0 * x))

    def purelin(self, x):
        """Returns purelin of a single variable x"""
        return x

    def tansig(self, x):
        """Returns tansig of a single variable x"""
        return 2.0/exp(1.0 + exp(-2.0 * x), -1.0)

    def linsig(self, x):
        """Returns linsig of a single variable x"""
        if x <= 1.0 and x >= -1.0:
            return x
        if x > 1:
            return 1.0
        else:
            return -1.0

    def change_weights(self):
        """Changes weight_matrix by adding delta_w_matrix"""
        #print 'weight_matrix orig'
        #print self.__weight_matrix
        self.__weight_matrix = self.__weight_matrix + self.__delta_w_matrix
        #print 'weight matrix new'
        #print self.__weight_matrix

    def rollback_weights(self):
        """Reset weight_matrix to weight_matrix_backup"""
        #print 'resetting weights'
        self.__weight_matrix = self.__weight_matrix_backup.copy()

    def weight_matrix_backup(self):
        """Copies the current weight_matrix to weight_matrix_backup"""
        self.__weight_matrix_backup = self.__weight_matrix.copy()

    def get_bias(self):
        """Returns the vectorneuron's bias vector"""
        return self.__bias_vector

    def get_delta_w(self):
        """Return the computed delta_w matrix used to alter the weights"""
        return self.__delta_w_matrix

    def get_result(self):
        """Returns the output of vectorneuron's neuron_compute function"""
        return self.__result

    def get_weight_matrix(self):
        """Returns the vectorneuron's current weight_matrix"""
        return self.__weight_matrix

    def get_weight_matrix_backup(self):
        """Returns a backup of the vectorneuron's previous weight_matrix"""
        return self.__weight_matrix_backup

    def get_transfer_function(self):
        """Returns the vectorneuron's transfer function"""
        return self.__transfer_function

    def write_weight_to_file(self, filename):
        """Write the vectorneuron's weight_matrix to filename """
        savetxt(filename, self.__weight_matrix)
        return True

    def write_bias_to_file(self, filename):
        """Write the vectorneuron's biias vector to filename"""
        savetxt(filename, self.__bias_vector)
        return True
Beispiel #17
0
def simulate_adaptive_control(model: SIR,
                              initial_run: int,
                              total_time: int,
                              lockdown: np.matrix,
                              migrations: np.matrix,
                              R_m: Dict[str, float],
                              beta_v: Dict[str, float],
                              beta_m: Dict[str, float],
                              evaluation_period: int = 2 * weeks,
                              adjacency: Optional[np.matrix] = None) -> SIR:
    n = len(model)
    model.set_parameters(Rt0 = R_m)\
         .run(initial_run, lockdown)
    days_run = initial_run
    gantt = []
    last_category = dict()
    while days_run < total_time:
        Gs, Ys, Os, Rs = set(), set(), set(), set()
        categories = dict(enumerate([Gs, Ys, Os, Rs]))
        category_transitions = {}
        for (i, unit) in enumerate(model):
            latest_Rt = unit.Rt[-1]
            if latest_Rt < 1:
                Gs.add(i)
                beta_cat = 0
            else:
                if days_run < initial_run + evaluation_period:  # force first period to be lockdown
                    Rs.add(i)
                    beta_cat = 3
                else:
                    if latest_Rt < 1.5:
                        Ys.add(i)
                        beta_cat = 1
                    elif latest_Rt < 2:
                        Os.add(i)
                        beta_cat = 2
                    else:
                        Rs.add(i)
                        beta_cat = 3
            if unit.name not in last_category:
                last_category[unit.name] = beta_cat
            else:
                old_beta_cat = last_category[unit.name]
                if old_beta_cat != beta_cat:
                    if beta_cat < old_beta_cat and beta_cat != (
                            old_beta_cat - 1):  # force gradual release
                        beta_cat = old_beta_cat - 1
                        if i in categories[old_beta_cat]:
                            categories[old_beta_cat].remove(i)
                        categories[beta_cat].add(i)
                    category_transitions[unit.name] = beta_cat
                    last_category[unit.name] = beta_cat
            gantt.append([unit.name, days_run, beta_cat, max(0, latest_Rt)])

        for (unit_name, beta_cat) in category_transitions.items():
            unit = model[unit_name]
            new_beta = beta_v[unit.name] - (
                beta_cat * (beta_v[unit.name] - beta_m[unit.name]) / 3.0)
            unit.beta[-1] = new_beta
            unit.Rt0 = new_beta * unit.gamma

        phased_migration = migrations.copy()
        for (i, j) in product(range(n), range(n)):
            if i not in Gs or j not in Gs:
                phased_migration[i, j] = 0
        model.run(evaluation_period, phased_migration)
        days_run += evaluation_period

    model.gantt = gantt
    return model
Beispiel #18
0
    def dot_graph(self,
                  pheromones: np.matrix = None,
                  eps: float = 0.01,
                  render=False,
                  normalize_pheromone=True,
                  show_decision=True,
                  show_greedy_path=False):
        p_no_diag = pheromones.copy()
        for u in range(pheromones.shape[0]):
            p_no_diag[u, u] = 0
        norm = np.max(p_no_diag) if normalize_pheromone else 1
        dot = graphviz.Digraph(comment="representation of current world state",
                               engine="neato")
        dot.attr(overlap="scale")
        dot.attr(K="1")
        dot.attr(maxiter="20000")
        dot.attr(start="42")
        for i in range(self.adjacency.shape[0]):
            if pheromones[i, i] / norm < eps:
                dot.node(f"{i}", f"{i}")
            else:
                dot.node(f"{i}", f"{i}:{pheromones[i,i]/norm:.2f}")
        for (i, j), v in np.ndenumerate(self.adjacency):
            if v > 0:
                label = f"{v}"
                color = "black"
                if pheromones is not None:
                    color = f"gray{int(90 - 90 * pheromones[i,j] / norm)}"
                    if pheromones[i, j] <= eps * np.max(pheromones):
                        label = ""
                    else:
                        label = f"{pheromones[i,j] / norm:.2f}"
                dot.edge(f"{i}", f"{j}", label=label, color=color)

        for i in range(self.adjacency.shape[0]):
            state = []
            start = []
            goal = []
            for agent in self.agents:
                if not show_decision:
                    if agent.state == i:
                        state.append(agent.graph_str)
                if agent.start == i:
                    start.append(agent.graph_str)
                if agent.goal == i:
                    goal.append(agent.graph_str)
            if not show_decision:
                if len(state) > 0:
                    s = f"{';'.join(state)}"
                    dot.node(f"state{i}", label=s, color="blue", shape="box")
                    dot.edge(f"state{i}", f"{i}", color="blue")
            if len(start) > 0:
                s = f"start\n{';'.join(start)}"
                dot.node(f"start{i}", label=s, color="green", shape="box")
                dot.edge(f"start{i}", f"{i}", color="green")
            if len(goal) > 0:
                s = f"goal\n{';'.join(goal)}"
                dot.node(f"goal{i}", label=s, color="red", shape="box")
                dot.edge(f"goal{i}", f"{i}", color="red")

        if show_decision:
            for agent in self.agents:
                dot.node(agent.graph_str,
                         label=agent.graph_str,
                         color="blue",
                         shape="box")
                dot.edge(agent.graph_str, f"{agent.state}", color="blue")
                next = agent.transition_options()
                value_sum = np.sum([
                    agent.transition_value(agent.state, node, **agent.kwargs)
                    for node in next
                ])
                if value_sum == 0:
                    value_sum = 1
                for node in next:
                    value = agent.transition_value(agent.state, node, **
                                                   agent.kwargs) / value_sum
                    dot.edge(agent.graph_str,
                             f"{node}",
                             color="orange",
                             fontcolor="orange",
                             label=f"{value:.2f}")

        if show_greedy_path:
            for agent in self.agents:
                for i, node in enumerate(agent.greedy_path):
                    dot.edge(agent.graph_str,
                             f"{node}",
                             color="yellow",
                             label=f"{i}",
                             fontcolor="yellow")

        if render:
            dot.render(tempfile.mktemp('.gv'), view=True)
        return dot
Beispiel #19
0
def simulate_adaptive_control_MHA(model: SIR,
                                  initial_run: int,
                                  total_time: int,
                                  lockdown: np.matrix,
                                  migrations: np.matrix,
                                  R_m: Dict[str, float],
                                  beta_v: Dict[str, float],
                                  beta_m: Dict[str, float],
                                  evaluation_period=2 * weeks):
    """ simulates the version of adaptive control suggested by the Indian Ministry of Home Affairs, where the trigger is based on infection count doubling time """
    n = len(model)
    model.set_parameters(Rt0 = R_m)\
         .run(initial_run, lockdown)
    days_run = initial_run
    gantt = []
    last_category = dict()
    while days_run < total_time:
        Gs, Ys, Os, Rs = set(), set(), set(), set()
        categories = dict(enumerate([Gs, Ys, Os, Rs]))
        category_transitions = {}
        for (i, unit) in enumerate(model):
            latest_Rt = unit.Rt[-1]
            if days_run < initial_run + evaluation_period:  # force first period to MHA
                if unit.I[-4] != 0 and unit.I[-1] / unit.I[
                        -4] > 2:  # doubling time trigger
                    Rs.add(i)
                    beta_cat = 3
                else:
                    Gs.add(i)
                    beta_cat = 0
            else:
                if latest_Rt < 1:
                    Gs.add(i)
                    beta_cat = 0
                elif latest_Rt < 1.5:
                    Ys.add(i)
                    beta_cat = 1
                elif latest_Rt < 2:
                    Os.add(i)
                    beta_cat = 2
                else:
                    Rs.add(i)
                    beta_cat = 3
            if unit.name not in last_category:
                last_category[unit.name] = beta_cat
            else:
                old_beta_cat = last_category[unit.name]
                if old_beta_cat != beta_cat:
                    if beta_cat < old_beta_cat and beta_cat != (
                            old_beta_cat - 1):  # force gradual release
                        beta_cat = old_beta_cat - 1
                    if i in categories[old_beta_cat]:
                        categories[old_beta_cat].remove(i)
                    categories[beta_cat].add(i)
                    category_transitions[unit.name] = beta_cat
                    last_category[unit.name] = beta_cat
            gantt.append([unit.name, days_run, beta_cat, max(0, latest_Rt)])

        for (unit_name, beta_cat) in category_transitions.items():
            unit = model[unit_name]
            new_beta = beta_v[unit.name] - (
                beta_cat * (beta_v[unit.name] - beta_m[unit.name]) / 3.0)
            unit.beta[-1] = new_beta
            unit.Rt0 = new_beta * unit.gamma

        phased_migration = migrations.copy()
        for (i, j) in product(range(n), range(n)):
            if i not in Gs or j not in Gs:
                phased_migration[i, j] = 0
        model.run(evaluation_period, phased_migration)
        days_run += evaluation_period

    model.gantt = gantt
    return model
Beispiel #20
0
class VectorNeuron(object):
    """
    The VectorNeuron class represents a single weight matrix and a corresponding
    transfer function.  

    An input to a VectorNeuron is first multiplied by the weight matrix.  The 
    result is then fed through a transfer function to produce the VectorNeuron's 
    output. 

    The output is either the containing neural network's final output or the input
    to another VectorNeuron.
    """

    __weight_matrix = None
    __weight_matrix_backup = None
    __bias_vector = None
    __delta_w_matrix = None
    __result = None
    __transfer_function = ""
    __mersenne_twister = None

    def __init__(self, left_num_neurons, right_num_neurons, transfer_function):
        """
        Initializes a vectorneuron with a weight matrix of size (left_num_neurons, right_num_neurons), 
        a bias vector of size (right_num_neurons, 1), and a transfer function transfer_function.
        """

        print('>>> Creating VectorNeuron: (%s, %s) %s' %
              (left_num_neurons, right_num_neurons, transfer_function))

        self.__weight_matrix = Matrix(rand(right_num_neurons,
                                           left_num_neurons))
        self.__weight_matrix_backup = self.__weight_matrix.copy()
        self.__bias_vector = Matrix(rand(right_num_neurons, 1))
        self.__delta_w_matrix = Matrix(
            rand(right_num_neurons, left_num_neurons))
        self.__mersenne_twister = MersenneTwister()
        self.__mersenne_twister.seed(int(1000))
        self.__transfer_function = transfer_function

    def neuron_compute(self, input_matrix):
        """Computes the vectorneuron output for input_matrix"""
        self.__result = self.__weight_matrix * input_matrix
        current_value = None
        transfer_function = self.__transfer_function
        row_dim = self.__weight_matrix.shape[0]
        input_col_dim = input_matrix.shape[1]

        for i in range(0, row_dim):
            for j in range(0, input_col_dim):
                current_value = self.__result[i, j]
                self.__result[i, j] = self.__bias_vector[i, 0] + current_value
                cmd = "self.%s(current_value)" % transfer_function
                self.__result[i, j] = eval(cmd)

    def compute_delta_w(self, m, lr):
        """Computes new delta_w matrix"""
        k = 0
        delta_w = None
        delta_w_row_dim = self.__delta_w_matrix.shape[0]
        delta_w_col_dim = self.__delta_w_matrix.shape[1]

        for i in range(0, delta_w_row_dim):
            for j in range(0, delta_w_col_dim):
                k = abs(
                    self.__mersenne_twister.randint(0, math.pow(2, 32)) % m)
                if k == 0:
                    delta_w = lr
                elif k == 1:
                    delta_w = -1.0 * lr
                else:
                    delta_w = 0.0
                self.__delta_w_matrix[i, j] = delta_w

    def compute_delta_w_annealing(self, n, m, lr):
        """Computes new delta_w matrix (annealing style)"""
        k = 0
        delta_w = None
        delta_w_row_dim = self.__delta_w_matrix.shape[0]

        for i in range(0, delta_w_row_dim):
            delta_w_matrix_col = self.__delta_w_matrix.shape[1]
            for j in range(0, delta_w_matrix_col):
                k = abs(
                    self.__mersenne_twister.randint(0, math.pow(2, 32)) % m)
                if k < n:
                    if k % 2 == 0:
                        if (k == 0):
                            delta_w = lr
                        else:
                            delta_w = lr / k
                    elif k % 2 == 1:
                        delta_w = -1.0 * lr / k
                    else:
                        delta_w = 0.0
                else:
                    delta_w = 0.0
                self.__delta_w_matrix[i, j] = delta_w

    def logsig(self, x):
        """Returns logsig of a single variable x"""
        return 1.0 / (1.0 + exp(-1.0 * x))

    def purelin(self, x):
        """Returns purelin of a single variable x"""
        return x

    def tansig(self, x):
        """Returns tansig of a single variable x"""
        return 2.0 / exp(1.0 + exp(-2.0 * x), -1.0)

    def linsig(self, x):
        """Returns linsig of a single variable x"""
        if x <= 1.0 and x >= -1.0:
            return x
        if x > 1:
            return 1.0
        else:
            return -1.0

    def change_weights(self):
        """Changes weight_matrix by adding delta_w_matrix"""
        #print 'weight_matrix orig'
        #print self.__weight_matrix
        self.__weight_matrix = self.__weight_matrix + self.__delta_w_matrix
        #print 'weight matrix new'
        #print self.__weight_matrix

    def rollback_weights(self):
        """Reset weight_matrix to weight_matrix_backup"""
        #print 'resetting weights'
        self.__weight_matrix = self.__weight_matrix_backup.copy()

    def weight_matrix_backup(self):
        """Copies the current weight_matrix to weight_matrix_backup"""
        self.__weight_matrix_backup = self.__weight_matrix.copy()

    def get_bias(self):
        """Returns the vectorneuron's bias vector"""
        return self.__bias_vector

    def get_delta_w(self):
        """Return the computed delta_w matrix used to alter the weights"""
        return self.__delta_w_matrix

    def get_result(self):
        """Returns the output of vectorneuron's neuron_compute function"""
        return self.__result

    def get_weight_matrix(self):
        """Returns the vectorneuron's current weight_matrix"""
        return self.__weight_matrix

    def get_weight_matrix_backup(self):
        """Returns a backup of the vectorneuron's previous weight_matrix"""
        return self.__weight_matrix_backup

    def get_transfer_function(self):
        """Returns the vectorneuron's transfer function"""
        return self.__transfer_function

    def write_weight_to_file(self, filename):
        """Write the vectorneuron's weight_matrix to filename """
        savetxt(filename, self.__weight_matrix)
        return True

    def write_bias_to_file(self, filename):
        """Write the vectorneuron's biias vector to filename"""
        savetxt(filename, self.__bias_vector)
        return True