使用python从头开始制作神经网络(学习笔记)

一、代码框架

class neuralNetwork:

        #初始化神经网络

        def  _init_( ):

                pass

        #训练神经网络

        def  _train( ):

                pass

        #查询神经网络

        def  query( );

                pass

二、开始

2.1 初始化网络

class neuralNetwork:
    def _init_(self, inputnodes, hiddennodes, outputnodes, learningrate):

        #设置每一个输入层、隐藏层、输出层的节点
        self.inodes = inputnodes
        self.hnodes = hiddennodes
        self.onodes = outputnodes

        #学习率
        self.lr = learningrate
        pass
    def train():
        pass
    def query():
        pass

#输入层、隐藏层、输出层的节点

input_nodes = 3
hidden_nodes = 3
output_nodes = 3

#学习率
learning_rate = 0.3

#创建一个神经网络的实例

n = neuralNetwork(input_nodes, hidden_nodes, output_nodes, learning_rate)

2.2 权重——网络的核心

#输入层和隐藏层之间的权重矩阵

self.wih = (numpy.random.rand(self.hnodes, self.inodes) - 0.5)

#输出层和隐藏层之间的权重矩阵

self.who = (numpy.random.rand(self.onodes, self.hnodes) - 0.5)

2.2.3权重——较复杂的权重

上面的初始化权重的方式也可以改为另一种较为流行的方式:使用正态概率分布采样权重,其中平均值为0,标准方差为节点传入链接数目的开方,即1/\sqrt{}传入链接数目。

此外,我们采用另一种做法,使用下一层的节点数的开方作为标准方差来初始化权重:

self.wih = numpy.random.normal(0.0, pow(self.hnodes, -0.5), (self.hnodes, self.inodes))

self.who = numpy.random.normal(0.0, pow(self.onodes, -0.5), (self.onodes, self.hnodes))

2.2.4 查询网络

query函数接受神经网络的输入,返回网络的输出。

应用numpy库,将链接权重矩阵W_{input _ hidden}点乘输入矩阵I。

hidden_inputs = numpy.dot(self.wih, inputs)

为了获得从隐藏层节点处出现的信号,简单地将S抑制函数应用到每一个出现的信号上:

O_{hidden} = sigmoid(X_{hidden})

所以需要导入scipy函数库

import scipy.special

在神经网络初始化的代码内部,定义了希望使用的激活函数。

# lambda接受了x, 返回scipy.special.expit(x),这就是S函数(sigmoid)

self.activation_function = lambda x: scipy.special.expit(x)

将激活函数应用到组合调整后,准备进入隐藏层节点的信号。

hidden_outputs = self.activation_function(hidden_inputs)

信号到达中间隐藏层后,最终又到达输出层,代码总结如下:

#计算信号进入隐藏层

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)

三、训练网络

训练任务分为两个部分:1.针对给定的训练样本计算输出。2.将计算得到的输出与所需输出对比,使用差值来指导网络权重的更新。

3.1 我们已经完成了第一部分,如下:

#先将输入和目标输出转换为列表形式

inputs = numpy.array(inputs_list, ndmin=2).T
targets = numpy.array(targets_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)

3.2 再改进权重

#预期目标输出值与实际计算得到的输出值之差:就是将targets矩阵和final_outputs矩阵中每个对应元素相减。

output_errors = targets - final_outputs
hidden_errors = numpy.dot(self.who.T, output_errors)

#再由权重更新公式 w = w + w;
w = α *  * sigmoid( ) * (1 -  sigmoid( ))  

self.who += self.lr * numpy.dot((output_errors * final_outputs * (1 - final_inputs)), numpy.transpose(hidden_outputs))
self.wih += self.lr * numpy.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)), numpy.transpose(inputs))

计算结束

四、数据集准备(MNIST手写数字的数据集)

链接:makeyourownneuralnetwork/mnist_dataset at master · makeyourownneuralnetwork/makeyourownneuralnetwork (github.com)

4.1 打开文件:

data_file = open(r"F:\diy_neuralnetwork_dataset\mnist_train_100.csv", 'r')
data_list = data_file.readlines()
data_file.close()

4.2 可视化数据

import numpy
import scipy.special
import os
import matplotlib.pyplot

