感知机神经元编程 和 sigmoid神经元编程练习
2018-06-13 本文已影响0人
zoulala
perceptron:
激活函数
image.png
感知机模型:f(x)=sign(w*x+b)
# ----------
#
# 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.
#
# YOUR CODE WILL GO IN LINES 51 AND 59.
# ----------
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.
"""
# For each data point:
for data_point in xrange(len(values)):
# TODO: Obtain the neuron's prediction for the data_point --> values[data_point]
prediction = self.activate(values[data_point])# TODO)
# Get the prediction accuracy calculated as (expected value - predicted value)
# expected value = train[data_point], predicted value = prediction
error = train[data_point] - prediction
# TODO: update self.weights based on the multiplication of:
# - prediction accuracy(error)
# - learning rate(eta)
# - input value(values[data_point])
weight_update = values[data_point]*error*eta# TODO
self.weights += weight_update
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()
sigmoid:
激活函数:sigmoid:1/(1+exp(x))
image.png
感知机与logistic regression的差别就是感知机激活函数是sign,logistic regression的激活函数是sigmoid
逻辑回归模型:f(x)= sigmoid(w*x+b)
# ----------
#
# 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(-self.last_input))
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)
error = y_true - y_pred
# YOUR CODE HERE
# TODO: compute derivative of logistic function at input strength
# Recall: d/dx logistic(x) = logistic(x)*(1-logistic(x))
dx = 1/(1+np.exp(-self.last_input))*(1-1/(1+np.exp(-self.last_input)))
# TODO: update self.weights based on learning rate, signal accuracy,
# function slope (derivative) and input value
dw = eta*error*dx*X
self.weights += dw
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()