数字识别手写神经网络实现基于MNIST数据集

Olive ·
更新时间:2024-09-20
· 511 次阅读

 MNIST数据集自行baidu下载,解压后放到项目文件里

git详细代码仓库:https://github.com/justDoForever/deep_learning/digital_recognition.py (python 2.7)

理论分析: https://www.zybuluo.com/hanbingtao/note/476663

代码如下:

# encoding:utf-8 #神经网络实现数字识别 import struct import sys from datetime import datetime from fcn import Network def transpose(param): pass class Loader(object): #数据基础加载器 def __init__(self,path,number): ''' :param path: 数据文件路经 :param number: 文件中样本个数 ''' self.path = path; self.number = number; def get_file_content(self): file = open(self.path,'rb') content = file.read() file.close(); return content; def to_int(self,byte): #将unsigned char转成int return struct.unpack('B',byte)[0] class ImgaeLoader(Loader): #这里的self即指向ImageLoader基类自身也指向Loader父类 def load(self): #首先得到文件内容 content = self.get_file_content() data_set = [] for i in range(self.number): data_set.append(self.get_one_sample(self.get_picture(content,i))) return data_set def get_picture(self, content, index): #获得图片二维矩阵 #t=图片样本前16位不是标签所以要从第17位开始(content[16]) start = index * 28 * 28 + 16; picture = []; for i in range(28): picture.append([]) for j in range(28): picture[i].append(self.to_int(content[start + i * 28 + j])) # if self.to_int(content[start + i * 28 + j]) != 0: # sys.stdout.write('*') # else: # sys.stdout.write(' ') # print ' ' return picture; def get_one_sample(self, picture): #将图片二维矩阵转为一维输入向量 sample = []; for i in range(28): for j in range(28): sample.append(picture[i][j]) return sample; class LabelLoder(Loader): def load(self): #标签前8位不是标签所以要从第9位开始(content[8]) content = self.get_file_content(); label_set = []; for i in range(self.number): label_set.append(self.norm(content[i + 8])) return label_set; def norm(self,label): #将label值一个0到9的数字转为一个10维的输出向量 label_vec = []; label_value = self.to_int(label) for i in range(10): if i == label_value: label_vec.append(0.9) else: label_vec.append(0.1) return label_vec def get_train_data_set(): image_loader = ImgaeLoader('train-images.idx3-ubyte',60) label_loader = LabelLoder('train-labels.idx1-ubyte',60) return image_loader.load(),label_loader.load(); def get_test_data_set(): image_loader = ImgaeLoader('t10k-images.idx3-ubyte',10) label_loader = LabelLoder('t10k-labels.idx1-ubyte',10) return image_loader.load(),label_loader.load() def now(): return datetime.now().strftime("%c") def get_result(input): max_value = - 1; max_index = -1; for i in range(len(input)): if input[i] > max_value: max_index = i; max_value = input[i] return max_index; def evaluate(net, test_data_set, test_labels): error = 0; for i in range(len(test_labels)): #样本和预测输出的虽然都是10维的一个向量,但是不能直接比较相等来代表预测是否正确 #因为预测值的10维向量不是0.1,0.9组成的,只能通过最大值的位置作为结果来比较 label = get_result(test_labels[i]) predict = get_result(net.predict(test_data_set[i])) if label != predict: error += 1; return float(error) / float(len(test_labels)) def train_and_evaluate(): epoch = 1; last_error_ratio = 1.0; #获取数据集并处理 # train_data_set,tain_labels = transpose(get_train_data_set()) # test_data_set,test_labels = transpose(get_test_data_set()) train_data_set, tain_labels = get_train_data_set() test_data_set, test_labels = get_test_data_set() #搭建神经网络 net = Network([784,300,10]); #训练 while True: net.train(tain_labels,train_data_set,1,0.01) epoch += 1; print '%s epoch: %d \n' % (now(),epoch) if epoch % 10 == 0: #每训练10次就通过测试样本计算错误率 error_ratio = evaluate(net,test_data_set,test_labels) print '%s epoch: %d error ratio : %f\n' % (now(),epoch,error_ratio) #如果错误率升高就停止训练防止过拟合,否则更新last_error_ratio为最新的错误率 if error_ratio > last_error_ratio: break; else: last_error_ratio = error_ratio; if __name__ == '__main__': train_and_evaluate(); # train_data_set, tain_labels = get_train_data_set() # print train_data_set,' ',tain_labels # a = [[1,2],[4,5]] # print a[-1]


作者:Justdoforever



mnist 神经网络

需要 登录 后方可回复, 如果你还没有账号请 注册新账号
相关文章