tensorflow卷积神经网络计算

卷积神经网络计算

记录m卷积网络计算过程

以tensorflow中的mnist_deep为例

在训练时保存checkpoint

saver = tf.train.Saver()
....
save_path = saver.save(sess,'mnist_deep/model.ckpt')

训练完成后,可以读取checkpoint,保存log可以用tensorboard查看模型结构

reader = tf.train.NewCheckpointReader('mnist_deep/model.ckpt')
all_variables = reader.get_variable_to_shape_map()
mnist = input_data.read_data_sets('../mnist-master/input_data')

saver = tf.train.import_meta_graph('mnist_deep/model.ckpt.meta')
with tf.Session() as sess:
    saver.restore(sess,'mnist_deep/model.ckpt')
    writer = tf.summary.FileWriter('mnist_deep/log')
    writer.add_graph(sess.graph)
    writer.flush()
    writer.close()

查看模型计算图,在log目录下运行cmd命令如下

tensorboard --logdir=log

按照提示信息打开浏览器,在浏览器中可以看到计算图如下
这里写图片描述

在tesnorboard中可以查看各个操作的详细情况,可以用以下方式看到任意一步的输出的结果

reader = tf.train.NewCheckpointReader('mnist_deep/model.ckpt')
all_variables = reader.get_variable_to_shape_map()
mnist = input_data.read_data_sets('../mnist-master/input_data')

saver = tf.train.import_meta_graph('mnist_deep/model.ckpt.meta')
with tf.Session() as sess:
    saver.restore(sess,'mnist_deep/model.ckpt') 

    input_x = mnist.test.images
    input_x = input_x[0:1,:]

    x = tf.get_default_graph().get_operation_by_name('Placeholder').outputs[0]
    keep_prob = tf.get_default_graph().get_operation_by_name('dropout/Placeholder').outputs[0]

    MatMul_output0 = tf.get_default_graph().get_operation_by_name('conv1/Conv2D').outputs[0]

    reshape_output = sess.run(tf.get_default_graph().get_operation_by_name('reshape/Reshape').outputs[0],feed_dict={x:input_x})
    result = sess.run(MatMul_output0,feed_dict={x:input_x})

如以上代码得到了’reshape/Reshape’跟’conv1/Conv2D’处的输出
既然可以得到每步输出,那就对照写下各个步骤的计算过程

首先看第一个卷积层
input:[none,28,28,1]
output:[none,28,28,32],
内部长这个样子的
这里写图片描述
输入28*28的单通道图片,feature map数量为32,边界补零方式为’same’,即输入输出大小相等
卷积函数如下

def Conv2D(x, W, bias,strides=[1, 1, 1, 1], padding='SAME'):
    if len(x.shape)!=4:
        print("input shape must be [samples,width,height,channel!]")
        return -1
    #补0后的图片大小
    pad_row = W.shape[0]-1
    pad_col = W.shape[1]-1

    filter_num = W.shape[3]

    sample_num = x.shape[0]
    width = x.shape[1]
    height = x.shape[2]
    channel = x.shape[3]

    new_width = width+pad_row
    new_height = height+pad_col


    x_pad = np.zeros((sample_num,new_width,new_height,channel),dtype=float)
    x_pad[:,int(pad_row/2):new_width-int(pad_row/2),int(pad_col/2):new_height-int(pad_col/2),:] = x
    x_output = np.zeros((sample_num,width,height,filter_num), dtype=float)

    #卷积计算
    for sample in range(sample_num):
        for fi in range(filter_num):
            for i in range(width):
                for j in range(height):
                    x_output[sample, i, j, fi] = x_output[sample,i,j,fi] + bias[fi]
                    for ch in range(channel):
                        mul = np.multiply(x_pad[sample,i:i+W.shape[0],j:j+W.shape[1],ch],W[:,:,ch,fi])
                        x_output[sample,i,j,fi] = x_output[sample,i,j,fi]+np.sum(np.sum(mul))
    return x_output

这一步完成了权值与输入数据的卷积以及加上偏置
再经过一个Relu激活函数如下

def ReLu(x):
    return np.maximum(x,0)

然后再经过一个最大池化层

def max_pool_2x2(x):
    width = x.shape[1]
    height = x.shape[2]
    m=0;
    n=0;
    x_out = np.zeros((x.shape[0], int(x.shape[1]/2), int(x.shape[2]/2), x.shape[3]), dtype=float)
    for filter_index in range(x.shape[3]):
        m=0
        for i in range(0,width,2):
            n=0;
            for j in range(0,height,2):
                x_out[0,m,n,filter_index] = np.max(x[0,i:i+2,j:j+2,filter_index])
                n=n+1
            m=m+1
    return x_out

然后再经过全连接层

def fc(x,W,bias):
    x_reshape = x.reshape(x.shape[0],-1)
    return np.dot(x_reshape,W)+bias

mnist例子中的网络结构并不复杂,inference过程很容易写出来,这里仅记录conv层的参数计算问题,

  • 第一个卷积层
    输入 [1,28,28,1],[1,28,28,32] [ 1 , 28 , 28 , 1 ] , 输 出 [ 1 , 28 , 28 , 32 ] ,权值w大小为 [5,5,1,32]b[1,32] [ 5 , 5 , 1 , 32 ] , 偏 置 b [ 1 , 32 ]

  • 第二个卷积层
    输入 [1,28,28,32],[1,28,28,64]w[5,5,32,64],b[1,64] [ 1 , 28 , 28 , 32 ] , 输 出 [ 1 , 28 , 28 , 64 ] , 权 值 w [ 5 , 5 , 32 , 64 ] , 偏 置 b [ 1 , 64 ]

第一个通道为1卷积层很容易理解,第二个卷积层中,通道(feature)数为32,可以这样理解,32个通道,每个通道都有64个5X5的卷积核,每个通道都分别与64个卷积核做卷积,得到 [1,28,28,32,64] [ 1 , 28 , 28 , 32 , 64 ] 输 出 ,最后,再将32个通道的各个feature相加得到最终的 [1,28,28,64] [ 1 , 28 , 28 , 64 ] 输 出 ,64个输出feature map,就有64个偏置,偏置相加是 2828 28 ∗ 28 中每个点都要加,也可以直接写成
import numpy as np
b = np.ones([1,28,28,64])*bias[0]
output = output+b
具体实现在自己写的Conv2D函数中循环部分

代码地址https://github.com/wangwei2009/tinydnn-tensorflow

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值