深度学习第一篇---pytorch入门

1 什么是pytorch?

PyTorch是一个基于Numpy的科学计算包,它主要有两个特点:第一,是GPU加速的张量计算;第二,是构建和训练神经网络的强大支持。PyTorch是Facebook人工智能研究团队开源的一个机器学习框架,它支持动态计算图,这意味着可以按照想要的方式定义、修改和执行计算图,而不是预先定义静态计算图。这样,PyTorch可以灵活地支持不同形式的计算图,并且非常适合用于研究和实验。同时,PyTorch也具有很好的可视化工具,方便用户对模型进行调试和优化。

2 张量

概念:几何代数中定义的张量是基于向量和矩阵的推广,比如我们可以将标量视为零阶张量,矢量可以视为一阶张量,矩阵就是二阶张量

张量维度

2.1张量创建

import torch

# 创建一个2x3的张量
x = torch.tensor([[1, 2, 3], [4, 5, 6]])

# 打印张量的形状和数据类型
print(x.shape)      # 输出: torch.Size([2, 3])
print(x.dtype)      # 输出: torch.int64

# 创建一个随机初始化的3x3浮点数张量
y = torch.rand(3, 3)
print(y)

# 创建一个随机初始化的3x3浮点数张量,符合正态分布
y = torch.randn(3, 3)
print(y)

# 创建一个全0的5x5张量
z = torch.zeros(5, 5)
print(z)

# 创建一个全1的4x4张量
w = torch.ones(4, 4)
print(w)

# 创建一个等差数列的张量
a = torch.linspace(0, 1, 5)
print(a)

# 创建一个随机整数的张量
b = torch.randint(low=0, high=10, size=(3, 3))
print(b)

x = x.new_ones(4, 3, dtype=torch.double) 
# 创建一个新的全1矩阵tensor,返回的tensor默认具有相同的torch.dtype和torch.device
# 也可以像之前的写法 x = torch.ones(4, 3, dtype=torch.double)
print(x)
x = torch.randn_like(x, dtype=torch.float)
# 重置数据类型
print(x)
# 结果会有一样的size
# 获取它的维度信息
print(x.size())
print(x.shape)


2.2 张量的操作

import torch

# 创建两个张量
a = torch.tensor([[1, 2, 3], [4, 5, 6]])
b = torch.tensor([[2, 3, 4], [5, 6, 7]])

# 加法方式1
c = a + b
print(c)

# 方式2
print(torch.add(a, b))

# 方式3 in-place,原值修改
a.add_(b) 
print(a)

# 减法
d = b - a
print(d)

# 乘法
e = a * b
print(e)

# 除法
f = b / a
print(f)

# 矩阵乘法
g = torch.matmul(a, b.T)
print(g)

# 求和
h = a.sum()
print(h)

# 求平均值
i = b.mean()
print(i)

# 求最大值
j = a.max()
print(j)

# 求最小值
k = b.min()
print(k)

# 如果x中只有一个元素,可以把x的数值取出来
print(type(x.item()))

# 怎么改变张量的形状
a = b.view(16)  
c = a.view(-1, 8) # -1是指这一维的维数由其他维度决定
print(a.size(), b.size(), c.size())

# Torch Tensors和Numpy array 共享底层的内存空间,当改变其中的一个值,另外一个值也随之被改变
a = torch.ones(5);# 5个1
print (a)

b = a.numpy(); #将tensor 转 numpy array
print (b)

a.add_(1); #改变a的值

print (a);
print (b);


a = np.ones(5);
print (a)

b =  torch.from_numpy(a); # 将numpy array 转tensor
print (b);

b.add_(1);

print (b);
print (a);

另外张量的计算时候需要注意在哪个设备上,若不同设备是不能参与计算的。

#判断服务器上已经安装了cuda和GPU
if torch.cuda.is_available():
   #将设备指定为GPU
   device = torch.device("cuda");
   #直接在GPU创建张量y,在CPU上创建张量X
   x = torch.randn(1);
   y = torch.ones_like(x,device=device);
   #将X转移到GPU上
   x = x.to(device);
   z = x.add(y); #此时和的结果z在GPU上
   print (z);
   print(z.to("cpu"),torch.double);

