python构建深度神经网络(续)


Posted in Python onMarch 10, 2018

这篇文章在前一篇文章:python构建深度神经网络(DNN)的基础上,添加了一下几个内容:

1) 正则化项

2) 调出中间损失函数的输出

3) 构建了交叉损失函数

4) 将训练好的网络进行保存,并调用用来测试新数据

1  数据预处理

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
# @Time : 2017-03-12 15:11 
# @Author : CC 
# @File : net_load_data.py 
 
from numpy import * 
import numpy as np 
import cPickle 
def load_data(): 
 """载入解压后的数据,并读取""" 
 with open('data/mnist_pkl/mnist.pkl','rb') as f: 
  try: 
   train_data,validation_data,test_data = cPickle.load(f) 
   print " the file open sucessfully" 
   # print train_data[0].shape #(50000,784) 
   # print train_data[1].shape #(50000,) 
   return (train_data,validation_data,test_data) 
  except EOFError: 
   print 'the file open error' 
   return None 
 
def data_transform(): 
 """将数据转化为计算格式""" 
 t_d,va_d,te_d = load_data() 
 # print t_d[0].shape # (50000,784) 
 # print te_d[0].shape # (10000,784) 
 # print va_d[0].shape # (10000,784) 
 # n1 = [np.reshape(x,784,1) for x in t_d[0]] # 将5万个数据分别逐个取出化成(784,1),逐个排列 
 n = [np.reshape(x, (784, 1)) for x in t_d[0]] # 将5万个数据分别逐个取出化成(784,1),逐个排列 
 # print 'n1',n1[0].shape 
 # print 'n',n[0].shape 
 m = [vectors(y) for y in t_d[1]] # 将5万标签(50000,1)化为(10,50000) 
 train_data = zip(n,m) # 将数据与标签打包成元组形式 
 n = [np.reshape(x, (784, 1)) for x in va_d[0]] # 将5万个数据分别逐个取出化成(784,1),排列 
 validation_data = zip(n,va_d[1]) # 没有将标签数据矢量化 
 n = [np.reshape(x, (784, 1)) for x in te_d[0]] # 将5万个数据分别逐个取出化成(784,1),排列 
 test_data = zip(n, te_d[1]) # 没有将标签数据矢量化 
 # print train_data[0][0].shape #(784,) 
 # print "len(train_data[0])",len(train_data[0]) #2 
 # print "len(train_data[100])",len(train_data[100]) #2 
 # print "len(train_data[0][0])", len(train_data[0][0]) #784 
 # print "train_data[0][0].shape", train_data[0][0].shape #(784,1) 
 # print "len(train_data)", len(train_data) #50000 
 # print train_data[0][1].shape #(10,1) 
 # print test_data[0][1] # 7 
 return (train_data,validation_data,test_data) 
def vectors(y): 
 "赋予标签" 
 label = np.zeros((10,1)) 
 label[y] = 1.0 #浮点计算 
 return label

2 网络定义和训练

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
# @Time : 2017-03-28 10:18 
# @Author : CC 
# @File : net_network2.py 
 
from numpy import * 
import numpy as np 
import operator 
import json 
# import sys 
 
class QuadraticCost(): 
 """定义二次代价函数类的方法""" 
 @staticmethod 
 def fn(a,y): 
  cost = 0.5*np.linalg.norm(a-y)**2 
  return cost 
 @staticmethod 
 def delta(z,a,y): 
  delta = (a-y)*sig_derivate(z) 
  return delta 
 
class CrossEntroyCost(): 
 """定义交叉熵函数类的方法""" 
 @staticmethod 
 def fn(a, y): 
  cost = np.sum(np.nan_to_num(-y*np.log(a)-(1-y)*np.log(1-a))) # not a number---0, inf---larger number 
  return cost 
 @staticmethod 
 def delta(z, a, y): 
  delta = (a - y) 
  return delta 
 
