python的生成器与yield关键字

 

python中有一个非常有用的语法叫做生成器,所利用到的关键字就是yield。有效利用生成器这个工具可以有效地节约系统资源,避免不必要的内存占用。

数据生成器的作用就是 他不需要把所有的值放在内存中,它是实时地生成数据 ; 

(这里所谓的生成数据 就是从ROM 当中加载到 RAM 中,并且释放上一次加载的数据)

 

你经常使用的 for..in ...这种形式的语句,我们称其为迭代器,

(不太理解迭代器,可以看这里https://blog.csdn.net/Pierce_KK/article/details/99640352

它可以处理像 列表,字符串,这类可迭代的对象, 你可以如你所愿的读取其中的元素,这确实很方便。

但是 你把所有的值都存储到了内存中,如果你有大量数据的话这个方式并不是你想要的。

在这里,所有的值都存在内存当中,所以并不适合大量数据

 

例如你用作深度学习的数据集很大, 有100w 张图片, 你不可能把这一百万张图片都加在到内存里, 然后在分成

训练集, 验证集和测试集 , 用与接下来的训练任务,  你的内存肯定扛不住你这么用的。。

 

 

 

众所周知,神经网络在训练的时候每次只接收一个 batch_size 大小的数据,

你把这么多数据加载进来也是没用,因为每次只用其中的一小部分, 所以我们完全可以每次只加载进来这一个batch_size

数量大小的图片, 训练之后再将他们释放掉,重新加载新的一批。

 

 

这就引出了python的生成器, 

python 通过 yield 函数来定义一个生成器, 也就是说你见到了一个函数, 它的结尾处不是return 而是 yield, 

那么, 就可以断言, 这个函数返回的是一个生成器 。 ---->     <class 'generator'>

二者的简单定义如下:

#  迭代器
for i in my_data:
    img = np.array(i)
    return img

# 生成器
for i in my_data:
    img = np.array(i)
    yield img

    #  img 是 <class 'generator'>

使用生成器 来执行,  程序仅仅会返回 yield 关键字后面的那个值, 并且是作为生成器返回,这并不占什么内存。

因为他只是一个生成器, 没有什么实质性的内容,

 

那么什么时候他才能有实质性的内容呢? 也就是什么时候他能够生成数据呢?

是在你调用它的时候, 但是要注意,与 for ... in ...的这种迭代器不同,生成器每次被调用 返回的都是一批数据,

我不是像迭代器那样 只返回一个数值。

实例如下;

mylist = [0, 1, 4]
for i in mylist :
   print(i)

# 输出结果 
0
1
4

# 这里虽说输出了三个结果,但是这是因为你调用了三次print函数

 

def creatGenerator():
    mylist =  [0, 1, 2]

    for i in mylist :
        yield i*i


mygenerator = creatGenerator()
print(type(mygenerator))

for j in mygenerator:
    print(j)

------- output------
0
1
4

<class 'generator'> 

可以看出, 生成器返回的(yield 回来的)是一个可迭代对象,(我们使用for.. in ..可以对其进行处理)

并且,我们只调用了一次 creatGenerator() , 他就给我们 yield 回来了三个值,这三个值组成了我们的可迭代对象。

 

 

正如上面所叙述的那样, 你调用一次函数 yield 回来的生成器, 就会一次产生一批数据, 并且这批数据是可以进行迭代的

这就与我们训练神经网络的初衷 完美的相吻合。

 

 

-----------------------------

 

前两天, 我见到了一种这样的写法, 大家可以体会下;

imagePaths = sorted(list(paths.list_images(args["dataset"])))
#  给生成器加了list 之后, 就原形毕露了
# 加了list 后,生成器首先要执行生成数据的操作, 然后再将生成的数据装入list
# 在用 sorted来排序, 

random.seed(42)
random.shuffle(imagePaths)

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值