神經網絡原理
學習過程:
在分類的時候,使用誤差進行修正參數,就像是在猜座標軸一個點的位置,第一次在點左邊,加上一段距離,第二次在右邊,這兩次猜的值與實際值的差值修正下一次的猜測加上或者減去的值,差值變小或者變大,相應的猜測減去或者加上的值也要相應調整。
核心思想
神經網絡的核心是使用多個分類器完成複雜發分類問題,就好比確定一個三角形需要三條直線。
神經網絡模型:
每一層輸入就是將各個輸入相加。
輸入層值:input(i)
隱含層輸入:hedden_input(j)=
輸出層輸入:output_in(k)=
神經網絡一般會使用sigmod作爲激活函數:,sigmod函數作爲激活函數,比較平滑的激活過程,更接近真實生物神經。
誤差反饋:
反饋過程:
每個節點的修正值根據誤差以及相應連接權值權重進行修改。
訓練中的誤差一般會使用誤差平方,避免正負誤差抵消,同時,誤差平方後,越小誤差平方後誤差越小,可以在誤差減小時使學習步長減小。
(tk:目標值,to:實際值)
編程部分:
這裏使用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
裏面的模型已經訓練好,可以使用,也可以自行繼續訓練。
有錯誤請指出,轉載請附加原創地址