MindSpore实现图片分类
505
2022-05-29
【MindSpore第六期两日集训营】于2021年11月6日到11月7日在B站拉开了帷幕,错过直播 https://live.bilibili.com/22127570 的老铁们别忘了还有录播,链接分别为:
第一天:
第六期两日集训营 | MindSpore AI电磁仿真 https://www.bilibili.com/video/BV1Y34y1Z7E8?spm_id_from=333.999.0.0
第六期两日集训营 | MindSpore并行使能大模型训练 https://www.bilibili.com/video/BV193411b7on?spm_id_from=333.999.0.0
第六期两日集训营 | MindSpore Boost,让你的训练变得飞快 https://www.bilibili.com/video/BV1c341187ML?spm_id_from=333.999.0.0
第二天:
第六期两日集训营 | MindSpore 控制流概述 https://www.bilibili.com/video/BV1A34y1d7G7?spm_id_from=333.999.0.0
第六期两日集训营 | MindSpore Lite1.5特性发布,带来全新端侧AI体验 https://www.bilibili.com/video/BV1f34y1o7mR?spm_id_from=333.999.0.0
第六期两日集训营 | 可视化集群调优重磅发布,从LeNet到盘古大模型都能调优 https://www.bilibili.com/video/BV1dg411K7Nb?spm_id_from=333.999.0.0
我们来看第二天第一讲:MindSpore 控制流概述
作业如下:
作业思路:
1.先看看如果不用控制流,Python本身应该怎么做这个题目。
2.看看如何能启动MindSpore控制流。
3.将Python相关代码放入MindSpore控制流的建立方式中,实现相关功能。
张小白的解题思路:
递归的话,看一下0~1000的累加求和,相当于实现满足两种要求:
n>=1时:
f(n)=f(n-1)+n
n=0时:
f(n)=0
其实从0开始加和从1开始加都一样。所以题目即可以从0开始算,也可以从1开始算。
先用Python实现一个简单的递归:
vi python_recursion_01.py
def f(n): if n == 0: return 0 else: return f(n-1) + n sum = f(100) print(sum)
执行一下:
python python_recursion_01.py
貌似没啥问题。
改成1000试试:
不行了。
因为Python3缺省的递归最大数为998,所以执行后直接报错。
我们试一下:
确实如此,但是有一种方法提高堆栈的最大值:
在代码中加入以下代码:
import sys sys.setrecursionlimit(20000)
这个20000是张小白自己设置的。越大估计越占内存吧。
不如再改为10000试试:
也不用再往上试了。按理说这样子就可以迁移到控制流里面了。
听了老师的控制流视频后,
也可以再看看官网介绍的文档 https://www.mindspore.cn/docs/programming_guide/zh-CN/r1.5/control_flow.html
因为MindSpore默认的模式为GRAPH_MODE模式,所以直接按照示例来写代码就可以直接用到MindSpore控制流了。
我们来依葫芦画瓢一下:
看示例,首先要在网络中生成控制流算子。所以需要按下图示例使用MindSpore特有的方式建立一个SingleIfNet的网络:
我们如法炮制:
vi python_recursion_02.py
import numpy as np from mindspore import context from mindspore import Tensor, nn from mindspore import dtype as ms import sys sys.setrecursionlimit(20000) zero = Tensor(np.array(0), dtype=ms.int32) one = Tensor(np.array(1), dtype=ms.int32) count = Tensor(np.array(100), dtype=ms.int32) class SingleIfNet(nn.Cell): def construct(self, n): if n == zero: return zero else: return self.construct( n - one ) + n forward_net = SingleIfNet() output = forward_net(count) print (output)
当然在这种情况下,我们需要进入mindspore1.5-gpu的conda 环境,运行一下:
加到100没问题,那加到10000呢?
看样子是没啥问题。
前面张小白的代码要解释一下,原来代码中使用0,1这些整型数进行比较,但是由于现在是进行控制流计算,所以直接比较整型和tensor是不行的。需要把整型换成tensor(张量)来比较。
所以张小白才定义了
zero = Tensor(np.array(0), dtype=ms.int32) one = Tensor(np.array(1), dtype=ms.int32) count = Tensor(np.array(100), dtype=ms.int32)
这几个值,然后 所谓的0,1,count比较也是变量跟这些tensor的比较。
其实如果这样实现的话,那么while循环的实现反而简单了。
先看一下纯Python怎么做。
vi python_while.py
def f(n): x = 0 out = 0 while x < n: x = x + 1 out = out + x return out sum = f(100) print(sum)
改成10000,1000000试试:
都没啥问题。
那么就继续改造成MindSpore控制流的方式:
vi python_while_02.py
import numpy as np from mindspore import context from mindspore import Tensor, nn from mindspore import dtype as ms import sys sys.setrecursionlimit(20000) zero = Tensor(np.array(0), dtype=ms.int32) one = Tensor(np.array(1), dtype=ms.int32) count = Tensor(np.array(100), dtype=ms.int32) class SingleIfNet(nn.Cell): def construct(self, n): x = zero out = zero while x < n: x = x + 1 out = out + x return out forward_net = SingleIfNet() output = forward_net(count) print (output)
执行一下:
python python_while_02.py
改成 普通python能计算的100万,看来mindspore控制流计算得比较吃力。
不过它算出来了:
而且似乎算错了,好像是溢出了——32位操作系统int类型的最大值是 2147483647,一共10位。
100万的计算结果,是500000500000,一共12位。
显然溢出了。
那只有改成int64:
cat python_while_03.py
python python_while_03.py
改成这样就没问题了。
张小白觉得前面maxdepth的显示非常得让人恼火。张小白也搜索到一些方式,比如尾递归的方法。
张小白找到了这篇:
https://blog.csdn.net/fall_song/article/details/106732276
先试试这篇好不好使:
vi python_recursion_03.py
import types def f_recursive(cur_i, cur_computer_result=1): if cur_i == 1: yield cur_computer_result yield f_recursive(cur_i - 1, cur_i + cur_computer_result) def f_recursive_wapper(generator, i): gen = generator(i) while isinstance(gen, types.GeneratorType): gen = gen.__next__() return gen print(f_recursive_wapper(f_recursive,10000))
执行一下代码,好像确实没问题。
那么能不能将其改造到MindSpore里面去呢。。。
按照 @Chameleon 老师 的提示,“定义一个函数f。然后f进行递归,在construct里去调用这个f”,我们来试试:
import types import numpy as np from mindspore import context from mindspore import Tensor, nn from mindspore import dtype as ms zero = Tensor(np.array(0), dtype=ms.int32) one = Tensor(np.array(1), dtype=ms.int32) count = Tensor(np.array(10000), dtype=ms.int32) count0 = 10000 def f_recursive(cur_i, cur_computer_result=one): if cur_i == one: yield cur_computer_result yield f_recursive(cur_i - one, cur_i + cur_computer_result) def f_recursive_wapper(generator, i): gen = generator(i) while isinstance(gen, types.GeneratorType): gen = gen.__next__() return gen output0 = f_recursive_wapper(f_recursive,count0) print(output0) class SingleIfNet(nn.Cell): def construct(self,n): out = f_recursive_wapper(f_recursive,n) return out forward_net = SingleIfNet() output = forward_net( count ) print (output)
python python_recursion_04.py
原生的方法输出的output0出来了。
但是mindspore控制流的方式报不支持yield.
也问了老师,说目前MindSpore控制流确实不支持yield语法。
张小白又找到一篇更高大上的做法:
https://zhuanlan.zhihu.com/p/37060182
不过这个改造成mindspore控制流方式估计难度更大。
好了,先不试验了。综上,MindSpore控制流的用法通过递归和非递归的例子,大家应该都能了解了吧。如果大家还有兴趣了解一下控制流是怎么做出来了,可以再听听视频,或者看看MIndSpore的源代码。MindSpore是开源的项目,你想看到的东西应该都能看到,就看你有没有心思去找了。
MindSpore代码仓:https://gitee.com/mindspore/mindspore.git
MindSpore官网:https://mindspore.cn
(全文完,谢谢阅读)
MindSpore Python
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。