Hi Belinda,

I think you would need to rewrite the train method to record the weights. However, I just had my class do a simpler version of this exercise for a homework assignment, using gnuplot and a basic perceptron (implemented in pure Python, not Conx). The link to the assignment is here:

http://science.slc.edu/~jmarshall/courses/2007/spring/robotics/assignments/a05/

In addition, I'll attach the completed code if you want to try it out. Hope this helps.
-jim


---------------------------
Jim Marshall
Computer Science Department
Sarah Lawrence College
Bronxville, New York


belinda thom wrote:
Hi,

Is there an easy way to record the changes made to weights during train, or would I have to basically rewrite that procedure to do what I want? I realize in non-toy problems, you'd probably not want to do this, but for simple examples (like And or fig 4.7 in Tom Mitchell's Machine Learning book) being able to access the weights as they change over time---e.g. to plot them---can be a useful pedagogical tool.

Please advise,

Thanks!

--b
_______________________________________________
Pyro-users mailing list
[email protected]
http://emergent.brynmawr.edu/mailman/listinfo/pyro-users
import random, string

def dotProduct(a, b):
    sum = 0.0
    for i in range(len(a)):
        sum = sum + a[i] * b[i]
    return sum

def pretty(values):
    return string.join(['%.3f' % v for v in values])

#--------------------------------------------------------------------------------

class Unit:

    def __init__(self, activation=0.0):
        self.activation = activation
        self.incomingConnections = []
        self.outgoingConnections = []

    def update(self):
        activations = [c.fromUnit.activation for c in self.incomingConnections]
        weights = [c.weight for c in self.incomingConnections]
        netActivation = dotProduct(activations, weights)
        self.activation = self.stepFunction(netActivation)

    def stepFunction(self, x):
        if x > 0:
            return 1
        else:
            return 0

#--------------------------------------------------------------------------------

class Connection:

    def __init__(self, fromUnit, toUnit):
        self.fromUnit = fromUnit
        self.toUnit = toUnit
        self.randomize()

    def randomize(self):
        self.weight = random.uniform(-0.1, +0.1)

#--------------------------------------------------------------------------------

class SimplePerceptron:

    def __init__(self, numInputs):
        # create the units
        self.outputUnit = Unit()
        self.inputLayer = [Unit() for k in range(numInputs)]
        # wire up the network
        self.allConnections = []
        for unit in self.inputLayer:
            self.connect(unit, self.outputUnit)
        # connect the bias unit
        biasUnit = Unit(1.0)
        self.connect(biasUnit, self.outputUnit)
        self.learningRate = 0.1

    def connect(self, fromUnit, toUnit):
        c = Connection(fromUnit, toUnit)
        fromUnit.outgoingConnections.append(c)
        toUnit.incomingConnections.append(c)
        self.allConnections.append(c)

    def setWeights(self, newWeights):
        assert len(newWeights) == len(self.allConnections), 'wrong number of weights'
        for (c, w) in zip(self.allConnections, newWeights):
            c.weight = w

    def initialize(self):
        for c in self.allConnections:
            c.randomize()
        print 'weights randomized'

    def propagate(self, pattern):
        assert len(pattern) == len(self.inputLayer), 'wrong pattern size'
        for (inputUnit, value) in zip(self.inputLayer, pattern):
            assert 0 <= value <= 1, 'invalid pattern value %g' % value
            inputUnit.activation = value
        self.outputUnit.update()
        return self.outputUnit.activation

    def test(self):
        print 'weights =', pretty([c.weight for c in self.allConnections])
        for pattern in self.inputs:
            output = self.propagate(pattern)
            print 'output on %s = %d' % (pattern, output)
        print

    def computeError(self):
        error = 0.0
        correct = 0
        for (pattern, target) in zip(self.inputs, self.targets):
            output = self.propagate(pattern)
            error = error + (target - output) ** 2
            if output == target:
                correct = correct + 1
        total = len(self.inputs)
        score = 100.0 * correct / total
        return (correct, total, score, error)

    # perceptron learning rule
    def teach(self, pattern, target):
        output = self.propagate(pattern)
        self.outputUnit.error = target - output
        for c in self.allConnections:
            increment = self.learningRate * c.toUnit.error * c.fromUnit.activation
            c.weight = c.weight + increment

    def teachDataset(self):
        assert len(self.inputs) > 0, 'no training data'
        dataset = zip(self.inputs, self.targets)
        random.shuffle(dataset)
        for (pattern, target) in dataset:
            #print '   teaching %s -> %s' % (pattern, target)
            self.teach(pattern, target)

    # changed
    def train(self, cycles=1000):
        assert len(self.inputs) > 0, 'no training data'
        (correct, total, score, error) = self.computeError()
        print 'Epoch #   0: TSS error %7.4f, %d/%d correct (%.1f%%)' % \
              (error, correct, total, score)
        self.learningRate = 0.001
        file = open('pathway.dat', mode='w')
        for c in self.allConnections:
            file.write('%12g ' % c.weight)
        file.write('\n')
        for t in range(1, cycles+1):
            self.teachDataset()
            (correct, total, score, error) = self.computeError()
            print 'Epoch #%4d: TSS error %7.4f, %d/%d correct (%.1f%%)' % \
                  (t, error, correct, total, score)
            for c in self.allConnections:
                file.write('%12g ' % c.weight)
            file.write('\n')
            if correct == total:
                print 'All patterns learned'
                break
        file.close()

#--------------------------------------------------------------------------------

# part 1
n = SimplePerceptron(2)
n.inputs = [[0, 0], [0, 1], [1, 0], [1, 1]]
n.targets = [0, 0, 0, 1]  # AND function

# to see training pathway, do this:
# >>> n.train()
# gnuplot> set style data linespoints
# gnuplot splot 'pathway.dat' pt 7

# part 2
carry = SimplePerceptron(3)
carry.inputs = [[0, 0, 0],
                [0, 0, 1],
                [0, 1, 0],
                [0, 1, 1],
                [1, 0, 0],
                [1, 0, 1],
                [1, 1, 0],
                [1, 1, 1]]
carry.targets = [0, 0, 0, 1, 0, 1, 1, 1]

sum = SimplePerceptron(3)
sum.inputs = carry.inputs
sum.targets = [0, 1, 1, 0, 1, 0, 0, 1]
_______________________________________________
Pyro-users mailing list
[email protected]
http://emergent.brynmawr.edu/mailman/listinfo/pyro-users

Reply via email to