#!/usr/bin/env python3 # coding: utf-8 import numpy as np # 计算tanh的值,激活函数 def tanh(x): return np.tanh(x) # 求tanh的导数 def tanh_deriv(x): return 1.0 - np.tanh(x)*np.tanh(x) # 逻辑函数 def logistic(x): return 1.0/(1.0 + np.exp(-x)) # 逻辑函数求导 def logistic_deriv(x): return logistic(x)*(1.0 - logistic(x)) class NeuralNetwork: def __init__(self, layers, activation='tanh'): """ :param layers: A list """ if activation == 'logistic': self.activation = logistic self.activation_deriv = logistic_deriv elif activation == 'tanh': self.activation = tanh self.activation_deriv = tanh_deriv self.weights = [] for i in range(1, len(layers) - 1): # 初始化 权值范围 [-0.25,0.25) # [0,1) * 2 - 1 => [-1,1) => * 0.25 => [-0.25,0.25) 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) def fit(self, x, y, learning_rate=0.2, epochs=10000): x = np.atleast_2d(x) temp = np.ones([x.shape[0], x.shape[1] + 1]) temp[:, 0:-1] = x x = temp y = np.array(y) for k in range(epochs): i = np.random.randint(x.shape[0]) a = [x[i]] # 正向计算 for l in range(len(self.weights)): a.append(self.activation(np.dot(a[l], self.weights[l]))) # 反向传播 error = y[i] - a[-1] deltas = [error*self.activation_deriv(a[-1])] # 开始反向计算,从倒数第二层开始计算 for j in range(len(a)-2, 0, -1): deltas.append(deltas[-1].dot(self.weights[j].T)*self.activation_deriv(a[j])) deltas.reverse() # 更新权值 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 predit(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