目錄
PyTorch 定義
核心作用
應用場景
Pytorch 基本語法
1. 張量的創建
2.?張量的類型轉換
3. 張量數值計算
4. 張量運算函數
5. 張量索引操作
6. 張量形狀操作
7. 張量拼接操作
8. 自動微分模塊
9. 案例-線性回歸案例
PyTorch 定義
# 清華鏡像pip install torch==2.0.1 -i https://pypi.tuna.tsinghua.edu.cn/simple
# 阿里云鏡像
https://mirrors.aliyun.com/pypi/simple/# 豆瓣鏡像
https://pypi.doubanio.com/simple/# 中科大鏡像
https://pypi.mirrors.ustc.edu.cn/simple/
核心作用
-
張量計算(Tensor Computations)
PyTorch 提供高效的Tensor
庫(類似 NumPy),支持 GPU 加速,能夠處理高維數組的數學運算(如矩陣乘法、卷積等),是構建神經網絡的數學基礎。 -
自動微分(Autograd)
通過autograd
模塊,PyTorch 可以自動計算張量的梯度(導數),這是訓練神經網絡的核心功能(如反向傳播)。 -
動態計算圖(Dynamic Computation Graph)
與 TensorFlow 的靜態圖不同,PyTorch 使用動態圖機制(即 "Define-by-Run"),允許在代碼運行時動態構建計算圖。這使得調試更直觀,靈活性更高,尤其適合研究場景。 -
深度學習模型構建
提供torch.nn
模塊,包含預定義的神經網絡層(如全連接層、卷積層、RNN 等),簡化了復雜模型的搭建過程。 -
部署與生產化
支持通過TorchScript
或ONNX
格式將模型導出到生產環境(如移動端、服務器端),并與 C++ 無縫集成。
應用場景
-
學術研究:PyTorch 的靈活性和易用性使其成為學術界的主流工具,大量論文代碼基于 PyTorch 實現。
-
自然語言處理(NLP):如 Transformer、BERT 等模型的實現。
-
計算機視覺(CV):圖像分類、目標檢測、生成對抗網絡(GAN)等。
-
強化學習:與 OpenAI Gym 等工具結合,訓練智能體。
-
工業原型開發:快速迭代和部署模型。
Pytorch 基本語法
1. 張量的創建
import torch
import numpy as np"""
創建張量的方式
? torch.tensor 根據指定數據創建張量
? torch.Tensor 根據形狀創建張量, 其也可用來創建指定數據的張量
"""
# 1.torch.tensor() 根據指定數據創建張量
# 0維張量:標量(scalar)
print(torch.tensor(10))
# 1維張量:向量(vector)
print(torch.tensor([10,10]))
# 2維張量:矩陣(matrix)
print(torch.tensor([[10,10],[10,10],[10,10]]))
# 多維張量
print(torch.tensor([[[10,10],[10,10],[10,10]]]))# numpy 數組, 由于 data 為 float64, 下面代碼也使用該類型
data_np=np.random.rand(2,3)
print(data_np)
print(torch.tensor(data_np))data =[[10.,20,30],[20,30,40]]
print(data)
print(torch.tensor(data))#2.torch.Tensor() 根據指定形狀創建張量,也可以用來創建指定數據的張量
#創建2行3列的張量, 默認 dtype 為 float32
data = torch.Tensor(2, 3)
print(data)
# 注意: 如果傳遞列表, 則創建包含指定元素的張量
print(torch.Tensor([2]))
print(torch.Tensor([[2, 3, 4], [5, 6, 7]]))"""
創建線性和隨機張量
? torch.arrange() 和 torch.linspace() 創建線性張量
? torch.randn() 創建隨機張量
"""
#創建線性
# 1. 在指定區間按照步長生成元素 [start, end, step)
data = torch.arange(0, 10, 2)
print(data)
# 2. 在指定區間按照元素個數生成 [start, end, num]
data = torch.linspace(0, 11, 10)
print(data)#torch.randn() 創建隨機張量
# 1. 創建隨機張量
data = torch.randn(2, 3) # 創建2行3列張量
print(data)"""
創建01張量
? torch.zeros() 創建全0張量
? torch.ones() 創建全1張量
? torch.full() 創建全為指定值張量
"""
#創建0、1、指定值張量
# 1. 創建指定形狀全0張量
data = torch.zeros(2, 3)
print(data)
# 2. 創建指定形狀全1張量
# torch.ones()創建全1張量
data = torch.ones(2, 3)
print(data)
# 3. 創建指定形狀指定值的張量
# torch.full()創建全為指定值張量
data = torch.full([2, 3], 10)
print(data)"""
張量元素類型轉換
data.type(torch.DoubleTensor)
? data.double()
"""
#張量的類型轉換
#data.type(torch.DoubleTensor)
data = torch.full([2, 3], 10)
print(data.dtype)
# 將 data 元素類型轉換為 float64 類型
data = data.type(torch.DoubleTensor)
print(data.dtype)
# 轉換為其他類型
data = data.type(torch.IntTensor)
data = data.type(torch.LongTensor)
data = data.type(torch.FloatTensor)# data.double()
data = torch.full([2, 3], 10)
print(data.dtype)
# 將 data 元素類型轉換為 float64 類型
data = data.double()
print(data.dtype)
# 轉換為其他類型
data = data.int()
data = data.long()
data = data.float()
2.?張量的類型轉換
import numpy as np
import torch"""
張量轉換為NumPy數組
? data_tensor.numpy()
"""
#使用Tensor.numpy()函數可以將張量轉換為ndarray數組
# 1. 將張量轉換為 numpy 數組
data_tensor = torch.tensor([2, 3, 4])
# 使用張量對象中的 numpy 函數進行轉換
data_numpy = data_tensor.numpy()
print(type(data_tensor))
print(type(data_numpy))
print(data_numpy)"""
NumPy數組轉換為張量
? 使用 from_numpy 可以將 ndarray 數組轉換為 Tensor。torch.from_numpy(data_numpy)
? 使用 torch.tensor 可以將 ndarray 數組轉換為 Tensor。torch.tensor(data_numpy)
"""
#使用from_numpy()可以將ndarray數組轉換為Tensor
data_numpy = np.array([2, 3, 4])
# 將 numpy 數組轉換為張量類型
# 1. from_numpy
# 2. torch.tensor(ndarray)
data_tensor = torch.from_numpy(data_numpy)
print(data_tensor)
print(data_numpy)# 使用torch.tensor()可以將ndarray數組轉換為Tensor。
data_numpy = np.array([2, 3, 4])
data_tensor = torch.tensor(data_numpy)
print(data_tensor)
print(data_numpy)"""
標量張量和數字轉換
? data.item()
"""
# 當張量只包含一個元素時, 可以通過 item() 函數提取出該值
data = torch.tensor([30,])
print(data.item())
data = torch.tensor(30)
print(data.item())
3. 張量數值計算
張量基本運算
import torch"""
張量基本運算
加減乘除取負號:
? add、sub、mul、div、neg等函數
? add_、sub_、mul_、div_、neg_等函數(其中帶下劃線的版本會修改原數據)
"""
data = torch.randint(0, 10, [2, 3])
print(data)
# 1. 不修改原數據
new_data = data.add(10) # 等價 new_data = data + 10
print(new_data)
# 2. 直接修改原數據 注意: 帶下劃線的函數為修改原數據本身
data.add_(10) # 等價 data += 10
print(data)
# 3. 其他函數
print(data.sub(100))
print(data.mul(100))
print(data.div(100))
print(data.neg())

