神经网络初探:手写数字识别

手写数字识别
数据集: m n i s t 50000 张训练图片+ 10000 张测试图片)
训练方法:随机梯度下降
代码( p y t h o n 3 ):
m n i s t _ l o a d e r . p y

import pickle
import numpy as np
def load_data():
    ff=open('E:/dl_python3/data/mnist.pkl', 'rb')
    training_data, validation_data, test_data=pickle.load(ff, encoding='iso-8859-1')
    return(training_data, validation_data, test_data)
def load_data_wrapper():
    tr_d, va_d, te_d = load_data()
    training_inputs = [np.reshape(x, (784, 1)) for x in tr_d[0]]
    training_results = [vectorized_result(y) for y in tr_d[1]]
    training_data = list(zip(training_inputs, training_results))
    validation_inputs = [np.reshape(x, (784, 1)) for x in va_d[0]]
    validation_data = list(zip(validation_inputs, va_d[1]))
    test_inputs = [np.reshape(x, (784, 1)) for x in te_d[0]]
    test_data = list(zip(test_inputs, te_d[1]))
    return (training_data, validation_data, test_data)
def vectorized_result(j):
    e=np.zeros((10, 1))
    e[j]=1.0
    return e

l e o l y _ n e t w o r k . p y

import numpy as np
import random

def sigmoid(x):
        return 1.0/(1.0+np.exp(-x))
def d_sigmoid(x):
    return sigmoid(x)*(1.0-sigmoid(x))
def d_cost(ans, y):
    return 2.0*(ans-y)

class network(object):
    def __init__(self, size):
        self.num=len(size)
        self.size=size
        self.bias=[np.random.randn(x, 1) for x in size[1::]]
        self.weight=[np.random.randn(x, y) for x, y in list(zip(size[1::], size[:-1:]))]
    def feed_forward(self, a):
        for w, b in list(zip(self.weight, self.bias)):
            a=sigmoid(np.dot(w, a)+b)
        return a
    def backprop(self, x, y):
        n_w=[np.zeros(w.shape) for w in self.weight]
        n_b=[np.zeros(b.shape) for b in self.bias]
        ans=x
        all_ans=[x]
        all_z=[]
        for w, b in list(zip(self.weight, self.bias)):
            z=np.dot(w, ans)+b
            all_z.append(z)
            ans=sigmoid(z)
            all_ans.append(ans)
        delta=d_cost(all_ans[-1], y)*d_sigmoid(all_z[-1])
        n_w[-1]=np.dot(delta, all_ans[-2].transpose())
        n_b[-1]=delta
        for i in range(2, self.num):
            delta=2.0*np.dot(self.weight[-i+1].transpose(), delta)*d_sigmoid(all_z[-i])
            n_w[-i]=np.dot(delta, all_ans[-i-1].transpose())
            n_b[-i]=delta
        return (n_w, n_b)
    def update(self, mini_batch, eta):
        n_w=[np.zeros(w.shape) for w in self.weight]
        n_b=[np.zeros(b.shape) for b in self.bias]
        for i, j in mini_batch:
            delta_n_w, delta_n_b=self.backprop(i, j)
            n_w=[nw+dnw for nw, dnw in list(zip(n_w, delta_n_w))]
            n_b=[nb+dnb for nb, dnb in list(zip(n_b, delta_n_b))]
        self.weight=[w-eta*nw for w, nw in list(zip(self.weight, n_w))]
        self.bias=[b-eta*nb for b, nb in list(zip(self.bias, n_b))]
    def evaluate(self, test_data):
        result=[(np.argmax(self.feed_forward(i)), j) for (i, j) in test_data]
        return sum(int(i==j) for (i, j) in result)
    def solve(self, training_data, epoch, mini_batch_size, eta, test_data=None):
        n=len(training_data)
        if test_data:
            nn=len(test_data)
        for now_epoch in range(epoch):
            random.shuffle(training_data)
            mini_batches=[training_data[i:min(i+mini_batch_size, n):] for i in range(0, n, mini_batch_size)]
            for mini_batch in mini_batches:
                self.update(mini_batch, 1.0*eta)
            if test_data:
                print('epoch{0}:{1}/{2}'.format(now_epoch, self.evaluate(test_data), nn))
            else:
                print('epoch{0}:complete!'.format(now_epoch))

d o . p y

import mnist_loader as ml
import leoly_network as ln
training_data, validation_data, test_data=ml.load_data_wrapper()
net=ln.network([784, 50, 10])
net.solve(training_data, 100, 10, 0.3, test_data=test_data)

猜你喜欢

转载自blog.csdn.net/leolyun/article/details/80065244
今日推荐