'''
用数组来实现深度学习的神经网络的计算,分为输入层,隐藏层,和输出层,参与计算的 有每个神经元的权重,以及偏置,还有
激活函数,也就是上面的 阶跃函数,sigmoid函数 relu函数
计算公式为 Y = XW + B
'''
def sigmoid_fun(x): # 激活函数
return 1 /(1 + np.exp(-x))
X1_in = np.array([0.1,0.2]) #定义2个输入神经元
X2_in = np.array([0.5,0.6,0.7]) # 定义另一个输入神经元
W_1 = np.array([[0.5,0.7,0.9],[1.1,1.3,1.5]]) #定义两个输入神经元的权重
B_1 = np.array([0.7,0.8,0.9]) # 定义一个偏置,偏置的个数和一个输入神经元的权重的个数相等
Y_1 = np.dot(X1_in,W_1) + B_1 # 得出输出层神经元
# 接下来是使用激活函数激活输出神经元
Z_1 = sigmoid_fun(Y_1)
print(Z_1)
'''
以上是 第0层到第一层的神经网络实现方式,如果要实现3层神经网络,则可以使用函数的方式来实现。
理论上 输入层和权重可以有无数个,就像大脑神经一样,四通八达
'''
def W_init_fun(): #定义一个权重和偏置的初始函数
dic_init = {} #定义一个 空的字典,用来保存 权重和偏置
dic_init['W1'] = np.array([[0.1,0.2,0.3],[0.4,0.5,0.6]])
# 定义一个2维数组作为输入层的权重,意味着输入参数至少要俩个参数
dic_init['B1'] = np.array([1.1,1.2,1.3]) # 偏置的个数决定了 输出层的个数 同时等于输入层一个元素权重的个数
# 以上是第一层的权重和偏置 上一层的输出层是下一层的输入层,上一层有3个输出元素,意味着下一次的输入有3个元素
dic_init['W2'] = np.array([[0.5,0.7],[0.4,0.6],[0.2,0.8]]) # 有3个输入元素,则需要对应3个权重
dic_init['B2'] = np.array([1.1,1.5]) # 一个输入元素对应的权重有两个,则偏置也为两个
#同理,上一层有两个输出,那么下一层就有2个输入
dic_init['W3'] = np.array([[1.0,1.7],[2.0,2.5]]) #两个输入参数,定义两个权重,对应两个输出
dic_init['B3'] = np.array([2.2,2.1]) #偏置决定了输出层的元素个数
return dic_init
def forword_fun(dic_in,x):
w1 , w2 , w3 = dic_in['W1'] , dic_in['W2'] , dic_in['W3'] #取出初始化函数的权重值
b1 , b2 , b3 = dic_in['B1'] , dic_in['B2'] , dic_in['B3'] #取出偏置值
Y1 = np.dot(x,w1) + b1 #计算第一层的输出值
Z1 = sigmoid_fun(Y1) #经过一个激活函数得出输出值
Y2 = np.dot(Z1,w2) + b2 #计算第二层的输出值
Z2 = sigmoid_fun(Y2) #经过激活函数得出第二层的输出值
Y3 = np.dot(Y2,w3) + b3 #计算第三层的输出值
Z3 = sigmoid_fun(Y3) #得出第三层的输出值
return Z3
# 以上函数实现了 三层网络神经的计算,最终得出经过激活函数的第三层的输出
Net_Init = W_init_fun() # 定义一个字典名字,并取出初始化的值
X = np.array([0.5,0.8]) # 定义初始底0层的输入元素
Y_sum = forword_fun(Net_Init,X)
print(Y_sum)
输出:
[0.7251195 0.7558389 0.78414719]
[0.99997897 0.9999989 ]
输出层的设计:
'''
输出层的设计
神经网络可以用在 分类问题 和 回归问题 上不过需要根据需要改变激活函数
一般来说,回归问题用恒等函数,回归问题用softmax函数
回归问题就是根据输入的参数来预测一个数值的问题
恒等函数 : 将输入函数原封不动的原样输出
'''
'''
#softmax 函数的实现
# 计算出第a个神经元的输出值y
'''
def softmax_fun(a):
exp_a = np.exp_exp(a)
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return y
'''
如果用上面的函数进行计算的话,存在一个弊端,那就容易溢出,如果是数据较小,那还好,但是如果是数据很大的话
就会溢出,导致计算机无法计算,所以需要修改一下,限制一下
方法就是通过减去一个数,其输出结果不变
我们可以减去输入数据中最大的,得出结果不变,可以避免数据溢出的情况
经过溢出处理之后,输出总和为1
意味着,可以输出某个元素的占比
'''
def Softmax_fun(a):
max_a = np.max(a)
exp_a = np.exp(a - max_a) #减去一个数,其结果不会改变
sum_exp_a = np.sum(exp_a)
y = exp_a / sum_exp_a
return y
text_array = np.array([0.2,0.5,0.2])
y_out = Softmax_fun(text_array)
print(y_out)
print(np.sum(y_out))
out:
[0.29852004 0.40295991 0.29852004]
1.0
不管Softmax的输入参数是多少,他的输出总是在0到1.0之间,而且总数总为1.0,意味着可以求出其中某个数的百分比