以一个两层神经网络(输入层一般不计算在内,又称为单隐层神经网络)为例,每一层的计算过程比较像逻辑回归。
根据链式求导法则对前面的权值进行更新,与逻辑回归当中也有相似之处,同时,由于偏置量是通过 x 0 x_0 x0整合到了权值当中,所以在更新权值的同时,偏置量也会同时更新。本部分具体可以看西瓜书中的推导。
def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
self.inputNodes = inputnodes
self.hiddenNodes = hiddennodes
self.outputNodes = outputnodes
self.lr = learningrate
self.wih = numpy.random.normal(0.0, pow(self.hiddenNodes, -0.5), (self.hiddenNodes, self.inputNodes))
self.vho = numpy.random.normal(0.0, pow(self.outputNodes, -0.5), (self.outputNodes, self.hiddenNodes))
self.activationFunction = lambda x: scipy.special.expit(x)
def train(self, inputLists, targetList):
inputs = numpy.array(inputLists, ndmin=2).T
targets = numpy.array(targetList, ndmin=2).T
hiddenInputs = numpy.dot(self.wih, inputs)
hiddenOutputs = self.activationFunction(hiddenInputs)
finalInputs = numpy.dot(self.vho, hiddenOutputs)
finalOutputs = self.activationFunction(finalInputs)
outputErrors = targets - finalOutputs
hiddenErrors = numpy.dot(self.vho.T, outputErrors)
#对vho进行更新
self.vho += self.lr * numpy.dot((outputErrors * finalOutputs * (1.0 - finalOutputs)),
numpy.transpose(hiddenOutputs))
self.wih += self.lr * numpy.dot((hiddenErrors * hiddenOutputs * (1.0 - hiddenOutputs)),
numpy.transpose(inputs))
def predict(self, inputLists):
inputs = numpy.array(inputLists, ndmin=2).T
hiddenInputs = numpy.dot(self.wih, inputs)
hiddenOutputs = self.activationFunction(hiddenInputs)
finalInputs = numpy.dot(self.vho, hiddenOutputs)
finalOutputs = self.activationFunction(finalInputs)
return finalOutputs
神经网络类
import numpy
import scipy.special
import matplotlib.pyplot
numpy.set_printoptions(suppress=True)
class neuralNetwork:
def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
self.inputNodes = inputnodes
self.hiddenNodes = hiddennodes
self.outputNodes = outputnodes
self.lr = learningrate
self.wih = numpy.random.normal(0.0, pow(self.hiddenNodes, -0.5), (self.hiddenNodes, self.inputNodes))
self.vho = numpy.random.normal(0.0, pow(self.outputNodes, -0.5), (self.outputNodes, self.hiddenNodes))
self.activationFunction = lambda x: scipy.special.expit(x)
def train(self, inputLists, targetList):
inputs = numpy.array(inputLists, ndmin=2).T
targets = numpy.array(targetList, ndmin=2).T
hiddenInputs = numpy.dot(self.wih, inputs)
hiddenOutputs = self.activationFunction(hiddenInputs)
finalInputs = numpy.dot(self.vho, hiddenOutputs)
finalOutputs = self.activationFunction(finalInputs)
outputErrors = targets - finalOutputs
hiddenErrors = numpy.dot(self.vho.T, outputErrors)
#对vho进行更新
self.vho += self.lr * numpy.dot((outputErrors * finalOutputs * (1.0 - finalOutputs)),
numpy.transpose(hiddenOutputs))
self.wih += self.lr * numpy.dot((hiddenErrors * hiddenOutputs * (1.0 - hiddenOutputs)),
numpy.transpose(inputs))
def predict(self, inputLists):
inputs = numpy.array(inputLists, ndmin=2).T
hiddenInputs = numpy.dot(self.wih, inputs)
hiddenOutputs = self.activationFunction(hiddenInputs)
finalInputs = numpy.dot(self.vho, hiddenOutputs)
finalOutputs = self.activationFunction(finalInputs)
return finalOutputs
处理minst数据集并对手写数字进行训练、识别。
import csv
inputNodes = 784 #输入层节点数量 28*28
hiddenNodes = 100 #隐藏层节点数量
outputNodes = 10 #输出层节点数量
learningRate = 0.08 #学习率
n = neuralNetwork(inputNodes, hiddenNodes, outputNodes, learningRate)
dataFile = open("NNone/mnist_train.csv", 'r')
dataList = dataFile.readlines()
dataFile.close()
epochs = 5
for i in range(epochs):
for record in dataList:
allValues = record.split(',')
inputs = (numpy.asfarray(allValues[1:]) / 255.0 * 0.99) + 0.01
targets = numpy.zeros(outputNodes) + 0.01
targets[int(allValues[0])] = 0.99
n.train(inputs, targets)
#定义混淆矩阵 行号为预测值 列号为真实值
result = numpy.zeros([10, 10])
numTrue = []
numPredict = []
testDataFile = open("NNone/mnist_test.csv", 'r')
testDataList = testDataFile.readlines()
print(type(testDataList))
testDataFile.close()
testWrongFile = open("NNone/testWrong.csv", 'w+', newline='')
# print(dataList[0])
scorecard = []
for record in testDataList:
allValues = record.split(',')
saveWrongData = allValues.copy()
correctValue = int(allValues[0]) #实际值
inputs = (numpy.asfarray(allValues[1:]) / 255.0 * 0.99) + 0.01 #归一化
outputs = n.predict(inputs)
label = numpy.argmax(outputs) #预测值
result[label, correctValue] += 1 #混淆矩阵
numTrue.append(correctValue)
numPredict.append(label)
if (label == correctValue):
scorecard.append(1)
else:
scorecard.append(0)
writer = csv.writer(testWrongFile)
saveWrongData[0] = label
writer.writerow(saveWrongData)
testWrongFile.close() #关闭文件
scorecardArray = numpy.asarray(scorecard)
print(scorecardArray.sum())
print(scorecardArray.size)
print("准确率:", scorecardArray.sum() / scorecardArray.size)
print(result)
使用sklearn中的方法做出混淆矩阵
from sklearn.metrics import classification_report
target_names = [str(i) for i in range(10)]
print(classification_report(numTrue, numPredict, target_names=target_names,digits=4))