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
2020-02-23 22:14:06 +08:00

81 lines
2.4 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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