"""
張量的點乘運算
? mul和運算符*
"""
data1 = torch.tensor([[1, 2], [3, 4]])
data2 = torch.tensor([[5, 6], [7, 8]])
# 第一種方式
data = torch.mul(data1, data2)
print(data)
# 第二種方式
data = data1 * data2
print(data)
乘法運算
"""
矩陣乘法運算
? 運算符@用于進行兩個矩陣的乘法運算
? torch.matmul 對應的維度必須符合矩陣運算規則
"""
# 乘法運算
data1 = torch.tensor([[1, 2], [3, 4], [5, 6]])
data2 = torch.tensor([[5, 6], [7, 8]])
# 方式一:
data3 = data1 @ data2
print("data3-->", data3)
# 方式二:
data4 = torch.matmul(data1, data2)
print("data4-->", data4)
4. 張量運算函數
import torch"""
張量運算函數
Sum,mean,sqrt,pow,exp,log等
"""data = torch.randint(0, 10, [2, 3], dtype=torch.float64)
print(data)
# 1. 計算均值
# 注意: tensor 必須為 Float 或者 Double 類型
print(data.mean())
# 2. 計算總和
print(data.sum())
# 3. 計算平方
print(torch.pow(data, 2))
# 4. 計算平方根
print(data.sqrt())
# 5. 指數計算, e^n 次方
print(data.exp())
# 6. 對數計算
print(data.log()) # 以 e 為底
print(data.log2())
print(data.log10())
5. 張量索引操作
import torch# 數據準備
# 隨機生成數據
data = torch.randint(0, 10, [4, 5])
print(data)"""
? 簡單行列索引的使用
"""
print(data[0])
print(data[:, 0])"""
? 列表索引的使用
"""
# 返回 (0, 1)、(1, 2) 兩個位置的元素
print(data[[0, 1], [1, 2]])
# 返回 0、1 行的 1、2 列共4個元素
print(data[[[0], [1]], [1, 2]])"""
? 范圍索引的使用
"""
# 前3行的前2列數據
print(data[:3, :2])
# 第2行到最后的前2列數據
print(data[2:, :2])"""
? 多維索引的使用
"""
data = torch.randint(0, 10, [3, 4, 5])
print(data)
# 獲取0軸上的第一個數據
print(data[0, :, :])
# 獲取1軸上的第一個數據
print(data[:, 0, :])
# 獲取2軸上的第一個數據
print(data[:, :, 0])
6. 張量形狀操作
"""
1.reshape 函數可以在保證張量數據不變的前提下改變數
據的維度
"""
data = torch.tensor([[10, 20, 30], [40, 50, 60]])
# 1. 使用 shape 屬性或者 size 方法都可以獲得張量的形狀
print(data.shape)
print(data.size)
# 2. 使用 reshape 函數修改張量形狀
new_data = data.reshape(1, 6)
print(new_data)
print(new_data.shape)
"""
2.squeeze 和 unsqueeze 函數可以用來減少或者增加維
度
"""
mydata1 = torch.tensor([1, 2, 3, 4, 5])
print('mydata1--->', mydata1.shape, mydata1) # 一個普通的數組 1維數據
mydata2 = mydata1.unsqueeze(dim=0)
print('在0維度上 拓展維度:', mydata2, mydata2.shape) #1*5
mydata3 = mydata1.unsqueeze(dim=1)
print('在1維度上 拓展維度:', mydata3, mydata3.shape) #5*1
mydata4 = mydata1.unsqueeze(dim=-1)
print('在-1維度上 拓展維度:', mydata4, mydata4.shape) #5*1
mydata5 = mydata4.squeeze()
print('壓縮維度:', mydata5, mydata5.shape) #1*5
"""
3.transpose 函數可以實現交換張量形狀的指定維度,
permute 可以一次交換更多的維度
"""
data = torch.tensor(np.random.randint(0, 10, [3, 4, 5]))
print(data)
print('data shape:', data.size())
# 1 交換1和2維度
mydata2 = torch.transpose(data, 1, 2)
print('mydata2.shape--->', mydata2.shape)
# 2 將data 的形狀修改為 (4, 5, 3), 需要變換多次
mydata3 = torch.transpose(data, 0, 1)
mydata4 = torch.transpose(mydata3, 1, 2)
print('mydata4.shape--->', mydata4.shape)
# 3 使用 permute 函數將形狀修改為 (4, 5, 3)
# 3-1 方法1
mydata5 = torch.permute(data, [1, 2, 0])
print('mydata5.shape--->', mydata5.shape)
# 3-2 方法2
mydata6 = data.permute([1, 2, 0])
print('mydata6.shape--->', mydata6.shape)
"""
4.view 函數也可以用于修改張量的形狀, 但是它要求被轉
換的張量內存必須連續,所以一般配合 contiguous 函數使
用
"""
# 1 若要使用view函數, 需要使用contiguous() 變成連續以后再使用view函數
# 2 判斷張量是否使用整塊內存
data = torch.tensor( [[10, 20, 30],[40, 50, 60]])
print('data--->', data, data.shape)
# 1 判斷是否使用整塊內存
print(data.is_contiguous()) # True
# 2 view
mydata2 = data.view(3, 2)
print('mydata2--->', mydata2, mydata2.shape)
7. 張量拼接操作
import torch
"""
1.cat()函數可以將張量按照指定的維度拼接起來
"""
data1 = torch.randint(0, 10, [1, 2, 3])
data2 = torch.randint(0, 10, [1, 2, 3])
print(data1)
print(data2)
# 1. 按0維度拼接
new_data = torch.cat([data1, data2], dim=0)
print(new_data.shape)
# 2. 按1維度拼接
new_data = torch.cat([data1, data2], dim=1)
print(new_data.shape)
# 3. 按2維度拼接
new_data = torch.cat([data1, data2], dim=2)
print(new_data.shape)
8. 自動微分模塊

