簡單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

裏面的模型已經訓練好,可以使用,也可以自行繼續訓練。

                                                                                                                                        有錯誤請指出,轉載請附加原創地址

 

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