yeild、keras深度通过numpy初始化variable、merge,pytorch训练可视化visdom、进行数据的深拷贝

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yangdashi888/article/details/87197252

最好的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()
                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'))

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)

参考博客:在PyTorch中使用Visdom可视化工具

visdom简易教程

猜你喜欢

转载自blog.csdn.net/yangdashi888/article/details/87197252
今日推荐