2.3 张量的实际意义

在电商中,通常需要对用户-品牌-时间-购买行为等多维数据进行建模和分析。这些数据可以被理解为张量的不同维度,每个维度都代表着不同的特征或属性。例如,假设我们需要对用户-品牌-时间-购买行为进行建模,我们可以构建一个四维张量来存储这些数据。其中,第一维表示用户,第二维表示品牌,第三维表示时间,第四维表示购买行为。张量中的每个元素则代表着对应维度上的具体数值,例如张量中[i, j, k, l]元素代表着第i个用户在第j个品牌上在第k个时间点的购买行为。
通过这种方式,我们可以在PyTorch中轻松地对这些张量进行各种数学操作和函数,例如对购买行为进行求和、求平均值、求最大值、求最小值等,或者对用户-品牌-时间进行矩阵运算,以便提取特征和进行预测。通过PyTorch中的张量,我们可以将复杂的电商数据转化为多维数组,从而更好地进行建模和分析,帮助电商企业实现数据驱动决策和智能化运营。

import torch

# 创建一个四维张量表示用户-品牌-时间-购买行为
tensor = torch.randn(10, 5, 20, 2)

# 求购买行为的总和
buy_sum = tensor[:, :, :, 1].sum()
print("购买行为总和:", buy_sum)

# 求用户-品牌的交叉统计
user_brand_count = tensor.sum(dim=2)
print("用户-品牌交叉统计:\n", user_brand_count)

# 对时间进行降维,求平均值
time_mean = tensor.mean(dim=2)
print("时间降维后的平均值:\n", time_mean)

# 对用户-品牌进行矩阵运算
user_brand_tensor = tensor[:, :, 0, :]
user_tensor = user_brand_tensor.sum(dim=1)
brand_tensor = user_brand_tensor.sum(dim=0)
user_brand_matrix = torch.matmul(user_tensor.T, brand_tensor)
print("用户-品牌矩阵:\n", user_brand_matrix)


上述代码中,我们首先创建了一个四维张量tensor,表示用户-品牌-时间-购买行为。然后,我们对这个张量进行了各种数学操作和函数。具体来说,我们使用sum()函数对购买行为进行求和,使用sum(dim=2)函数对用户-品牌进行交叉统计,使用mean(dim=2)函数对时间进行降维,使用matmul()函数对用户-品牌进行矩阵运算,以获得用户-品牌之间的相关性。这些操作可以帮助我们更好地理解和分析电商数据。

import torch

# 创建一个2x3的张量
x = torch.tensor([[1, 2, 3], [4, 5, 6]])

# 创建一个1x3的张量
y = torch.tensor([10, 20, 30])

# 对x和y进行加法
z = x + y
print(z)

#输出如下
tensor([[1, 2, 3],
       [4, 5, 6]])
tensor([10, 20, 30])
tensor([[11, 22, 33],
       [14, 25, 36]])

在这个示例中,我们创建了一个2x3的张量x和一个1x3的张量y。两个张量在第一维上的形状不一致,但由于PyTorch支持广播机制,系统会自动地将y进行扩展,使得它的形状变为2x3,然后再和x进行加法运算。最终的结果是一个2x3的张量z,其中每个元素都是对应位置上x和y元素的和。在实际应用中,广播机制可以大大简化计算过程,避免了对数据进行显式的扩展和复制。例如,在深度学习中,广播机制可以使得模型对不同形状的输入数据进行处理,从而提高模型的通用性和适用性。同时,广播机制还可以使得模型的参数共享,从而减少模型的参数量,提高模型的训练效率。

3 自动求导和梯度

PyTorch中的自动求导机制是通过autograd模块实现的,该模块可以自动地对张量进行求导,同时还支持高阶求导和自定义求导函数。在PyTorch中,每个张量都有一个requires_grad属性,当设置为True时,表示需要对该张量进行求导。
下面是一个简单的示例,说明如何使用PyTorch中的自动求导机制

import torch

# 创建一个张量,并设置requires_grad=True
x = torch.tensor([2.0], requires_grad=True)

