[deeplearning]深度学习框架torch的概念以及数学内容

(提前声明:这边的操作系统为ubuntn22.04,至于window上如何进行安装和导入按这边不是很理解)

(另外代码样例基本不使用notebook,paddle等等在线工具,而是使用本机安装好的python环境,和pytorch框架)

pytorch的安装这里也不太多阐述了,其实就是一个函数库罢了,另外一些不同的数学库,自己按需寻找就好了捏。其实具体的使用后面会与很多,这里只简单介绍一些数学相关的知识捏

1.关于代码部分

其实关于代码,这里其实更多的讲一些关于张量tensor的操作

当然在进行pytorch以及相关的操作之前,我们需要做的一件事情就是激活d2l环境

(conda安装详见文章最开始的一个链接)

 conda activate d2l

(1)tensor

在pytorch和tf中,用来表示数据基本就是是用tensor这种东西,中文称之为“张量”。

tensor很类似数组的封装对象,但是tensor本质上可以理解为一个多维度的数据存储容器

其中,如果我们想要创建一个tensor,则大概是这样的

x = torch.arange(12)

这样会自动创建出一个一个维度的向量,尺寸为12的tensor,其中数据是从0开始,一直排列到11,如果你用打印输出的方式,你能见到这个东西

(其实应该是底层修改了tostring之类的方法。。。。)

当然除此之外,我们可以直接指定数据和形式

torch.tensor([[2, 1, 4, 3], [1, 2, 3, 4], [4, 3, 2, 1]])

这样最终的输出结果为

这就是我们需要的格式了

以及,如果我们想要创建更多维度的时候,仍然是可以是用这种方法

x=torch.arange(3,3,3)

这个最中的创造结果我就先不打出来了,反正就是一个多维度的情况,3,3,3的一个立方体

总的来说tensor是这两种主流框架存储数据最基本的形式之一,获取数据要转化成这样子,训练的数据需要这个样子,就连最后的输出也是这个东西。。。

(2)tensor的基本操作

对与tensor的基本操作我想简单的分为两种,对与对与tensor本身的修改和查看,以及对与彼此之间的运算情况。

首先是对与tensor的基本属性查看,我们经常用到的几个函数为

#访问形状(这个函数可以让你了解到这个tensor是啥形状的)
print(x.shape)
#tensor‘s size (the num of elements)
print(x.numel())

一个检查形状(维度和每一个维度的大小),一个可以检查元素数目,当然其他的api还有很多很多,按照自己的需求获取就可以了

然后是对与tensor的运算,其实对与普通的运算符:+-×/% ** == >........等等等,tensor奉行的原则是按照每一个元素对应进行计算。

如果两个tensor的shape和size不一致,底层会使用boardcast方案,将两个tensor通过复制某些维度上的数据,实现计算。

但是对于一些特别的要求,我们要使用函数进行计算

比如最常见的,tensor点乘就是我们在线性代数中常用的一种方式

#点乘
torch.dot(x, y)

#矩阵的乘法
torch.mm(x, y)

(这个好像同样存在广播机制,但是最好不要这样干。。。。你都用上向量了)

在比如对与某个tensor,我们可能刚开始创建的时候忘记shape了,我们就可以重新用reshap函数重新设置一遍形状

#amend the tensor (to more or less deminsions)
X = x.reshape(3, 4)

这样形状就会被我设置为一个三行四列的tensor了,数据会按照顺序重新进行排列。

其实对与tensor来说能调用的函数和功能非常多,按照需求进行更改吧

(3)维度,升维,降维,拼接

首先我们必须要引入tensor dimension这个东西,一般来说,我们生活中的最高维度是三维,但是实际在数学计算的过程中,dim不一定局限于3。

我们举个实际应用中的例子:在构建tensor的时候,比如我们也许会构建一个2,3,4的东西

则第一个维度,编号为0(和数组一样的索引开始),尺寸为2

第二个维度,编号为1,尺寸为3

第三个维度,编号为2,尺寸为4

在目前这个上下文语境中,我们可以人为0是行展开的方向,1是列展开的方向。。。。

这就是维度的概念和现实情况的匹配

至于升高和降低维度,其实就是在修改axis的数量。比如这里我们举例一个降低维度的案例:

x = torch.arange(4, dtype=torch.float32)
x, x.sum()

整体求和,算是一种比较极端的降维方法之一,当然也可以沿着某个方向进行求和,降低维度

A_sum_axis0 = A.sum(0)

沿着0方向进行降低维度,在一般的矩阵中,这个代码实现的就是按照行展开的方向进行求和

升高维度其实一般都是reshape。。。。毕竟没人喜欢闲着没事给自己填堵

其实在这里我还想要介绍一个api,对与tensor进行某个方向的拼接

tensor.cat(x,y,dim=0)

这个是让两个矩阵or向量按照地一个维度的方向进行和并操作的方法

其实这些函数在本质上都不难,其实重点就是关于dim/axis的理解问题

