slowfast官方代码阅读过程中的Python基础补充(一)

torch.clamp()

clamp是夹紧的意思。函数的功能是将input Tensor,夹紧到[min,max]区间中,输出同样为Tensor。

torch.clamp(input, min, max, out=None) → Tensor

实现过程:

      | min, if x_i < min
y_i = | x_i, if min <= x_i <= max
      | max, if x_i > max

示例:
示例:

torch.linspace()

PyTorch的官方网站上找到了这个函数的详细说明

torch.linspace(start, end, steps=100, out=None, dtype=None, layout=torch.strided, device=None, requires_grad=False) → Tensor

函数的作用是,返回一个一维的tensor(张量),这个张量包含了从start到end,分成steps个线段得到的向量。常用的几个变量:

start: 开始值
end: 结束值
steps:分割的点数,默认是100
dtype:返回值(张量)的数据类型

import torch
print(torch.linspace(3,10,5))
#tensor([ 3.0000,  4.7500,  6.5000,  8.2500, 10.0000])
 
 
type=torch.float
print(torch.linspace(-10,10,steps=6,dtype=type))
#tensor([-10.,  -6.,  -2.,   2.,   6.,  10.])

frame.shape()

frame.shape[0]:图像的垂直尺寸(高度)
frame.shape[1]:图像的水平尺寸(宽度)
frame.shape[2]:图像的通道数。

.long()

long() 函数将数字或字符串转换为一个长整型

torch.index_select()

index_select(
    dim,
    index
)

dim:表示从第几维挑选数据,类型为int值;
index:表示从第一个参数维度中的哪个位置挑选数据,类型为torch.Tensor类的实例;

seek()

seek() 方法用于移动文件读取指针到指定位置。
参数

  • offset – 开始的偏移量,也就是代表需要移动偏移的字节数
  • whence – 可选,默认值为 0。给offset参数一个定义,表示要从哪个位置开始偏移;0代表从文件开头开始算起,1代表从当前位置开始算起,2代表从文件末尾算起。

返回值
如果操作成功,则返回新的文件位置,如果操作失败,则函数返回 -1。

numpy.frombuffer(buffer, dtype=float, count=_1, offset=0)

Interpret a buffer as a 1-dimensional array.

参数
buffer : buffer_like

An object that exposes the buffer interface.  

dtype : data-type, optional

Data-type of the returned array; default: float.  

count : int, optional

Number of items to read. `-1` means all data in the buffer.  

offset : int, optional

Start reading the buffer from this offset (in bytes); default: 0.  

Notes
If the buffer has data that is not in machine byte-order, this should be specified as part of the data-type, e.g.:

  dt = np.dtype(int)  
  dt = dt.newbyteorder(' ')  
  np.frombuffer(buf, dtype=dt)  

The data of the resulting array will not be byteswapped, but will be interpreted correctly.

Examples

s = 'hello world' np.frombuffer(s, dtype='S1', count=5, offset=6) array(['w', 'o', 'r', 'l', 'd'],
 dtype='|S1')  
np.frombuffer(b'\x01\x02', dtype=np.uint8) array([1, 2], dtype=uint8) np.frombuffer(b'\x01\x02\x03\x04\x05', dtype=np.uint8, count=3) array([1, 2, 3], dtype=uint8)

math.inf

浮点正无限。(对于负无限,使用 -math.inf。)等于输出float(‘inf’)。

ndarray与tensor的相互转换

import numpy as np
import tensorflow as tf

#  函数法
# 先找出一个ndarray的数据,这里我直接定义一个
a = np.ndarray([3,4]) # 3x4形状的ndarray数据

b = tf.convert_to_tensor(a)
print(b) # out:Tensor("Const:0", shape=(3, 4), dtype=float64)


#  通过调用启动会话进行转换
op = tf.constant([1, 2, 3, 4])
print(op) # out:Tensor("Const_1:0", shape=(4,), dtype=int32)

sess = tf.InteractiveSession()
op_ndarray = op.eval() # 这里等效于op_ndarray = sess.run(op)
print(op_ndarray) # out:

Python @函数装饰器及用法

假设用 funA() 函数装饰器去装饰 funB() 函数,如下所示:

#funA 作为装饰器函数
def funA(fn):
    #...
    fn() # 执行传入的fn参数
    #...
    return '...'
@funA
def funB():
    #...

实际上,上面程序完全等价于下面的程序:

def funA(fn):
    #...
    fn() # 执行传入的fn参数
    #...
    return '...'
def funB():
    #...
funB = funA(funB)

通过比对以上 2 段程序不难发现,使用函数装饰器 A() 去装饰另一个函数 B(),其底层执行了如下 2 步操作:

  1. 将 B 作为参数传给 A() 函数;

  2. 将 A() 函数执行完成的返回值反馈回 B。

举个例子:

