什么是神经网络算法?
神经网络就像一个黑盒子,我们只需要将数据输入进去,经过黑盒子的内部处理,就可以得到我们想要的结果 神经网络的命名来自于神经元 神经网络图如下
神经网络算法有什么用?
能够解决分类问题,聚类问题,拟合问题等诸多类型问题,可以说的上是比较万能的一种模型
重要概念
输入层 隐藏层 输出层 多层权值 激活函数 ReLU函数 代价函数 正向传播 反向传播
输入层
神经网络的头部,接受数据 和线性回归或者逻辑回归一样,都是一组样本,但是不需要在这个时候将Y值放进去
隐藏层
隐藏层可以有多层,在每一层都会得到一个新的预测值,这个预测值会和上一层到这一层的权值有关 隐藏层的预测值个数不一定和特征个数相等,是可以调节的
输出层
得到最终的预测结果,个数必须要和Y的特征个数相同 通过预测值和真实值的特殊处理,可以得到代价函数
多层权值
神经网络是有多层权值的,权值的层数等于总层数-1,在一个3层的神经网络中,有一个隐藏层,那么权值层数就有2个 每一层权值的个数为下一层节点个数*这一层节点个数,即对于输入层来说
X
1
=
[
a
,
b
,
c
]
X_1 = [a, b, c]
X 1 = [ a , b , c ] ,有三个节点,下一层的
X
2
=
[
a
,
b
]
X_2 = [a, b]
X 2 = [ a , b ] ,有两个节点,那么第一层的权值应当是这种形式
W
1
=
[
[
a
1
,
b
1
,
c
1
]
,
[
a
2
,
b
2
,
c
2
]
]
W_1 = [[a_1, b_1, c_1], [a_2, b_2, c_2]]
W 1 = [ [ a 1 , b 1 , c 1 ] , [ a 2 , b 2 , c 2 ] ]
激活函数
如果是解决逻辑回归问题,可以选用sigmod函数,
h
(
z
)
=
1
1
+
e
(
−
z
)
h(z) = \frac{1}{1 + e^(-z)}
h ( z ) = 1 + e ( − z ) 1
ReLU函数
在神经网络中,ReLU函数也可以作为激活函数,相比sigmod函数,更加简洁、高效,并且不会出现指数爆炸的问题。ReLU函数形式如下:
f
(
x
)
=
m
a
x
(
0
,
x
)
f(x) = max(0, x)
f ( x ) = m a x ( 0 , x )
代价函数
如果是解决逻辑回归问题,可以选用交叉熵损失函数 ,逻辑回归
正向传播
神经网络的正向传播过程就是求预测值的过程 对于一个只有一个隐藏层的神经网络,它的一组初始
X
1
=
[
1
,
2
,
3
,
4
]
X_1=[1, 2, 3, 4]
X 1 = [ 1 , 2 , 3 , 4 ] ,对应的权值
W
1
=
[
[
0.2
,
0.3
,
0.1
,
0.4
]
,
[
0.1
,
0.2
,
0.4
,
0.3
]
,
[
0.3
,
0.2
,
0.1
,
0.4
]
,
[
0.4
,
0.1
,
0.2
,
0.3
]
]
W_1=[[0.2, 0.3, 0.1, 0.4], [0.1, 0.2, 0.4, 0.3], [0.3, 0.2, 0.1, 0.4], [0.4, 0.1, 0.2, 0.3]]
W 1 = [ [ 0 . 2 , 0 . 3 , 0 . 1 , 0 . 4 ] , [ 0 . 1 , 0 . 2 , 0 . 4 , 0 . 3 ] , [ 0 . 3 , 0 . 2 , 0 . 1 , 0 . 4 ] , [ 0 . 4 , 0 . 1 , 0 . 2 , 0 . 3 ] ] ,那么它的
Z
1
=
[
2.7
,
2.9
,
2.6
,
2.4
]
Z_1=[2.7, 2.9, 2.6, 2.4]
Z 1 = [ 2 . 7 , 2 . 9 , 2 . 6 , 2 . 4 ] 再根据ReLU激活函数,得到
A
1
=
[
2.7
,
2.9
,
2.6
,
2.4
]
A_1 = [2.7 , 2.9, 2.6, 2.4]
A 1 = [ 2 . 7 , 2 . 9 , 2 . 6 , 2 . 4 ] 再将
A
1
A_1
A 1 的结果当作下一层的输入值,继续重复计算,得到
Z
2
Z_2
Z 2 并用sigmod函数,代入
Z
2
Z_2
Z 2 ,得到
A
2
A_2
A 2 ,
A
2
A_2
A 2 应该是一个0~1之间的小数,将0.5作为阈值(根据情况也可能不是0.5),大于0.5的变成1,小于等于0.5的变成0,就能得到预测值了
反向传播(以下计算过程只当作参考,不保证正确)
神经网络的反向传播就是根据预测值的准确性,更新每一层权值的过程 如果输出层的值是
A
2
A_2
A 2 ,那么首先得到
d
Z
2
=
A
2
−
y
dZ_2 = A_2 - y
d Z 2 = A 2 − y ,再通过
1
m
∗
d
Z
2
∗
A
1
T
\frac{1}{m} * dZ_2 * A_1^T
m 1 ∗ d Z 2 ∗ A 1 T 就可以得到
d
W
2
dW_2
d W 2 ,最后
W
2
=
d
W
1
∗
l
r
W_2 = dW_1 * lr
W 2 = d W 1 ∗ l r
d
Z
1
dZ_1
d Z 1 的计算要稍微复杂一点,公式为
(
W
2
∗
d
Z
2
)
∗
(
1
−
A
1
2
)
(W_2 * dZ_2) * (1 - A_1^2)
( W 2 ∗ d Z 2 ) ∗ ( 1 − A 1 2 ) ,
d
W
1
=
1
m
∗
d
Z
1
∗
X
T
dW_1 = \frac{1}{m} * dZ_1 * X^T
d W 1 = m 1 ∗ d Z 1 ∗ X T
自定义Python代码实现单隐藏层神经网络(自定义代码存在许多问题,不推荐使用,只当作算法的参考)
import pandas as pd
import numpy as np
from sklearn. model_selection import train_test_split
import matplotlib. pyplot as plt
def initialize_parameters ( n_x, n_h, n_y) :
"""
n_x是输入层节点个数,n_h是隐藏层节点个数,n_y是输出层节点个数
"""
W1 = np. random. randn( n_h, n_x) * 0.01
b1 = np. zeros( ( n_h, 1 ) )
W2 = np. random. randn( n_y, n_h) * 0.01
b2 = np. zeros( ( n_y, 1 ) )
assert ( W1. shape == ( n_h, n_x) )
assert ( b1. shape == ( n_h, 1 ) )
assert ( W2. shape == ( n_y, n_h) )
assert ( b2. shape == ( n_y, 1 ) )
parameters = {
'W1' : W1,
'b1' : b1,
'W2' : W2,
'b2' : b2
}
return parameters
def sigmod ( Z) :
return 1 / ( 1 + np. exp( - Z) )
def ReLU ( Z) :
return np. maximum( 0 , Z)
def J ( A2, y) :
m = y. shape[ 1 ]
cost = - 1 / m * np. sum ( y * np. log( A2) + ( 1 - y) * np. log( 1 - A2) )
cost = np. squeeze( cost)
assert ( isinstance ( cost, float ) )
return cost
def forward_propagation ( X, parameters) :
"""
X是输入值,是众多样本中的一行数据
parameters是一个字典,里面有各个层的权值
"""
W1 = parameters[ 'W1' ]
b1 = parameters[ 'b1' ]
W2 = parameters[ 'W2' ]
b2 = parameters[ 'b2' ]
Z1 = np. dot( W1, X) + b1
A1 = ReLU( Z1)
Z2 = np. dot( W2, A1) + b2
A2 = sigmod( Z2)
cache = {
'Z1' : Z1,
'A1' : A1,
'Z2' : Z2,
'A2' : A2
}
return cache
def backward_propagation ( X, y, parameters, cache, lr) :
m = X. shape[ 1 ]
W1 = parameters[ 'W1' ]
b1 = parameters[ 'b1' ]
W2 = parameters[ 'W2' ]
b2 = parameters[ 'b2' ]
A1 = cache[ 'A1' ]
A2 = cache[ 'A2' ]
dZ2 = A2 - y
dW2 = 1 / m * np. dot( dZ2, A1. T)
db2 = 1 / m * np. sum ( dZ2, axis= 1 , keepdims= True )
dZ1 = np. dot( W2. T, dZ2) * ( 1 - np. power( A1, 2 ) )
dW1 = 1 / m * np. dot( dZ1, X. T)
db1 = 1 / m * np. sum ( dZ1, axis= 1 , keepdims= True )
W1 = W1 - lr * dW1
b1 = b1 - lr * db1
W2 = W2 - lr * dW2
b2 = b2 - lr * db2
parameters = {
'W1' : W1,
'b1' : b1,
'W2' : W2,
'b2' : b2
}
return parameters
def bp_model ( X, y, n_h, lr= 0.0002 , epochs= 10000 , err_torlance= 1e - 12 ) :
"""
X是所有样本
y是对应样本输出
n_h是隐藏层的节点个数
lr是学习率
epochs是迭代次数
"""
np. random. seed( 12 )
n_x = X. shape[ 1 ]
n_y = y. shape[ 1 ]
parameters = initialize_parameters( n_x, n_h, n_y)
last_cost = 0
for i in range ( epochs) :
cache = forward_propagation( X. T, parameters)
cost = J( cache[ 'A2' ] , y. T)
parameters = backward_propagation( X. T, y. T, parameters, cache, lr)
if i % 100 == 0 :
print ( "cost:" , cost)
if np. fabs( cost - last_cost) < err_torlance:
break
last_cost = cost
return parameters
def plot_decision_boundary ( model, X, y) :
x1_min, x1_max = X[ : , 0 ] . min ( ) , X[ : , 0 ] . max ( )
x2_min, x2_max = X[ : , 1 ] . min ( ) , X[ : , 1 ] . max ( )
h = 0.01
xx, yy = np. meshgrid( np. arange( x1_min, x1_max, h) , np. arange( x2_min, x2_max, h) )
Z = model( np. c_[ xx. ravel( ) , yy. ravel( ) ] )
Z = Z. reshape( xx. shape)
plt. contourf( xx, yy, Z, cmap= plt. cm. Spectral)
plt. ylabel( 'x2' )
plt. xlabel( 'x1' )
plt. scatter( X[ : , 0 ] , X[ : , 1 ] , c= y)
def predict ( X, parameters) :
cache = forward_propagation( X, parameters)
predictions = np. array( cache[ 'A2' ] >= 0.5 , dtype= int )
return predictions
if __name__ == '__main__' :
df = pd. read_csv( 'NeuralNetwork_Data1.csv' )
X = df[ [ 'x1' , 'x2' ] ] . values
y = df[ 'y' ] . values. reshape( - 1 , 1 )
X_train, x_test, y_train, y_test = train_test_split( X, y, test_size= 0.3 )
parameters = bp_model( X_train, y_train, n_h= 3 , lr= 0.002 , epochs= 20000 )
plot_decision_boundary( lambda x: predict( x. T, parameters) , X_train, y_train)
plt. title( 'bp' )
plt. scatter( X_train[ : , 0 ] , X_train[ : , 1 ] , c= y_train)
使用sklearn的neural_network模块中的MLPClassifier进行分类
from sklearn. neural_network import MLPClassifier
from sklearn. datasets import load_breast_cancer
from sklearn. model_selection import train_test_split
import matplotlib. pyplot as plt
breast_cancer = load_breast_cancer( )
X = breast_cancer. data
y = breast_cancer. target
print ( X. shape)
X_train, X_test, y_train, y_test = train_test_split( X, y, test_size= 0.3 )
mlp_classifier = MLPClassifier( )
mlp_classifier. fit( X_train, y_train)
print ( "预测准确率:" , mlp_classifier. score( X_test, y_test) )
plt. figure( )
y_predict_list = [ ]
hidden_layers = list ( range ( 100 , 1000 , 100 ) )
for n in hidden_layers:
mlp_classifier = MLPClassifier( ( n, ) )
mlp_classifier. fit( X_train, y_train)
y_predict_list. append( mlp_classifier. score( X_test, y_test) )
plt. plot( hidden_layers, y_predict_list)
plt. xticks( hidden_layers)
plt. show( )
得到单隐藏层情况下,节点数由100个到1000个(步长为100)的预测准确率变化