您的位置:首页 > 理论基础 > 计算机网络

可以多分类的神经网络

2016-04-26 11:54 573 查看
'''
11行神经网络①
层数可变,多类
'''
import numpy as np
import matplotlib.pyplot as plt

class BPNN(object):
def __init__(self, neurals, epsilon=0.01, lamda=0.01):
if not isinstance(neurals, list): raise '出错:参数 neurals 必须是 list 类型'
self.neurals = neurals   # 各层神经元数目,如:[3,10,8,2]
self.size = len(neurals)

self.epsilon = epsilon  # 学习速率
self.lamda = lamda      # 正则化强度

self.w = [np.random.randn(i,j) for i,j in zip(neurals[:-1], neurals[1:])] + [None]
self.b = [None] + [np.random.randn(1,j) for j in neurals[1:]]
self.l = [None] * self.size
self.l_delta = [None] * self.size

self.probs = None

# 前向传播
def forward(self, X):
self.l[0] = X
for i in range(1, self.size-1):
self.l[i] = np.tanh(np.dot(self.l[i-1], self.w[i-1]) + self.b[i]) # tanh 函数
self.l[-1] = np.exp(np.dot(self.l[-2], self.w[-2]) + self.b[-1])
self.probs = self.l[-1] / np.sum(self.l[-1], axis=1, keepdims=True)

# 后向传播
def backward(self, y):
self.l_delta[-1] = np.copy(self.probs)
self.l_delta[-1][range(self.n_samples), y] -= 1
for i in range(self.size-2, 0, -1):
self.l_delta[i] = np.dot(self.l_delta[i+1], self.w[i].T) * (1 - np.power(self.l[i], 2)) # tanh 函数的导数

# 更新权值、偏置
def update(self):
self.b[-1] -= self.epsilon * np.sum(self.l_delta[-1], axis=0, keepdims=True)
for i in range(self.size-2, -1, -1):
self.w[i] -= self.epsilon * (np.dot(self.l[i].T, self.l_delta[i+1]) + self.lamda * self.w[i])
if i == 0: break
self.b[i] -= self.epsilon * np.sum(self.l_delta[i], axis=0)

# 计算损失
def calculate_loss(self, y):
loss = np.sum(-np.log(self.probs[range(self.n_samples), y]))
loss += self.lamda/2 * np.sum([np.sum(np.square(wi)) for wi in self.w[:-1]]) # 可选
loss *= 1/self.n_samples  # 可选
return loss

# 拟合
def fit(self, X, y, n_iter=1000, print_loss=True):
self.n_samples = X.shape[0] # 样本大小(样本数目)

for i in range(n_iter):
self.forward(X)
self.backward(y)
self.update()

if not print_loss: continue
if i%100 == 0: print(self.calculate_loss(y))

# 预测
def predict(self, x):
self.forward(x)
return np.argmax(self.probs, axis=1)

def plot_decision_boundary(clf, X, y):
# Set min and max values and give it some padding
x_min, x_max = X[:, 0].min() - .5, X[:, 0].max() + .5
y_min, y_max = X[:, 1].min() - .5, X[:, 1].max() + .5
h = 0.01
# Generate a grid of points with distance h between them
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
# Predict the function value for the whole gid
Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)
# Plot the contour and training examples
plt.contourf(xx, yy, Z, cmap=plt.cm.Spectral)
plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Spectral)

def test1():
X = np.array([[0,0,1],[0,1,1],[1,0,1],[1,1,1]])
#y = np.array([0,1,1,0]) # 两类
y = np.array([0,1,2,3])  # 多类

# bpnn = BPNN([3, 10, 8, 1])
bpnn = BPNN([3, 10, 8, 4])
bpnn.fit(X, y, n_iter=1000)

print('训练结果:', bpnn.predict(X))

def test2():
from sklearn.datasets import make_moons
from sklearn.linear_model import LogisticRegressionCV

X, y = make_moons(200, noise=0.20)
plt.scatter(X[:,0], X[:,1], s=40, c=y, cmap=plt.cm.Spectral)
plt.show()

clf = LogisticRegressionCV()
clf.fit(X, y)
plot_decision_boundary(clf, X, y)
plt.show()

#nn = BPNN([2,5,4,2])
nn = BPNN([2,4,2])
nn.fit(X, y, n_iter=1000)
plot_decision_boundary(nn, X, y)
plt.show()

if __name__ == '__main__':
#test1()
test2()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: