您的位置:首页 > 理论基础 > 计算机网络

使用python实现简单全连接神经网络

2016-08-02 15:51 1196 查看
最近在学习神经网络的相关知识,特在此做一个笔记。

python语言的功能很强大,可以使用很少的代码实现很多功能,因此大家如果想研究深度学习的话,一定要懂得python语言。

这篇笔记记录我的第一次使用python编写神经网络代码的过程,其中代码基本是借鉴neural networks and deep learning上的知识,这本书对神经网络学习有很大帮助,浅显易懂的深入了CNN的知识,初学者可以研究一下。

好了,多的不说,直接上代码:

这里我做的是最简单的mnist手写字的识别,首先是数据库处理。

这里我下载了42028张mnist图片,每张图片大小是28*28,需要的可以到这里下载。

一般需要把数据转化为pkl文件,便于存储和以后的使用。

import os
import cPickle
import numpy
from PIL import Image
import commondata	#自己定义的文件,里面有一些公用的变量

dirname = 'train'		#图片根目录
myfile = 'train.pkl'		#生成的文件名称

number = 0			#图片个数
for filename in os.listdir(dirname):
filename1 = dirname + '/' + filename
for filename2 in os.listdir(filename1):
number += 1				</span>

pictures = numpy.empty((number,commondata.ImageWidth*commondata.ImageHeight))	#图片文件
lables = numpy.empty(number)							#标签文件

index = 0
lable = 0

for filename in os.listdir(dirname):
filename1 = dirname + '/' + filename
for filename2 in os.listdir(filename1):
filename2 = filename1 + '/' + filename2
image = Image.open(filename2)
image = image.convert('L')					#为了简便,先统一转化为灰度图片
image = image.resize((commondata.ImageHeight,commondata.ImageWidth))
image_narray = numpy.asarray(image,dtype = 'float64')/256
pictures[index] = numpy.ndarray.flatten(image_narray)
lables[index] = lable
index = index + 1
lable = lable + 1

lables = lables.astype(numpy.int)
write_file=open(myfile,'wb')
cPickle.dump([pictures[:],lables[:]],write_file,-1)
write_file.close()
运行此代码,可以生成一个名字为train.pkl的文件,然后更改根目录和生成文件的名称可以得到test.pkl

生成文件后,还需要调用此文件:

import cPickle
import numpy as np
import commondata

NumClass = commondata.NumClass
ImageWidth = commondata.ImageWidth
ImageHeight = commondata.ImageHeight

def vectorized_result(j):
e = np.zeros((NumClass,1))
e[j] = 1.0
return e

def load_data():
f = open('data.pkl','rb')
training_data = cPickle.load(f)
f.close()

f = open('test.pkl','rb')
test_data = cPickle.load(f)
f.close()

return (training_data,test_data)

def load_data_wrapper():
tr_d,te_d = load_data()
training_inputs = [np.reshape(x,(ImageWidth*ImageHeight,1)) for x in tr_d[0]]
training_results = [vectorized_result(y) for y in tr_d[1]]
training_data = zip(training_inputs,training_results)
test_inputs = [np.reshape(x,(ImageWidth*ImageHeight,1)) for x in te_d[0]]
test_data = zip(test_inputs,te_d[1])
return (training_data,test_data)
这段代码的作用是读取生成的pkl文件,并以标准化的格式返回。

其中vectorized_result的作用是将一个数值转化为向量,比如在手写数字问题中,一共有10个类,需要的向量长度为10,则1应该转化为[0,1,0,0,0,0,0,0,0,0],2应该转化为[0,0,1,0,0,0,0,0,0,0].

接下来便是最核心的代码:

import myalgorithm				#自己的算法
import numpy as np

import random

class Network(object):

def __init__(self,sizes):						#初始化,sizes的形式一般为[784,50,10,10]之类的
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):						#前向传播过程
for b,w in zip(self.biases,self.weights):
a = myalgorithm.sigmoid(np.dot(w,a)+b)
return a

def update_mini_batch(self,mini_batch,eta):				#根据一个minibatch训练样本调整参数
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):						#反向传播
nabla_b = [np.zeros(b.shape) for b in self.biases]
nabla_w = [np.zeros(w.shape) for w in self.weights]

activation = x
activations = [x]
zs = []
for b,w in zip(self.biases,self.weights):
z = np.dot(w,activation)+b
zs.append(z)
activation = myalgorithm.sigmoid(z)
activations.append(activation)

delta = self.cost_derivative(activations[-1],y)*myalgorithm.sigmoid_prime(zs[-1])
nabla_b[-1] = delta
nabla_w[-1] = np.dot(delta,activations[-2].transpose())
for l in xrange(2,self.num_layers):
z = zs[-l]
sp = myalgorithm.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):						#测试函数
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 (output_activations - y)

def SGD(self,training_data,epochs,mini_batch_size,eta,test_data = None):	#SGD算法
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)


代码解释见注释,

然后便可以训练:

import data
training_data,test_data = data.load_data_wrapper()

import network
net = network.Network([784,30,10])
net.SGD(training_data,30,10,1.5,test_data = test_data)

import cPickle
write_file = open('weight.pkl','wb')
cPickle.dump([net.weights[:],net.biases[:]],write_file,-1)
write_file.close()
训练完成后把权值存储起来。

如果想使用训练的模型进行分类,也很简单,如下代码:

import numpy
import commondata
from PIL import Image
import cPickle
import myalgorithm

filename = 'test1.jpg'			#需要分类的文件名

read_file = open('weight.pkl','rb')
weights,biases = cPickle.load(read_file)
read_file.close()

def outcome(weights,biases,a):
for b,w in zip(biases,weights):
a = myalgorithm.sigmoid(numpy.dot(w,a)+b)
return numpy.argmax(a)

def get_predict(filename):
image = Image.open(filename)
image = image.convert('L')
image = image.resize((commondata.ImageHeight,commondata.ImageWidth))
image_narray = numpy.asarray(image,dtype = 'float64')/256
image_vector = numpy.ndarray.flatten(image_narray)
test = numpy.reshape(image_vector,(commondata.ImageHeight*commondata.ImageHeight,1))
result = outcome(weights,biases,test)
print result



调用get_predict函数便可以预测图片所属的类别

整个项目代码:http://download.csdn.net/detail/zsy162534/9592826
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  神经网络