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

这篇文章在前一篇文章: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构建深度神经网络(DNN)
  • python实现简单神经网络算法
  • Python实现的三层BP神经网络算法示例
  • Python实现的径向基(RBF)神经网络示例
  • Python编程实现的简单神经网络算法示例
  • python实现神经网络感知器算法
  • python机器学习之神经网络(三)
  • python机器学习之神经网络(一)
  • Python实现感知器模型、两层神经网络
  • TensorFlow平台下Python实现神经网络
(0)

相关推荐

  • Python编程实现的简单神经网络算法示例

    本文实例讲述了Python编程实现的简单神经网络算法.分享给大家供大家参考,具体如下: python实现二层神经网络 包括输入层和输出层 # -*- coding:utf-8 -*- #! python2 import numpy as np #sigmoid function def nonlin(x, deriv = False): if(deriv == True): return x*(1-x) return 1/(1+np.exp(-x)) #input dataset x = np.

  • TensorFlow平台下Python实现神经网络

    本篇文章主要通过一个简单的例子来实现神经网络.训练数据是随机产生的模拟数据集,解决二分类问题. 下面我们首先说一下,训练神经网络的一般过程: 1.定义神经网络的结构和前向传播的输出结果 2.定义损失函数以及反向传播优化的算法 3.生成会话(Session)并且在训练数据上反复运行反向传播优化算法 要记住的一点是,无论神经网络的结构如何变化,以上三个步骤是不会改变的. 完整代码如下: import tensorflow as tf #导入TensorFlow工具包并简称为tf from numpy

  • Python实现的径向基(RBF)神经网络示例

    本文实例讲述了Python实现的径向基(RBF)神经网络.分享给大家供大家参考,具体如下: from numpy import array, append, vstack, transpose, reshape, \ dot, true_divide, mean, exp, sqrt, log, \ loadtxt, savetxt, zeros, frombuffer from numpy.linalg import norm, lstsq from multiprocessing impor

  • python构建深度神经网络(DNN)

    本文学习Neural Networks and Deep Learning 在线免费书籍,用python构建神经网络识别手写体的一个总结. 代码主要包括两三部分: 1).数据调用和预处理 2).神经网络类构建和方法建立 3).代码测试文件 1)数据调用: #!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2017-03-12 15:11 # @Author : CC # @File : net_load_data.py # @Soft

  • python机器学习之神经网络(一)

    python有专门的神经网络库,但为了加深印象,我自己在numpy库的基础上,自己编写了一个简单的神经网络程序,是基于Rosenblatt感知器的,这个感知器建立在一个线性神经元之上,神经元模型的求和节点计算作用于突触输入的线性组合,同时结合外部作用的偏置,对若干个突触的输入求和后进行调节.为了便于观察,这里的数据采用二维数据. 目标函数是训练结果的误差的平方和,由于目标函数是一个二次函数,只存在一个全局极小值,所以采用梯度下降法的策略寻找目标函数的最小值. 代码如下: import numpy

  • python机器学习之神经网络(三)

    前面两篇文章都是参考书本神经网络的原理,一步步写的代码,这篇博文里主要学习了如何使用neurolab库中的函数来实现神经网络的算法. 首先介绍一下neurolab库的配置: 选择你所需要的版本进行下载,下载完成后解压. neurolab需要采用python安装第三方软件包的方式进行安装,这里介绍一种安装方式: (1)进入cmd窗口 (2)进入解压文件所在目录下 (3)输入 setup.py install 这样,在python安装目录的Python27\Lib\site-packages下,就可

  • python实现神经网络感知器算法

    现在我们用python代码实现感知器算法. # -*- coding: utf-8 -*- import numpy as np class Perceptron(object): """ eta:学习率 n_iter:权重向量的训练次数 w_:神经分叉权重向量 errors_:用于记录神经元判断出错次数 """ def __init__(self, eta=0.01, n_iter=2): self.eta = eta self.n_iter

  • Python实现的三层BP神经网络算法示例

    本文实例讲述了Python实现的三层BP神经网络算法.分享给大家供大家参考,具体如下: 这是一个非常漂亮的三层反向传播神经网络的python实现,下一步我准备试着将其修改为多层BP神经网络. 下面是运行演示函数的截图,你会发现预测的结果很惊人! 提示:运行演示函数的时候,可以尝试改变隐藏层的节点数,看节点数增加了,预测的精度会否提升 import math import random import string random.seed(0) # 生成区间[a, b)内的随机数 def rand(

  • python实现简单神经网络算法

    python实现简单神经网络算法,供大家参考,具体内容如下 python实现二层神经网络 包括输入层和输出层 import numpy as np #sigmoid function def nonlin(x, deriv = False): if(deriv == True): return x*(1-x) return 1/(1+np.exp(-x)) #input dataset x = np.array([[0,0,1], [0,1,1], [1,0,1], [1,1,1]]) #out

  • Python实现感知器模型、两层神经网络

    本文实例为大家分享了Python实现感知器模型.两层神经网络,供大家参考,具体内容如下 python 3.4 因为使用了 numpy 这里我们首先实现一个感知器模型来实现下面的对应关系 [[0,0,1], --- 0 [0,1,1], --- 1 [1,0,1], --- 0 [1,1,1]] --- 1 从上面的数据可以看出:输入是三通道,输出是单通道. 这里的激活函数我们使用 sigmoid 函数 f(x)=1/(1+exp(-x)) 其导数推导如下所示: L0=W*X; z=f(L0);

随机推荐