08机器学习实战之BP神经网络
1. 背景:
1.1 以人脑中的神经网络为启发,历史上出现过很多不同版本 1.2 最著名的算法是1980年的 backpropagation 2. 多层向前神经网络(Multilayer Feed-Forward Neural Network) 2.1 Backpropagation被使用在多层向前神经网络上 2.2 多层向前神经网络由以下部分组成: 输入层(input layer), 隐藏层 (hidden layers), 输入层 (output layers)



感知机的推导过程(只有一层,没有激活函数)

加入激活函数
防止局部极小值,增加冲量项
代码实现:
import numpy as np def tanh(x): return np.tanh(x) def tanh_deriv(x): return 1.0 - np.tanh(x) * np.tanh(x) def logistic(x): return 1 / (1 + np.exp(-x)) def logistic_deriv(x): return logistic(x) * (1 - logistic(x)) class NeuralNetwork: def __init__(self, layers, activation="tanh"): if activation == "logistic": self.activation = logistic self.activation_deriv = logistic_deriv elif activation == "tanh": self.activation = tanh self.activation_deriv = tanh_deriv self.weights = [] # len(layers)layer是一个list[10,10,3],则len(layer)=3 for i in range(1, len(layers) - 1): # 初始化 权值范围 [-0.25,0.25) # [0,1) * 2 - 1 => [-1,1) => * 0.25 => [-0.25,0.25) # 加1是增加了一个bias self.weights.append((2 * np.random.random((layers[i - 1] + 1, layers[i] + 1)) - 1) * 0.25) self.weights.append((2 * np.random.random((layers[i] + 1, layers[i + 1])) - 1) * 0.25) # print(len(self.weights)) def fit(self, x, y, learning_rate=0.2, epochs=10000): x = np.atleast_2d(x) # 确保X是一个二维的数据集,每一行代表一个实例 temp = np.ones([x.shape[0], x.shape[1] + 1]) temp[:, 0:-1] = x x = temp # 以上三行就是为了给x增加一个值全为1的维度,作为bias,w[-1] * 1=bias y = np.array(y) for k in range(epochs): # 开始迭代,采用随机梯度,每次抽取一个实例 i = np.random.randint(x.shape[0]) # x.shape[0] is the number of the trainingset samples a = [x[i]] # choose a sample randomly to train the model for l in range(len(self.weights)): # 正向进行计算更新,把第一层的输出,作为下一层的输入,此处用了一个小递归,a[l] a.append(self.activation(np.dot(a[l], self.weights[l]))) error = y[i] - a[-1] # a[-1]就是我们最终预测的输出 deltas = [error * self.activation_deriv(a[-1])] for l in range(len(a) - 2, 0, -1): # 从倒数第二层到第0层,每次回退一层 deltas.append(deltas[-1].dot(self.weights[l].T) * self.activation_deriv(a[l])) deltas.reverse() # 从后往前计算出所有的delta,然后反转 for i in range(len(self.weights)): layer = np.atleast_2d(a[i]) delta = np.atleast_2d(deltas[i]) self.weights[i] += learning_rate * layer.T.dot(delta) def predict(self, x): x = np.array(x) temp = np.ones(x.shape[0] + 1) temp[0:-1] = x a = temp for l in range(0, len(self.weights)): a = self.activation(np.dot(a, self.weights[l])) return a if __name__ == '__main__': nn = NeuralNetwork([2, 2, 1], 'tanh') x = np.array([[0, 0], [0, 1], [1, 0], [1, 1]]) y = np.array([0, 1, 1, 0]) nn.fit(x, y) for i in [[0, 0], [0, 1], [1, 0], [1, 1]]: print(i, nn.predict(i))
结果
[0, 0] [-0.00096734] [0, 1] [0.99820279] [1, 0] [0.99812838] [1, 1] [-0.01110901]
一、显示一下数据集
from sklearn.datasets import load_digits
import pylab as pl digits = load_digits() print(digits.data.shape) # (1797, 64) pl.gray() pl.matshow(digits.images[0]) pl.show()
手写字识别
import numpy as np from sklearn.datasets import load_digits from sklearn.metrics import confusion_matrix, classification_report from sklearn.preprocessing import LabelBinarizer from ml08BP_neuralNetwork import NeuralNetwork from sklearn.model_selection import train_test_split # 加载数据集 digits = load_digits() X = digits.data y = digits.target # 处理数据,使得数据处于0,1之间,满足神经网络算法的要求 X -= X.min() X /= X.max() # 层数: # 输出层10个数字 # 输入层64因为图片是8*8的,64像素 # 隐藏层假设100 nn = NeuralNetwork([64, 100, 10], 'logistic') # 分隔训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y) # 转化成sklearn需要的二维数据类型 labels_train = LabelBinarizer().fit_transform(y_train) labels_test = LabelBinarizer().fit_transform(y_test) print("start fitting") # 训练3000次 nn.fit(X_train, labels_train, epochs=3000) predictions = [] for i in range(X_test.shape[0]): o = nn.predict(X_test[i]) # np.argmax:第几个数对应最大概率值 predictions.append(np.argmax(o)) # 打印预测相关信息 print(confusion_matrix(y_test, predictions)) print(classification_report(y_test, predictions))
结果
矩阵对角线代表预测正确的数量,发现正确率很多
这张表更直观地显示出预测正确率: 共450个案例,成功率94%

更多精彩