自己编写深度学习框架ANNbox【高仿tensorflow】__05循环神经网络编写:实现RNN(01)

文章列表
1.自己编写深度学习框架ANNbox【高仿tensorflow】__01实现全连接.
2.自己编写深度学习框架ANNbox【高仿tensorflow】__02实现不同的优化方法.
3.自己编写深度学习框架ANNbox【高仿tensorflow】__03文本情感分析.
4.自己编写深度学习框架ANNbox【高仿tensorflow】__04卷积神经网络编写:实现AlexNet.
5.自己编写深度学习框架ANNbox【高仿tensorflow】__05循环神经网络编写:实现RNN(01).

自己编写神经网络库ANNbox【高仿tensorflow】__05循环神经网络编写:实现RNN(01)

为了实现RNN,真是费了老劲了,幸好工作氛围不错,业余还有精力来编ANNbox,在这里要感谢单位。我想尽量用之前定义好的函数来实现最基本的RNN。其实许多时候,在tensorflow中,我们可以不用调用诸如rnn_cell.BasicRNNCell、tf.nn.rnn这样的函数,而是通过自己定义rnn模块的前向计算函数,利用tensorflow强大的计算图结构管理就可以实现循环神经网络。而实现这些需要以下4点技术支持:
01. 拓扑结构管理
02. 域名控制(variable_scope)
03. 各类逻辑操作(concat/unstack)
04. 基本的数学运算(对各类tensor的加减乘除/激活函数/优化器/……)
通过前面几节工作的铺垫,到这里,第1点及第4点都已经基本实现,本节着重介绍第2点及第3点的原理实现,最后给出一个利用框架实现二进制加法运算的算例。

6.1 variable_scope类(利用上下文管理器实现变量的作用域限定)

变量名是在基类Node中定义的,所以用全局变量scope_name来传递作用域名称(默认值为’’),scope_name在variable_scope的初始化函数中被赋值,并在variable_scope上下文作用域范围结束的时候重新赋为空字符。用gloaba_resue(默认值为FALSE)来传递同名get_variable变量是否重用,在variable_scope上下文作用域范围结束的时候重新赋为False。相应的编程实现如下:

class variable_scope():
    def __init__(self,local_scope_name='',reuse=False):
        scope_name[0]=local_scope_name
        global_resue[0]=reuse

    def __enter__(self):
        '''enter()返回一个对象。上下文管理器会使用这一对象作为as所指的变量'''
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        '''
        结束上下文作用域的范围,并将global_resue设置为0
        '''
        scope_name[0]=''
        global_resue[0]=False

为了实现name传递,我在Node基类中对变量名称加上了variable_scope域名对其命名的管理

class Node(object):
def __init__(self,inbound_nodes=[],name='',value=None,shape=[],is_get_variable=False):      
......
        if(scope_name[0]!='' and name!=''):
            self.name=scope_name[0]+'/'+name
        if(scope_name[0]!='' and name==''):
            self.name=scope_name[0]
        if(scope_name[0]=='' and name!=''):
            self.name=name
        ......

6.2 get_variable类(创建共享变量)

