DNN基于python的实现

使用DNN实现手写数字识别

使用mnist 数据集,基于python基础库,用含一层隐藏层的神经网络训练一个简单的模型来识别手写数字。
准确率 90%以上。
并用自己的手写数字的图片验证。

加载所需的库

import sys ,os 
import numpy as np
import matplotlib.pyplot as plt
sys.path.append(os.pardir) #加入当前目录,要用到mnist.py
from dataset.mnist import load_mnist
from PIL import Image

加载mnist数据集

#(训练图像,训练标签),(测试图像,测试标签)
# mnist的图像均为28*28尺寸的数据,通道为1
(x_train_origin,t_train_origin),(x_test_origin,t_test_origin) = load_mnist(normalize=True,flatten=False,one_hot_label=True)

m_train = x_train_origin.shape[0] #训练集大小
m_test = x_test_origin.shape[0] #测试集大小
num_px = x_train_origin.shape[2] #px = height = width

num_category = 10 #分类类别个数总共有10个0-9

print("number of trainning sample is :"+repr(m_train))
print("number of test sample is :"+repr(m_test))

print("shape of x_train is :"+repr(x_train_origin.shape))
print("shape of t_train is :"+repr(t_train_origin.shape))
print("shape of x_test is :"+repr(x_test_origin.shape))
print("shape of t_test is :"+repr(t_test_origin.shape))
number of trainning sample is :60000
number of test sample is :10000
shape of x_train is :(60000, 1, 28, 28)
shape of t_train is :(60000, 10)
shape of x_test is :(10000, 1, 28, 28)
shape of t_test is :(10000, 10)

reshape

将数据集的shape转变成(nx,m) ,nx为特征数量,这里即像素个数,m为数据大小.
方便神经网络的计算

train_set_x = x_train_origin.reshape(x_train_origin.shape[0],-1).T
train_set_y = t_train_origin.T
test_set_x = x_test_origin.reshape(x_test_origin.shape[0],-1).T
test_set_y  = t_test_origin.T

print("shape of train_set_x is :"+repr(train_set_x.shape))
print("shape of train_set_y is :"+repr(train_set_y.shape))
print("shape of test_set_x is :"+repr(test_set_x.shape))
print("shape of test_set_y is :"+repr(test_set_y.shape))
shape of train_set_x is :(784, 60000)
shape of train_set_y is :(10, 60000)
shape of test_set_x is :(784, 10000)
shape of test_set_y is :(10, 10000)

显示图像

index = 0
plt.imshow(x_train_origin[index].reshape((28,28)),cmap = plt.cm.gray)
print("y is:"+str(np.argmax(t_train_origin[index])))
y is:5
output_8_1.png

sigmoid函数

1/(1+exp(-z))

def sigmoid(z):
    """
    计算z的sigmoid 值
    Arguments:
    z -- 实数或任意数组
    Return:
    s --  返回类型与z一致
   """
    
    s = 1 / (1+np.exp(-z))
    return s    
s = sigmoid(0)
print("s is :"+str(s))
s is :0.5

初始化参数 w ,b

def initilize_params(dim,num_categories) :
    """
    init w and b 
    Arguments:
        dim -- size of w
        num_categories: number of total categories
    Return :
    w -- shape of (dim,num_categories)
    b -- shape of (num_categories,1)
     """
    w = np.zeros((dim,num_categories))
    b = np.zeros((num_categories,1))
    assert(w.shape == (dim,num_categories))
    assert(b.shape == (num_categories,1))
    return w,b

前向传播与反向传播

 def propagate(w,b,X,Y): 
    """
    Arguments:
        w-- weights,numpy array of shape(num_px*num_px,num_categories)
        b -- bias of shape (num_categories,1)
        X -- data of shape (num_px*num_px,number of examples)
        Y -- tag of shape (num_categories, number of example)
        
        Return :
            grads -- a dict ,derivative of dw,db
            cost  -- current cost 
    """
    m = X.shape[1]
    #前向传播 START 计算损失
    #caculate W^T*X +b
    z = np.dot(w.T,X) + b  #shape is:(num_categories,number of examples)
    yhat = sigmoid(z)  # 每个样本0-9的预测概率,shape is same as z 
    #计算损失
    cost = -np.sum((Y * np.log(yhat) + (1-Y)*np.log(1-yhat)))/m
    # 前向传播 END
    
    # 反向传播 START
    dw = np.dot(X , (yhat - Y).T)/m #shape is same with w
    db =  np.sum((yhat - Y),axis = 1)/m #shape is same with b
    db = db.reshape(b.shape)
    #反向传播 END
    
    assert(dw.shape == w.shape)
    assert(db.shape == b.shape)
    
    grads = {"dw":dw,
                "db":db}
    
        
    return grads, cost 


优化

def optimize(w,b,X,Y,number_iterations,learning_rate):
        """
        optimize w and b by running gradient descent algorithm
    Arguments:
        w-- weights,numpy array of shape(num_px*num_px,num_categories)
        b -- bias of shape (num_categories,1)
        X -- data of shape (num_px*num_px,number of examples)
        Y -- tag of shape (num_categories, number of example)
        number_iterations -- number of iterate for gradient descent 
        learning_rate -- learning rate for gradient descent   
        
        Return :
            params -- a dict ,include w ,b 
            grads -- a dict ,derivative of dw,db
            cost  -- current cost 
    """
        costs= []
        for i in range(number_iterations):
        
            grads, cost = propagate(w,b,X,Y)
    
            dw = grads["dw"]
            db = grads["db"]
        
            #update w and b 
            w = w -  learning_rate*dw
            b = b  -learning_rate*db    
        
            if(i % 100) == 0:
                costs.append(cost)
                print ("cost after iteration %i is :%f" %(i,cost))

        params = {"w":w,
                     "b": b}
        grads = {"dw":dw,
                "db":db}
        return params,grads,costs
    