#funA 作为装饰器函数
def funA(fn):
    print("啦啦啦")
    fn() # 执行传入的fn参数
    print("嘻嘻嘻")
    return "装饰器函数的返回值"
@funA
def funB():
    print("学习 Python")
print(funB)

执行出来:

啦啦啦
学习 Python
嘻嘻嘻
装饰器函数的返回值

显然,被“@函数”修饰的函数不再是原来的函数,而是被替换成一个新的东西(取决于装饰器的返回值),即如果装饰器函数的返回值为普通变量,那么被修饰的函数名就变成了变量名;同样,如果装饰器返回的是一个函数的名称,怎么被修饰的函数名依然表示一个函数。实际上,所谓函数装饰器,就是通过装饰器函数,在不修改原函数的前提下,来对函数的功能进行合理的扩充。

带参数的函数装饰器

当 funB() 函数无参数时,可以直接将 funB 作为 funA() 的参数传入。但是,如果被修饰的函数本身带有参数,那应该如何传值呢?
比较简单的解决方法就是在函数装饰器中嵌套一个函数,该函数带有的参数个数和被装饰器修饰的函数相同。例如:

def funA(fn):
    # 定义一个嵌套函数
    def say(arc):
        print("Python教程:",arc)
    return say
@funA
def funB(arc):
    print("funB():", a)
funB("http://c.biancheng.net/python")

程序执行结果为:

Python教程: http://c.biancheng.net/python

等价于:

def funA(fn):
    # 定义一个嵌套函数
    def say(arc):
        print("Python教程:",arc)
    return say
def funB(arc):
    print("funB():", a)
   
funB = funA(funB)
funB("http://c.biancheng.net/python")

显然,通过 funB() 函数被装饰器 funA() 修饰,funB 就被赋值为 say。这意味着,虽然我们在程序显式调用的是 funB() 函数,但其实执行的是装饰器嵌套的 say() 函数。

但还有一个问题需要解决,即如果当前程序中,有多个(≥ 2)函数被同一个装饰器函数修饰,这些函数带有的参数个数并不相等,怎么办呢?

最简单的解决方式是用 *args 和 **kwargs 作为装饰器内部嵌套函数的参数,*args 和 **kwargs 表示接受任意数量和类型的参数。举个例子:

def funA(fn):
    # 定义一个嵌套函数
    def say(*args,**kwargs):
        fn(*args,**kwargs)
    return say
@funA
def funB(arc):
    print("C语言中文网:",arc)
@funA
def other_funB(name,arc):
    print(name,arc)
funB("http://c.biancheng.net")
other_funB("Python教程:","http://c.biancheng.net/python")

运行结果为:

C语言中文网: http://c.biancheng.net
Python教程: http://c.biancheng.net/python

函数装饰器可以嵌套

上面示例中,都是使用一个装饰器的情况,但实际上,Python 也支持多个装饰器,比如:

@funA
@funB
@funC
def fun():
    #...

上面程序的执行顺序是里到外,所以它等效于下面这行代码:

fun = funA( funB ( funC (fun) ) )

class

需求:
1.房子有户型,总面积和家具名称列表
新房子没有任何的家具
2.家具有名字和占地面积,其中
床:占地4平米
衣柜:占地2平米
餐具:占地1.5平米
3.将以上三件家具添加到房子中
4.打印房子时,要输出:户型,总面积,剩余面积,家具名称列表

class house:
    def __init__(self, houseType, houseArea):
        self.houseType = houseType
        self.area = houseArea
        self.fire_area = houseArea
        self.fitment = []

    def __str__(self):
        return '户型:%s\n总面积:%s平米\n剩余面积:%s平米\n家具:%s' % (self.houseType, self.area, self.fire_area, ','.join(self.fitment))

    def add_fitment(self, fitmentname):
        if fitmentname.area < self.fire_area:
            self.fitment.append(fitmentname.name)
            self.fire_area -= fitmentname.area
        else:
            print('%s的占地%s平米太大了,房子剩余面积%s平米太小了' % (fitmentname.name, fitmentname.area, self.fire_area))


class fitment:
    def __init__(self, name, area):
        self.name = name
        self.area = area

    def __str__(self):
        return '%s占地%s平米' % (self.name, self.area)


bed = fitment('架子床', 4)
bureau = fitment('折叠衣柜', 2)
cutlery = fitment('餐桌', 1.5)
# print(bed)
# print(bureau)
# print(cutlery)

xiaoming_house = house('两室一厅', 100)
xiaoming_house.add_fitment(bed)
xiaoming_house.add_fitment(cutlery)
print(xiaoming_house)

仍不懂的:

frames = [frame.to_rgb().to_ndarray() for frame in video_frames]
frames = torch.as_tensor(np.stack(frames))

你可能感兴趣的:(slowfast官方代码阅读过程中的Python基础补充(一))