python構(gòu)建深度神經(jīng)網(wǎng)絡(luò)(續(xù))
這篇文章在前一篇文章:python構(gòu)建深度神經(jīng)網(wǎng)絡(luò)(DNN)的基礎(chǔ)上,添加了一下幾個(gè)內(nèi)容:
1) 正則化項(xiàng)
2) 調(diào)出中間損失函數(shù)的輸出
3) 構(gòu)建了交叉損失函數(shù)
4) 將訓(xùn)練好的網(wǎng)絡(luò)進(jìn)行保存,并調(diào)用用來(lái)測(cè)試新數(shù)據(jù)
1 數(shù)據(jù)預(yù)處理
#!/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():
"""載入解壓后的數(shù)據(jù),并讀取"""
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():
"""將數(shù)據(jù)轉(zhuǎn)化為計(jì)算格式"""
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萬(wàn)個(gè)數(shù)據(jù)分別逐個(gè)取出化成(784,1),逐個(gè)排列
n = [np.reshape(x, (784, 1)) for x in t_d[0]] # 將5萬(wàn)個(gè)數(shù)據(jù)分別逐個(gè)取出化成(784,1),逐個(gè)排列
# print 'n1',n1[0].shape
# print 'n',n[0].shape
m = [vectors(y) for y in t_d[1]] # 將5萬(wàn)標(biāo)簽(50000,1)化為(10,50000)
train_data = zip(n,m) # 將數(shù)據(jù)與標(biāo)簽打包成元組形式
n = [np.reshape(x, (784, 1)) for x in va_d[0]] # 將5萬(wàn)個(gè)數(shù)據(jù)分別逐個(gè)取出化成(784,1),排列
validation_data = zip(n,va_d[1]) # 沒(méi)有將標(biāo)簽數(shù)據(jù)矢量化
n = [np.reshape(x, (784, 1)) for x in te_d[0]] # 將5萬(wàn)個(gè)數(shù)據(jù)分別逐個(gè)取出化成(784,1),排列
test_data = zip(n, te_d[1]) # 沒(méi)有將標(biāo)簽數(shù)據(jù)矢量化
# 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):
"賦予標(biāo)簽"
label = np.zeros((10,1))
label[y] = 1.0 #浮點(diǎn)計(jì)算
return label
2 網(wǎng)絡(luò)定義和訓(xùn)練
#!/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():
"""定義二次代價(jià)函數(shù)類(lèi)的方法"""
@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():
"""定義交叉熵函數(shù)類(lèi)的方法"""
@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):
"""定義網(wǎng)絡(luò)結(jié)構(gòu)和方法"""
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):
"""權(quán)值初始化"""
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):
"""權(quán)值另一種初始化"""
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: # 每次提取一個(gè)批次的樣本
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") #保存網(wǎng)絡(luò)網(wǎng)絡(luò)參數(shù)
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) #將測(cè)試樣本標(biāo)簽化為矩陣
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) #加上權(quán)值項(xiàng)
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: #每次只取一個(gè)樣本?
deltab,deltaw = self.backprop(x,y)
able_b =[a_b+dab for a_b, dab in zip(able_b,deltab)] #實(shí)際上對(duì)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) ]
#增加正則化項(xiàng):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) #調(diào)用不同代價(jià)函數(shù)的方法求梯度
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):
"""將訓(xùn)練好的網(wǎng)絡(luò)采用json(java script object notation)將對(duì)象保存成字符串保存,用于生產(chǎn)部署
encoder=json.dumps(data)
python 原始類(lèi)型(沒(méi)有數(shù)組類(lèi)型)向 json 類(lèi)型的轉(zhuǎn)化對(duì)照表:
python json
dict object
list/tuple arrary
int/long/float number
.tolist() 將數(shù)組轉(zhuǎn)化為列表
>>> 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__)}
# 保存網(wǎng)絡(luò)訓(xùn)練好的權(quán)值,偏置,交叉熵參數(shù)。
f = open(filename, "w")
json.dump(data,f)
f.close()
def load_net(filename):
"""采用data=json.load(json.dumps(data))進(jìn)行解碼,
decoder = json.load(encoder)
編碼后和解碼后鍵不會(huì)按照原始data的鍵順序排列,但每個(gè)鍵對(duì)應(yīng)的值不會(huì)變
載入訓(xùn)練好的網(wǎng)絡(luò)用于測(cè)試"""
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"]) #網(wǎng)絡(luò)初始化
net.weight = [np.array(w) for w in data["weight"]] #賦予訓(xùn)練好的權(quán)值,并將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):
"""賦予標(biāo)簽"""
label = np.zeros((10,1))
label[y] = 1.0 #浮點(diǎn)計(jì)算
return label
3) 網(wǎng)絡(luò)測(cè)試
#!/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 調(diào)用訓(xùn)練好的網(wǎng)絡(luò)進(jìn)行測(cè)試
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2017-03-28 17:27 # @Author : CC # @File : forward_test.py import numpy as np # 對(duì)訓(xùn)練好的網(wǎng)絡(luò)直接進(jìn)行調(diào)用,并用測(cè)試樣本進(jìn)行測(cè)試 import net_load_data #導(dǎo)入測(cè)試數(shù)據(jù) import net_network2 as net train_data,validation_data,test_data = net_load_data.data_transform() net = net.load_net(filename= "net_save") #導(dǎo)入網(wǎng)絡(luò) output = [(np.argmax(net.forward(x)),y) for (x,y) in test_data] #測(cè)試 print sum(int(y1 == y2) for (y1,y2) in output) #輸出最終值
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python tkinter庫(kù)繪制春聯(lián)和福字的示例詳解
馬上要過(guò)年了,這篇文章將用到Python中的tkinter庫(kù)來(lái)寫(xiě)一副春聯(lián)&福字送給大家。文中的實(shí)現(xiàn)方法講解詳細(xì),感興趣的小伙伴可以試一試2022-01-01
python 實(shí)現(xiàn)在shell窗口中編寫(xiě)print不向屏幕輸出
這篇文章主要介紹了python 實(shí)現(xiàn)在shell窗口中編寫(xiě)print不向屏幕輸出的代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02
詳解Python如何檢查一個(gè)數(shù)字是否是三態(tài)數(shù)
在數(shù)學(xué)中,三態(tài)數(shù)(Triangular?Number)是一種特殊的數(shù)列,它是由自然數(shù)按照一定規(guī)律排列而成的,本文主要介紹了如何使用Python檢查判斷一個(gè)數(shù)字是否是三態(tài)數(shù),需要的可以參考下2024-03-03
python使用knn實(shí)現(xiàn)特征向量分類(lèi)
這篇文章主要為大家詳細(xì)介紹了python使用knn實(shí)現(xiàn)特征向量分類(lèi),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12
Python實(shí)現(xiàn)過(guò)迷宮小游戲示例詳解
這篇文章主要介紹的是基于Python實(shí)現(xiàn)一個(gè)簡(jiǎn)單的過(guò)迷宮小游戲,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Python有一定的幫助,感興趣的可以學(xué)習(xí)一下2021-12-12
Tensorflow 定義變量,函數(shù),數(shù)值計(jì)算等名字的更新方式
今天小編就為大家分享一篇Tensorflow 定義變量,函數(shù),數(shù)值計(jì)算等名字的更新方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02
Python使用random.shuffle()打亂列表順序的方法
今天小編就為大家分享一篇Python使用random.shuffle()打亂列表順序的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-11-11
python 通過(guò)字符串調(diào)用對(duì)象屬性或方法的實(shí)例講解
下面小編就為大家分享一篇python 通過(guò)字符串調(diào)用對(duì)象屬性或方法的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-04-04