class Network(object): 
 """定义网络结构和方法""" 
 def __init__(self,sizes,cost): 
  self.num_layer = len(sizes) 
  self.sizes = sizes 
  self.cost = cost 
  # print "self.cost.__name__:",self.cost.__name__ # CrossEntropyCost 
  self.default_weight_initializer() 
 def default_weight_initializer(self): 
  """权值初始化""" 
  self.bias = [np.random.rand(x, 1) for x in self.sizes[1:]] 
  self.weight = [np.random.randn(y, x)/float(np.sqrt(x)) for (x, y) in zip(self.sizes[:-1], self.sizes[1:])] 
 
 def large_weight_initializer(self): 
  """权值另一种初始化""" 
  self.bias = [np.random.rand(x, 1) for x in self.sizes[1:]] 
  self.weight = [np.random.randn(y, x) for x, y in zip(self.sizes[:-1], self.sizes[1:])] 
 def forward(self,a): 
  """forward the network""" 
  for w,b in zip(self.weight,self.bias): 
   a=sigmoid(np.dot(w,a)+b) 
  return a 
 
 def SGD(self,train_data,min_batch_size,epochs,eta,test_data=False, 
   lambd = 0, 
   monitor_train_cost = False, 
   monitor_train_accuracy = False, 
   monitor_test_cost=False, 
   monitor_test_accuracy=False 
   ): 
  """1)Set the train_data,shuffle; 
   2) loop the epoches, 
   3) set the min_batches,and rule of update""" 
  if test_data: n_test=len(test_data) 
  n = len(train_data) 
  for i in xrange(epochs): 
   random.shuffle(train_data) 
   min_batches = [train_data[k:k+min_batch_size] for k in xrange(0,n,min_batch_size)] 
 
   for min_batch in min_batches: # 每次提取一个批次的样本 
    self.update_minbatch_parameter(min_batch,eta,lambd,n) 
   train_cost = [] 
   if monitor_train_cost: 
    cost1 = self.total_cost(train_data,lambd,cont=False) 
    train_cost.append(cost1) 
    print "epoche {0},train_cost: {1}".format(i,cost1) 
   if monitor_train_accuracy: 
    accuracy = self.accuracy(train_data,cont=True) 
    train_cost.append(accuracy) 
    print "epoche {0}/{1},train_accuracy: {2}".format(i,epochs,accuracy) 
   test_cost = [] 
   if monitor_test_cost: 
    cost1 = self.total_cost(test_data,lambd) 
    test_cost.append(cost1) 
    print "epoche {0},test_cost: {1}".format(i,cost1) 
   test_accuracy = [] 
   if monitor_test_accuracy: 
    accuracy = self.accuracy(test_data) 
    test_cost.append(accuracy) 
    print "epoche:{0}/{1},test_accuracy:{2}".format(i,epochs,accuracy) 
  self.save(filename= "net_save") #保存网络网络参数 
 
 def total_cost(self,train_data,lambd,cont=True): 
  cost1 = 0.0 
  for x,y in train_data: 
   a = self.forward(x) 
   if cont: y = vectors(y) #将测试样本标签化为矩阵 
   cost1 += (self.cost).fn(a,y)/len(train_data) 
  cost1 += lambd/len(train_data)*np.sum(np.linalg.norm(weight)**2 for weight in self.weight) #加上权值项 
  return cost1 
 def accuracy(self,train_data,cont=False): 
  if cont: 
   output1 = [(np.argmax(self.forward(x)),np.argmax(y)) for (x,y) in train_data] 
  else: 
   output1 = [(np.argmax(self.forward(x)), y) for (x, y) in train_data] 
  return sum(int(out1 == y) for (out1, y) in output1) 
 def update_minbatch_parameter(self,min_batch, eta,lambd,n): 
  """1) determine the weight and bias 
   2) calculate the the delta 
   3) update the data """ 
  able_b = [np.zeros(b.shape) for b in self.bias] 
  able_w=[np.zeros(w.shape) for w in self.weight] 
  for x,y in min_batch: #每次只取一个样本? 
   deltab,deltaw = self.backprop(x,y) 
   able_b =[a_b+dab for a_b, dab in zip(able_b,deltab)] #实际上对dw,db做批次累加,最后小批次取平均 
   able_w = [a_w + daw for a_w, daw in zip(able_w, deltaw)] 
  self.weight = [weight - eta * (dw) / len(min_batch)- eta*(lambd*weight)/n for weight, dw in zip(self.weight,able_w) ] 
  #增加正则化项:eta*lambda/m *weight 
  self.bias = [bias - eta * db / len(min_batch) for bias, db in zip(self.bias, able_b)] 
 
 def backprop(self,x,y): 
  """" 1) clacu the forward value 
   2) calcu the delta: delta =(y-f(z)); deltak = delta*w(k)*fz(k-1)' 
   3) clacu the delta in every layer: deltab=delta; deltaw=delta*fz(k-1)""" 
  deltab = [np.zeros(b.shape) for b in self.bias] 
  deltaw = [np.zeros(w.shape) for w in self.weight] 
  zs = [] 
  activate = x 
  activates = [x] 
  for w,b in zip(self.weight,self.bias): 
   z =np.dot(w, activate) +b 
   zs.append(z) 
   activate = sigmoid(z) 
   activates.append(activate) 
   # backprop 
  delta = self.cost.delta(zs[-1],activates[-1],y) #调用不同代价函数的方法求梯度 
  deltab[-1] = delta 
  deltaw[-1] = np.dot(delta ,activates[-2].transpose()) 
  for i in xrange(2,self.num_layer): 
   z = zs[-i] 
   delta = np.dot(self.weight[-i+1].transpose(),delta)* sig_derivate(z) 
   deltab[-i] = delta 
   deltaw[-i] = np.dot(delta,activates[-i-1].transpose()) 
  return (deltab,deltaw) 
 
 def save(self,filename): 
  """将训练好的网络采用json(java script object notation)将对象保存成字符串保存,用于生产部署 
  encoder=json.dumps(data) 
  python 原始类型(没有数组类型)向 json 类型的转化对照表: 
   python    json 
   dict    object 
  list/tuple   arrary 
  int/long/float  number 
  .tolist() 将数组转化为列表 
  >>> a = np.array([[1, 2], [3, 4]]) 
  >>> list(a) 
  [array([1, 2]), array([3, 4])] 
  >>> a.tolist() 
  [[1, 2], [3, 4]] 
  """ 
  data = {"sizes": self.sizes,"weight": [weight.tolist() for weight in self.weight], 
    "bias": ([bias.tolist() for bias in self.bias]), 
    "cost": str(self.cost.__name__)} 
  # 保存网络训练好的权值,偏置,交叉熵参数。 
  f = open(filename, "w") 
  json.dump(data,f) 
  f.close() 
 
