作者:夏风喃喃
参考:《动手学深度学习第二版》李沐
import torch #Pytorch支持
import os #文件操作
import pandas as pd #数据处理
import numpy as np #Python算术运算包
from matplotlib import pyplot as plt #绘图
from IPython import display #交互式Python库
from torch.distributions import multinomial #多项分布包
import random #随机数
创建数据:
x = torch.arange(12) #创建递增数据
torch.zeros((2, 3, 4)) #创建全零数据
torch.ones((2, 3, 4)) #创建全一数据
torch.randn(3, 4) #创建均值0,标准差1的正态分布数据
torch.tensor([[2, 1], [1, 2]]) #创建自定义张量数据
X = x.reshape(3, 4) #数据整形
x.shape #打印数据形状
len(x) #打印数据长度
x.numel() #打印数据元素个数
数据运算:
torch.exp(x) #指数运算
torch.cat((X, Y), dim=0) #数据拼接
X.sum(axis=0) #数据内元素求和,降维
A.sum(axis=1, keepdims=True) #数据内元素求和,不降维
A.mean(axis=0) #数据平均值,降维
A.cumsum(axis=0) #数据元素的累积总和
A.T #矩阵转置
A * B #哈达玛积,元素对应相乘
torch.dot(x, y) #点积,对应元素乘积之和
torch.mv(A, x) #向量积,矩阵与向量的乘积
torch.mm(A, B) #矩阵乘法,矩阵与矩阵的乘积
torch.abs(u).sum() #数据的L1范数
torch.norm(u) #数据的L2范数
本地运算:
X[:] = X + Y #X参与运算前后地址不变
X += Y #X参与运算前后地址不变
tensor张量与numpy标量转换:
A = X.numpy() #转换为标量
B = torch.tensor(A) #转换为张量
a.item() #单元素数据转换为标量
float(a) #单元素数据转换为标量
int(a) #单元素数据转换为标量
创建数据集:
#创建文件夹,如果已存在不会报错
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:
# 列名,必须有列名,否则第一行数据会被read_csv识别为表头
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')
读取数据集:
data = pd.read_csv(data_file) #使用read_csv函数读取数据集
处理缺失值:
inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2] #定位输入的列
inputs = inputs.fillna(inputs.mean()) #对输入列中NaN数据用列均值代替
#当一列只接受两种类型的类别值,则转换为两列,每列用1或0代表能否接受一种类别值
inputs = pd.get_dummies(inputs, dummy_na=True)
转换为张量格式:
#将预处理好的数据转换为张量格式,以便后续操作
X, y = torch.tensor(inputs.values), torch.tensor(outputs.values)
为绘图做准备的三个函数:
def use_svg_display():
"""使用svg格式显示绘图。"""
display.set_matplotlib_formats('svg')
def set_figsize(figsize=(3.5, 2.5)):
"""设置matplotlib的图表大小。"""
use_svg_display()
plt.rcParams['figure.figsize'] = figsize
def set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend):
"""设置matplotlib的轴。"""
axes.set_xlabel(xlabel)
axes.set_ylabel(ylabel)
axes.set_xscale(xscale)
axes.set_yscale(yscale)
axes.set_xlim(xlim)
axes.set_ylim(ylim)
if legend:
axes.legend(legend)
axes.grid()
plot绘图函数:
def plot(X, Y=None, xlabel=None, ylabel=None, legend=None, xlim=None,
ylim=None, xscale='linear', yscale='linear',
fmts=('-', 'm--', 'g-.', 'r:'), figsize=(3.5, 2.5), axes=None):
"""绘制数据点。"""
if legend is None:
legend = []
set_figsize(figsize)
axes = axes if axes else d2l.plt.gca()
# 如果 `X` 有一个轴,输出True
def has_one_axis(X):
return (hasattr(X, "ndim") and X.ndim == 1 or
isinstance(X, list) and not hasattr(X[0], "__len__"))
if has_one_axis(X):
X = [X]
if Y is None:
X, Y = [[]] * len(X), X
elif has_one_axis(Y):
Y = [Y]
if len(X) != len(Y):
X = X * len(Y)
axes.cla()
for x, y, fmt in zip(X, Y, fmts):
if len(x):
axes.plot(x, y, fmt)
else:
axes.plot(y, fmt)
set_axes(axes, xlabel, ylabel, xlim, ylim, xscale, yscale, legend)
使用plot绘图函数绘图:
plot(x,[f(x),3 * x - 3],'x','f(x)',legend=['f(x)', 'Tangent line (x=1)'])
x.requires_grad_(True) #确定自变量x,需要求梯度
y = 2 * torch.dot(x, x) #因变量y的计算
y.backward() #确定因变量y,需要反向传播
y.sum().backward() #非标量向量求导,需要求和反向传播
x.grad #得到dy/dx的梯度导数值
x.grad.zero_() #计算下一次的梯度时,先需要梯度清零
u = y.detach() #detach后,u为y的值,而不是y的表达式
fair_probs = torch.ones([6])/6
#按fair_probs中数的大小为概率随机抽取一个数据并置为1,抽取后会放回
multinomial.Multinomial(1, fair_probs).sample()