# 定义一个函数y=x^2+2x+1
y = x ** 2 + 2 * x + 1

# 对y进行求导
y.backward()

# 打印x的梯度
print(x.grad)

在这个示例中,我们创建了一个张量x,并将requires_grad属性设置为True,表示需要对它进行求导。然后,我们定义一个函数y=x^2+2x+1,并对它进行求导,即调用backward()函数。最后,我们打印x的梯度,即可得到y对x的导数,即4。这里的梯度,需要重点总结一下,梯度是指函数在某一点处的变化率,它是一个向量,包含了函数在每个自变量维度上的偏导数。

我们可以看一个稍微更复杂的函数,z= y^2 - x^2,那么z在自变量x上的倒数是-2x,在y自变量上的倒数是-2y。


image.png
import torch

# 创建一个张量,并设置requires_grad=True
x = torch.tensor([2.0], requires_grad=True)
y = torch.tensor([3.0], requires_grad=True)

# 定义一个函数z=y^2 - x^2
z = y ** 2 -  x ** 2;

# 对y进行求导
z.backward()

# 打印x的梯度
print (z)
print(y.grad)
print(x.grad)
print ('x.requires_grad=',x.requires_grad,'y.requires_grad=',y.requires_grad,'z.requires_grad=',z.requires_grad)


# 输出
tensor([5.], grad_fn=<SubBackward0>)
tensor([6.])
tensor([-4.])
x.requires_grad= True y.requires_grad= True z.requires_grad= True


关于自动求导的”自动“怎么理解?z并没有指定requires_grad = true, 但是由于x和y被设置了,z也被自动的设置为了requires_grad = true。

4 线性回归模型

这段代码定义了一个简单的线性模型(LinearModel),并使用均方差损失函数(mean_squared_error)和梯度下降法(train)进行训练。训练数据是输入x_train和输出y_train。在训练过程中,首先通过正向传播(model.forward)计算模型的预测输出(y_pred),然后计算损失(loss),接着通过反向传播(计算梯度dW和db)更新模型的权重和偏置(model.W和model.b)。训练过程会迭代num_epochs次,每10次输出当前的损失值。最终训练得到的模型可以用于预测新的输入数据。

import torch
import numpy as np


# 模型定义
class LinearModel:
   def __init__(self, input_size, output_size):
       self.W = np.random.randn(input_size, output_size)  # 随机初始化权重
       self.b = np.zeros((output_size, 1))  # 初始化偏置

   def forward(self, x):
       return np.dot(x, self.W) + self.b


# 损失函数
def mean_squared_error(y_true, y_pred):
   return np.mean((y_true - y_pred) ** 2)


# 训练过程
def train(model, x_train, y_train, learning_rate, num_epochs):
   for epoch in range(num_epochs):
       # 正向传播
       y_pred = model.forward(x_train)

       # 计算损失
       loss = mean_squared_error(y_train, y_pred)

       # 反向传播(梯度下降法更新参数)
       dW = np.dot(x_train.T, (y_pred - y_train)) / x_train.shape[0]  # 权重梯度
       db = np.mean(y_pred - y_train, axis=0, keepdims=True).T  # 偏置梯度

       model.W -= learning_rate * dW
       model.b -= learning_rate * db

       if epoch % 10 == 0:
           print(f"Epoch {epoch}, Loss: {loss}")


if __name__ == '__main__':
   x_train = np.array([[1, 2, 3], [4, 5, 6]])
   y_train = np.array([[3], [7]])

   model = LinearModel(input_size=3, output_size=1)
   train(model, x_train, y_train, learning_rate=0.01, num_epochs=100)


输出:
Epoch 0, Loss: 153.96475781916735
Epoch 10, Loss: 0.5371193011886801
Epoch 20, Loss: 0.49120240483116584
Epoch 30, Loss: 0.4497690875642887
Epoch 40, Loss: 0.41183070630810104
Epoch 50, Loss: 0.3770924577692135
Epoch 60, Loss: 0.34528440820059597
Epoch 70, Loss: 0.3161593929820811
Epoch 80, Loss: 0.28949109602634426
Epoch 90, Loss: 0.2650722911885265

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容