深度学习(一)autoencoder的Python实现(2)

来源:互联网 发布:菜鸟网络招聘信息 编辑:程序博客网 时间:2024/04/30 00:43

这一篇章,我将对autoencoder的主要功能进行Python的实现,并通过一个小例子进行验证,其中深度学习和autoencoder的基本原理,在上一篇章深度学习(一)autoencoder的Python实现(1)中解释了,

1类的定义

首先我们建立bean.py文件,在里面定义两个类,一个是神经网络类nn和训练时autoencoder类

import numpy as np#创建神经网络类# nodes为1*n矩阵,表示每一层有多少个节点,例如[3,4,5]# 表示三层,第一层有3个节点,第二层4个,第三层5个class nn():    def __init__(self,nodes):#输入为神经网络结构        self.layers = len(nodes)        self.nodes = nodes        self.u = 1.0 # 学习率        self.W = list() # 权值        self.B = list() # 偏差值        self.values = list() # 层值        self.error = 0 # 误差        self.loss = 0 # 损失        for i in range(self.layers-1):            # 权值初始化,权重范围-0.5~0.5            self.W.append(np.random.random((self.nodes[i],            self.nodes[i+1])) - 0.5)               # 偏差B值初始化            self.B.append(0)        for j in range(self.layers):            # 节点values值初始化            self.values.append(0)#创建autoencoder类,可以看成是多个神经网络简单的堆叠而来class autoencoder():    def __init__(self):        self.encoders = list()    def add_one(self,nn):        self.encoders.append(nn)

2方法

建立工具文件util.py,在里面编写相关的调用方法
首先导入包numpy和上文编写的bean

import numpy as npfrom bean import nn,autoencoder

建立autoencoder结构方法

#建立autoencoder框架def aebuilder(nodes):    layers = len(nodes)    ae = autoencoder() #获取autoencoder类    for i in range(layers-1):        #训练时,我们令输入等于输出,所以每一个训练时的autoencoder层为[n1,n2,n1]形式的结构        ae.add_one(nn([nodes[i],nodes[i+1],nodes[i]]))       return ae

开始进行训练

#训练autoencoder,ae为Autoencoder的训练模型,x为输入,interactions为训练迭代次数def aetrain(ae,x,interations):    elayers = len(ae.encoders)    for i in range(elayers):        #单层Autoencoder训练        ae.encoders[i] = nntrain(ae.encoders[i],x,x,interations)        #单层训练后,获取该Autoencoder层中间层的值,作为下一层的训练输入        nntemp = nnff(ae.encoders[i],x,x)        #feed forward        x = nntemp.values[1]       return ae 

其中nntrain即普通的神经网络训练,nnff为feed forward,获取当前前向计算值,下面将代码具体展现

#对神经网络进行训练def nntrain(nn,x,y,iterations):    for i in range(iterations):        nnff(nn,x,y)        nnbp(nn)    return nn

前向输出函数,nnff

#前馈函数def nnff(nn,x,y):    layers = nn.layers    # 获取训练样本数量    numbers = x.shape[0]    # 赋予初值    nn.values[0] = x    for i in range(1,layers):        nn.values[i] = sigmod(np.dot(nn.values[i-1],nn.W[i-1])+nn.B[i-1])    # 最后一层与实际的误差    nn.error = y - nn.values[layers-1]    # 代价损失    nn.loss = 1.0/2.0*(nn.error**2).sum()/numbers    return nn   

其中单层输出y=sigmod(wx+b),sigmod函数如下

# 激活函数def sigmod(x):    return 1.0 / (1.0 + np.exp(-x))

完成nnff后,接下来是最重要的back propagation,nnbp。
本文的损失函数不考虑任何正则项和约束项,为最简单的autoencoder,函数如下
这里写图片描述
这里写图片描述
需要涉及到权值更新公式,
这里写图片描述
其中l为神经网络当前层数,α为学习速率,我们需要求α后的导数项
这里写图片描述
进一步获得
这里写图片描述
需要求得δl+1i
当计算最后一层时,
这里写图片描述
其中f(z)即sigmod函数,f’(z)=f(z)(1-f(z))
当不是最后一层时
这里写图片描述
如果对公式有所疑问,可以参考文献Stanford,里面给出了具体说明。
接下来就要展示nnbp代码

#BP函数def nnbp(nn):    layers = nn.layers;    #初始化delta    deltas = list();    for i in range(layers):        deltas.append(0)    #最后一层的delta为    deltas[layers-1] = -nn.error*nn.values[layers-1]*(1-nn.values[layers-1])    #其他层的delta为    for j in range(1,layers-1)[::-1]:#倒过来        deltas[j] = np.dot(deltas[j+1],nn.W[j].T)*nn.values[j]*(1-nn.values[j])    #更新W值和B值    for k in range(layers-1):        nn.W[k] -= nn.u*np.dot(nn.values[k].T,deltas[k+1])/(deltas[k+1].shape[0])        nn.B[k] -= nn.u*deltas[k+1]/(deltas[k+1].shape[0])    return nn

到这里,完成了工具文件中的代码

3测试

建立test.py,开始我们的小测试

import utilfrom bean import autoencoder,nnimport numpy as np# 测试数据,x为输入,y为输出x = np.array([[0,0,1,0,0],            [0,1,1,0,1],            [1,0,0,0,1],            [1,1,1,0,0],            [0,1,0,1,0],            [0,1,1,1,1],            [0,1,0,0,1],            [0,1,1,0,1],            [1,1,1,1,0],            [0,0,0,1,0]])y = np.array([[0],            [1],            [0],            [1],            [0],            [1],            [0],            [1],            [1],            [0]])################################## step1 建立autoencoder#弄两层autoencoder,其中5为输入的维度nodes=[5,3,2]#建立auto框架ae = util.aebuilder(nodes)#设置部分参数#训练,迭代次数为6000ae = util.aetrain(ae, x, 6000)############################### step2 微调#建立完全体的autoencoder,最后层数1为输出的特征数nodescomplete = np.array([5,3,2,1])aecomplete = nn(nodescomplete)# 将之前训练得到的权值赋值给完全体的autoencoder# 训练得到的权值,即原来的autoencoder网络中每一个autoencoder中的第一层到中间层的权值for i in range(len(nodescomplete)-2):    aecomplete.W[i] = ae.encoders[i].W[0]# 开始进行神经网络训练,主要就是进行微调   aecomplete = util.nntrain(aecomplete, x, y, 3000)# 打印出最后一层的输出print aecomplete.values[3]

运行的结果为
这里写图片描述
还是大致满足要求的。

本章节代码已经上传到github,可以点击链接获得,不过后期会有一定的改进

其中autoencoder 还有很多的改进,比如 sparse autoencoder,denosing autoencoder等,在接下来的章节将会继续用Python实现,还有具体的代码,也会上传。

7 0
原创粉丝点击