美文网首页
DNN基于python的实现

DNN基于python的实现

作者: 倔犟的贝壳 | 来源:发表于2019-06-25 16:34 被阅读0次

使用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

相关文章

网友评论

      本文标题:DNN基于python的实现

      本文链接:https://www.haomeiwen.com/subject/urcxcctx.html