机器学习(11.1)--神经网络(nn)算法的深入与优化(1)--介绍

在前面的文章已经对神经网络的基本算法流程做了详细的介绍
机器学习(1)--神经网络初探
机器学习(10.4)--手写数字识别的不同算法比较(4)--神经网络

但中间也存在很多不是很明确的地方,同时也存在一些优化的可能
本系列文章将对这些相关内容做更深一步的研究与解析
这篇文章是本系列的总体介绍、一些说明及一些相关文章的索引
1、关于初始代码段的说明,本系列方章将以 机器学习(10.4)--手写数字识别的不同算法比较(4)--神经网络
    中的第三段代码段为基本代码,之后深入与优化的过程如无特别说明,都将以这段代码为基础,
    本篇文章,将设置多种的参数,提供测试,之后代码如无特殊说明,将以下参数为基础进行深入与研究,
        mnistNN(midLayes=[30],epochs=15,learningRate=3,batchNum=10)
    即每组的batch有10条记录,中间层有30个神经元,学习率为3,

2、之前的神经网络未解决的问题:
    2.1、激活函数(即代码中的 sigmoid)是什么?
        这个在  机器学习09--神经网络的激活函数(Activation Function)及python代码实现  有了介绍
    2.2、代价(Cost)函数是什么作用是什么?
        其实在这段代码段里时看不到代价函数,因为根本没写,但为什么还要有这个东西?
        2.2.1 机器学习(11.2)--神经网络(nn)算法的深入与优化(2) -- QuadraticCost、CorssEntropyCost、SoftMax javascript数据变化测试代码 
        2.2.2 机器学习(11.3)--神经网络(nn)算法的深入与优化(3) -- QuadraticCost(二次方代价函数)数理分析
        2.2.3 机器学习(11.4)--神经网络(nn)算法的深入与优化(4) -- CorssEntropyCost(交叉熵代价函数)数理分析与代码实现


3、有什么地方可以优化的
    3.1 softmax 是什么,在  TensorFlow实例(4)--MNIST简介及手写数字分类算法  中已经应用了softmax,

        但那是GOOGLE的TensorFlow已经封装好的function

        3.1.1 机器学习(11.2)--神经网络(nn)算法的深入与优化(2) -- QuadraticCost、CorssEntropyCost、SoftMax javascript数据变化测试代码   中有一个SoftMax数值变化的简单小程序,有兴趣可以使用看看
        3.1.2 机器学习(11.5)--神经网络(nn)算法的深入与优化(5) -- softmax的代码实现


代码段为即为前面1点提到的基本代码段,后面有多种调用参数,除了第一种,别的都被我注释了,想测试的可以行调整

# -*- coding:utf-8 -*-
import pickle  
import gzip  
import numpy as np  
import random

#激活函数
def sigmoid(z):  
    return 1.0 / (1.0 + np.exp(-z))  
  
def sigmoid_deriv(z):  
    return sigmoid(z) * (1 - sigmoid(z)) 

#读取数据
def loadData(trainingNum = None,testNum=None):
    with gzip.open(r'mnist.pkl.gz', 'rb')  as f:
        training_data, validation_data, test_data = pickle.load(f,encoding='bytes') 
    training_label = np.zeros([training_data[1].shape[0],10,1])
    for index,val in enumerate(training_data[1]): training_label[index][val] = 1
    training_data = list(zip(training_data[0].reshape(-1,784,1),training_label))
    test_data = list(zip(test_data[0].reshape(-1,784,1),test_data[1]))
    if trainingNum !=None:
        training_data = training_data[0:trainingNum]
    if trainingNum !=None:
        test_data = test_data[0:testNum] 

    return training_data,test_data

def batchData(batch,layers,weights,biases):
    batch_w = [np.zeros(b.shape) for b in weights]  
    batch_b = [np.zeros(b.shape) for b in biases]  
    for item in batch:
        item_w,item_b=itemData(item,layers,weights,biases)
        #当batch下每条记录计算完后加总
        for index in range(0,len(batch_w)):
            batch_w[index] = batch_w[index] + item_w[index]
            batch_b[index] = batch_b[index] + item_b[index]
    return batch_w,batch_b

def itemData(item,layers,weights,biases):
    '''单条记录的正反向计算'''
    #正向计算
    zs = []
    acts = [item[0]]
    for w,b in zip(weights,biases):
        z = np.dot(w,acts[-1]) + b
        zs.append(z)
        acts.append(sigmoid(z))
    
    #反向计算
    item_w = [np.zeros(b.shape) for b in weights]   
    item_b = [np.zeros(b.shape) for b in biases]  
    for index in range(-1,-1 * len(layers),-1):
        if index == -1:
            item_b[index] = acts[index] - item[1] 
        else:
            item_b[index] = np.dot(weights[index + 1].T,item_b[index + 1])
        item_b[index] = item_b[index] * sigmoid_deriv(zs[index])  
        item_w[index] = np.dot(item_b[index],acts[index - 1].T)
    return item_w,item_b

def predict(test_data,weights,biases):
    #6、正向计算测试集:计算出结果
    #7、和正确结果比较,统计出正确率
    correctNum=0
    for testImg,testLabel in test_data:
        for w,b in  zip( weights,biases):
            testImg= sigmoid(np.dot(w, testImg)+b)  
        if np.argmax(testImg)==testLabel : correctNum+=1
    return correctNum

def mnistNN(trainingNum = None,testNum = None,midLayes=[20,15],epochs=6,batchNum=10,learningRate=3):
    training_data,test_data=loadData(trainingNum,testNum)

    #1、读取数据,调整数据格式以适配算法,设置基本参数
    layers = [training_data[0][0].shape[0]]+midLayes+[training_data[0][1].shape[0]] 
    trainingNum = len(training_data)

    #2、建立初始化的weights和biases
    weights = [np.random.randn(layers[x + 1],layers[x])  for x in range(len(layers) - 1)]
    biases = [np.random.randn(layers[x + 1],1)  for x in range(len(layers) - 1)]

    for j in range(epochs):
        random.shuffle(training_data)  
        batchGroup = [training_data[x:x + batchNum] for x in range(0,trainingNum,batchNum)]
        for batch in batchGroup:
            batch_w,batch_b=batchData(batch,layers,weights,biases)
            #一组batch计算结束后,求平均并修正weights和biases
            for index in range(0,len(batch_w)):
                batch_w[index] = batch_w[index] / batchNum
                weights[index] = weights[index] - learningRate * batch_w[index]
                batch_b[index] = batch_b[index] / batchNum
                biases[index] = biases[index] - learningRate * batch_b[index]
        print("共 %d 轮训练,第 %d 轮训练结束,测试集数量为 %d 条,测试正确 %d 条。"%(epochs,j+1,len(test_data),predict(test_data,weights,biases)))


#参数组1  多调试几次,你会发现这组数据结果比较不稳定
mnistNN(midLayes=[30],epochs=15,learningRate=3)   


#参数组2 这组数据结果相对稳定,但部份正确率并不见得比组1好
#mnistNN(midLayes=[20,15],epochs=6,learningRate=3)  #参数组2 这组数据结果相对稳定,但部份正确率并不见得比组1好


#比起参数组2,在结果上并没有显著的差异,说明神经层的增加并不一定会影响到最终结果
#那什么样的是合理的,即使最终算法就是正确的,但在测试时,都要从各种参数中去测试,才能找到合理的参数
#mnistNN(midLayes=[25,20,15],epochs=6,learningRate=3)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值