import torch"""
1. 當X為標量時梯度的計算
"""
def test01():x = torch.tensor(5)# 目標值y = torch.tensor(0.)# 設置要更新的權重和偏置的初始值w = torch.tensor(1., requires_grad=True, dtype=torch.float32)b = torch.tensor(3., requires_grad=True, dtype=torch.float32)# 設置網絡的輸出值z = x * w + b # 矩陣乘法# 設置損失函數,并進行損失的計算loss = torch.nn.MSELoss()loss = loss(z, y)# 自動微分loss.backward()# 打印 w,b 變量的梯度# backward 函數計算的梯度值會存儲在張量的 grad 變量中print("W的梯度:", w.grad)print("b的梯度", b.grad)
test01()"""
2. 當X為矩陣時梯度的計算
"""
def test02():# 輸入張量 2*5x = torch.ones(2,5)# 目標值是 2*3y = torch.zeros(2,3)# 設置要更新的權重和偏置的初始值w = torch.randn(5, 3,requires_grad=True)b = torch.randn(3, requires_grad=True)# 設置網絡的輸出值z = torch.matmul(x, w) + b # 矩陣乘法# 設置損失函數,并進行損失的計算loss = torch.nn.MSELoss()loss = loss(z, y)# 自動微分loss.backward()# 打印 w,b 變量的梯度# backward 函數計算的梯度值會存儲在張量的 grad 變量中print("W的梯度:", w.grad)print("b的梯度", b.grad)
test02()
9. 案例-線性回歸案例
線性回歸:一種用于建立輸入特征(X)與連續型輸出(y)之間線性關系的監督學習模型。
模型公式:

