This repository has been archived on 2020-04-25. You can view files and clone it, but cannot push or open issues or pull requests.
ml/nn/neuralNetwork.py

81 lines
2.4 KiB
Python
Raw Permalink Normal View History

2020-02-23 14:14:06 +00:00
#!/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