def sigmoid(z):
return 1.0/(1.0+np.exp(-z))
def feedforward(self, a):
for b, w in zip(self.biases, self.weights):
a = sigmoid(np.dot(w, a)+b)
return a"""
network.py
~~~~~~~~~~
A module to implement the stochastic gradient descent learning
algorithm for a feedforward neural network. Gradients are calculated
using backpropagation. Note that I have focused on making the code
simple, easily readable, and easily modifiable. It is not optimized,
and omits many desirable features.
"""
#### Libraries
# Standard library
import random
# Third-party libraries
import numpy as np
class Network(object):
def __init__(self, sizes):
"""The list ``sizes`` contains the number of neurons in the
respective layers of the network. For example, if the list
was [2, 3, 1] then it would be a three-layer network, with the
first layer containing 2 neurons, the second layer 3 neurons,
and the third layer 1 neuron. The biases and weights for the
network are initialized randomly, using a Gaussian
distribution with mean 0, and variance 1. Note that the first
layer is assumed to be an input layer, and by convention we
won't set any biases for those neurons, since biases are only
ever used in computing the outputs from later layers."""
self.num_layers = len(sizes)
self.sizes = sizes
self.biases = [np.random.randn(y, 1) for y in sizes[1:]]
self.weights = [np.random.randn(y, x)
for x, y in zip(sizes[:-1], sizes[1:])]
def feedforward(self, a):
"""Return the output of the network if ``a`` is input."""
for b, w in zip(self.biases, self.weights):
a = sigmoid(np.dot(w, a)+b)
return a
def SGD(self, training_data, epochs, mini_batch_size, eta,
test_data=None):
"""Train the neural network using mini-batch stochastic
gradient descent. The ``training_data`` is a list of tuples
``(x, y)`` representing the training inputs and the desired
outputs. The other non-optional parameters are
self-explanatory. If ``test_data`` is provided then the
network will be evaluated against the test data after each
epoch, and partial progress printed out. This is useful for
tracking progress, but slows things down substantially."""
if test_data: n_test = len(test_data)
n = len(training_data)
for j in xrange(epochs):
random.shuffle(training_data)
mini_batches = [
training_data[k:k+mini_batch_size]
for k in xrange(0, n, mini_batch_size)]
for mini_batch in mini_batches:
self.update_mini_batch(mini_batch, eta)
if test_data:
print "Epoch {0}: {1} / {2}".format(
j, self.evaluate(test_data), n_test)
else:
print "Epoch {0} complete".format(j)
def update_mini_batch(self, mini_batch, eta):
"""Update the network's weights and biases by applying
gradient descent using backpropagation to a single mini batch.
The ``mini_batch`` is a list of tuples ``(x, y)``, and ``eta``
is the learning rate."""
nabla_b = [np.zeros(b.shape) for b in self.biases]
nabla_w = [np.zeros(w.shape) for w in self.weights]
for x, y in mini_batch:
delta_nabla_b, delta_nabla_w = self.backprop(x, y)
nabla_b = [nb+dnb for nb, dnb in zip(nabla_b, delta_nabla_b)]
nabla_w = [nw+dnw for nw, dnw in zip(nabla_w, delta_nabla_w)]
self.weights = [w-(eta/len(mini_batch))*nw
for w, nw in zip(self.weights, nabla_w)]
self.biases = [b-(eta/len(mini_batch))*nb
for b, nb in zip(self.biases, nabla_b)]
def backprop(self, x, y):
"""Return a tuple ``(nabla_b, nabla_w)`` representing the
gradient for the cost function C_x. ``nabla_b`` and
``nabla_w`` are layer-by-layer lists of numpy arrays, similar
to ``self.biases`` and ``self.weights``."""
nabla_b = [np.zeros(b.shape) for b in self.biases]
nabla_w = [np.zeros(w.shape) for w in self.weights]
# feedforward
activation = x
activations = [x] # list to store all the activations, layer by layer
zs = [] # list to store all the z vectors, layer by layer
for b, w in zip(self.biases, self.weights):
z = np.dot(w, activation)+b
zs.append(z)
activation = sigmoid(z)
activations.append(activation)
# backward pass
delta = self.cost_derivative(activations[-1], y) * \
sigmoid_prime(zs[-1])
nabla_b[-1] = delta
nabla_w[-1] = np.dot(delta, activations[-2].transpose())
# Note that the variable l in the loop below is used a little
# differently to the notation in Chapter 2 of the book. Here,
# l = 1 means the last layer of neurons, l = 2 is the
# second-last layer, and so on. It's a renumbering of the
# scheme in the book, used here to take advantage of the fact
# that Python can use negative indices in lists.
for l in xrange(2, self.num_layers):
z = zs[-l]
sp = sigmoid_prime(z)
delta = np.dot(self.weights[-l+1].transpose(), delta) * sp
nabla_b[-l] = delta
nabla_w[-l] = np.dot(delta, activations[-l-1].transpose())
return (nabla_b, nabla_w)
def evaluate(self, test_data):
"""Return the number of test inputs for which the neural
network outputs the correct result. Note that the neural
network's output is assumed to be the index of whichever
neuron in the final layer has the highest activation."""
test_results = [(np.argmax(self.feedforward(x)), y)
for (x, y) in test_data]
return sum(int(x == y) for (x, y) in test_results)
def cost_derivative(self, output_activations, y):
"""Return the vector of partial derivatives \partial C_x /
\partial a for the output activations."""
return (output_activations-y)
#### Miscellaneous functions
def sigmoid(z):
"""The sigmoid function."""
return 1.0/(1.0+np.exp(-z))
def sigmoid_prime(z):
"""Derivative of the sigmoid function."""
return sigmoid(z)*(1-sigmoid(z))That is the idea, but I need to understand the algorithm first. Every AI tutorial/example I have found uses Python. It has been a while, but I could probably dig up the C++ matrix operations from school work. Pretty basic unless you are going for ultimate optimization. I am just trying to figure out how it al works.It just provides a function, which returns a value between 0 and 1, non linear, based on the input value.
Is sigmoid() defined inside the class? Alignment seems to suggest so, but then it should be called as self.sigmoid() and should take "self" as a first argument.
And in recent versions there is optional strong typing, but it kind of defeats the purpose.
Thanks for all the tips.
I finally got it all working, after fixing several typos. I am still pretty shaky on how Python works. I would like to be able to use VSCode, but it does not seem to be able to find numpy for some reason. If I could find a tutorial on Python for someone that already knows how to program it would be helpful. It is just too painful going through all the basics in what I have found so far, just to try and pick out what is specific to Python.
If I could find a tutorial on Python for someone that already knows how to program it would be helpful.
A good way to use Python for ML and other things is to use Jupyter Notebook, it is very interactive and shows you plots and graphs interleaved with your input.
I haven't really used Python with VSCode, but it is not Code that has to find a package like numpy. Numpy is installed as a Python extension using pip, and then an IDE like Code just uses the version of Python you tell it to. If numpy is not recognized, you are probably not pointing Code at the right version of Python on your computer.
A good hint for using Python for ML and visualization is to use the Anaconda distribution. Anaconda comes with all the important numerical and graphing packages included out of the box, so it simplifies things tremendously.
I dislike cloud/web applications, so aside from taking a look at notebooks I pretty much ignored it.
You probably should change over to python 3, python2.7 is very obsolete and you’ll probably find that a lot of tutorials and libraries simply don’t work with it.
That could be, but all the ML examples I have seen so far use 2.7, so I would think using 3.x would be more problematic. Also since I am on a win7 machine, the latest versions simply will not work to begin with. I have plenty of VMs; Mac, Linux, and windows from DOS to 10., but I prefer to work natively when I can.
Well, I am not planning on writing very much new Python code. I will be using C/C++ when I start writing for myself. I just need to understand the Python so I can understand, and work thought, the examples I find. Which reminds me, I need to look up tuples as I do not think they are what I am thinking they are.
Well, I am not planning on writing very much new Python code. I will be using C/C++ when I start writing for myself. I just need to understand the Python so I can understand, and work thought, the examples I find. Which reminds me, I need to look up tuples as I do not think they are what I am thinking they are.
Then for your own sake, do not learn Python2!
Thanks for the warning, but as far as I understand it Python 2 was never the same as Python 3. 3 was not just an updated version like C++98 vs C++17. Therefore I never expected code written in one to work flawlessly with the other, anymore than I would expect the same from code written in any two different languages, regardless of the similarities.
Well, I am not planning on writing very much new Python code. I will be using C/C++ when I start writing for myself. I just need to understand the Python so I can understand, and work thought, the examples I find. Which reminds me, I need to look up tuples as I do not think they are what I am thinking they are.
Then for your own sake, do not learn Python2!
;D
Well, if you expect C++17 code to compile with C++98 compiler, good luck. That's not what I would consider as "just an updated version". Also C++17 has removed and deprecated quite a few things that worked in C++98 - auto_ptr, functional, random_shuffle() among others. So even the backwards compatibility isn't 100%.
That's the same sort of difference we are talking about with Python 2 vs Python 3.
There might come a time when I need some updated functionality, but until then, there is no benefit to updating for the sake of having the latest and greatest...anything.
Given that you literally don't know much about the language, are asking for advice - and then promptly decide to ignore it, good luck :-//
The right tool for the job is not necessarily the shiniest one.It's not that, using the latest and newest, at all. It's that Python 2 is no longer officially supported (https://docs.python.org/2.7/); it is EOL'd.
Given that you literally don't know much about the language, are asking for advice - and then promptly decide to ignore it, good luck :-//
No, I was asking about a specific problem, where it turned out I was confused by the format and did not notice the function was outside the class. Since what I am working on uses Python 2, trying to use Python 3 would only cause troubles, as you repeatedly state. In fact, I would probably be having even more trouble. So, actually I am following your advice, just not the way you keep insisting on. Oh wait, I should find newer examples, right? Well, this is what I started with and what I intend to finish, before starting another one. If it makes you feel better, the next one I have planned will use Python 3, If what ever I do after that goes back to Python 2, then I will do the same. Once I get a good enough understanding of all this, I might never use Python again.
The right tool for the job is not necessarily the shiniest one.
Sure, but while I may agree with you if you had to deal with a large code base written in Python 2 and porting it to Python 3 would be a major risk, if you're just starting with Python and are dealing with some code example, that's a completely wrong approach IMHO. That would be a bit like trying to learn C in 2022 using the original C and the first edition of the K&R book and complaining this is all confusing and that all compilers you've tried so far keep giving you warnings and errors.
I did start with Python 3, the latest Anaconda version. It did not work on my ancient machine.Well, Python 3 works on any version of Linux you have a compiler for, including for machines over two decades old, so it's not that.
The problem with Python is that you only have ONE implementation AFAIK. That's interestingly (but understandably) the case for most languages that are not standardized.
Are you one of those people clinging on to an ancient OS like XP? :P
without having to go through hoops. ;DIs that even possible? I am constantly stuck in some kind of loop. At the moment I cannot get my phone to connect to the computer. It will start charging, but I cannot upload my app for testing. I have quite a few steps between that and when I get to anything discussed in this thread.
If there is only one implementation, does that not mean, by definition, that the one implementation is the standard?
3.7 still worksPython 3.8 is the last version to run on Windows 7, or 3.7 on XP. So get that, at least. You might be missing a few minor language features and some library improvements but it will be substantially similar.
Can you tell me what Windows 10, or 11, offers that XP did not?You've got to be kidding. The APIs constantly move forward on all axes. Whether you deem these improvements 'worthy' or not, software developers need to track them. At some point supporting the old way either hobbles functionality unnecessarily, or is just a waste of maintenance effort. How do you propose they even set up an automated test environment for Windows 7 when it's no longer available? Microsoft no longer supports XP or 7, so neither does Python. It shouldn't be a big surprise. I really don't quite grok why people expect a 13 / 21 year old operating system to run modern code, and act all indignant about it when developers stop supporting their vintage OS. That's the consequence of wanting to run ancient software. Do you also expect a DOS 6.22 Python interpreter to be released by the Python team?
My 20 year old machine specs out similar to any modern onelolwut