利用Python简单搭建单层神经网络

  最近看了一篇文章,作者在不借助任何框架的情况下搭建了一个非常简单的神经网络,感觉有点儿意思。加之自己刚刚入门深度学习,于是按照流程实现了一遍,顺便在其中回顾所学的基础知识,如有疏漏,还望指正。
  这是一个单层神经网络,只有输入层和输出层,对输出结果还做了Sigmoid非线性变换。如下是展示问题的表格:
在这里插入图片描述
我们希望通过训练数据来训练模型,得到最后的输出结果。

import numpy as np

#定义网络结构和训练过程
class NeutralNetwork():
    def __init__(self):
        #利用随机数种子生成随机数,会使每次生成的初始权重相同
        np.random.seed(1)
        #生成了3*1的随机权重矩阵
        self.synaptic_weights = 2*np.random.random((3,1))-1
        
    #定义sigmoid激活函数
    def sigmoid(self,x):
        return 1/(1+np.exp(-x))
        
    #定义sigmoid函数的导数
    def sigmoid_derivative(self,x):
        return x*(1-x)
    
    #对节点的输出值进行激活        
    def think(self,inputs):
        inputs = inputs.astype(float)
        #前向传播结果
        output = self.sigmoid(np.dot(inputs,self.synaptic_weights))
        return output
        
    #定义训练过程,参数为输入值,输出值,训练轮数
    def train(self,training_inputs,training_outputs,train_steps):     
        for step in range(train_steps):
            output = self.think(training_inputs)
            #计算训练数据真实值和网络预测值的训练误差
            error = training_outputs - output
            #模拟反向传播过程,调整误差
            adjustments = np.dot(training_inputs.T,error*self.sigmoid_derivative(output))
            #微调权重参数
            self.synaptic_weights = self.synaptic_weights + adjustments
            

  上面定义了网络的结构的训练过程,在NeutralNetwork类中,我们定义了五个函数,第一个函数定义了边的权重,初始权重是的3乘1矩阵,其中数值大小随机生成,在-1~1之间;第二个函数使用了numpy中的部分函数定义了sigmoid激活函数,用于去线性化;第三个函数sigmoid_derivative()定义了sigmoid的求导结果,f’(x) = f(x)*(1-f(x)),用于对权重参数的调整;第四个函数定义了前向传播的过程,并对前向传播结果进行了sigmoid激活,返回最后的输出结果;第五个函数也是最主要的函数,定义了训练过程,其中有三个参数,分别代表训练数据的输入值、输出值和训练轮数,首先计算了训练数据真实值和网络预测值的训练误差,然后利用误差加权导数公式,根据所得到的误差范围,对权重进行了一些较小的调整。就这样,一个简单的神经网络结构结搞定了。

#定义主函数入口,只在本文件中执行
if __name__ == '__main__':
    
    neutral_work = NeutralNetwork()
    
    print("开始时的权重为:%s"%neutral_work.synaptic_weights)
    #训练数据输入值
    training_inputs = np.array([[0,0,1],
                                [1,1,1],
                                [1,0,1],
                                [0,1,1]])
    #训练数据真实结果
    training_outputs = np.array([[0,1,1,0]]).T
    
    neutral_work.train(training_inputs,training_outputs,20000)
    
    print("训练完成后的权重为:%s"%neutral_work.synaptic_weights)
    #自定义数据做预测
    user_input_one = str(input("请输入第一个值: "))
    
    user_input_two = str(input("请输入第二个值: "))
    
    user_input_three = str(input("请输入第三个值: "))
    
    print("考虑新的输入值: ",user_input_one,user_input_two,user_input_three)
    
    new_output = neutral_work.think(np.array([user_input_one,user_input_two,user_input_three]))
    
    print("预测的输出值为:%s"%new_output)

  接下来就是输入数据的训练过程了,设定训练轮数为20000,运行函数后最后结果如下:

开始时的权重为:[[-0.16595599]
			   [ 0.44064899]
 			   [-0.99977125]]
训练完成后的权重为:[[10.38040701]
                  [-0.20641179]
                  [-4.98452047]]

请输入第一个值: 1

请输入第二个值: 0

请输入第三个值: 0
考虑新的输入值:  1 0 0
预测的输出值为:[0.99996897]

可以看到,在训练20000轮后,权重有了较大的改变,对预测数据的预测输出值非常接近于1。和训练数据类似,结果都和输入数据的第一位数字相同。就这样就完成了一个简单神经网络的搭建过程,可以对深度学习的基础知识有更深刻的了解。

猜你喜欢

转载自blog.csdn.net/qq_40739970/article/details/84992923