预测

def predicate (X ,w ,b):
    """
    predicate of data
    Arguments:
        w-- weights,numpy array of shape(num_px*num_px,num_categories)
        b -- bias of shape (num_categories,1)
        X -- data of shape (num_px*num_px,number of examples)
        
        Return :
        Y_pred_one_hot_label -- the predicate result of X,shape is :(num_categories,number of examples) 
        Y_pred_number -- a vector ,the predicate with a excactly number for each X
    """
    m = X.shape[1]
    z = np.dot(w.T,X)+b
    yhats = sigmoid(z).T
    Y_pred_one_hot_label = np.zeros((b.shape[0],m)) #one-hot-label 
    Y_pred_number =np.zeros((1,m)) #a number that it predicate
    for i in range(yhats.shape[0]):
        max_index = np.argmax(yhats[i])
        Y_pred_one_hot_label[max_index,i] = 1
        Y_pred_number[0,i] = int(max_index)
    return Y_pred_one_hot_label,Y_pred_number
        
    

构建模型

把所有东西整合起来,构建模型

def nurvus_network_model(train_set_x, train_set_y, test_set_x, test_set_y, num_categories, number_iterations=2000, learning_rate=0.5):
        """
    construct a model to predicate number picture
    Arguments:
        train_set_x-- training data,numpy array of shape(num_px*num_px,number of examples)
        train_set_y -- the tag of trainning data  of shape (num_categories,number of examples)
        test_set_x -- test examples,numpy array of shape (num_px*num_px,number of examples)
        test_set_y -- the tag of test  data  of shape (num_categories,number of examples)
        num_categories -- number of categories
        number_iterations -- the number of iterate for optimize
        learning_rate --

        Return :
        d -- dictionary contain info for model
    """
        dim = train_set_x.shape[0]
        # init w and b
        w, b = initilize_params(dim, num_categories)
        params, grads, costs = optimize(
            w, b, train_set_x, train_set_y, number_iterations=number_iterations, learning_rate=learning_rate)
        w = params["w"]
        b = params["b"]

        Y_pred_train_one_hot_label, Y_pred_train_number = predicate(
            train_set_x, w, b)
        Y_pred_test_one_hot_label, Y_pred_test_number = predicate(
            test_set_x, w, b)

        print("train accuracy: {} %".format(
            100 - np.mean(np.sum(np.abs(Y_pred_train_one_hot_label - train_set_y), axis=0)/2) * 100))
        print("test accuracy: {} %".format(
            100 - np.mean(np.sum(np.abs(Y_pred_test_one_hot_label - test_set_y), axis=0)/2) * 100))

        d = {"w":w,
             "b":b,
            "costs":costs,
            "Y_pred_train":Y_pred_train_number,
            "Y_pred_train_one_hot":Y_pred_train_one_hot_label,
            "Y_pred_test":Y_pred_test_number,
            "Y_pred_test_one_hot":Y_pred_test_one_hot_label,
            "learning_rate":learning_rate,
            "iterations":number_iterations}
        return d
number_categories = 10 
d = nurvus_network_model(train_set_x,train_set_y,test_set_x,test_set_y,num_categories = 10,number_iterations=2000,learning_rate=0.6)
cost after iteration 0 is :6.931472
cost after iteration 100 is :0.903445
cost after iteration 200 is :0.813852
.......
cost after iteration 1800 is :0.656671
cost after iteration 1900 is :0.654527
train accuracy: 91.66 %
test accuracy: 91.82 %
index = 20
y_pred_test = d["Y_pred_test"]
plt.imshow(test_set_x[:,index].reshape((28,28)),cmap = plt.cm.gray)
print("y is:"+str(np.argmax(test_set_y[:,index])))

print("your predicate result is :"+str(int(y_pred_test[0,index])))
y is:9
your predicate result is :9
output_27_1.png

画出损失函数图

costs = d["costs"]
plt.plot(costs)
plt.xlabel("iterations/hundreds")
plt.ylabel("costs")
plt.show()
output_29_0.png

用自己的图片测试

import scipy
from PIL import Image
from scipy import ndimage

my_image_name = "5.jpeg"
#my_image_name = "2.jpeg"
#my_image_name = "7.jpeg"
fname = my_image_name
image_origin = Image.open(fname)
a = np.asarray(image_origin)
print(a.shape)
image = image_origin.convert(mode = "L")
image = image.resize((28,28),resample = Image.ANTIALIAS)

a = np.asarray(image)
plt.imshow(image,cmap=plt.cm.gray) #显示图像
a = 255 -a 
mean = np.mean(a)
a = np.where(a < mean,0,a)
a = a/255
input_x = a.reshape((28*28,1))

onehotlabel,predicate_number = predicate(input_x, d["w"],d["b"])
print("your predicate number is :"+str(int(predicate_number[0][0])))


(28, 28, 3)
your predicate number is :5
output_31_1.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,736评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,167评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,442评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,902评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,302评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,573评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,847评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,562评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,260评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,531评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,021评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,367评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,016评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,068评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,827评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,610评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,514评论 2 269

推荐阅读更多精彩内容