动手学深度学习v2学习篇预备知识一

84 阅读4分钟

cover_image

《动手学深度学习》v2学习篇--预备知识(一)

原创 Bob新视界 Bob的AI视界


大家好,我是Bob。

一个想和大家一起慢慢变富的AI程序员

热爱分享AI前瞻思考、项目经验、面试技巧。

欢迎关注我,一起探索,一起破圈!

前言

嘿!这里是笔者的《动手学深度学习》v2学习篇,最近一段时间由于工作需要,目前在深度学习“深度学习”,以下皆为学习笔记与思考的分享。欢迎指正与follow。

本次分享:数据基本操作

torch数据创建你会发现与numpy非常相似,张量(tensor)也可以类比为(ndarray)。当然他们并不相同。对于torch,GPU很好地支持加速计算,而NumPy仅支持CPU计算;张量类支持自动微分。使得张量类更适合深度学习

导入torch

import torch  #导入torch

数据创建

torch.arange(12)   
  
#向量包含以0开始的前12个整数


torch.zeros((2, 3, 4))   
  
#形状为(2,3,4)的张量,其中所有元素都设置为0  



torch.ones((2, 3, 4))  
  
#形状为(2,3,4)的张量,其中所有元素都设置为1  



torch.randn(3, 4)   
  
#形状为(3,4)的张量,每个元素都从均值为0、标准差为1的标准高斯分布中随机采样


torch.tensor([[2, 1, 4, 3][1, 2, 3, 4][4, 3, 2, 1]]#Python列表(也可以是nparray类型),赋予张量确定值

张量属性

torch.arange(12)   
  
x.shape    
  
#结果:torch.Size([12])


x.numel()   
  
#结果:12


X = x.reshape(34)  
  
#改变张量的形状,张量的大小不会改变

简单运算

以下 加、减、乘、除、求幂都是两个张量同一位置元素进行运算。**是求幂

x = torch.tensor([1.0248])  
y = torch.tensor([2222])  
x + y, x - y, x * y, x / y, x ** y   

结果:

(tensor([ 3.,  4.,  6., 10.]),  
 tensor([-1.,  0.,  2.,  6.]),  
 tensor([ 2.,  4.,  8., 16.]),  
 tensor([0.50001.00002.00004.0000]),  
 tensor([ 1.,  4., 16., 64.]))

张量连结

X = torch.arange(12, dtype=torch.float32).reshape((3,4))  
Y = torch.tensor([[2.0143], [1234], [4321]])  
  
torch.cat((X, Y), dim=0), torch.cat((X, Y), dim=1)

这里的dim可以理解为维度,dim=0,第0个维度(这里是指行向量方向)方向堆叠,

(tensor([[ 0.,  1.,  2.,  3.],  
         [ 4.,  5.,  6.,  7.],  
         [ 8.,  9., 10., 11.],  
         [ 2.,  1.,  4.,  3.],  
         [ 1.,  2.,  3.,  4.],  
         [ 4.,  3.,  2.,  1.]]),  
 tensor([[ 0.,  1.,  2.,  3.,  2.,  1.,  4.,  3.],  
         [ 4.,  5.,  6.,  7.,  1.,  2.,  3.,  4.],  
         [ 8.,  9., 10., 11.,  4.,  3.,  2.,  1.]]))

广播机制

a = torch.arange(3).reshape((31))  
b = torch.arange(2).reshape((12))  
a, b


(tensor([[0],  
         [1],  
         [2]]),  
 tensor([[0, 1]]))

不同形状张量相加

a + b  

由于a和b形状不同,如果让它们相加,它们的形状不匹配。我们将两个矩阵广播为一个更大的 矩阵,如下所示:矩阵a将复制列, 矩阵b将复制行,然后再按元素相加。

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

索引与切片

张量[ ]里的“ ,”用来分割不同维度的切片取值,没有就是指第一个维度。

X[-1], X[1:3]  
# 访问最后一行, 访问第1行和第2行

修改

X[0:2, :] = 12  
  
# 0、1行的所有值改为12


X[1, 2] = 9  
  
#第一维度为1,第二维度为2所得到的值

内存问题

id()可以理解为c++里的找指针,就是数据在内存中的的地址

before = id(Y)  
Y = Y + X  
id(Y) == before  
  
答案是False

节省内存—原地更新(以下例子)

Z = torch.zeros_like(Y)  
print('id(Z):'id(Z))  
Z[:] = X + Y  
print('id(Z):'id(Z))  
  
地址一致


before = id(X)  
X += Y  
id(X) == before  
  
地址一致

数据预处理

大多数情况,我们的数据并不是直接的数字,而是保存在各种格式的文件里的数字,文字等,甚至存在缺失值。我们需要进行处理,转换成张量。

比如

import os  
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')


import pandas as pd  
  
data = pd.read_csv(data_file)  
print(data)

原始数据

   NumRooms Alley   Price  
0       NaN  Pave  127500  
1       2.0   NaN  106000  
2       4.0   NaN  178100  
3       NaN   NaN  140000

缺失值处理

**为了处理缺失的数据,典型的方法包括 插值法 和 删除法 , ** 其中插值法用一个替代值弥补缺失值,而删除法则直接忽略缺失值。在( 这里,我们将考虑插值法 )。

iloc先考虑列再其次是行,这里利用已有数据的平均值填充NAN

inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2]  
inputs = inputs.fillna(inputs.mean(numeric_only=True))


inputs = pd.get_dummies(inputs, dummy_na=True)

转为numpy再转为tensor

import torch  
  
X = torch.tensor(inputs.to_numpy(dtype=float))  
y = torch.tensor(outputs.to_numpy(dtype=float))  
  
X, y

结果如下:

(array([[3., 1., 0.],  
        [2., 0., 1.],  
        [4., 0., 1.],  
        [3., 0., 1.]]dtype=float64),  
 array([127500., 106000., 178100., 140000.]dtype=float64))

下一次分享:线性代数、微积分、微分、概率。