极简神经网络
import numpy as np
np.random.seed(0)
def sigmoid(x, deriv=False):
if deriv: # 导数
return x * (1 - x) # S'(x) = S(x) (1 - S(x))
return 1 / (1 + np.exp(-x))
# 样本
X = np.array([[0, 0, 1],
[0, 1, 1],
[1, 0, 1],
[1, 1, 1],
[0, 1, 0]]) # 5*3
y = np.array([[0],
[1],
[1],
[1],
[0]]) # 5*1
# 初始化权重系数(随机)
n = 4 # 神经元个数
d = X.shape[1] # dimensionality
w1 = np.random.random((d, n)) # Weight1
w2 = np.random.random((n, 1)) # Weight2
# 训练
for j in range(99999):
l1 = sigmoid(np.dot(X, w1)) # Layer1
l2 = sigmoid(np.dot(l1, w2)) # Layer2
l2_error = y - l2
l2_delta = l2_error * sigmoid(l2, deriv=True) # △Layer2
if j % 9999 == 0:
print('Error:%f' % np.mean(np.abs(l2_error)))
l1_error = l2_delta.dot(w2.T)
l1_delta = l1_error * sigmoid(l1, deriv=True) # △Layer1
w2 += l1.T.dot(l2_delta)
w1 += X.T.dot(l1_delta)
参数更新原理
封装成类
import numpy as np, matplotlib.pyplot as mp
from sklearn.datasets import make_blobs, make_moons, make_circles
from sklearn.model_selection import train_test_split
np.random.seed(0)
class NN:
"""Neural Netword"""
def __init__(self, n):
self.n = n # 神经元个数
self.w1 = None # Weight1
self.w2 = None # Weight2
def sigmoid(self, x, deriv=False):
if deriv:
return x * (1 - x)
return 1 / (1 + np.exp(-x))
def fit(self, X, y):
y = y.reshape(-1, 1)
d = X.shape[1]
w1 = 2 * np.random.random((d, self.n)) - 1
w2 = 2 * np.random.random((self.n, 1)) - 1
for j in range(99999):
l1 = self.sigmoid(np.dot(X, w1))
l2 = self.sigmoid(np.dot(l1, w2))
l2_error = y - l2
l2_delta = l2_error * self.sigmoid(l2, deriv=True)
l1_error = l2_delta.dot(w2.T)
l1_delta = l1_error * self.sigmoid(l1, deriv=True)
w2 += l1.T.dot(l2_delta)
w1 += X.T.dot(l1_delta)
self.w1 = w1
self.w2 = w2
def predict(self, X):
l1 = self.sigmoid(np.dot(X, self.w1))
l2 = self.sigmoid(np.dot(l1, self.w2))
return np.round(l2)
def score(self, X, y):
y_predict = self.predict(X).reshape(-1)
return np.mean(y_predict == y)
def visualization(X1, X2, y1, y2, i):
mp.subplot(2, 3, i)
mp.scatter(X1[:, 0], X1[:, 1], c=y1, alpha=0.1)
mp.scatter(X2[:, 0], X2[:, 1], s=9, c=y2)
mp.xticks(())
mp.yticks(())
# 创建样本集
n_samples = 400
samples = [make_blobs(n_samples, centers=2),
make_moons(n_samples, noise=0.05),
make_circles(n_samples, noise=.1, factor=.3)]
for i in range(3):
# 样本
X, y = samples[i]
X_train, X_test, y_train, y_test = train_test_split(X, y)
visualization(X_train, X_test, y_train, y_test, i + 1)
# 神经网络
nn = NN(5)
nn.fit(X_train, y_train)
y_predict = nn.predict(X_test).reshape(-1)
visualization(X_train, X_test, y_train, y_predict, i + 4)
print('Precision: %.2f' % nn.score(X_test, y_test))
mp.show()
如图示,简单的神经网络可以完成分类任务,但分类效果一般(尤其是线性不可分的数据)
对此可引入ReLU,详情猛戳Python手写非线性神经网络