Perception Rule

ωi=ωi+Δωi\omega_{i} = \omega_{i} + \Delta\omega_{i}

Δωi=η(yy^)xi\Delta\omega_{i} = \eta(y-\hat{y})x_{i}

y^=(iωixi0)\hat{y} = (\displaystyle\sum_{i}\omega_{i}x_{i}\ge0)

y : target y^\hat{y}:output η\eta: learning rate x : inuput

Gradient descent

a=iXiωia=\displaystyle\sum_{i}X_{i}\omega_{i}

y^={a0}\hat{y} = \{a\ge0\}

E(ω)=12(x,y)D(ya)2E(\omega) = \frac{1}{2}\displaystyle\sum_{(x,y)\in{D}}(y-a)^2

Eωi=(x,y)D(ya)(xi)\frac{\partial{E}}{\partial\omega_{i}}=\displaystyle\sum_{(x,y)\in{D}}(y-a)(-x_{i})

perception: guarantee finite convergence, must have linear separability

gradient descent: calculus, robusut, converge local optimum

Sigmoid

σ(a)=11+ea\sigma(a)=\frac{1}{1+e^{-a}}

Dσ(a)=σ(a)(1σ(a))D\sigma(a)=\sigma(a)(1-\sigma(a))

Back progagation

many local optima!!!

Preference bias

# ----------
#
# In this exercise, you will update the perceptron class so that it can update
# its weights.
#
# Finish writing the update() method so that it updates the weights according
# to the perceptron update rule. Updates should be performed online, revising
# the weights after each data point.
# 
# ----------

import numpy as np


class Perceptron:
    """
    This class models an artificial neuron with step activation function.
    """

    def __init__(self, weights = np.array([1]), threshold = 0):
        """
        Initialize weights and threshold based on input arguments. Note that no
        type-checking is being performed here for simplicity.
        """
        self.weights = weights.astype(float) 
        self.threshold = threshold


    def activate(self, values):
        """
        Takes in @param values, a list of numbers equal to length of weights.
        @return the output of a threshold perceptron with given inputs based on
        perceptron weights and threshold.
        """

        # First calculate the strength with which the perceptron fires
        strength = np.dot(values,self.weights)

        # Then return 0 or 1 depending on strength compared to threshold  
        return int(strength > self.threshold)


    def update(self, values, train, eta=.1):
        """
        Takes in a 2D array @param values consisting of a LIST of inputs and a
        1D array @param train, consisting of a corresponding list of expected
        outputs. Updates internal weights according to the perceptron training
        rule using these values and an optional learning rate, @param eta.
        """

        # YOUR CODE HERE

        # TODO: for each data point...

            # TODO: obtain the neuron's prediction for that point

            # TODO: update self.weights based on prediction accuracy, learning
            # rate and input value
        index = 0
        for value in values:
            y_hat = self.activate(value)
            delta_weight = eta * (train[index] - y_hat) * value
            self.weights = self.weights + delta_weight
            index += 1

def test():
    """
    A few tests to make sure that the perceptron class performs as expected.
    Nothing should show up in the output if all the assertions pass.
    """
    def sum_almost_equal(array1, array2, tol = 1e-6):
        return sum(abs(array1 - array2)) < tol

    p1 = Perceptron(np.array([1,1,1]),0)
    p1.update(np.array([[2,0,-3]]), np.array([1]))
    assert sum_almost_equal(p1.weights, np.array([1.2, 1, 0.7]))

    p2 = Perceptron(np.array([1,2,3]),0)
    p2.update(np.array([[3,2,1],[4,0,-1]]),np.array([0,0]))
    assert sum_almost_equal(p2.weights, np.array([0.7, 1.8, 2.9]))

    p3 = Perceptron(np.array([3,0,2]),0)
    p3.update(np.array([[2,-2,4],[-1,-3,2],[0,2,1]]),np.array([0,1,0]))
    assert sum_almost_equal(p3.weights, np.array([2.7, -0.3, 1.7]))

if __name__ == "__main__":
    test()

Xor gate

# ----------
#
# In this exercise, you will create a network of perceptrons that can represent
# the XOR function, using a network structure like those shown in the previous
# quizzes.
#
# You will need to do two things:
# First, create a network of perceptrons with the correct weights
# Second, define a procedure EvalNetwork() which takes in a list of inputs and
# outputs the value of this network.
#
# ----------

import numpy as np


class Perceptron:
    """
    This class models an artificial neuron with step activation function.
    """

    def __init__(self, weights=np.array([1]), threshold=0):
        """
        Initialize weights and threshold based on input arguments. Note that no
        type-checking is being performed here for simplicity.
        """
        self.weights = weights
        self.threshold = threshold

    def activate(self, values):
        """
        Takes in @param values, a list of numbers equal to length of weights.
        @return the output of a threshold perceptron with given inputs based on
        perceptron weights and threshold.
        """

        # First calculate the strength with which the perceptron fires
        strength = np.dot(values, self.weights)

        # Then return 0 or 1 depending on strength compared to threshold
        return int(strength > self.threshold)