def load_net(filename): 
 """采用data=json.load(json.dumps(data))进行解码, 
 decoder = json.load(encoder) 
 编码后和解码后键不会按照原始data的键顺序排列,但每个键对应的值不会变 
 载入训练好的网络用于测试""" 
 f = open(filename,"r") 
 data = json.load(f) 
 f.close() 
 # print "data[cost]", getattr(sys.modules[__name__], data["cost"])#获得属性__main__.CrossEntropyCost 
 # print "data[cost]", data["cost"], data["sizes"] 
 net = Network(data["sizes"], cost=data["cost"]) #网络初始化 
 net.weight = [np.array(w) for w in data["weight"]] #赋予训练好的权值,并将list--->array 
 net.bias = [np.array(b) for b in data["bias"]] 
 return net 
 
def sig_derivate(z): 
 """derivate sigmoid""" 
 return sigmoid(z) * (1-sigmoid(z)) 
 
def sigmoid(x): 
 sigm=1.0/(1.0+exp(-x)) 
 return sigm 
 
def vectors(y): 
 """赋予标签""" 
 label = np.zeros((10,1)) 
 label[y] = 1.0 #浮点计算 
 return label

3) 网络测试

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
# @Time : 2017-03-12 15:24 
# @Author : CC 
# @File : net_test.py 
 
import net_load_data 
# net_load_data.load_data() 
train_data,validation_data,test_data = net_load_data.data_transform() 
 
import net_network2 as net 
cost = net.QuadraticCost 
cost = net.CrossEntroyCost 
lambd = 0 
net1 = net.Network([784,50,10],cost) 
min_batch_size = 30 
eta = 3.0 
epoches = 2 
net1.SGD(train_data,min_batch_size,epoches,eta,test_data, 
   lambd, 
   monitor_train_cost=True, 
   monitor_train_accuracy=True, 
   monitor_test_cost=True, 
   monitor_test_accuracy=True 
   ) 
print "complete"

4 调用训练好的网络进行测试

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 
# @Time : 2017-03-28 17:27 
# @Author : CC 
# @File : forward_test.py 
 
