最好的yeild解释网站:Python yield 使用浅析 其里面有解释怎么判断一个函数是不是generator
https://www.jianshu.com/p/d09778f4e055
1、yeild的使用,代码例子如下:
def yield_test(n, index):
for i in range(n):
# 每次迭代运行到yeild处返回值并停止,下次迭代的时候继续执行后面的代码
yield call(i)
print("{}={}".format(index, i))
def call(i):
return i * 2
def normalize(x):
return x - 30
def testsum():
data1 = yield_test(3, "first")
print("test")
# 打断点只能捕捉到一次,而zip在迭代的时候是会不断执行map,其中map是把某个操作应用到对于的
# 变量上
img_normalize = map(normalize, data1)
# 其无法直接对yeild返回数据进行操作,要通过map,否则会报:TypeError: unsupported operand type(s) for -: 'generator' and 'int'
# img_normalize=data1-30
data2 = yield_test(5, "second")
# 其中zip里的元素都是需要支持迭代的,例如列表,数组,这里的yeild,如果data1、data2不同长度,则其
# zip只能迭代到小的那个size为准,
return zip(img_normalize, data2)
# return zip(22,33)
if __name__ == '__main__':
train = testsum()
for i, n in enumerate(train):
print("OK_data1={} data2={}".format(n[0], n[1]))
其输出为:
test
OK_data1=-30 data2=0
first=0
second=0
OK_data1=-28 data2=2
first=1
second=1
OK_data1=-26 data2=4
first=2
关于yield的一个结论:
一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。
yield 的好处是显而易见的,把一个函数改写为一个 generator 就获得了迭代能力,比起用类的实例保存状态来计算下一个 next() 的值,不仅代码简洁,而且执行流程异常清晰。
判断一个函数是不是可迭代的:
>>> from collections import Iterable
>>> isinstance(fab, Iterable)
False
>>> isinstance(fab(5), Iterable)
True
2、keras进行变量初始化、特征融合:
import numpy as np
import keras.layers as keraslayer
import keras
from keras import backend as K
img = np.random.randn(1, 4, 5)
# 第二维度1到3的数据,最后的维度大小为(1,3,5)
imgcopy = img[:, 1:]
# 第二个维度取从后往前一列的数据,最后的维度大小为(1,1,5)
imgcopy2 = img[:, -1:]
# 第二个维度取从后往前两列的数据,最后的维度大小为(1,2,5)
imgcopy3=img[:,-2:]
tensor1 = np.random.randn(1, 1, 2, 3)
tensor2 = np.random.randn(1, 1, 2, 3)
# 初始化一个变量,具体可以参考文章:https://keras-cn.readthedocs.io/en/latest/backend/
input1 = K.variable(value=tensor1)
input2 = K.variable(value=tensor2)
# input2=K.placeholder(shape=(1,2,3))
# 这里是进行特征图融合的函数,其中concat_axis是指按第几个维度进行融合,由于通道的总矩阵为(B,C,H,W),第3维度则是W,
# 具体可以看数据输出。
tensor3 = keraslayer.merge([input1, input2], mode='concat', concat_axis=3)
tensor4=keraslayer.merge([input1,input2],mode="concat",concat_axis=1)
# 如果使用input1.eval()会报错
print(K.eval(input1))
print(K.eval(input2))
print(K.eval(tensor3))
print(K.eval(tensor4))
输出为:
[[[[1.3389711 0.905703 1.4339311]
[1.8254985 0.4211271 1.7143093]]]]
[[[[-0.2599192 -0.7234859 -0.8696323 ]
[-0.95569044 0.01362781 0.9983865 ]]]]
[[[[ 1.3389711 0.905703 1.4339311 -0.2599192 -0.7234859
-0.8696323 ]
[ 1.8254985 0.4211271 1.7143093 -0.95569044 0.01362781
0.9983865 ]]]]
[[[[ 1.3389711 0.905703 1.4339311 ]
[ 1.8254985 0.4211271 1.7143093 ]]
[[-0.2599192 -0.7234859 -0.8696323 ]
[-0.95569044 0.01362781 0.9983865 ]]]]
3、pytorch训练可视化visdom:
其中实验visdom模块可视化pytorch训练过程的数据,其中在训练过程的应用代码为:
import visdom
vis = visdom.Visdom()
if np.mod(index, 15) == 0:
print('epoch {}, {}/{},train loss is {}'.format(epo, index, len(train_dataloader), iter_loss))
# vis.close(),其中opts里的title是可视化窗口名称
vis.images(output_np[:, None, :, :], win='train_pred', opts=dict(title='train prediction'))
vis.images(bag_msk_np[:, None, :, :], win='train_label', opts=dict(title='label'))
#其中X指的是在可视化界面上X轴的坐标,其大小跟all_train_iter_loss的size大小一致。
vis.line(all_train_iter_loss, X=X_index, win='train_iter_loss', opts=dict(title='train iter loss'))
注意:这里的的images输入现在:
a、支持最大四个维度,维度可以小于4,其会被看成【b,c,h,w】. 其中c可以是小于3的任何值。
b、其输入tensor可以是【h,w】.
如果是可视化深度网络的某些层的输出,则其使用的函数是heatmap()比较好.不过其输入只能是是dims==2的数据。不能批量化画热力图
参考链接:PyTorch可视化工具Visdom实战
faceboolresearch/visdom/example/demo.py --好
3、torch进行数据的深拷贝:
其中使用到tensor里面的内建函数clone();例如:
new_tensor=x.clone() #如果x有梯度信息,则会把其梯度也拷贝了。增加了程序空间占用,不好。
其中如果是python里的数据例如列表、元组、numpy里的数据要进行深拷贝则是使用copy.deepcopy()例如:
if n_samples_for_each_video == 1:
sample['frame_indices'] = list(range(1, n_frames + 1))
dataset.append(sample)
else:
if n_samples_for_each_video > 1:
step = max(1,
math.ceil((n_frames - 1 - sample_duration) /
(n_samples_for_each_video - 1)))
else:
step = sample_duration
for j in range(1, n_frames, step):
sample_j = copy.deepcopy(sample)
sample_j['frame_indices'] = list(
range(j, min(n_frames + 1, j + sample_duration)))
dataset.append(sample_j)