模仿人类的神经细胞运作原理而形成一种网络模型,就是神经网络模型 它由输入层,隐含层(隐藏层),输出层组成,每层都会有大于等于1个神经元(即图中的圆圈)。 每层的神经元都会通过线进行连接,连接方式为全连接(例:第一层的任意一个点和第二层的点全部点连接起来)。 (1)输入层:用于向神经网络输入数据,通常只有一层 (2)隐含层:用于进行计算,通常有多个层 (当隐含层足够多时,可称该网络为深度神经网络) (感知机模型就是隐含层只有0层且输出层只有一个神经元的神经网络模型) (3)输出层:用于神经网络输出结果,通常只有一层 直观的理解,神经网络就像是一个函数,给予输入,得到输出(例如函数 y = 2x ,输入1,得到2) 而神经网络通常是用来解决当函数体写不出来的情况。 举个例子,输入身高(x1),体重(x2),得出你的性别(y),y = f(x1,x2)这种函数是写不出来的,而神经网络可以学习出来,具体后面会讲。
什么是感知机模型? 它是由输入层和输出层组成,由于只有两层,可以说它是最简单的神经网络模型了 该图: (1)没有隐含层,黄色圆圈就是输出层(只有一个神经元) (2)输入层(蓝色圆圈)有三个输入神经元 (3)计算公式: y = w1 * x1 + w2 * x2 + w3 * x3 (w1,w2,w3是随机初始化得到的) (4)断依据: 设定一个阈值b 如果y >= b ,那么网络输出1;否则,输出0 (5)因此,整个感知机可以写成: h = 0 ,w1 * x1 + w2 * x2 + w3 * x3 < b h = 1 ,w1 * x1 + w2 * x2 + w3 * x3 >= b (6)整个网络好比输入了身高(x1),年龄(x2),体重(x3),得出结果性别(当性别为男时,h为1;当性别为女时,h为0),但w1,w2,w3是随机数来的,因此该网络其实不具备得出正确性别的功能,要想得出正确的性别,就要更新w1,w2和w3的值。这时需要用到梯度下降法。
假设: 1.有一个男人:身高1.8m,年龄30,体重70kg, 2.也就是说当 x1 = 1.8,x2 = 30,x3 = 70时,应该是要输出就是 h = 1 ,这个应该的输出我们叫真实值,或者标签。 3.但网络的输出却是0,这个网络的输出值成为预测值 4.这时预测值和真实值存在差别 = 1 - 0 = 1 ,但我们不能就这样简单的相减,为了能达到更新的效果,我们通常使用均方误差 5.均方误差cost =(真实值 - 预测值)² 6.为什么要用均方误差,而不是直接相减,请看下图。当直接相减时,函数是一条直线,没有最小值,当使用均方误差时,函数呈现一个碗状,存在最小值,而当均方误差最小的时候,就是真实值和预测值差别最小的时候。 7.该图是假设只有一个w作为自变量,cost作为因变量 8.梯度下降法就好比爬山,如图中的小人,站在斜坡上,根据自己所处位置的倾斜程度,向低处走。 9.梯度下降法更新w值的公式:w = w + α * d(w)式中 α 是学习率(即爬山的每一步的大小,可以小步走,也可以跨大步),d(w)是当前所在位置的导数(即爬山的方向,关于求导的知识可自行学习,因为用代码实现的时候并不需要我们去计算) 10.关于α学习率的大小选择:如果太小,每一步就会太小,因此爬山会很慢;如果太大,会一步从一个山头跨越到另一个山头,从而走不到最低点。而α的大小是要不断测试才知道的。
这份代码是用tensorflow写的,我会进行适当的解释。因此不太懂tensorflow的需要自行学习 这个代码是用感知机实现 and(与)计算 tensorflow是先创建一个网络,我们称之为图,然后再启动这个网络(图)。
import tensorflow as tf #导入tensorflow包 import numpy as np #导入numpy包 #data是四组输入和真实值的组合(例子:[0,1,0,0]中前三个数字 0 1 0 是输入,最后的0是真实值) data = [[1,1,1,1],[1,0,0,0],[0,1,0,0],[0,0,0,0]] #----------------------------开始创建图------------------------------------ #tf.placeholder是指先创建一个空的模型,之后再填入数据 x = tf.placeholder(tf.float32,([1,3])) #输入层是一行散列的矩阵 real = tf.placeholder(tf.float32,([1,1])) #真实值是一个一行一列的矩阵 #tf.Variable 是指变量,之后对图进行训练时只有变量会发生变化 w = tf.Variable(tf.random.normal([3,1])) #w(权重)是一个三行一列的矩阵 #tf.add(a,b)--> a + b tf.matmul(a,b)--> 矩阵a,b相乘 y = tf.add(tf.matmul(x,w)) #y(预测值)的计算方式 #tf.pow(a,b)-->a的b次方 tf.subtract(a,b)--> a - b cost = tf.pow(tf.subtract(y,real),2) #均方误差的计算 相当于 (y - real)² # 使用梯度下降法进行训练 学习率为0.1 目标是最小化 cost(均方误差) train = tf.train.GradientDescentOptimizer(0.1).minimize(cost) init = tf.global_variables_initializer() #有变量时,就要对变量进行初始化 #----------------------------创建图完毕------------------------------------ #----------------------------开始启动图------------------------------------ sess = tf.Session() #启动图 sess.run(init) #启动初始化 #训练100次 for j in range(100): for i in range(len(data)): #使用run进行训练,对创建图中使用placeholder创建的元素进行数据填入 #如下,x的填入值是np.array([[data[i][0],data[i][1],data[i][2]]]) sess.run(train,feed_dict={x:np.array([[data[i][0],data[i][1],data[i][2]]]) ,real:np.array([[data[i][3]]])}) #输出cost(均方误差),方便查看效果 print(sess.run(cost,feed_dict={x:np.array([[data[i][0],data[i][1],data[i][2]]]) ,real:np.array([[data[i][3]]])})) print('w:',sess.run(w)) #输出w(权重) result = [sess.run(y,feed_dict={x:np.array([[1,1,1]])}), sess.run(y,feed_dict={x:np.array([[1,0,0]])}), sess.run(y,feed_dict={x:np.array([[0,1,0]])}), sess.run(y,feed_dict={x:np.array([[0,0,0]])})] #设置阈值0.5,大于等于0.5的就当作是1,否则为0 for i in range(len(result)): if result[i] >= 0.5: result[i] = 1 else: result[i] = 0 print('1 and 1',result[0]) print('1 and 0',result[1]) print('0 and 1',result[2]) print('0 and 0',result[3]) sess.close() #记得关闭 #----------------------------关闭图------------------------------------