(4)切片,索引

对有数组来说,我们通过索引可以很轻松的访问某个元素,而对与tensor来说也是一样的,我们按照维度的顺序,确定某个数据的做表,我们可以修改这些数据

加入我们现在存在这样的一个数据

tensor([[2, 1, 4, 3],
        [1, 2, 3, 4],
        [4, 3, 2, 1]])

很显然这个矩阵的形状应该是3,4 ,其中比如说我们想要读取第二行第二列的数据,则为

print( x[1,1] ),输出结果为2

其实这个和数组没有人和去别,那么我们为什么还要作出一个区分呢,因为切片

切片这个东西在不同的语言里面都不一样,在go中就是数组的意思

但在这里,切片是一种语法,用来在某个维度上划分范围

语法为a:b,意思是在这个维度切割出a到b-1这段范围的内容,

来吧,我们据个例子

X=x[:,0:2,:]

这个意思是,第一个维度保留,第二个维度保留0到1的位置,第三个维度全部保留

(由于上面的东西不太一样,所以这里我们只看前面两个维度)

所以结果就是

tensor([[2, 1],
             [1, 2],
             [4, 3]])

 差不多这个样子,简单来说就是用来划分范围用来划分维度,这就是在pytorch中切片的用法

(5)内存的重新分配问题

其实在其他语言中,我们通过改变指向修改地址的方式很常见,因为毕竟存在指针这个东西,而且以地址作为根本机制存在

但是在pytorch的底层运算中,施行的机制是先计算,然后再指向,这样就造成了一个很严重的影响

x=。。。。
y=。。。。。

y=x+y

在这个阶段中y的指向地址会发生变化,而不是在y的原本地址上修改

解决方案有两种:

第一种是是用切片语法进行赋值

Z = np.zeros_like(Y)

Z[:] = X + Y

这样子,Z的地址是不会发生改变的,但是终究还是有点麻烦

Y+=X

这种简单粗暴的做法反而更加有效果好吧

2.关于数据处理

数据在进行一些操作的时候,最要做的是就是一一个规定的形式进行我们需要的操作,但是我们采集到的原始数据集合并不是我们的函数能使用的东西,所以我们就要从csv等等来源中获取数据,然后使用

(1)从csv中获取数据

这里创建了一个csv文件,并且手动添加一些数据(NA代表这里没有数据的意思)

#创建一个数据集合文件
os.makedirs(os.path.join('..', 'data'), exist_ok=True)
data_file = os.path.join('..', 'data', 'house_tiny.csv')
with open(data_file, 'w') as f:
    f.write('NumRooms,Alley,Price\n')  # 列名
    f.write('NA,Pave,127500\n')  # 每行表示一个数据样本
    f.write('2,NA,106000\n')
    f.write('4,NA,178100\n')
    f.write('NA,NA,140000\n')

(2)我们通过函数接受文件


#获取到数据集合文件
data = pd.read_csv(data_file)

(3)数据填充

#为NA填充该列的平均值(如果不是数字就两说)
inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]
inputs = inputs.fillna(inputs.mean())  #填充数值

#将数值为有限离散数值的列拆分开
inputs = pd.get_dummies(inputs, dummy_na=True) #对与discrete来说,使用类似热编码的技术来进行处理
print(inputs)

(4)最后转化为tensor的形式

#转化为张量的形式
x = torch.tensor(inputs.to_numpy(dtype=float))
y = torch.tensor(outputs.to_numpy(dtype=float))
#其实这样的数据就可以拿去训练了(不过你连模型都没有)

3.一些可能会用得到的数学知识

因为毕竟我这三门课当是考得还是挺好的,但是忘了很多,这里只补充一些可能不是很接触到的情况

(1)微积分部分

微积分部分需要补充的概念其实就是梯度,这个东西我们在学习函数开始,我们就知道这个东西了,没错,二维函数图像中的倾率就是一种梯度的运算结果。

梯度本身是一个向量,代表着图像可视化以后,图像某一点上起伏的数值

梯度可以理解为函数的斜率或者在三维图上表示的下降或升高方向。

在数学中,梯度表示函数在某一点上的变化率或斜率。对于多元函数,梯度是一个向量,其中每个分量表示函数在相应变量方向上的偏导数。梯度的方向指示了函数在给定点上最陡峭的下降或升高方向。

在机器学习和优化算法中,梯度在训练模型和调整参数时起着重要的作用。通过计算损失函数对模型参数的梯度,可以确定参数的更新方向,使得损失函数最小化或最大化。

在三维图像中,可以将梯度看作是函数曲面上某一点处的切平面的法向量。梯度的方向指示了在该点上曲面上升最快或下降最快的方向。

(2)线性代数部分:

在线性代数的部分,只要补充一个范数的概念,不同的范数有不同的计算方式

这里举出一个例子,一个向量的二范数,其实就是模的长度

(3)概率论部分:

等待补充,我感觉这部分就是代码需要看看文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值