- w:權重(斜率),控制每個特征的影響力
- b:偏置(截距),調整整體偏移
目標:找到最佳的 w 和 b,使預測值最接近真實值。
損失函數:用于衡量模型預測值與真實值之間的差異。
在線性回歸中,常用的損失函數是均方誤差(MSE),即所有樣本預測值與真實值差的平方的平均值。
均方誤差(MSE)公式:
梯度下降:是一種優化算法,用于找到損失函數的最小值。通過計算損失函數關于參數的梯度(導數),然后沿著梯度的反方向更新參數,逐步逼近最小值。
參數更新公式:
梯度計算(以MSE為例):
-
關鍵參數:
-
學習率(ηη):控制步長,過大易震蕩,過小收斂慢
-
迭代次數:決定更新輪次
-
線性回歸,損失函數和梯度下降,三者的協同工作流程
-
初始化參數:隨機設置 ww 和 bb 的初始值
-
前向傳播:計算預測值 y^=wX+by^?=wX+b
-
損失計算:通過MSE評估預測誤差
-
梯度計算:求損失對 ww 和 bb 的偏導數
-
參數更新:沿負梯度方向調整 ww 和 bb
-
重復2-5步:直到損失收斂或達到最大迭代次數
實例演示(房價預測)
場景:用房屋面積(xx)預測房價(yy)
-
數據:
面積(㎡) 房價(萬元) 80 320 100 400 120 480
步驟:
-
假設模型:
- 初始化:設 w=3, b=50
-
預測值:
-
第一樣本:
-
-
計算損失:
-
計算梯度:
-
更新參數(設 η=0.0001η=0.0001):
- 準備訓練集數據
- 構建要使用的模型
- 設置損失函數和優化器
- 模型訓練
代碼案例
import torch
from torch.utils.data import TensorDataset # 構造數據集對象
from torch.utils.data import DataLoader # 數據加載器
from torch import nn # nn模塊中有平方損失函數和假設函數
from torch import optim # optim模塊中有優化器函數
from sklearn.datasets import make_regression # 創建線性回歸模型數據集
import matplotlib.pyplot as pltplt.rcParams['font.sans-serif'] = ['SimHei'] # 用來正常顯示中文標簽
plt.rcParams['axes.unicode_minus'] = False # 用來正常顯示負號# 構建數據集
def create_dataset():x,y,coef=make_regression(n_samples=100,n_features=1,noise=10,coef=True,bias=1.5,random_state=0)x = torch.tensor(x)y = torch.tensor(y)return x,y,coef# 構造數據集
x, y, coef = create_dataset()
# 構造數據集對象
dataset = TensorDataset(x, y)
# 構造數據加載器
# dataset=:數據集對象
# batch_size=:批量訓練樣本數據
# shuffle=:樣本數據是否進行亂序
dataloader = DataLoader(dataset=dataset, batch_size=16, shuffle=True)
# 構造模型
# in_features指的是輸入張量的大小size
# out_features指的是輸出張量的大小size
model = nn.Linear(in_features=1, out_features=1)# 損失和優化器
# 構造平方損失函數
criterion = nn.MSELoss()
# 構造優化函數
optimizer = optim.SGD(params=model.parameters(), lr=1e-2)epochs = 100
# 損失的變化
loss_epoch = []
total_loss=0.0
train_sample=0.0
for _ in range(epochs):for train_x, train_y in dataloader:# 將一個batch的訓練數據送入模型y_pred = model(train_x.type(torch.float32))# 計算損失值loss = criterion(y_pred, train_y.reshape(-1, 1).type(torch.float32))total_loss += loss.item()train_sample += len(train_y)# 梯度清零optimizer.zero_grad()# 自動微分(反向傳播)loss.backward()# 更新參數optimizer.step()# 獲取每個batch的損失loss_epoch.append(total_loss/train_sample)# 繪制損失變化曲線
plt.plot(range(epochs), loss_epoch)
plt.title('損失變化曲線')
plt.grid()
plt.show()# 繪制擬合直線
plt.scatter(x, y)
x = torch.linspace(x.min(), x.max(), 1000)
y1 = torch.tensor([v * model.weight + model.bias for v in x])
y2 = torch.tensor([v * coef + 1.5 for v in x])
plt.plot(x, y1, label='訓練')
plt.plot(x, y2, label='真實')
plt.grid()
plt.legend()
plt.show()