# Part 1: Set up the perceptron network
perceptron_input_1 = Perceptron(weights=np.array([1, 0])) # input1
perceptron_input_2 = Perceptron(weights=np.array([1, 1]), threshold=1.5) # and gate
perceptron_input_3 = Perceptron(weights=np.array([0,1])) # input 2
perceptron_output = Perceptron(weights=np.array([1, -3, 1]), threshold=0.5)
Network = [
    # input layer, declare input layer perceptrons here
    [perceptron_input_1, perceptron_input_2, perceptron_input_3],
    # output node, declare output layer perceptron here
    [perceptron_output]
]


# Part 2: Define a procedure to compute the output of the network, given inputs
def EvalNetwork(inputValues, Network):
    """
    Takes in @param inputValues, a list of input values, and @param Network
    that specifies a perceptron network. @return the output of the Network for
    the given set of inputs.
    """

    # YOUR CODE HERE
    layer_inputs = inputValues
    for layer in Network:
        layer_outputs = [weight.activate(layer_inputs) for weight in layer]
        layer_inputs = layer_outputs
    # Be sure your output value is a single number
    OutputValue = layer_inputs[0]
    return OutputValue


def test():
    """
    A few tests to make sure that the perceptron class performs as expected.
    """
    print "0 XOR 0 = 0?:", EvalNetwork(np.array([0, 0]), Network)
    print "0 XOR 1 = 1?:", EvalNetwork(np.array([0, 1]), Network)
    print "1 XOR 0 = 1?:", EvalNetwork(np.array([1, 0]), Network)
    print "1 XOR 1 = 0?:", EvalNetwork(np.array([1, 1]), Network)


if __name__ == "__main__":
    test()
# ----------
# 
# As with the previous perceptron exercises, you will complete some of the core
# methods of a sigmoid unit class.
#
# There are two functions for you to finish:
# First, in activate(), write the sigmoid activation function.
# Second, in update(), write the gradient descent update rule. Updates should be
#   performed online, revising the weights after each data point.
# 
# ----------

import numpy as np


class Sigmoid:
    """
    This class models an artificial neuron with sigmoid activation function.
    """

    def __init__(self, weights = np.array([1])):
        """
        Initialize weights based on input arguments. Note that no type-checking
        is being performed here for simplicity of code.
        """
        self.weights = weights

        # NOTE: You do not need to worry about these two attribues for this
        # programming quiz, but these will be useful for if you want to create
        # a network out of these sigmoid units!
        self.last_input = 0 # strength of last input
        self.delta      = 0 # error signal

    def activate(self, values):
        """
        Takes in @param values, a list of numbers equal to length of weights.
        @return the output of a sigmoid unit with given inputs based on unit
        weights.
        """

        # YOUR CODE HERE

        # First calculate the strength of the input signal.
        strength = np.dot(values, self.weights)
        self.last_input = strength

        # TODO: Modify strength using the sigmoid activation function and
        # return as output signal.
        # HINT: You may want to create a helper function to compute the
        #   logistic function since you will need it for the update function.
        result = 1 / (1 + np.exp(-strength))
        return result

    def update(self, values, train, eta=.1):
        """
        Takes in a 2D array @param values consisting of a LIST of inputs and a
        1D array @param train, consisting of a corresponding list of expected
        outputs. Updates internal weights according to gradient descent using
        these values and an optional learning rate, @param eta.
        """

        # TODO: for each data point...
        for X, y_true in zip(values, train):
            # obtain the output signal for that point
            y_pred = self.activate(X)

            # YOUR CODE HERE

            # TODO: compute derivative of logistic function at input strength
            # Recall: d/dx logistic(x) = logistic(x)*(1-logistic(x))

            # TODO: update self.weights based on learning rate, signal accuracy,
            # function slope (derivative) and input value
            slope = [-(y_true - y_pred) * y_pred * (1- y_pred) * X[i] for i in range(len(X))]
            for i in range(len(X)):
                self.weights[i] += eta * -slope[i]

def test():
    """
    A few tests to make sure that the perceptron class performs as expected.
    Nothing should show up in the output if all the assertions pass.
    """
    def sum_almost_equal(array1, array2, tol = 1e-5):
        return sum(abs(array1 - array2)) < tol

    u1 = Sigmoid(weights=[3,-2,1])
    assert abs(u1.activate(np.array([1,2,3])) - 0.880797) < 1e-5

    u1.update(np.array([[1,2,3]]),np.array([0]))
    assert sum_almost_equal(u1.weights, np.array([2.990752, -2.018496, 0.972257]))

    u2 = Sigmoid(weights=[0,3,-1])
    u2.update(np.array([[-3,-1,2],[2,1,2]]),np.array([1,0]))
    assert sum_almost_equal(u2.weights, np.array([-0.030739, 2.984961, -1.027437]))

if __name__ == "__main__":
    test()

results matching ""

    No results matching ""