简单python神经网络从原理到搭建框架以及模板使用实例(python识别手写字体)

神经网络原理

学习过程:

       在分类的时候,使用误差进行修正参数,就像是在座标轴一个点的位置,第一次在点左边,加上一段距离,第二次在右边,这两次猜的值与实际值的差值修正下一次的猜测加上或者减去的值,差值变小或者变大,相应的猜测减去或者加上的值也要相应调整。

核心思想

      神经网络的核心是使用多个分类器完成复杂发分类问题,就好比确定一个三角形需要三条直线。

 

神经网络模型:

 

每一层输入就是将各个输入相加。

 输入层值:input(i)

隐含层输入:hedden_input(j)=\sum (input(i)*w(i,j)))

输出层输入:output_in(k)=\sum (hedden_out(j)*w(k,j))

神经网络一般会使用sigmod作为激活函数:y=1/(1+e^-x),sigmod函数作为激活函数,比较平滑的激活过程,更接近真实生物神经。

误差反馈:

反馈过程:

      每个节点的修正值根据误差以及相应连接权值权重进行修改。

       训练中的误差一般会使用误差平方,避免正负误差抵消,同时,误差平方后,越小误差平方后误差越小,可以在误差减小时使学习步长减小。

\partial E/\partial W(j,k)=\partial (tk-t0)^2=-2*(tk-to)*(\partial ok/\partial w(j,k)))    (tk:目标值,to:实际值)

\partial (ok)=sigmod(\sum w(i,j)*oj)

\sum sigmod(x)=sigmod(x)(1-sigmod(x))

\small \partial E/\partial W(j,k)=-(tk-to)sigmod(\sum w(j,k)*oj)*(1-sigmod(\sum w(j,k)*oj))

编程部分:

这里使用python

里边的权值相乘相加可使用矩阵乘法完成(numpy.dot)

 

神经网络基本框架:

neuralnetwork.py

# coding=utf8
import time
from matplotlib import pyplot
import numpy
import scipy.special


class neuralnetwork:
    # 初始化神经网络,输入层,隐含层,输出层,学习速率
    def __init__(self, input_nodes, hidden_nodes, output_nodes, learning_rate):
        self.input_nodes = input_nodes
        self.hidden_nodes = hidden_nodes
        self.output_nodes = output_nodes
        self.learning_rate = learning_rate
        self.wih = numpy.random.rand(hidden_nodes, input_nodes) - 0.5
        self.who = numpy.random.rand(output_nodes, hidden_nodes) - 0.5
        self.activation_function = lambda x: scipy.special.expit(x)
        pass

    def query(self, input_list):  # 输入得到答案
        inputs = numpy.array(input_list, ndmin=2).T
        hidden_inputs = numpy.dot(self.wih, inputs)
        hidden_outputs = self.activation_function(hidden_inputs)
        final_inputs = numpy.dot(self.who, hidden_outputs)
        final_outputs = self.activation_function(final_inputs)
        return final_outputs
        pass

    def train(self, input_list, target_list):  # 训练,输入,目标输出
        inputs = numpy.array(input_list, ndmin=2).T
        hidden_inputs = numpy.dot(self.wih, inputs)
        hidden_outputs = self.activation_function(hidden_inputs)
        final_inputs = numpy.dot(self.who, hidden_outputs)
        final_outputs = self.activation_function(final_inputs)
        targets = numpy.array(target_list, ndmin=2).T
        output_error = targets - final_outputs
        hidden_error = numpy.dot(self.who.T, output_error)
        self.who += self.learning_rate * numpy.dot((output_error * final_outputs) * (1.0 - final_outputs),
                                                   numpy.transpose((hidden_outputs)))
        self.wih += self.learning_rate * numpy.dot((hidden_error * hidden_outputs) * (1.0 - hidden_outputs),
                                                   numpy.transpose(inputs))
        pass

有了这个框架,其他功能都可以在这个上面进行修改使用

下面是一个实际使用:

neuralnetwork打包成一个固定的神经网络函数。

network.py

# coding=utf8
from neuralnetwork import neuralnetwork
from matplotlib import pyplot
import numpy


# 创建一个神经网络,输入层784个节点,隐含层300个节点,输出层十个节点,训练速率0.2
# network_1 = neuralnetwork(784, 300, 10, 0.2)


# 保存网络参数到配置文件
def save_net(network_1):
    wih_csv = open('conf/wih.csv', 'w')
    for i in network_1.wih:
        for j in i:
            wih_csv.write(str(j) + ' ')
        wih_csv.write('\n')
    wih_csv.close()

    who_csv = open('conf/who.csv', 'w')
    for i in network_1.who:
        for j in i:
            who_csv.write(str(j) + ' ')
        who_csv.write('\n')
    who_csv.close()


# 训练网络
def train_net(data):
    network_1 = neuralnetwork(784, 300, 10, 0.3)
    set_net(network_1)
    ans = int(data[0])  # 正确答案
    input_list = numpy.array(map(float, data[1:]))  # 输入数据
    input_list = input_list / 255.0 * 0.99 + 0.01
    target = numpy.zeros(10) + 0.01
    target[ans] = 0.99
    network_1.train(input_list, target)  # 训练
    save_net(network_1)
    pass


# 将配置文件参数设置到网络
def set_net(network_1):
    wih_csv = open('conf/wih.csv', 'r')
    wih_data = wih_csv.readlines()
    wih_csv.close()
    r = 0
    for w in wih_data:
        w = w.split()
        w = map(float, w)
        network_1.wih[r] = numpy.array(w)
        r += 1

    who_csv = open('conf/who.csv', 'r')
    who_data = who_csv.readlines()
    who_csv.close()
    r = 0
    for w in who_data:
        w = w.split()
        w = map(float, w)
        network_1.who[r] = numpy.array(w)
        r += 1
    pass


# 询问答案
def query(input_list):
    network_1 = neuralnetwork(784, 300, 10, 0.1)
    set_net(network_1)
    network_1.query(input_list)
    output_list = list(network_1.query(input_list))
    return output_list.index(max(output_list))

以下是使用搭建好的神经网络进行手写字体识别,神经网络已经训练好,并将神经网络的参数已经写到了配置文件中,直接使用network中的query函数

test.py

# coding=utf8
from PIL import Image
from matplotlib import pyplot
import numpy, cv2
import network

for i in range(20):
    img = cv2.imread('picture/{}.png'.format(i), 0)
    img = cv2.resize(img, (28, 28))
    img = numpy.array(img)
    # img = img.dot((numpy.array([1.0 / 3, 1.0 / 3, 1.0 / 3])).T)
    img = img / 255.0 * 0.99 + 0.01
    img = 1.0 - img
    input_list = img
    pyplot.imshow(input_list, cmap='Greys')  # 显示处理后的测试图片
    pyplot.show()
    input_list = numpy.asfarray(input_list.reshape(784))  # 处理成1*784
    print(i, network.query(input_list))  # 询问答案
    # net.train_net([i % 10] + list((input_list - 0.01) * 255 / 0.9))

此工程链接: https://git.swustacm.cn/hoojou/neural   或者:https://github.com/hoojoulin/neural

里面的模型已经训练好,可以使用,也可以自行继续训练。

                                                                                                                                        有错误请指出,转载请附加原创地址

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章