神经网络/自编码器的实现(向量版本)
# -*- coding: utf-8 -*-
"""
Created on Tue Jan 2 17:47:29 2018
@author: lyh
"""
import numpy as np
from sklearn.preprocessing import MinMaxScaler
#激活函数
def tanh(x):
return (np.exp(x) - np.exp(-x)) / (np.exp(x) + np.exp(-x))
#激活函数 tanh导数
def d_tanh(x):
return 1 + np.negative(np.square(tanh(x)))
#计算cost
def cost(a,y):
return np.negative(y * np.log(a)) + ((1 + np.negative(y)) * np.log(1 + np.negative(a)))
#计算dA
def da(a,y):
return np.negative(y / a) + ((1 + np.negative(y)) / (1 + np.negative(a)))
#自定义多层神经网络
def neuralNetwork(l,n,X,y,lr,iterations):
"""
loss function: -ylogy_hat + (1-y)log(1-y_hat)
params:
l : The number of layers
n : The number of nodes on each layer
X : x
y : y
lr : learning rate
iterations : Number of iterations
"""
A = [X]
W,b,Z = [0],[0],[0]
dZ,dA,dW,db = [0],[0],[0],[0]
m = X.shape[1]
loss = 1000
#初始化
for i in range(1,l):
W.append(np.random.rand(n[i],n[i-1]))
b.append(np.random.rand(n[i]).reshape(n[i],1))
A.append(0)
Z.append(0)
dZ.append(0)
dA.append(0)
dW.append(0)
db.append(0)
for index in range(iterations):
#前馈传播
for i in range(1,l):
Z[i] = np.dot(W[i],A[i-1]) + b[i].reshape(len(b[i]),1)
A[i] = tanh(Z[i])
#最后一层dA
"""
if((np.isnan(np.mean(cost(A[l-1], y)))) | (np.mean(cost(A[l-1], y)) == loss)):
print("迭代停止")
#break
else:"""
loss = np.mean(cost(A[l-1], y))
print(index,loss)
dA[l-1] = da(A[l-1], y)
#反向传播
for i in range(1,l):
layer = l-i
dZ[layer] = dA[layer] * d_tanh(Z[layer]) #对应元素相乘
dW[layer] = 1/m * (np.dot(dZ[layer], A[layer-1].T))
db[layer] = 1/m * np.sum(dZ[layer], axis=1, keepdims=True)
dA[layer - 1] = np.dot(W[layer].T, dZ[layer])
#更新权值
W[layer] -= lr * dW[layer]
b[layer] -= lr * db[layer]
return A,W,b
#构造自编码器
def AutoEncoder(X,n,lr,it):
"""
loss function: -ylogy_hat + (1-y)log(1-y_hat)
params:
n : The number of nodes on each layer
X : x
lr : learning rate
iterations : Number of iterations
"""
row = X.shape[0]
col = X.shape[1]
X = X.reshape(row * col,1)
l = len(n)
scaler = MinMaxScaler().fit(X)
X_scaler = scaler.transform(X)
print(X_scaler.shape)
print("input ",X)
#print("归一化 ",X)
A,W,b = neuralNetwork(l,n,X_scaler,X_scaler,lr,it)
print("AutoEncoder output ",scaler.inverse_transform(A[l-1]).reshape(row,col))
#X = np.array([5,5,10,1,5,9,7,4,6,8])
#X = X.reshape(len(X),1)
#测试
from sklearn import datasets
iris = datasets.load_iris()
data = iris["data"]
X = data
row = X.shape[0]
col = X.shape[1]
AutoEncoder(X,[row * col,2,row * col],0.05,100)
此版本目前存在一个Bug 在自编码器中,当对输入标准化之后,等于或接近零的数值在还原之后变成了负数。 解释半天找不到原因,有没有大佬知道是什么原因的,欢迎指出问题所在,谢谢。