使用python实现简单全连接神经网络
2016-08-02 15:51
1196 查看
最近在学习神经网络的相关知识,特在此做一个笔记。
python语言的功能很强大,可以使用很少的代码实现很多功能,因此大家如果想研究深度学习的话,一定要懂得python语言。
这篇笔记记录我的第一次使用python编写神经网络代码的过程,其中代码基本是借鉴neural networks and deep learning上的知识,这本书对神经网络学习有很大帮助,浅显易懂的深入了CNN的知识,初学者可以研究一下。
好了,多的不说,直接上代码:
这里我做的是最简单的mnist手写字的识别,首先是数据库处理。
这里我下载了42028张mnist图片,每张图片大小是28*28,需要的可以到这里下载。
一般需要把数据转化为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].
接下来便是最核心的代码:
代码解释见注释,
然后便可以训练:
如果想使用训练的模型进行分类,也很简单,如下代码:
调用get_predict函数便可以预测图片所属的类别
整个项目代码:http://download.csdn.net/detail/zsy162534/9592826
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
相关文章推荐
- 使用tensorflow实现全连接神经网络的简单示例,含源码
- 使用keras实现简单的前向全连接神经网络
- 使用keras实现简单的前向全连接神经网络
- 使用Python实现神经网络
- Python实现神经网络Part 3: 多层全连接神经网络
- 数学建模_以fisheriris数据为例使用新版本神经网络工具箱feedforwardnet进行简单实现
- python使用socket进行简单网络连接的方法
- 最简单的全连接神经网络实现
- 使用python实现深度神经网络 5
- python神经网络案例——FC全连接神经网络实现mnist手写体识别
- 机器学习算法练习之(二):Python和Tensorflow分别实现简单的神经网络
- 三层神经网络简单实现(Python版)
- 使用python实现深度神经网络 3
- 使用python实现深度神经网络 4
- 神经网络算法推导,附python实现一个简单神经网络
- 《神经网络与深度学习》第一章 使用神经网络来识别手写数字(三)- 用Python代码实现
- 【深度学习】1.2:简单神经网络的python实现
- 基于python实现一个简单的神经网络
- Python网络编程:使用pexpect实现快速ssh连接
- python实现简单神经网络算法