找回密码
 会员注册
查看: 37|回复: 0

深度学习理论基础(一)Python及Torch基础篇

[复制链接]

3

主题

0

回帖

10

积分

新手上路

积分
10
发表于 2024-9-12 18:29:00 | 显示全部楼层 |阅读模式
学习目录:深度学习理论基础(一)Python及Torch基础篇深度学习理论基础(二)深度神经网络DNN深度学习理论基础(三)封装数据集及手写数字识别深度学习理论基础(四)Parser命令行参数模块深度学习理论基础(五)卷积神经网络CNN深度学习理论基础(六)Transformer多头自注意力机制深度学习理论基础(七)Transformer编码器和解码器本文目录学习目录:Ⅰ:Python基础一、变量类型与输出语句1.变量类型(1)集合(使用较少)(2)元组(3)列表(4)字典2.输出语句二、函数1.python函数规范2.输入任意数量的参数3.输入参数的默认值4.主函数三、类1.类的特殊方法2.类的实例化与访问3.类的继承四、调用其他文件函数五、续行符‘\’六、tqdm进度条类七、enumerate函数--返回迭代对象的索引及其对应元素(返回第一个为索引,第二个为元素)八、sorted--排序函数九、断言语句assertⅡ:Torch基础一、维度变换1.reshape()2.transpose()3.permute()4.view()5.unsqueeze()二、mask掩码替换---masked_fill()三、矩阵乘法(点积运算)---torch.matmul()四、模块类中的forward方法调用五、模型中可优化参数1.查看模型中可学习(优化)的参数---model.named_parameters()2.将普通张量转换为模型可学习的参数---nn.Parameter()六、保存与导入模型特别注意Ⅰ:Python基础注释使用#号进行单行注释,或者''''''或""""""进行批量注释。快速注释方法:选中注释的内容按下Ctrl+/。#单行注释'''批量注释'''"""批量注释"""123Python里换行符(回车)可以替代分号(;),所以一般不出现分号;Python是动态输入类型的语言,像Matlab一样,变量类型是动态推断的;静态类型的C语言须声明变量类型,如inta=1,而Python只需要a=1;Python中代码包含关系使用缩进来表示,而不是使用括号来进行包含。一、变量类型与输出语句1.变量类型基本变量类型:字符串、数字、布尔型;高级变量类型:集合、元组、列表、字典。str_v="arealman"#字符串num_v=415411#数字bool_v=True#布尔set_v={1,2,3,1}#集合tuple_v=(1,2,3)#元组list_v=[1,2,3]#列表dict_v={'a':1,'b':2,'c':3}#字典1234567这里我们不再讲述基本变量类型,因为和c语言的变量类型没任何区别。主要讲述高级变量类型。(1)集合(使用较少)定义:  集合是无序且元素唯一的集合数据类型。  集合使用大括号{}定义,其中的元素通过逗号分隔。特点:  唯一性:集合中的元素是唯一的,不会出现重复元素。  无序性:集合中的元素无序存储,因此不能通过索引访问。  高效性:集合提供了高效的成员检测操作。  示例:my_set={1,2,3,'a','b','c'}●常用操作:  添加元素:使用add()方法或者update()方法添加新元素。  删除元素:使用remove()或者discard()方法删除元素。  集合运算:包括并集、交集、差集等。(2)元组定义:  元组是有序的不可变序列。  元组使用圆括号()定义,其中的元素通过逗号分隔。特点:  不可变性:元组一旦创建,其元素不可更改,删除或添加。  有序性:元组中的元素按照它们的插入顺序存储,并且可以通过索引访问。  示例:my_tuple=(1,2,'a','b')常用操作:  访问元组元素:通过索引访问元组中的元素,索引从0开始。  切片:可以通过切片操作获取元组的子元组。  元组拆包:将元组的元素解包给多个变量。  不可变性:元组的元素不能被修改、删除或添加。●元组的创建:一种是规范括号法,一种是省略括号法。规范的括号法:(1,2,3)#输出:(1,2,3)12省略括号法(核心):1,2,3#输出:(1,2,3)12●元组的拆分解包:元组拆分法——极速创建新变量a,b,c=1,2,3print(c,b,a)#输出:321123元组拆分法——极速交换变量值a,b=1,2b,a=a,bprint(a,b)#输出:211234元组拆分法——只要前两个答案values=98,99,94,94,90,92a,b,*rest=valuesa,b,rest#输出:(98,99,[94,94,90,92])1234(3)列表定义:  列表是Python中最常用的数据结构之一,是有序的可变序列。  列表使用方括号[]定义,其中的元素通过逗号分隔。特点:  可变性:列表是可变的,即你可以修改列表中的元素、添加新元素或删除元素。  有序性:列表中的元素按照它们的插入顺序存储,并且可以通过索引访问。  可包含任意类型的数据:列表中的元素可以是不同类型的数据,包括其他列表。  示例:my_list=[1,2,3,'a','b','c']常用操作:  访问列表元素:通过索引访问列表中的元素,索引从0开始。  切片:可以通过切片操作获取列表的子列表。  添加元素:使用append()、insert()或者使用加号+添加新元素。  删除元素:使用del语句、remove()方法或者pop()方法删除元素。  修改元素:通过索引直接赋值。●列表的切片操作列表的访问操作如同数组的访问一样,如list_v[0]就是’a‘。list_v=['a','b','c','d','e']print(list_v)print(list_v[1:4])#从索引[1]开始,切到索引[4]之前。包含索引[1],但不包括索引[4]print(list_v[1:])#从索引[1]开始,切到结尾print(list_v[:4])#从列表开头开始,切到索引[4]之前,不包括索引[4]""" 输出结果: ['a','b','c','d','e'] ['b','c','d'] ['b','c','d','e'] ['a','b','c','d']"""print(list_v[2:-2])#从索引[2]开始,并切除列表结尾两个元素print(list_v[:-2])#切除结尾两个元素""" 输出结果: ['c'] ['a','b','c']"""#--------------------------------------------------list_v=['a','b','c','d','e','f','g']print(list_v[::2])#从开头到结尾,每2个元素采样一次print(list_v[::3])#从开头到结尾,每3个元素采样一次print(list_v[1:-1:2])#切除一头一尾后,每2个元素采样一次""" 输出结果: ['a','c','e','g'] ['a','d','g'] ['b','d','f']"""12345678910111213141516171819202122232425262728293031●列表for循环schools=['中南大学','湖南大学','三峡大学','长江大学']forschoolinschools: message=f"{school},youareagreatschool!" print(message)print("Ican'twaittovisityou!")输出结果: 中南大学,youareagreatschool! 湖南大学,youareagreatschool! 三峡大学,youareagreatschool! 长江大学,youareagreatschool! Ican'twaittovisityou!123456789101112●列表推导式只需要看懂即可!value=[i**2foriin[1,2,3,4,5]]print(value)输出结果: [1,4,9,16,25]//--------------------------------value=[i**2foriin[1,2,3,4,5]ifi0,"x应该大于0"#条件为真,不会触发异常y=-1asserty>0,"y应该大于0"#条件为假,触发AssertionError异常,并打印附带的错误消息123456  Ⅱ:Torch基础一、维度变换1.reshape()用于改变矩阵的形状。可以生成多个维度,只要生成的维度相乘等于数据总个数即可。(1)输入两个参数.reshape(2,6)表示生成2行6列的矩阵。x=np.arange(12).reshape(2,6)x=torch.Tensor(x)print(x)"""tensor([[0.,1.,2.,3.,4.,5.],[6.,7.,8.,9.,10.,11.]])"""1234567(2)输入三个参数.reshape(2,3,2)表示生成2行的3行2列(3,2)形状的矩阵。x=np.arange(12).reshape(2,3,2)x=torch.Tensor(x)print(x)"""tensor([[[0.,1.],[2.,3.],[4.,5.]],[[6.,7.],[8.,9.],[10.,11.]]])"""123456789101112(3)输入四个参数.reshape(2,1,2,3)表示生成2行(1,2,3)形状的矩阵。x=np.arange(12).reshape(2,1,2,3)#2*1*2*3=12x=torch.Tensor(x)print(x)"""tensor([[[[0.,1.,2.],[3.,4.,5.]]],[[[6.,7.,8.],[9.,10.,11.]]]])"""12345678910112.transpose()transpose只能操作2D矩阵的转置,即只能对两个维度的矩阵进行转换维度。importnumpyasnpimporttorch#创建x=np.arange(12).reshape(2,6)#从数字1到12,形成2行6列的矩阵x=torch.Tensor(x)print(x)print(x.shape)#查看矩阵形状"""tensor([[0.,1.,2.,3.,4.,5.],[6.,7.,8.,9.,10.,11.]])torch.Size([2,6])"""a=x.transpose(1,0)print(a)print(a.shape)#查看矩阵形状"""tensor([[0.,6.],[1.,7.],[2.,8.],[3.,9.],[4.,10.],[5.,11.]])torch.Size([6,2])"""12345678910111213141516171819202122232425263.permute()  变换tensor数据的维度。transpose只能操作2D矩阵的转置,无法操作超过2个维度,所以要想实现多个维度的转置,既可以用一次性的permute,也可以多次使用transpose。importtorch"""torch.randn函数是PyTorch中用于生成具有正态分布(均值为0,标准差为1)的随机数的函数。它可以用于创建具有指定形状的张量,并且张量中的每个元素都是独立的随机数,遵循标准正态分布(均值为0,标准差为1)"""x=torch.randn(2,3,5)#生成2行,3行5列(3,5)形状的矩阵,元素随机且符合正态分布。print(x.size())#torch.Size([2,3,5])a=x.permute(2,0,1)#将x原来的第2维度换到第0维度,原来的第0维度换到第1维度,原来的第1维度换到第2维度。print(a.size())#torch.Size([5,2,3])1234567894.view()  主要用于Tensor维度的重构,即返回一个有相同数据但不同维度的Tensor。操作对象应该是Tensor类型。如果不是Tensor类型,可以通过tensor=torch.tensor(data)来转换。importtorchtemp=[1,2,3,4,5,6]#temp的类型为list,非Tensortemp=torch.tensor(temp)#将temp由list类型转为Tensor类型print(temp)#torch.Size([6])print(temp.view(2,3))#将temp的维度改为2*3print(temp.view(2,3,1))#将temp的维度改为2*3*1print(temp.view(2,3,1,1))#更多的维度也没有问题,只要保证维度改变前后的元素个数相同就行,即2*3*1*1=612345678910115.unsqueeze()用于tensor数据。输入一个参数,即在第几个维度上添加一个大小为1的新维度。importtorch#创建一个张量data=torch.tensor([[1,2,3],[4,5,6]])#在第1维度上添加维度unsqueeze_tensor=data.unsqueeze(1)print(unsqueeze_tensor.shape)#输出:torch.Size([2,1,3])#在第2维度上添加维度unsqueeze_tensor2=data.unsqueeze(2)print(unsqueeze_tensor2.shape)#输出:torch.Size([2,3,1])12345678910111213二、mask掩码替换—masked_fill()  用于tensor数据。masked_fill(mask==0,-1e9)是一种PyTorch中的张量操作,用于根据给定的条件(mask==0)来填充张量的值。具体意思是将张量中所有与mask相应位置为0的元素替换为-1e9(负无穷),而保留其他元素不变。其中判断条件mask可以等于任何值,只要mask矩阵中有该值就行,且替换元素也可以是任何值!  该操作主要用于深度学习中,经过掩码操作后使用nn.Softmax(data)后,data矩阵中有负无穷的地方全变为0。消除影响。importtorch#创建一个张量data=torch.tensor([[1,2,3],[4,5,6],[7,8,9]])#创建一个掩码张量mask=torch.tensor([[0,1,2],[3,0,1],[0,1,0]])#根据掩码将张量中的0替换为-1e9result=data.masked_fill(mask==0,-1e9)print(result)"""tensor([[-1000000000,2,3],[4,-1000000000,6],[-1000000000,8,-1000000000]])data中对应元素mask为0的地方全变为了负无穷。"""result1=data.masked_fill(mask==3,-1e9)print(result1)"""tensor([[1,2,3],[-1000000000,5,6],[7,8,9]])data中对应元素mask为3的地方全变为了负无穷。"""1234567891011121314151617181920212223242526272829三、矩阵乘法(点积运算)—torch.matmul()用于tensor数据。(1)两个一维矩阵乘法。importtorchx=torch.tensor([1,2])y=torch.tensor([3,4])print(torch.matmul(x,y))"""输出:tensor(11)"""#我们可以获取一维tensor()里的值,使用.item(),只能用于括号里只有一个元素的tensor数据。print(torch.matmul(x,y).item())"""输出:11"""1234567891011121314(2)两个二维矩阵乘法。importtorchx=torch.tensor([[1,2],[3,4]])y=torch.tensor([[5,6,7],[8,9,10]])print(torch.matmul(x,y))"""输出:tensor([[21,24,27],[47,54,61]])"""123456789(3)一维矩阵和二维矩阵乘法。importtorchx=torch.tensor([1,2])y=torch.tensor([[5,6,7],[8,9,10]])print(torch.matmul(x,y))"""输出:tensor([21,24,27])"""12345678四、模块类中的forward方法调用  在PyTorch中,forward方法是定义在自定义模块类中的一个特殊方法,用于指定模块的前向传播逻辑。当你调用模块的实例并传递输入数据时,PyTorch会自动调用该实例的forward方法来执行前向传播,并返回计算结果。  实例化类时传入的参数是__init__()中的参数,用于初始化模型的一些基本参数或层。而在实例化后的对象中传入参数时,这里传入的参数是forward()中的参数,用于将数据输入给模型。传入参数时自动调用forward()方法!classMultiHeadAttention(nn.Module):def__init__(self,heads,d_model,dropout=0.1):super().__init__()self.d_model=d_modelself.d_k=d_model//headsself.h=headsself.q_linear=nn.Linear(d_model,d_model)self.v_linear=nn.Linear(d_model,d_model)self.k_linear=nn.Linear(d_model,d_model)self.dropout=nn.Dropout(dropout)self.out=nn.Linear(d_model,d_model)defforward(self,q,k,v,mask=None):bs=q.size(0)#performlinearoperationandsplitintoNheadsk=self.k_linear(k).view(bs,-1,self.h,self.d_k)q=self.q_linear(q).view(bs,-1,self.h,self.d_k)v=self.v_linear(v).view(bs,-1,self.h,self.d_k)#transposetogetdimensionsbs*N*sl*d_modelk=k.transpose(1,2)q=q.transpose(1,2)v=v.transpose(1,2)scores=attention(q,k,v,self.d_k,mask,self.dropout)concat=scores.transpose(1,2).contiguous().view(bs,-1,self.d_model)output=self.out(concat)returnoutput#实例化类,实例化时传入的参数是__init__()中的参数。atten=MultiHeadAttention(heads,d_model,dropout=dropout)#在实例化后的对象中传入参数时,这里传入的参数是forward()中的参数,传入参数时自动调用forward()方法!output=attn(x2,x2,x2,mask)12345678910111213141516171819202122232425262728293031323334353637五、模型中可优化参数1.查看模型中可学习(优化)的参数—model.named_parameters()"""classMyModule(nn.Module):详细类的定义省略"""if__name__=='__main__': model=MyModule(4,2)#实例化模型类 forname,paraminmodel.named_parameters():#返回模型科学系的参数名称,以及参数。 print(name,param.shape)12345672.将普通张量转换为模型可学习的参数—nn.Parameter()    nn.Parameter可以看作是一个类型转换函数,将一个不可训练的类型Tensor转换成可以训练的类型parameter,并将这个parameter绑定到这个module里面(net.parameter()中就有这个绑定的parameter,所以在参数优化的时候可以进行优化),所以经过类型转换这个变量就变成了模型的一部分,成为了模型中根据训练可以改动的参数。使用这个函数的目的也是想让某些变量在学习的过程中不断的修改其值以达到最优化。  nn.Parameter()添加的参数会被添加到Parameters列表中,会被送入优化器中随训练一起学习更新。举例:importtorchfromtorchimportnnclassMyModule(nn.Module):def__init__(self,input_size,output_size):super(MyModule,self).__init__()self.test=torch.rand(input_size,output_size)self.test2=nn.Parameter(torch.rand(input_size,output_size))self.linear=nn.Linear(input_size,output_size)defforward(self,x):returnself.linear(x)if__name__=='__main__': model=MyModule(4,2) forname,paraminmodel.named_parameters():#返回模型参数名称,以及参数 print(name,param.shape)123456789101112131415161718输出模型参数如下:六、保存与导入模型教程详情可查看地址!特别注意  假如我们将代码放在并行云计算上进行训练,在训练时,我们使用cuda训练,将训练好以后,得到模型文件。我们将含有模型文件的代码复制一份放到我们本机上进行测试(当然可以在并行云上测试)。  在测试时,如果本地只是安装了torch(可以导入使用cpu进行训练的模型),而没有安装cuda时,是无法导入刚才训练好的模型文件的(因为模型是在cuda上训练得到的)。则我们需要在本地上虚拟环境上安装cuda就可以正常导入模型文件进行测试了。可以通过pytorch官网中找到合适的torch版本然后复制命令进行安装即可!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2024-12-26 23:58 , Processed in 0.900950 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表