image_array = numpy.asfarray(all_values[1:]).reshape((28, 28))
matplotlib.pyplot.imshow(image_array, camp='Greys', interpolation='None')

4.3 准备MNIST训练数据

第一件事是将输入颜色值从较大的0到255的范围,缩放至0.01到1.0的范围。选择0.01为范围最低点,可以避免0值输入造成权重更新失败。不选择0.99作为输入上限,因为输入1.0也不会造成任何问题,我们只需要避免输出值为1.0。

将在0到255范围内的原始输入值除以255,就可以得到0到1范围的输入值。然后,需要将所得到的输入乘以0.99,把他们的范围变成0.0到0.99。接下来,加上0.01,这些值整体偏移到所需的范围0.01到1.00.

如下:

scaled_input = (numpy.asfarray(all_values[1:]) / 255.0 * 0.99) + 0.01

print(scaled_input)

创建目标矩阵:

output_nodes = 10
targets = numpy.zeros(output_nodes) + 0.01
targets[int(all_values[0])] = 0.99

4.4 测试网络

test_data_file = open("F:\diy_neuralnetwork_dataset\mnist_test_10.csv")
test_data_list = test_data_file.readlines()
test_data_file.close()

4.5 一些改进

添加世代:有些人把训练一次成为1个世代。可以添加世代:

epochs = 5
for e in range(epochs):
    for record in training_data_list:
        all_values = record.split(',')
        inputs = (numpy.asfarray(all_values[1:]) / 250.0 * 0.99) + 0.01
        targets = numpy.zeros(output_nodes) + 0.01
        targets[int(all_values[0])] = 0.99
        n.train(inputs, targets)
        pass
    pass

改变网络形状:改变隐藏层节点的数目;改变学习率的大小

五、最终代码:

import numpy
import scipy.special
import os
import matplotlib.pyplot


class neuralNetwork():
    def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):
        self.inodes = inputnodes
        self.hnodes = hiddennodes
        self.onodes = outputnodes
        self.lr = learningrate
        self.wih = numpy.random.normal(0.0, pow(self.hnodes, -0.5), (self.hnodes, self.inodes))
        self.who = numpy.random.normal(0.0, pow(self.onodes, -0.5), (self.onodes, self.hnodes))
        self.activation_function = lambda x: scipy.special.expit(x)
        pass

    def train(self, inputs_list, targets_list):
        inputs = numpy.array(inputs_list, ndmin=2).T
        targets = numpy.array(targets_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)
        output_errors = targets - final_outputs
        hidden_errors = numpy.dot(self.who.T, output_errors)
        self.who += self.lr * numpy.dot((output_errors * final_outputs * (1 - final_inputs)),
                                        numpy.transpose(hidden_outputs))
        self.wih += self.lr * numpy.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)),
                                        numpy.transpose(inputs))
        pass

    def query(self, inputs_list):
        inputs = numpy.array(inputs_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


input_nodes = 784
hidden_nodes = 200
output_nodes = 10
learning_rate = 0.1
n = neuralNetwork(input_nodes, hidden_nodes, output_nodes, learning_rate)

training_data_file = open("F:\diy_neuralnetwork_dataset\mnist_train_100.csv", 'r')
training_data_list = training_data_file.readlines()
training_data_file.close()

epochs = 5
for e in range(epochs):
    for record in training_data_list:
        all_values = record.split(',')
        inputs = (numpy.asfarray(all_values[1:]) / 250.0 * 0.99) + 0.01
        targets = numpy.zeros(output_nodes) + 0.01
        targets[int(all_values[0])] = 0.99
        n.train(inputs, targets)
        pass
    pass

test_data_file = open("F:\diy_neuralnetwork_dataset\mnist_test_10.csv")
test_data_list = test_data_file.readlines()
test_data_file.close()

scorecard = []
for record in test_data_list:
    all_values = record.split(',')
    correct_label = int(all_values[0])
    inputs = (numpy.asfarray(all_values[1:]) / 250.0 * 0.99) + 0.01
    outputs = n.query(inputs)
    label = numpy.argmax(outputs)
    if (label == correct_label):
        scorecard.append(1)
    else:
        scorecard.append(0)
        pass
    pass

scorecard_array = numpy.asarray(scorecard)
print("performance = ", scorecard_array.sum() / scorecard_array.size)

运算的结果是:

performance =  0.1
 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值