get_variable和variable的区别网上有许多,这里不再相信介绍。但我需要声明一下循环神经网络中为什么要用到get_variable(),其实这里的get_variable主要是用来创建共享变量,由前面 深度学习基础模型算法原理及编程实现–06.循环神经网络(https://blog.csdn.net/drilistbox/article/details/79720859) 中不难发现,在RNN的每层神经网络中,沿时间轴及深度轴传递的权重矩阵都是一致的,即每个权重矩阵会用到许多次,但用的都是同一内存上的变量,且还需分别更新,因此需要用的get_variable创建共享变量:即在reuse=true及get_variable变量拥有同样的名字的情况下,不同的get_variable实例对象拥有不同地址,但是其属性self.value是共享的,共享的value值用全局共用字典get_variable_dict来管理。
在编程实现的时候,我们用一个全局变量get_variable_dict来存放get_variable实例对象的value值,每次创建get_variable实例的时候需判定当前对象在get_variable_dict中是否存在同名变量,并且当前variable_scope中的reuse是否为True,通过这两个因素来决定是重复调用get_variable_dict中存放的get_variable实例对象的值。
如果我们在计算图中某个节点定义了一个变量w,后来又在其他节点用get_variable来同一作用域下定义同名变量w/w,下面的3个图给出了大致流程:
这里写图片描述

图3中定义了一个同名的get_variable实例对象w,且当前作用域的resue为true,由于当前get_variable_dict的键值中有同名变量,所以共享在get_variable_dict已有的权重系数的内存空间。编程实现如下:

class get_variable(Node):
    '''变量节点,功能仿造tensorflow中的get_variable,用于存放输入权重系数及偏执系数'''
    def __init__(self,name='',shape=[],initializer=None):
        '''输入层的节点没有传入节点(inbound nodes),所有无需向构造函数中传递任何inbound nodes'''
        Node.__init__(self,name=name,value=None,is_get_variable=True)
        self.shape=shape
        if(self.name in get_variable_dict.keys() and global_resue[0]==True):
            '''get_variable_dict中存在同名变量,并且可以重用,因此无需分配内存'''
            self.value=get_variable_dict[self.name]
        if(self.name in get_variable_dict.keys() and global_resue[0]==False):
            '''get_variable_dict中存在同名变量,需要将resue设为True,否则为False'''
            raise Exception(self,"already exist in current scrope, do you want to set reuse to True!")
#            '''get_variable_dict中存在同名变量,并且不可以重用,因此需管理名称,并分配内存'''
#            '''名称管理'''
#            ind=0
#            while self.name+str(ind) in get_variable_dict.keys():
#                ind+=1
#            self.name=self.name+str(ind)
#            '''重新分配内存'''
#            get_variable_dict[self.name]=initializer(shape)
#            self.value=get_variable_dict[self.name]
#            '''暂时封存'''
##            trainables.append(self) #将variable添加进trainables列表中
        if(self.name not in get_variable_dict.keys()):
            '''get_variable_dict中不存在同名变量,则不管能不能重用,均需分配内存'''
            get_variable_dict[self.name]=initializer(shape)
            self.value=get_variable_dict[self.name]
            '''暂时封存'''
#            trainables.append(self) #将variable添加进trainables列表中
        '''所有的get_variable变量都要加入trainables'''
        trainables.append(self) #将variable添加进trainables列表中
        if(isLEnd[0]==False):L_initial_with_variable_and_constant.append(self) #将variable存入节点列表L中

    def forward(self):
        pass
#        self.value = self.initializer(self.shape)

    def backward(self):
        self.gradients={self:np.zeros_like(self.value)}
        for n in self.outbound_nodes:
            grad_cost=n.gradients[self]
            self.gradients[self]+=grad_cost*1

6.3 concat类(多个张亮按指定维度合并为一个张量)

这里写图片描述

上图中详细的符号定义及代码推导请参考【深度学习基础模型算法原理及编程实现–03.全链接】。相应的代码实现如下:

class concat(Node):
    '''
    tf.concat(concat_dim, values, name='concat')
    这里将多个tensor合并为一个tensor,所以当前类concat自身就可以用来做作为合并后的tensor,无需向unstack中用中间传输节点transmit_node
    '''
    def __init__(self, axis, *L, name=''):
        Node.__init__(self, inbound_nodes=L[0], name=name)
        self.axis=axis
        #缺少检查所有inbound_nodes节点在 除了self.axis这一维度上的 shape是否相等,必须要有
        self.shape=L[0][0].shape[:]
        self.shape[self.axis]=0
        for L_ in L[0]:
            self.shape[self.axis]+=L_.shape[self.axis]

    def forward(self):
        len_shape=len(self.shape)
#        print(self.shape)
        self.value=np.zeros(self.shape)
        ind_start=0
        for L_ in self.inbound_nodes:
            exec('self.value['+':,'*self.axis+str(ind_start)+':'+str(ind_start+L_.shape[self.axis])+',:'*(len_shape-1-self.axis)+']=L_.value')
            ind_start+=L_.shape[self.axis]

    def backward(self):
        len_shape=len(self.shape)
        self.gradients={n: np.zeros_like(n.value) for n in self.inbound_nodes}
        grad_cost=self.outbound_nodes[0].gradients[self]
        ind_start=0
        for in_node in self.inbound_nodes:
            exec('self.gradients[in_node]=grad_cost['+':,'*self.axis+str(ind_start)+':'+str(ind_start+in_node.shape[self.axis])+',:'*(len_shape-1-self.axis)+']')
            ind_start+=in_node.shape[self.axis]

6.4 unstack类(一个R维张量按指定维度拆分为多个R-1维张量)

这里写图片描述

上图中详细的符号定义及代码推导请参考【[深度学习基础模型算法原理及编程实现–06.循环神经网络][6]】。相应的代码实现如下:

class unstack(Node):
    '''
    tf.concat(concat_dim, values, name='concat')
    这里将多个tensor合并为一个tensor,所以当前类concat自身就可以用来做作为合并后的tensor,无需向unstack中用中间传输节点transmit_node
    '''
    def __init__(self, axis, *L, name=''):
        Node.__init__(self, inbound_nodes=L[0], name=name)
        self.axis=axis
        #缺少检查所有inbound_nodes节点在 除了self.axis这一维度上的 shape是否相等,必须要有
        self.shape=L[0][0].shape[:]
        self.shape[self.axis]=0
        for L_ in L[0]:
            self.shape[self.axis]+=L_.shape[self.axis]

    def forward(self):
        len_shape=len(self.shape)
#        print(self.shape)
        self.value=np.zeros(self.shape)
        ind_start=0
        for L_ in self.inbound_nodes:
            exec('self.value['+':,'*self.axis+str(ind_start)+':'+str(ind_start+L_.shape[self.axis])+',:'*(len_shape-1-self.axis)+']=L_.value')
            ind_start+=L_.shape[self.axis]

    def backward(self):
        len_shape=len(self.shape)
        self.gradients={n: np.zeros_like(n.value) for n in self.inbound_nodes}
        grad_cost=self.outbound_nodes[0].gradients[self]
        ind_start=0
        for in_node in self.inbound_nodes:
            exec('self.gradients[in_node]=grad_cost['+':,'*self.axis+str(ind_start)+':'+str(ind_start+in_node.shape[self.axis])+',:'*(len_shape-1-self.axis)+']')
            ind_start+=in_node.shape[self.axis]

6.5 transmit_node类(用于unstack分解操作用的中间暂存变量,不放入feed_dict_inside【非常重要】)

6.6 验证算例

这里写图片描述

详细的代码如下:

6.6.1 ANNbox版本:

# -*- coding: utf-8 -*-
import sys
sys.path.append('./../ANNbox')
import ANNbox as tf
#import tensorflow as tf
import numpy as np

fp=open('annbox_febug.txt',"w")

def binary2int(binary):
    out=0
    for index,num in enumerate(binary[::-1]):
        out += num*pow(2,index)
    return out

def binary2int2(binary):
    out=0
    for index,num in enumerate(binary):
        out += num*pow(2,index)
    return out

'''RNN参数设置,计算8位二进制加法,因此序列长度为8,每次向place_holder中喂入batch_size大小的数据,包括两个相加的二进制序列和一个结果二进制序列,hidden_size表示RNN的隐层节点维数'''
sequence_length=8
batch_size=100
input_size=2
hidden_size=8
output_size= 1
epochs=500
seed_=1

n_classes=output_size
state_size=hidden_size
##RNN的初始化状态,全设为零。注意state是与input保持一致,接下来会有concat操作,所以这里要有batch的维度。即每个样本都要有隐层状态
#init_state=tf.zeros([batch_size,state_size],dtype=tf.float32)

#定义rnn_cell的权重参数,
with tf.variable_scope('rnn_cell'):
    W=tf.get_variable('W',[input_size+state_size,state_size],initializer=tf.truncated_normal_initializer(mean=0.,stddev=0.1))
    b=tf.get_variable('b',[state_size],initializer=tf.constant_initializer(0.0))

#使之定义为reuse模式,循环使用,保持参数相同
rnn_cell_ind=0
def rnn_cell(rnn_input,state):
    with tf.variable_scope('rnn_cell',reuse=True):
        W=tf.get_variable('W',[input_size+state_size,state_size],initializer=tf.truncated_normal_initializer(mean=0.,stddev=0.1))
        b=tf.get_variable('b',[state_size],initializer=tf.constant_initializer(0.0))
    # 定义rnn_cell具体的操作,这里使用的是最简单的rnn,不是LSTM
    global rnn_cell_ind
    rnn_cell_ind+=1
    cnt=tf.concat(1,(rnn_input,state),name='cnt'+str(rnn_cell_ind)+'_in_rnn_cell')
    mtl=tf.matmul(cnt,W,name='mtl'+str(rnn_cell_ind)+'_in_rnn_cell')
    add=tf.Add(mtl,b,name='add'+str(rnn_cell_ind)+'_in_rnn_cell')
    return tf.nn.tanh(add,name='tanh'+str(rnn_cell_ind))
#    return tf.tanh(tf.matmul(tf.concat((rnn_input,state),1),W)+b)

'''推断过程,即是RNN模型的构建过程'''
def inference(x_input):
    '''将输入转换到tensorflow中RNN需要的格式'''
    rnn_inputs=tf.unstack(input_holder,axis=1,name='x_inputs')
    '''构建rnn单元和rnn网络'''
    '''方法01,简单两句搞定,关键在与返回值上,输出看了下,states只有两个值,应该一个是初始状态,一个是末状态,而其他的中间状态其实涵盖在outputs里了,需要直接去取就好,不知道LSTM的输出是怎样,states会不会是8个,得去试一下'''
    #rnn_cell=tf.nn.rnn_cell.BasicRNNCell(hidden_size)
    #rnn_outputs,final_state=tf.nn.rnn(rnn_cell,rnn_inputs,dtype=tf.float32)
    '''方法02'''
    #RNN的初始化状态,全设为零。注意state是与input保持一致,接下来会有concat操作,所以这里要有batch的维度。即每个样本都要有隐层状态
    init_state=tf.zeros([batch_size,state_size],name='init_state')
    state=init_state
    rnn_outputs=[]
    #循环num_steps次,即将一个序列输入RNN模型
    for rnn_input in rnn_inputs:
        state=rnn_cell(rnn_input,state)
        rnn_outputs.append(state)

    '''定义输出层权值和偏置,用variable_scope和get_variable是为了变量的不重复,否则测试和训练会构建重复的variable出来,Tensorboard里面网络的graph会变的比较乱'''
    with tf.variable_scope('hidden_to_output_layer'):
        w2out=tf.get_variable('w2out',shape=[hidden_size,output_size],initializer=tf.truncated_normal_initializer(mean=0.,stddev=0.1))
        bias2out=tf.get_variable('bias2out',shape=[output_size],initializer=tf.constant_initializer(0.0))
    logits=[tf.Add(tf.matmul(rnn_output,w2out,name='matmul_'+str(ind)),bias2out,name='Add'+str(ind)) for ind,rnn_output in enumerate(rnn_outputs)]
    y_pred=tf.concat(1,[tf.nn.sigmoid(logit,name='sigmoid_'+str(ind)) for ind,logit in enumerate(logits)],name='concat_result')
    return y_pred

def generateBinaryDict():
    largest_number=pow(2,8)
    int2binary={}
    binary=np.unpackbits(np.array([range(largest_number)],dtype=np.uint8).T,axis=1).astype('float32')
    for i in range(largest_number):
        int2binary[i]=binary[i]
    return int2binary

input_holder=tf.placeholder(tf.float32,[batch_size,8,2],name='input_placeholder')
label_holder=tf.placeholder(tf.float32,[batch_size,8],name='label_placeholder')
y_pred=inference(input_holder)

sub=tf.nn.Sub(y_pred,label_holder,name='sub')
loss=tf.reduce_mean(tf.square(sub,name='square'),name='reduce_mena')
#op=tf.train.AdagradOptimizer(1.0).minimize(loss)
learning_rate=1e0
Momentum_rate=0.95
op=tf.train.MomentumOptimizer(learning_rate,Momentum_rate).minimize(loss)
init=tf.global_variables_initializer()
np.random.seed(seed_)
#with tf.Session() as sess:
init.run()
binary_dict=generateBinaryDict()
for e in range(epochs):
    batch_in_data=[]
    batch_out_data=[]
    reshape_bi_list=[]
    '''生成minibatch data,其实没必要,但是为了规范'''
    for i in range(batch_size):
        x_int1=np.random.randint(0,128)
        x_int2=np.random.randint(0,128)
        y_true_int=x_int1+x_int2

        x_bi1=binary_dict[x_int1]
        x_bi2=binary_dict[x_int2]
        y_true_bi=binary_dict[y_true_int]
        '''注意输入和输出都需要反向,因为建的RNN是从前往后传信息的,而二进制加法的进位规则是从后往前计算并进位的'''
        for j in range(8):
            reshape_bi_list.append(x_bi1[7-j])
            reshape_bi_list.append(x_bi2[7-j])
        batch_out_data.append(y_true_bi[::-1])

    batch_in_data=np.reshape(reshape_bi_list,[-1,8,2])
    batch_out_data=np.reshape(batch_out_data,[-1,8])

    op.run(feed_dict={input_holder: batch_in_data,label_holder: batch_out_data})
    loss_value=loss.my_eval(feed_dict={input_holder: batch_in_data,label_holder: batch_out_data})
    y_pred_value=y_pred.my_eval(feed_dict={input_holder: batch_in_data,label_holder: batch_out_data})

#    print('iteration at: % d,mean loss is: %f' % (e,loss_value))
    x_left=np.array([binary2int2(l) for l in batch_in_data[:,:,0]])
    x_right=np.array([binary2int2(l) for l in batch_in_data[:,:,1]])
    pre=np.array([binary2int2(l) for l in np.round(y_pred_value)])
#    print('acc:',(((x_left+x_right)==pre).astype('int')).mean())
    print('iteration at: % d,mean loss is: %f acc:%f' % (e,loss_value,(((x_left+x_right)==pre).astype('int')).mean()))


    tem=W.value
    fp.write('epoch:{}, W:\n'.format(e))
    for ind in range(tem.shape[0]):
        for jnd in range(tem.shape[1]):
            fp.write('{:3.3f} '.format(tem[ind,jnd]))
        fp.write('\n')
    tem=b.value
    fp.write('epoch:{}, W:\n'.format(e))
    for ind in range(len(tem)):
        fp.write('{:3.3f} '.format(tem[ind]))
    fp.write('\n')
    fp.write('iteration at:{:3.2f},mean loss is:{:3.2f}, acc:{:3.2f}'.format(e,loss_value,(((x_left+x_right)==pre).astype('int')).mean()))

fp.close()

6.6.2 tensorflow版本:

# -*- coding:utf-8 -*-
#import sys
#sys.path.append('./../ANNbox')
#import ANNbox as tf
import tensorflow as tf
import numpy as np

fp=open('tensorflow_febug.txt',"w")

def binary2int(binary):
    out=0
    for index,num in enumerate(binary[::-1]):
        out += num*pow(2,index)
    return out

def binary2int2(binary):
    out=0
    for index,num in enumerate(binary):
        out += num*pow(2,index)
    return out

'''RNN参数设置,计算8位二进制加法,因此序列长度为8,每次向place_holder中喂入batch_size大小的数据,包括两个相加的二进制序列和一个结果二进制序列,hidden_size表示RNN的隐层节点维数'''
sequence_length=8
batch_size=100
input_size=2
hidden_size=8
output_size= 1
epochs=500
seed_=1

n_classes=output_size
state_size=hidden_size
##RNN的初始化状态,全设为零。注意state是与input保持一致,接下来会有concat操作,所以这里要有batch的维度。即每个样本都要有隐层状态
#init_state=tf.zeros([batch_size,state_size],dtype=tf.float32)

#定义rnn_cell的权重参数,
with tf.variable_scope('rnn_cell'):
    W=tf.get_variable('W',[input_size +state_size,state_size],initializer=tf.truncated_normal_initializer(mean=0.,stddev=0.1,seed=seed_))
    b=tf.get_variable('b',[state_size],initializer=tf.constant_initializer(0.0))

#使之定义为reuse模式,循环使用,保持参数相同
rnn_cell_ind=0
def rnn_cell(rnn_input,state):
    with tf.variable_scope('rnn_cell',reuse=True):
        W=tf.get_variable('W',[input_size+state_size,state_size],initializer=tf.truncated_normal_initializer(mean=0.,stddev=0.1,seed=seed_))
        b=tf.get_variable('b',[state_size],initializer=tf.constant_initializer(0.0))
    # 定义rnn_cell具体的操作,这里使用的是最简单的rnn,不是LSTM
    global rnn_cell_ind
    rnn_cell_ind+=1
    cnt=tf.concat(1,(rnn_input,state))
    mtl=tf.matmul(cnt,W)+b

    return tf.nn.tanh(mtl)
#    return tf.tanh(tf.matmul(tf.concat((rnn_input,state),1),W)+b)

'''推断过程,即是RNN模型的构建过程'''
def inference(x_input):
    '''将输入转换到tensorflow中RNN需要的格式'''
    rnn_inputs=tf.unstack(x_input,axis=1)
    '''构建rnn单元和rnn网络'''
    '''方法01,简单两句搞定,关键在与返回值上,输出看了下,states只有两个值,应该一个是初始状态,一个是末状态,而其他的中间状态其实涵盖在outputs里了,需要直接去取就好,不知道LSTM的输出是怎样,states会不会是8个,得去试一下'''
#    rnn_cell=tf.nn.rnn_cell.BasicRNNCell(hidden_size)
#    rnn_outputs,final_state=tf.nn.rnn(rnn_cell,rnn_inputs,dtype=tf.float32)
    '''方法02'''
    #RNN的初始化状态,全设为零。注意state是与input保持一致,接下来会有concat操作,所以这里要有batch的维度。即每个样本都要有隐层状态
    init_state=tf.zeros([batch_size,state_size])
    state=init_state
    rnn_outputs=[]
    #循环num_steps次,即将一个序列输入RNN模型
    for rnn_input in rnn_inputs:
        state=rnn_cell(rnn_input,state)
        rnn_outputs.append(state)

    '''定义输出层权值和偏置,用variable_scope和get_variable是为了变量的不重复,否则测试和训练会构建重复的variable出来,Tensorboard里面网络的graph会变的比较乱'''
    with tf.variable_scope('hidden_to_output_layer'):
        w2out=tf.get_variable('w2out',shape=[hidden_size,output_size],initializer=tf.truncated_normal_initializer(mean=0.,stddev=0.1,seed=seed_))
        bias2out=tf.get_variable('bias2oput',shape=[output_size],initializer=tf.constant_initializer(0.0))
    logits=[tf.matmul(rnn_output,w2out)+bias2out for ind,rnn_output in enumerate(rnn_outputs)]
    y_pred=tf.concat(1,[tf.nn.sigmoid(logit) for ind,logit in enumerate(logits)])
    return y_pred

def generateBinaryDict():
    largest_number=pow(2,8)
    int2binary={}
    binary=np.unpackbits(np.array([range(largest_number)],dtype=np.uint8).T,axis=1)
    for i in range(largest_number):
        int2binary[i]=binary[i]
    return int2binary

input_holder=tf.placeholder(tf.float32,[None,8,2])
label_holder=tf.placeholder(tf.float32,[None,8])
y_pred=inference(input_holder)

loss=tf.reduce_mean(tf.square(y_pred-label_holder))
#op=tf.train.AdagradOptimizer(1.0).minimize(loss)
learning_rate=1e0
Momentum_rate=0.95
op=tf.train.MomentumOptimizer(learning_rate,Momentum_rate).minimize(loss)
init=tf.initialize_all_variables()
np.random.seed(seed_)
with tf.Session() as sess:
    sess.run(init)
    binary_dict=generateBinaryDict()
    for e in range(epochs):
        batch_in_data=[]
        batch_out_data=[]
        reshape_bi_list=[]
        '''生成minibatch data,其实没必要,但是为了规范'''
        for i in range(batch_size):
            x_int1=np.random.randint(0,128)
            x_int2=np.random.randint(0,128)
            y_true_int=x_int1+x_int2

            x_bi1=binary_dict[x_int1]
            x_bi2=binary_dict[x_int2]
            y_true_bi=binary_dict[y_true_int]
            '''注意输入和输出都需要反向,因为建的RNN是从前往后传信息的,而二进制加法的进位规则是从后往前计算并进位的'''
            for j in range(8):
                reshape_bi_list.append(x_bi1[7-j])
                reshape_bi_list.append(x_bi2[7-j])
            batch_out_data.append(y_true_bi[::-1])

        batch_in_data=np.reshape(reshape_bi_list,[-1,8,2])
        batch_out_data=np.reshape(batch_out_data,[-1,8])

        sess.run(op,feed_dict={input_holder:batch_in_data,label_holder:batch_out_data})
        loss_value=sess.run(loss,feed_dict={input_holder:batch_in_data,label_holder:batch_out_data})
        y_pred_value=sess.run(y_pred,feed_dict={input_holder:batch_in_data,label_holder:batch_out_data})
        x_left=np.array([binary2int2(l) for l in batch_in_data[:,:,0]])
        x_right=np.array([binary2int2(l) for l in batch_in_data[:,:,1]])
        pre=np.array([binary2int2(l) for l in np.round(y_pred_value)])
        print('iteration at:% d,mean loss is:%f acc:%f' % (e,loss_value,(((x_left+x_right)==pre).astype('int')).mean()))

        tem=sess.run(W)

        fp.write('epoch:{}, W:\n'.format(e))
        for ind in range(tem.shape[0]):
            for jnd in range(tem.shape[1]):
                fp.write('{:3.3f} '.format(tem[ind,jnd]))
            fp.write('\n')
        tem=sess.run(b)
        fp.write('epoch:{}, W:\n'.format(e))
        for ind in range(len(tem)):
            fp.write('{:3.3f} '.format(tem[ind]))
        fp.write('\n')
        fp.write('iteration at:{:3.2f},mean loss is:{:3.2f}, acc:{:3.2f}'.format(e,loss_value,(((x_left+x_right)==pre).astype('int')).mean()))      
fp.close()

6.7 代码文件

https://pan.baidu.com/s/1QIE0a6NdJOEKO7_pKtNTOQ#list/path=%2F

猜你喜欢

转载自blog.csdn.net/drilistbox/article/details/81487836