import numpy as np 
# 对训练好的网络直接进行调用,并用测试样本进行测试 
import net_load_data #导入测试数据 
import net_network2 as net 
train_data,validation_data,test_data = net_load_data.data_transform() 
net = net.load_net(filename= "net_save")  #导入网络 
output = [(np.argmax(net.forward(x)),y) for (x,y) in test_data] #测试 
print sum(int(y1 == y2) for (y1,y2) in output)  #输出最终值

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
跟老齐学Python之大话题小函数(2)
Oct 10 Python
Python简单计算文件MD5值的方法示例
Apr 11 Python
python如何实现一个刷网页小程序
Nov 27 Python
对Python捕获控制台输出流的方法详解
Jan 07 Python
Python学习笔记之变量、自定义函数用法示例
May 28 Python
利用anaconda保证64位和32位的python共存
Mar 09 Python
python3.6 tkinter实现屏保小程序
Jul 30 Python
django foreignkey外键使用的例子 相当于left join
Aug 06 Python
python os.path.isfile()因参数问题判断错误的解决
Nov 29 Python
关于Keras模型可视化教程及关键问题的解决
Jan 24 Python
Python爬虫实现HTTP网络请求多种实现方式
Jun 19 Python
Python基础教程之输入输出和运算符
Jul 26 Python
python构建深度神经网络(DNN)
Mar 10 #Python
Python使用numpy实现BP神经网络
Mar 10 #Python
python实现日常记账本小程序
Mar 10 #Python
python实现简单神经网络算法
Mar 10 #Python
TensorFlow saver指定变量的存取
Mar 10 #Python
TensorFLow用Saver保存和恢复变量
Mar 10 #Python
tensorflow创建变量以及根据名称查找变量
Mar 10 #Python
You might like
php表单提交问题的解决方法
2011/04/12 PHP
Mootools 1.2教程 定时器和哈希简介
2009/09/15 Javascript
JAVASCRIPT车架号识别/验证函数代码 汽车车架号验证程序
2012/01/08 Javascript
javascript的解析执行顺序在各个浏览器中的不同
2014/03/17 Javascript
JS实现的N多简单无缝滚动代码(包含图文效果)
2015/11/06 Javascript
原生JS封装Ajax插件(同域、jsonp跨域)
2016/05/03 Javascript
js中常用的Math方法总结
2017/01/12 Javascript
JS实现汉字与Unicode码相互转换的方法详解
2017/04/28 Javascript
Express下采用bcryptjs进行密码加密的方法
2018/02/07 Javascript
Element-ui table中过滤条件变更表格内容的方法
2018/03/02 Javascript
Vue.directive 自定义指令的问题小结
2018/03/04 Javascript
详解vue中async-await的使用误区
2018/12/05 Javascript
vue实现todolist功能、todolist组件拆分及todolist的删除功能
2019/04/11 Javascript
express中static中间件的具体使用方法
2019/10/17 Javascript
react国际化化插件react-i18n-auto使用详解
2020/03/31 Javascript
[44:15]国士无双DOTA2 6.82版本详解(上)
2014/09/28 DOTA
使用grappelli为django admin后台添加模板
2014/11/18 Python
Python找出9个连续的空闲端口
2016/02/01 Python
用python实现百度翻译的示例代码
2018/03/09 Python
对python中raw_input()和input()的用法详解
2018/04/22 Python
django ManyToManyField多对多关系的实例详解
2019/08/09 Python
修改 CentOS 6.x 上默认Python的方法
2019/09/06 Python
解决安装pyqt5之后无法打开spyder的问题
2019/12/13 Python
CentOS7下安装python3.6.8的教程详解
2020/01/03 Python
Python利用myqr库创建自己的二维码
2020/11/24 Python
CSS3 实现童年的纸飞机
2019/05/05 HTML / CSS
应用电子技术专业个人求职信
2013/09/21 职场文书
幼儿教师考核制度
2014/01/25 职场文书
总经理文秘岗位职责
2014/02/03 职场文书
运动会开幕式解说词
2014/02/05 职场文书
消防先进事迹材料
2014/02/10 职场文书
基层党组织公开承诺书
2014/03/28 职场文书
教师节宣传方案
2014/05/23 职场文书
假释思想汇报范文
2014/10/11 职场文书
2019年最新七夕唯美祝福语(60条)
2019/07/22 职场文书
Python数据可视化之绘制柱状图和条形图
2021/05/25 Python