BPNN神经网络的Python实现

关于前置的数学知识,可以查看https://blog.csdn.net/cufewxy1/article/details/80445023

首先是bpnn.py,实现了BPNeuralNetwork类。

import numpy
import scipy.special
import pickle
from datetime import datetime


class BPNeuralNetwork(object):

    def __init__(self, input_size, hidden_size, output_size, activation_func = scipy.special.expit, learning_rate = 0.1):
        self.input_size = input_size
        self.hidden_size = hidden_size
        self.output_size = output_size
        self.activation_func = activation_func
        self.learning_rate = learning_rate

        # self.wih = numpy.random.sample([hidden_size, input_size]) - 0.5
        self.wih = numpy.random.normal(0.0, pow(hidden_size, -0.5), [hidden_size, input_size])
        # wih_{i,j} links input_j with hidden_i
        
        self.bih = numpy.random.sample([hidden_size, 1]) - 0.5
        
        # self.who = numpy.random.sample([output_size, hidden_size]) - 0.5 
        self.who = numpy.random.normal(0.0, pow(output_size, -0.5), [output_size, hidden_size]) 
        # who_{i,j} links hidden_j with output_i
        
        self.bho = numpy.random.sample([output_size, 1]) - 0.5

    @staticmethod
    def load(filename):
        with open(filename, 'rb') as f:
            return pickle.load(f)
        
    def train(self, inputs, targets):
        inputs = numpy.array(inputs, ndmin = 2).T
        targets = numpy.array(targets, ndmin = 2).T

        hidden_in = numpy.dot(self.wih, inputs) + self.bih
        hidden_out = self.activation_func(hidden_in)
        output_in = numpy.dot(self.who, hidden_out) + self.bho
        output_out = self.activation_func(output_in)
        
        delta_output_out = output_out - targets
        delta_output_in = delta_output_out * output_out * (1 - output_out)
        delta_bho = delta_output_in
        delta_who = numpy.dot(delta_output_in, hidden_out.T)
        delta_hidden_out = numpy.dot(self.who.T, delta_output_in)
        delta_hidden_out = numpy.dot(self.who.T, delta_output_out)
        delta_hidden_in = delta_hidden_out * hidden_out * (1 - hidden_out)
        delta_bih = delta_hidden_in
        delta_wih = numpy.dot(delta_hidden_in, inputs.T)

        self.who -= (self.learning_rate * delta_who)
        self.bho -= (self.learning_rate * delta_bho)
        self.wih -= (self.learning_rate * delta_wih)
        self.bih -= (self.learning_rate * delta_bih)
    
    def dump(self, filename = 'bpnn_%s.dat' % datetime.now().strftime('%Y-%m-%d_%H:%M:%S')):
        with open(filename, 'wb') as f:
            pickle.dump(self, f)

    def query(self, inputs):
        inputs = numpy.array(inputs, ndmin = 2).T
        hidden_in = numpy.dot(self.wih, inputs) + self.bih
        hidden_out = self.activation_func(hidden_in)
        output_in = numpy.dot(self.who, hidden_out) + self.bho
        output_out = self.activation_func(output_in)
        return output_out.reshape(self.output_size)

然后是__init__.py,使用mnist手写数字数据集对我们的BPNN进行测试,准确率可达97%以上。

import tensorflow as tf
from tensorflow import keras
import numpy as np
import matplotlib.pyplot as plt

from bpnn import BPNeuralNetwork


def main():
    bp = BPNeuralNetwork(28*28, 500, 10)
    # mnist = keras.datasets.fashion_mnist
    mnist = keras.datasets.mnist
    (train_images, train_labels), (test_images, test_labels) = mnist.load_data()
    train_images = train_images / 255.0
    test_images = test_images / 255.0

    for i in range(5):
        for train_image, train_label in zip(train_images, train_labels):
            inputs = train_image.reshape((1, 28 * 28))
            targets = [0] * 10
            targets[train_label] = 1
            bp.train(inputs, targets)
        print('training complete!')
    cnt = 0
    acc = 0
    for test_image, test_label in zip(test_images, test_labels):
        cnt += 1
        inputs = test_image.reshape((1, 28*28))
        result = bp.query(inputs)
        if np.argmax(result) == test_label:
            acc += 1
    print(acc*100.0/cnt)
    bp.dump()


if __name__ == '__main__':
    main()

你可能感兴趣的:(BPNN神经网络的Python实现)