python
-
import库失败:原因是解释器选择不对,pip3 install numpy是把numpy库安装在3.xxx的python解释器中,但是我是在3.9.6的解释器下运行的,所以找不到,此时需要把解释器换成3.11.9即可。
-
Super(Net,self)._init_()
这是对继承自父类的属性进行初始化,子类继承了父类的所有属性和方法,父类属性自然会用父类方法来进行初始化。
class farther(object):def __init__(self):self.x = '这是属性'def fun(self):print(self.x)print('这是方法')class son(farther):def __init__(self):super(son,self).__init__()print('实例化执行')test = son() test.fun() test.x
如果没有super(x,self).init()
AttributeError: 'son' object has no attribute 'x'
即son类不能继承父类的方法和参数
-
查看已经安装的库pip3 list
-
解释代价函数、损失函数和目标函数
1.代价函数:定义在整个训练集上,是所有样本损失函数的平均。用于衡量模型在所有样本上的平均表现。(针对多个样本,衡量多个样本的预测值 ∑ y i \sum y_i ∑yi与真实值 ∑ y \sum y ∑y之间的差距)。
2.损失函数:定义在单个样本上的,算的是一个样本的误差(针对单个样本,衡量单个样本的预测值y1和真实值y的差)。训练的每个步骤中使用的,目地是找到每个样本的最优解。
3.目标函数:梯度下降等优化算法就是针对目标函数来进行的。其实代价函数就可以是一种目标函数,换句话说,目标函数可以直接选用代价函数。但是我们经常给代价函数添加一个正则项,最终作为模型的目标函数。
-
池化层中参数详解torch.nn.Maxpool2d(kernel_size,stride=None,padding=0,dilation=1,return_indices=False,ceil_mode=False)
1.kernel_size:表示最大池化的窗口大小,如果是3就表示窗口大小是3$\times 3 ,如果是元组( 3 , 2 ),那么窗口大小就是 3 3,如果是元组(3,2),那么窗口大小就是3 3,如果是元组(3,2),那么窗口大小就是3\times$2.
2.stride:确定窗口如何移动,如果不置顶,那么默认步长就与最大池化窗口一致。如果指定了参数,例如为元组(2,3)那么窗口将每次向右移动3个元素位置,向下移动2个元素位置.
3.padding:控制如何进行填充,默认值为0。如果是单个值,例如1,那么就会填充一圈0。还可以用元组如(2,1)填充,表示在上下两个方向填充两行0,左右两个方向填充一列0.
4.dilation:空洞卷积,默认为1,如果kernel_size=3,那么卷积核就是3$\times 3 的框。如果 d i l a t i o n = 2 , k e r n e l s i z e = 3 ,那么卷积核中的每列数据与每列数据中间再加一列空洞,即卷积核是 5 3的框。如果dilation=2,kernel_size=3,那么卷积核中的每列数据与每列数据中间再加一列空洞,即卷积核是5 3的框。如果dilation=2,kernelsize=3,那么卷积核中的每列数据与每列数据中间再加一列空洞,即卷积核是5\times$5的框.
5.return_indices:布尔类型的值,表示返回值中是否包含最大值位置的索引。这个最大值是所有窗口中产生的最大值,如果窗口产生的最大值总共有5个,就会有5个返回值。
6.ceil_mode:表示输出采用的是floor还是ceiling格式,floor就是向下取整,ceiling就是向上取整
-
Conv2d参数详解Conv2d(in_channels,out_channels,kernel_size,stride=1,padding=0,dilation=1,groups=1,bias=True,padding_mode=‘zeros’)用于创建二维的卷积层
1.in_channels:输入数据个数,有几个矩阵输入就是几。
2.out_channels:输出通道个数,即有几个输出。
3.kernel_size=3:卷积层的大小是3 × \times ×3
需要注意的是,输出图片尺寸公式如下:p=padding,k=kernel_size,s=stride
-
转置卷积(Conv2DTranspose)
表示执行上采样。对于语义分割,首先用编码器提取特征图,然后用解码器恢复原始图像大小。转置卷积又叫反卷积,然而transpose做的事情是转置卷积而不是反卷积,所以反卷积这个名字不够准切。为什么呢,因为标准卷积操作是: y = C x y=Cx y=Cx,相应的转置卷积操作是: x = C T y x=C^Ty x=CTy.蓝色是输入矩阵,灰色是卷积核,绿色是输出矩阵.
-
转置卷积的输出与输入关系是:H_out = (H_in - 1)stride + kernel_size - 2padding. 如果是s=1,直接反卷积操作即可.**但如果是s>1,**就需要对原始数据进行差值变换,即每相邻数据之间插入s-1列/行数据,变换后数据为:
如输入数据是2✖️2的矩阵,stride=2,p=0,卷积核3✖️3.
差值后的数据为 H n e w = 2 + ( 2 − 1 ) ∗ ( 2 − 1 ) = 3 H_{new}=2+(2-1)*(2-1)=3 Hnew=2+(2−1)∗(2−1)=3.
之后还要对变换后的数据进行padding:
所以 p a d d i n g n e w = 3 − 0 − 1 = 2 padding_{new}=3-0-1=2 paddingnew=3−0−1=2,从而新数据是7✖️7的:
然后对这个新数据进行3✖️3,padding=0,stride=1的正常卷积操作可以得到(input-kernel_size+2p)/s+1=(7-3+0)+1=5的输出数据.
-
Torch.nn.ConvTranspose2d(in_channels,out_channels,kernel_size,stride=1,padding=0,output_padding=0,groups=1,bias=True)
其中output_padding指的是输出图边缘需要填充的行.
-
-
nn.Linear的基本用法:
torch.nn.Linear(in_features, out_features, bias=True)
- in_features 表示输入的神经元个数
- out_features 表示输出神经元个数
- bias = True 表示是否包含偏置
实战如下:
X = torch.Tensor([[0.1,0.2,0.3,0.3,0.3],[0.4,0.5,0.6,0.6,0.6],[0.7,0.8,0.9,0.9,0.9],
])
model = nn.Linear(in_features=5,out_features=10, bias=True) #定义线性层,输入特征是5,下层神经元个数是10
经过线性层,做了一件事,即:
-
torch.tensor():
-
torch.tensor()是一个多维矩阵,其中包含同种类型的元素.通过数据构造张量.
-
torch.Tensor()生成一个32位浮点数的张量,如果没有传入数据就返回空张量,但无论传入数据本身的数据类型是什么,返回的都是32位浮点数的张量.
-
-
构造模型:Module类
Module类是nn模块提供的一个模型构造类,是所有神经网络模块的基类,可以继承它来定义模型,定义一个继承Module的类
-
torch.rand():
()里面有几个数字就是生成几维张量。
所以torch.rand(2,4)就是生成两行四列的张量:
torch.rand(2,3,4)就是2个平行摆放的3行4列三维张量:
张量有专属的高维张量单位,那就是batch。(batchsize)
torch.rand(2,3,4,5)表示生成2套3层4行5列的四维张量:
通俗理解就是
-
四维张量是3套3维张量并排摆放:
-
五维张量就是3套4维张量并排摆放:
-
nn.Sequential():
nn.Sequential是一个序列容器,用于搭建神经网络的模块被按照被传入构造器的顺序添加到容器中。除此之外,一个包含神经网络模块的OrderedDict也可以被传入nn.Sequential()容器中。利用nn.Sequential()搭建好模型架构,模型前向传播时调用forward()方法,模型接收的输入首先被传入nn.Sequential()包含的第一个网络模块中。然后,第一个网络模块的输出传入第二个网络模块作为输入,按照顺序依次计算并传播,直到nn.Sequential()里的最后一个模块输出结果.
-
requires_grad,requires_grad_(),grad_fn的区别:
- x.grad_fn和x.requires_grad为x的属性
- x.grad_fn:积分方法名,默认为None
- x.requires_grad:是否积分的属性,默认为False
- x.requires_grad_():设置积分的方法,设置之后requires_grad为True
只有那些requires_grad 和 is_leaf 的属性同时为 True 的 Tensor 才会有 grad 属性
-
叶子张量(x.is_leaf)
-
is_leaf为True的时候为叶子节点(或叶子张量);非叶节点的梯度值在反向传播过程中使用完后就会被清除,不会被保留。只有叶节点的梯度值能够被保留下来
-
对于tensor中的requires_grad属性,当requires_grad()为True时我们将会记录tensor的运算过程并为自动求导做准备
-
在Pytorch神经网络中,我们反向传播backward()就是为了求叶子节点的梯度
-
在调用backward()时,只有当requires_grad和is_leaf同时为真时,才会计算节点的梯度值
-
当tensor的requires_grad值为True时,在backward()反向传播计算梯度时才会被计算,在所有的requires_grad=True中:
非叶子节点的梯度值在反向传播过程中使用完后会清除;只有叶子节点的梯度值能够被保留下来;被保留下来的叶子节点的梯度值会存入tensor的grad属性中。
-
可以使用retain.grad()这个属性保留反向传播的grad
-
-
x.requires_grad属性表示x能否求导;x.is_leaf表示x求导之后的值是否需要保留。
grad_fn用来记录变量是怎么来的,方便计算梯度。y= x*3,grad_fn记录了y由x计算的过程。如果x是直接创建的,那么它就没有grad_fn,显示为None,称x这种直接创建的为叶子节点。但是y有grad_fn.
-
torch.ones_like和torch.zeros_like:
这两个函数的基本功能是根据给定张量,生成与其形状相同的全1张量或全0张量。
-
torch.autograd.grad(outputs, inputs,grad_outputs=None,retain_graph=None,create_graph=False,only_inputs=True,allow_unused=False)
-
outputs为求导的因变量;inputs为求导的自变量;grad_outputs:如果outputs为标量,则
grad_outputs=None
,也就是说,可以不用写; 如果outputs 是向量,则此参数必须写;retain_graph: True 则保留计算图, False则释放计算图;
**allow_unused:允许输入变量不进入计算create_graph:**若要计算高阶导数,则必须选为True
-
**print(torch.autograd.grad(z,x)[0])**返回一个元组,分别是梯度值和grad_fn(计算tensor的运算信息),由于我们只需要梯度值,因此就取[0].
-
如果输出为向量,需要将grad_outputs设置为全1,与outputs形状相同的张量.
-
-
torch.nn.MSELoss(size_average=None,reduce=None,reduction=‘mean’)
- 该函数用于计算两个输入对应元素差值平方和的均值.
- 如果同时给出了size_average、reduce、reduction三个参数,则首先看前两个参数。如果前两个参数均为None,则函数的返回值由reduction参数决定。如果前两个参数不全为None,则函数的返回值由前两个参数决定,在这种情况下,为None的那个参数默认为True.
- 使用的话,可以loss = torch.nn.MSELoss() ; loss = loss(input,target)
-
torch.cat()
- 函数将两个张量按指定维度拼接在一起.
- dim=0表示把矩阵列接上去;dim=1表示按矩阵行拼接.
- dim=k表示按照张量的第k个分量进行拼接.此时其他分量的维数都不变,只有第k个分量的维数改变.
-
torch.rand()与torch.randn()
- torch.rand()生成在区间[0,1)内均匀分布的随机数.
- torch.rand()生成从标准正态分布(均值为0,标准差为1)中采样的随机数.从而它生成的值可以在负无穷到正无穷之间.
-
train(),eval(),no_grad()
- train()是nn.Module的方法,也就是如果定义了一个网络model,那么model.train()表示将该model设置为训练模式,一般在开始新epoch训练,会首先执行该命令.
- **eval()**也是nn.Module的方法,如果定义了一个网络model,那么model.eval()表示将该model设置为验证模式
- no_grad()是torch库的方法,和上下文管理器with搭配使用。作用是禁用梯度计算。当确定不会调用tensor.backward()时,它将减少计算的内存消耗。一般进行模型验证时就不需要计算梯度和反向传播
-
torch.optim.SGC(params,lr)
-
params(必须参数):这是一个包含了需要优化的参数(张量)的迭代器,例如模型的参数model.parameters().
-
SGD是optim中的一个算法—随机梯度下降算法.
-
torch.optim是一个实现各种优化算法的库.
-
optimizer = optim.SGD(model.parameters(),lr=0.01)
这是定义了一个优化器,下面要用到.
-
-
.parameters()
-
model.parameters()保存的是weights和bais参数的值.
-
计算模型参数,返回一个关于模型参数的迭代器.
-
该方法可以获得所有可学习参数
-
-
loss.backward()和optimizer.step()和optimizer.zero_grad()
- loss.backward():将损失loss向输入测进行反向传播.这一步会计算损失函数关于所有变量x的梯度值 d d x l o s s \frac{d}{dx}loss dxdloss,并将其累积为x∗grad 进行备用,即 x ∗ g r a d = ( x ∗ g r a d ) p r e + d d x l o s s x∗grad=(x∗grad)_{pre}+\frac{d}{dx}loss x∗grad=(x∗grad)pre+dxdloss,公式中的 ( x ∗ g r a d ) p r e (x∗grad)_{pre} (x∗grad)pre 指的是上一个epoch累积的梯度.(其实这一步就是计算Loss的梯度值.)
- optimizer.step():利用优化器对参数x进行更新,以SGD为例,更新公式为 x = x − l r ∗ ( x ∗ g r a d ) x = x-lr*(x*grad) x=x−lr∗(x∗grad).(这一步是做一次梯度下降)
- optimizer.zero_grad():清除优化器关于所有参数x的累积梯度 x ∗ g r a d x*grad x∗grad,一般在loss.backward()之前使用,即清除 ( x ∗ g r a d ) p r e (x*grad)_{pre} (x∗grad)pre.(这一步是清除之前计算的梯度值)
-
if __name__ == ‘__main__’
通俗的理解__name__ == ‘__main__’:假如你叫小明.py,在朋友眼中,你是小明(__name__ == ‘小明’);在你自己眼中,你是你自己(__name__ == ‘__main__’)。
if __name__ == '__main__'的意思是:当.py文件被直接运行时,if__name__ == '__main__'之下的代码块将被运行;当.py文件以模块形式被导入时,if __name__ == '__main__'之下的代码块不被运行。(通俗地讲就是,自己执行自己时就会执行__name__ == '__main__'下的代码;但如果别的代码调用这个文件的时候,就不会执行__name__ == '__main__'下面的代码).
-
loss.detach().numpy()
当使用autograd跟踪张量的操作历史时,有时需要从计算图中分离张量以进行进一步的计算。在这种情况下,可以使用detach()方法来创建一个新的张量,该张量与原始张量具有相同的值,但不再与计算图相关联。然后,如果需要将该张量转换为Numpy数组,可以使用numpy()方法。因此tensor.detach().numpy()表示将张量分离并转换为Numpy()数组.
-
pyDOE库的用途
pydoe包是python关于实验设计采样的工具包,其中包含了拉丁超立方等方法.
-
import torch和import torch.nn as nn的区别
- import torch导入了pytorch库,而import torch.nn as nn导入了pytorch库中的神经网络模块(torch.nn)
- import torch只导入pytorch的核心功能,如张量操作;但导入神经网络模块之后可以定义神经网络层、损失函数等.
-
torch.cuda()
-
torch.cuda模块是’pytorch中用于支持使用cuda加速的模块.cuda . 通过
torch.cuda
,你可以将张量移动到GPU上执行计算,并利用 GPU 提供的并行计算能力加速深度学习模型的训练和推断。 -
例如,你可以使用
torch.cuda.is_available()
来检查当前环境是否支持 CUDA 加速,使用tensor.cuda()
将张量移动到 GPU 上,以及使用torch.cuda.device_count()
获取可用的 GPU 数量等.
-
-
device = torch.device( ‘cuda’ if torch.cuda.is_available() else ‘cpu’ )
-
首先,torch.device()可以指定张量所在的设备。因为张量可以放置在不同的设备上,如GPU(CUDA)或CPU.
-
其次,如果当前环境支持cuda加速,就指定在cuda设备上创建张量,否则就在cpu上放置张量.
-
-
nn.Linear(3,3) → \rightarrow →print(net.parameters())
首先创建一个3输入3输出的线性层,然后输出每个节点的待定参数,发现每个参数应该数:每个节点的1$\times 3 的 t e n s o r ,一共有 3 个 t e n s o r ,表示每个节点的权重。同时还有一个 1 3的tensor,一共有3个tensor,表示每个节点的权重。同时还有一个1 3的tensor,一共有3个tensor,表示每个节点的权重。同时还有一个1\times$3的tensor,表示每个节点的偏置.
-
nn.ModuleList
-
类似于nn.Sequential,这两个东西我们称之为容器。nn.ModuleList是一个存储不同module,并自动将每个module的parameters添加到网络之中的容器.
-
nn.Sequential内部实现了forward函数,因此可以不用写forward函数,而nn.ModuleList则没有实现内部forward函数.
-
nn.Sequential里面的模块按照顺序进行排列的,所以必须确保前一个模块的输出大小和下一个模块的输入大小是一致的。而nn.ModuleList 并没有定义一个网络,它只是将不同的模块储存在一起,这些模块之间并没有什么先后顺序可言。
-
如果网络中有重复的层一般考虑用for循环创建:
layers = [nn.Linear(10,10) for i in range(2)]
-
-
view(-1,1)
- view()相当于reshape,重新调整tensor的形状.
- 参数-1代表自动调整这个维度上元素的个数,以保证元素的总数不变.
-
fig , ax = plt.subplots()的用法
- 它是用来创建总画布/figure"窗口"的,有figure就可以在上面作图
- fig,ax = plt.subplots()等价于fig ,ax = plt.subplots(nrows=1,ncols=1)(nrows表示subplot的行数,ncols表示subplot的列数
- fig,ax = plt.subplots(2,3)表示一次性在figure上创建2*3的网格,这个画布上网格的名字是ax。使用plt.subplot()只能一个一个的添加.
-
torch.arange(start=0,end,step=1)与torch.linspace(start,end,steps=100)
- torch.arange(start=0,end,step=1)返回大小为 e n d − s t a r t s t e p \frac{end-start}{step} stepend−start的一维张量,其值介于区间 [ s t a r t , e n d ) [start,end) [start,end),以step为步长等间隔取值.
- torch.linspace返回一维张量,但是与torch.arange不同的是,这个函数指定的是一共生成多少个点.如torch.linspace(3,10,5)的结果是tensor([ 3.0000, 4.7500, 6.5000, 8.2500, 10.0000]),即一共生成5个点.
-
torch.nn.init.xavier_normal_(tensor,gain=1)
- 用于初始化权重,目的是尽可能地让输入和输出服从相同的分布,能够避免后面层的激活函数的输出值趋于0.
-
.weight.data与.weight的区别
- .weight.data:得到一个tensor,不可以计算梯度.
- ,weight:得到一个parameter的变量,可以计算梯度.
- 但两个方法的值是一样的,只是数据类型不一样:
-
torch.from_numpy(ndarray)
从numpy.ndarray创建一个张量。返回(得到)的张量和ndarray共享同一内存,对张量的修改将反应在ndarray中,反之亦然。返回的张量是不能调整大小的
-
x.float()
比如一开始创建了一个tensor:
x = torch.tensor([1,2,3])
然后利用x.float()可以将其中的数变为float型的.得到:
tensor([1., 2., 3.])
-
a = self.linears[-1](a)
self.linears是一个包含多个线性层的nn.ModuleList。对self.linears中最后一个线性层(self.linear[-1])输入张量a.
-
numpy.random.choice(a, size=None, replace=True, p=None).
-
从a(只要是ndarray都可以,但要是一维)中抽取数字,组成大小是size的数组,replace表示可以取相同的数字,False表示不可以取相同的数字.
-
数组p:与数组a相对应,表示取数组a中每个元素的概率,默认为选取每个元素的概率相同.
-
np.random.choice(5)#从[0,5)中随机输出一个随机数
-
-
torch.manual_seed()
- 在随机数生成中,种子起到确定性作用。给定相同的种子,每次运行相同的随机数生成算法都会得到相同的随机数序列。这对于实验的可重复性和结果的一致性非常重要。
- 先用torch.manual_seed(123)固定随机数,这样的话用torch.randn(2,3)生成的数是随机的,但是随机之后是固定的.
- 在生成随机数之前,可以使用torch.manual_seed(seed)函数,用于指定生成随机数的种子,用于保证生成的随机数是可重复出现的.
-
%的用法
-
取模运算符,5%2 = 1.
-
字符串格式化,如:
print('%d km ',1990) #整数型
-
-
np.meshgrid()
二维坐标系中,X轴可以取三个值 1,2,3, Y轴可以取两个值 7,8, 请问可以获得多少个点的坐标?
显而易见是 6 个:
(1, 7) (2, 7) (3, 7)
(1, 8) (2, 8) (3, 8)np.meshgrid()
就是干这个的!#coding:utf-8 import numpy as np # 坐标向量 a = np.array([1,2,3]) # 坐标向量 b = np.array([7,8]) # 从坐标向量中返回坐标矩阵 # 返回list,有两个元素,第一个元素是X轴的取值,第二个元素是Y轴的取值 res = np.meshgrid(a,b) #返回结果: [array([ [1,2,3] [1,2,3] ]), array([ [7,7,7] [8,8,8] ])]
就是a生成len(b)次,而b的第一个数生成len(a)次
-
batch_size
batch_size:表示单次传递给程序用以训练的数据(样本)个数。比如我们的训练集有1000个数据。这是如果我们设置batch_size=100,那么程序首先会用数据集中的前100个参数,即第1-100个数据来训练模型。当训练完成后更新权重,再使用第101-200的个数据训练,直至第十次使用完训练集中的1000个数据后停止。
-
fig,(au1,au2) = plt.subplots(1,2,figsize=(10,4))
指定绘图区为(10,4),并且图是一行两列,默认两列各占一半,即(5,4)(5,4)
-
f-string字符串用法
f-string用大括号 {} 表示被替换字段,其中直接填入替换内容
name="lihua"print(f"my name is {name}") >>>>>'my name is lihua'
-
plt.tight_layout()
-
在 matplotlib 中,轴域(包括子图)的位置以标准化图形坐标指定。 可能发生的是,你的轴标签或标题(有时甚至是刻度标签)会超出图形区域,因此被截断
-
当你拥有多个子图时,你会经常看到不同轴域的标签叠在一起。
-
解决方法:
#在plt.show()前加上: plt.tight_layout()
-
-
colorbar
- colorbar主要通过figure.colorbar方法绘制
- 先用im = au.imshow(data)生成二维数据data的热图,然后用au.figure.colorbar(im)生成热图im的colorbar.
-
异常处理try:··· except:
try:# 可能会发生异常的代码块# 1. 单独的except except :print("输入有问题,程序不能正常输出结果。")# 2. except+异常名称 except ZeroDivisionError:print("输入有问题,程序不能正常输出结果。")# 3. except 异常名称 as 别名 except ZeroDivisionError as e:print(e) # 4. except (异常名称1, 异常名称1) as 别名 except (ZeroDivisionError,ValueError) as e:print(e)
-
scipy.io.loadmat获取.mat文件
只需使用scipy.io库即可:
import scipy.io as siodatay=sio.loadmat('/Users/ruyuqi/Downloads/Reduced-Order-Modeling-Tutorials-main-2/notebooks/burgers_data_R10.mat')print datay
-
h5py文件和HDF5
- HDF(Hierarchical Data Format)指一种为存储和处理大容量科学数据设计的文件格式及相应库文件
- h5py文件是存放两类对象的容器,数据集(dataset)和组(group),dataset类似数组类的数据集合,和numpy的数组差不多。group是像文件夹一样的容器,它好比python中的字典,有键(key)和值(value)。group中可以存放dataset或者其他的group。一个 HDF5 文件从一个命名为 “/” 的 group 开始,所有的 dataset 和其它 group 都包含在此 group 下,当操作 HDF5 文件时,如果没有显式指定 group 的 dataset 都是默认指 “/” 下的 dataset,另外类似相对文件路径的 group 名字都是相对于 “/” 的
echo命令:
echo的功能是在显示器上显示一段文字,一般起到提示的作用。此外,也可以直接在文件中写入要写的内容。也可以用于脚本编程时显示某一个变量的值。
运行openfoam
blockMesh
icoFoam
touch cavity.foam