深度学习之PyTorch(上)
PyTorch是一个开源的Python机器学习库,基于Torch库(一个有大量机器学习算法支持的科学计
算框架,有着与Numpy类似的张量(Tensor)操作,采用的编程语言是 Lua),底层由C++实现,
应用于人工智能领域,如计算机视觉和自然语言处理。
PyTorch官网:https://pytorch.org/,安装教程见主页。
通过 PyTorch 训练一个模型一般分为以下 4 个步骤:
准备数据 → 构建模型 → 定义损失函数与优化器 → 模型训练
一、张量创建
1、基本张量创建
1.1、torch.tensor(data)创建指定内容的张量
传入一个标量
import torch
tensor1 = torch.tensor(10)
print(tensor1)
tensor(10)
传入一个向量
tensor2 = torch.tensor([1,2,3])
print(tensor2)
# print(tensor2)
1.2、torch.Tensor(size)创建指定形状的张量
这个大写的Tensor也可以传入内容创建,默认是按形状
tensor3 = torch.Tensor(3,2,4)
print(tensor3)
print(tensor3.size())
print(tensor3.dtype)
result:
tensor([[[0., 0., 0., 0.],
[0., 0., 0., 0.]],
[[0., 0., 0., 0.],
[0., 0., 0., 0.]],
[[0., 0., 0., 0.],
[0., 0., 0., 0.]]])
torch.Size([3, 2, 4])
torch.float32
1.3、torch.IntTensor()、torch.FloatTensor()等,或者torch.tensor中通过dtype指定参数类型创建指定类型的张量
tensor1 = torch.tensor([1,2,3],dtype = torch.int64)
print(tensor1)
print(tensor1.dtype)
tensor2 = torch.IntTensor([1,2,3])
print(tensor2)
print(tensor2.dtype)
result:tensor([1, 2, 3])
torch.int64
tensor([1, 2, 3], dtype=torch.int32)
torch.int32
2、指定区间的张量创建
2.1、torch.arange(start,end,step)在区间内按步长创建张量,不包括end
tensor1 = torch.arange(10,30,2)
print(tensor1)
print(tensor1.size())
tensor([10, 12, 14, 16, 18, 20, 22, 24, 26, 28])
torch.Size([10])
2.2、torch.linspace(start,end,steps)在区间内按元素数量创建张量,包括end
tensor1 = torch.linspace(10,30,5)
print(tensor1)
print(tensor1.size())
tensor([10., 15., 20., 25., 30.])
torch.Size([5])
2.3、torch.logspace(start,end,steps,base)在指数区间内按指定底数创建张量,包括end
tensor1 = torch.logspace(1,3,3,2)
print(tensor1)
tensor([2., 4., 8.])
3、按数值填充张量


补充:torch.eye创建单位矩阵,如果只传入一个值那就是方阵
tensor1 = torch.eye(3,4)
print(tensor1)
tensor([[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.]])
4、随机张量创建


补充:torch.randperm(n)生成0到n-1的随机排列,类似洗牌
tensor1 = torch.randperm(6)
print(tensor1)
tensor([5, 2, 0, 1, 4, 3])
torch.random.initial_seed()查看随机数种子
torch.manual_seed(seed)设置随机数种子
print(torch.random.initial_seed())
#1381529020242300
torch.manual_seed(42)
print(torch.random.initial_seed())
#42
二、张量转换
1、张量元素类型转换
1.1、Tensor.type(dtype)修改张量类型
import torch
tensor1 = torch.tensor([1,2,3])
print(tensor1,tensor1.dtype)
tensor1 = tensor1.type(torch.float32)
print(tensor1,tensor1.dtype)
tensor([1, 2, 3]) torch.int64
tensor([1., 2., 3.]) torch.float32
1.2、Tensor.double()等修改张量的类型
tensor1 = tensor1.double()
print(tensor1,tensor1.dtype)
tensor([1., 2., 3.], dtype=torch.float64) torch.float64
补充:torch.complex是复数类型
2、Tensor与ndarray转换
注意copy()是对于ndarray而言的,写代码的时候要看清楚类型,在ndarray的后面接一个copy(),
对于tensor也有一个方法叫clone()
2.1、Tensor.numpy()将Tensor转换为ndarray,共享内存,使用copy()避免共享内存
这里可以看出共享内存
np.set_printoptions(precision = 6)
torch.set_printoptions(precision = 6)
tensor1 = torch.rand(3,2)
print(tensor1)
ndarray1 = tensor1.numpy()
print(ndarray1)
ndarray1[1,0] = 2
print(ndarray1)
print(tensor1)
tensor([[0.306238, 0.535756],
[0.378546, 0.316012],
[0.790295, 0.365583]])
[[0.306238 0.535756]
[0.378546 0.316012]
[0.790295 0.365583]]
[[0.306238 0.535756]
[2. 0.316012]
[0.790295 0.365583]]
tensor([[0.306238, 0.535756],
[2.000000, 0.316012],
[0.790295, 0.365583]])
使用copy()不共享内存
ndarray2 = tensor1.numpy().copy()
tensor1[:,0] = 10
print(tensor1)
print(ndarray2)
tensor([[10.000000, 0.049914],
[10.000000, 0.325573],
[10.000000, 0.058194]])
[[0.043996 0.049914]
[2. 0.325573]
[0.902513 0.058194]]
2.2、torch.from_numpy(ndarray)将ndarray转换为Tensor,共享内存,使用copy避免内存共享
ndarray1 = np.random.randn(3)
tensor1 = torch.from_numpy(ndarray1)
print(tensor1)
print(ndarray1)
tensor([-0.985477, 0.635086, 1.754846], dtype=torch.float64)
[-0.985477 0.635086 1.754846]
tensor2 = torch.from_numpy(ndarray1.copy())
tensor2[0] = 1.5
print(tensor2)
print(ndarray1)
tensor([1.500000, 1.199748, 1.003381], dtype=torch.float64)
[-0.62402 1.199748 1.003381]
3、Tensor与标量转换
若张量中只有一个元素,Tensor.item()可以提取张量中元素为标量
tensor1 = torch.tensor(10)
print(tensor1)
print(tensor1.shape)
a = tensor1.item()
print(a)
tensor(10)
torch.Size([])
10
三、张量数值计算
1、基本运算
1.1、四则运算
下划线会修改原数据

print(tensor1.add(10))
print(tensor1)
tensor([[14, 11, 13],
[19, 14, 16]])
tensor([[4, 1, 3],
[9, 4, 6]])
print(tensor1.add_(10))
print(tensor1)
tensor([[14, 11, 13],
[19, 14, 16]])
tensor([[14, 11, 13],
[19, 14, 16]])
1.2、取负数neg()、neg_()
同样,加下划线改变原数据
1.3、求幂**、pow()、pow_()
对每个元素求幂,同样,加下划线改变原数据
1.4、求平方根sqrt()、sqrt_()
同上
1.5、exp()、exp_()以e为底数求幂
同上
1.6、log()、log_()以 e 为底求对数
同上
2、哈达玛积(元素级乘法)
两个矩阵对应位置元素相乘称为哈达玛积(Hadamard product),使用*、mul()实现两个形状相同
的张量之间对位相乘。
3、矩阵乘法运算@、matmul()、mm()
mm()严格用于二维矩阵相乘。@、matmul()支持多维张量,按最后两个维度做矩阵乘法,其他维
度相同,或者至少一个张量对应维度为 1,广播后进行运算,像这样。
tensor1 = torch.Tensor(4,2,3,5) tensor2 = torch.Tensor(1,1,5,6) print((tensor1 @ tensor2).shape)
意思就是张量相乘,维度必须一样,然后最后两个维度要符合矩阵乘法的规格。
tensor1 = torch.tensor([[1,2],[3,4],[0,1]])
tensor2 = torch.tensor([[5,6],[7,8]])
print(tensor1 @ tensor2)
tensor([[19, 22],
[43, 50],
[ 7, 8]])
4、节省内存
首先我们讲哈达玛积,如果直接运行print(X*Y),这样X的值本身不会改变;如果X = X * Y,做了一
步这样的赋值操作,其实是创建了一个新的变量,只是这个变量名字叫X而已,没有做到节省内存
空间的作用,可以查看id,如果运行的是mul_,则可以保存,如果用X *= Y,这样也可以。
X = torch.randint(1,10,(3,2,4))
Y = torch.randint(1,10,(3,2,4))
print(id(X))
X = X * Y
print(id(X))
2486393500000
2486393499120
接下来讲矩阵乘法,矩阵乘法用X @= Y这样的形式行不通,得X[:] = X @ Y,用 X @ Y 的结果,
原地覆盖 X 本身的所有元素,这样能节省内存的前提是,乘出来的矩阵规格要小于等于之前的规
格并且能广播,广播也有batch广播和矩阵规格广播,广播需要维度为1。
四、张量运算函数
这些都是多对一的函数,有一个统计聚合效果

sum函数在用的时候可以设置dim,这个指的是针对哪一个维度,比如我这里的dim = 0,就是针对
batch = 3这个维度,设置哪一个dim,就是把那个dim压缩没
import torch
tensor1 = torch.randint(1,10,(3,2,4))
print(tensor1)
print(tensor1.sum())
sum = torch.sum(tensor1, dim=0)
print(sum)
tensor([[[2, 4, 5, 6],
[6, 6, 5, 5]],
[[1, 4, 9, 4],
[8, 2, 2, 9]],
[[6, 5, 4, 2],
[8, 2, 2, 3]]])
tensor(110)
tensor([[ 9, 13, 18, 12],
[22, 10, 9, 17]])
五、张量索引
1、简单索引
可以【0,1,2】也可以【0】【1】【2】这样写,然后如果写比如【0,1】,意思就是第一个矩
阵的第一行。
import torch
tensor1 = torch.randint(1,10,(3,5,4))
print(tensor1)
print(tensor1[0,1,2])
tensor([[[9, 2, 1, 1],
[1, 6, 5, 9],
[6, 1, 2, 4],
[4, 3, 7, 5],
[2, 4, 6, 2]],
[[1, 5, 4, 7],
[8, 9, 3, 7],
[1, 1, 3, 1],
[1, 2, 1, 7],
[1, 7, 7, 7]],
[[8, 3, 9, 1],
[7, 9, 1, 3],
[7, 2, 3, 2],
[3, 7, 2, 8],
[2, 5, 8, 6]]])
tensor(5)
2、范围索引
看这种范围索引主要要看逗号在哪里,注意:-1就是最后一行
这个意思是所有矩阵的第1行拼起来
print(tensor1[:,1])
tensor([[3, 6, 2, 2],
[2, 6, 3, 7],
[5, 3, 2, 4]])
这个意思是包括第1个矩阵的之后所有矩阵,每个矩阵的1到3行,这里也可以写1:4:2,考虑步长
print(tensor1[1:,1:4])
tensor([[[2, 6, 3, 7],
[4, 1, 4, 9],
[6, 6, 5, 8]],
[[5, 3, 2, 4],
[5, 2, 8, 3],
[6, 9, 9, 9]]])
3、列表索引
这个就相当于【0,1,3】和【1,2,1】,列表索引的列表长度要一致
print(tensor1[[0,1],[1,2],[3,1]])
tensor([2, 1])
上面是一一对应的情况,以下是一对多的情况
print(tensor1[[[0],[1]],[1,2]])
tensor([[[3, 6, 2, 2],
[3, 7, 6, 3]],
[[2, 6, 3, 7],
[4, 1, 4, 9]]])
4、布尔索引
mask = tensor1[:,0,2] > 4
print(mask)
print(tensor1[mask])
tensor([ True, False, True])
tensor([[[4, 3, 7, 4],
[3, 6, 2, 2],
[3, 7, 6, 3],
[3, 2, 3, 7],
[8, 9, 8, 9]],
[[7, 6, 5, 4],
[5, 3, 2, 4],
[5, 2, 8, 3],
[6, 9, 9, 9],
[9, 3, 3, 2]]])
mask的shape一定要和矩阵的shape保持一致,不然会报错,所以这里要提前转置一下
mask = tensor1[:,1,:] > 5
print(mask)
tensor2 = tensor1.mT
print(tensor2[mask])
tensor([[False, True, False, False],
[False, True, False, True],
[False, False, False, False]])
tensor([[3, 6, 7, 2, 9],
[1, 6, 1, 6, 8],
[5, 7, 9, 8, 3]])
六、张量形状操作
1、交换维度
如果是一般情况下,一个tensor.T做转置,是全部反转,比如【3,2,5】这个shape,T了之后就
是【5,2,3】,这样元素的坐标也是全部反转,如果只想转置矩阵,要用.mT,m是matrix的意
思。

2、调整形状

用reshape的时候,元素个数要匹配,-1就是自己计算维度,在这个案例中为20。
2)view()调整张量的形状,需要内存连续,共享内存
is_contiguous()判断是否连续,contiguous()转成连续

3、增删维度
在这里-1就是最后一维

4、张量的拼接和堆叠


七、自动微分模块(计算梯度)

自动微分的关键就是记录节点的数据与运算。数据记录在张量的 data 属性中,计算记录在张量的
grad_fn 属性中。
x = torch.tensor(10.0)
y = torch.tensor(3.0)
w = torch.rand(1,1,requires_grad=True)
b = torch.rand(1,1,requires_grad=True)
z = w * x + b
print(z)
print(z.requires_grad)
print(x.is_leaf)
print(y.is_leaf)
print(z.is_leaf)
print(w.is_leaf)
print(b.is_leaf)
loss = torch.nn.MSELoss()
loss_value = loss(z,y)
print(loss_value)
print(loss_value.is_leaf)
loss_value.backward()
print(w.grad)
print(b.grad)
tensor([[4.8459]], grad_fn=<AddBackward0>)
True
True
True
False
True
True
tensor(3.4073, grad_fn=<MseLossBackward0>)
False
tensor([[36.9177]])
tensor([[3.6918]])
有时我们希望将某些计算移动到计算图之外,可以使用 Tensor.detach()返回一个新的变量,该变
量与原变量具有相同的值,但丢失计算图中如何计算原变量的信息。换句话说,梯度不会在该变量
处继续向下传播。
这里的z2不可以运行backward方法,因为requires_grad被关闭了
x = torch.tensor(2.0, requires_grad=True)
y = x.detach()
print(x)
print(y)
z1 = x ** 2
z1.backward()
print(x.grad)
print(z1)
z2 = y ** 2
print(z2)
tensor(2., requires_grad=True)
tensor(2.)
tensor(4.)
tensor(4., grad_fn=<PowBackward0>)
tensor(4.)

八、线性回归案例

import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
import torch
import matplotlib.pyplot as plt
from torch import nn, optim
from torch.utils.data import TensorDataset, DataLoader
x = torch.randn(100,1)
w = torch.tensor([2.5])
b = torch.tensor([5.2])
noise = torch.randn(100,1) * 0.5
y = w * x + b + noise
dataset = TensorDataset(x, y)
dataloader = DataLoader(dataset,batch_size = 10,shuffle = True)
model = nn.Linear(1,1)
loss = nn.MSELoss()
optimizer = optim.SGD(model.parameters(),lr = 0.001)
epochs = 1000
loss_list = []
for epoch in range(epochs):
total_loss = 0
iter_num = 0
for x_batch, y_batch in dataloader:
y_pred = model(x_batch)
loss_value = loss(y_pred, y_batch)
loss_value.backward()
optimizer.step()
optimizer.zero_grad()
total_loss += loss_value.item()
iter_num += 1
loss_list.append(total_loss / iter_num)
print("斜率:",model.weight)
print("截距:",model.bias)
fig,ax = plt.subplots(1,2,figsize=(12,4))
ax[0].plot(loss_list)
ax[0].set_xlabel('epoch')
ax[0].set_ylabel('loss')
ax[1].scatter(x,y)
y_hat = model.weight.item() * x + model.bias.item()
ax[1].plot(x,y_hat,color='red')
plt.show()
E:\anaconda3\envs\PyTorch\python.exe E:\Py_project\PyTorch\linear_regression.py
斜率: Parameter containing:
tensor([[2.4992]], requires_grad=True)
截距: Parameter containing:
tensor([5.1325], requires_grad=True)

九、激活函数
1、Sigmoid


import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
import torch
import matplotlib.pyplot as plt
x = torch.linspace(-10,10,1000,requires_grad=True)
y = torch.sigmoid(x)
fig,ax = plt.subplots(1,2,figsize=(12,4))
ax[0].plot(x.data,y.data,color='purple')
ax[0].set_title('sigmoid(x)')
ax[0].axhline(y = 1,color='gray',linewidth = 1,alpha = 0.7)
ax[0].axhline(y = 0.5,color='gray',linewidth = 1,alpha = 0.7)
ax[0].spines['top'].set_visible(False)
ax[0].spines['right'].set_visible(False)
ax[0].spines['left'].set_position('zero')
ax[0].spines['bottom'].set_position('zero')
y.sum().backward()
ax[1].plot(x.data,x.grad,color='purple')
ax[1].set_title("sigmoid'(x)")
ax[1].spines['top'].set_visible(False)
ax[1].spines['right'].set_visible(False)
ax[1].spines['left'].set_position('zero')
ax[1].spines['bottom'].set_position('zero')
plt.show()

注意这里为什么要
y.sum().backward()
因为backward只能对标量使用,如果直接对y进行backward就不知道到底要对哪一个数值进行求梯
度,为什么要选择sum而不是拆开来对应x1y1这样求呢,是因为能影响到梯度的只有对应的yn,其
它的是当作常数,所以即使sum了也不影响,如下图:

2、Tanh
import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
import torch
import matplotlib.pyplot as plt
x = torch.linspace(-5,5,1000,requires_grad=True)
y = torch.tanh(x)
fig,ax = plt.subplots(1,2,figsize=(12,4))
ax[0].plot(x.data,y.data,color='purple')
ax[0].set_title('tanh(x)')
ax[0].axhline(y = 1,color='gray',linewidth = 1,alpha = 0.7)
ax[0].axhline(y = -1,color='gray',linewidth = 1,alpha = 0.7)
ax[0].spines['top'].set_visible(False)
ax[0].spines['right'].set_visible(False)
ax[0].spines['left'].set_position('zero')
ax[0].spines['bottom'].set_position('zero')
y.sum().backward()
ax[1].plot(x.data,x.grad,color='purple')
ax[1].set_title("tanh'(x)")
ax[1].spines['top'].set_visible(False)
ax[1].spines['right'].set_visible(False)
ax[1].spines['left'].set_position('zero')
ax[1].spines['bottom'].set_position('zero')
plt.show()

3、ReLU
import torch
import matplotlib.pyplot as plt
x = torch.linspace(-5,5,1000,requires_grad=True)
y = torch.relu(x)
fig,ax = plt.subplots(1,2,figsize=(12,4))
ax[0].plot(x.data,y.data,color='purple')
ax[0].set_title('relu(x)')
ax[0].spines['top'].set_visible(False)
ax[0].spines['right'].set_visible(False)
ax[0].spines['left'].set_position('zero')
ax[0].spines['bottom'].set_position('zero')
y.sum().backward()
ax[1].plot(x.data,x.grad,color='purple')
ax[1].set_title("relu'(x)")
ax[1].spines['top'].set_visible(False)
ax[1].spines['right'].set_visible(False)
ax[1].spines['left'].set_position('zero')
ax[1].spines['bottom'].set_position('zero')
plt.show()

4、softmax
import torch
x = torch.randn(3,5)
y_prob = torch.softmax(x, dim=1)
print(y_prob)
tensor([[0.6430, 0.0900, 0.2124, 0.0300, 0.0246],
[0.0299, 0.1759, 0.2867, 0.0711, 0.4363],
[0.3348, 0.4210, 0.2128, 0.0076, 0.0238]])
十、全连接层(初始化)
1、常见初始化方法
初始化为全0
import torch.nn as nn
linear = nn.Linear(5, 2)
# 初始化全0
nn.init.zeros_(linear.bias)
print(linear.bias)
Parameter containing:
tensor([0., 0.], requires_grad=True)
初始化为任意常数用constant
import torch.nn as nn
linear = nn.Linear(5, 2)
nn.init.constant_(linear.bias,10)
print(linear.bias)
Parameter containing:
tensor([10., 10.], requires_grad=True)
秩初始化
import torch.nn as nn
linear = nn.Linear(5, 2)
nn.init.eye_(linear.weight)
print(linear.weight)
Parameter containing:
tensor([[1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0.]], requires_grad=True)
正态分布初始化
linear = nn.Linear(5, 2)
nn.init.normal_(linear.weight,mean = 5,std = 1)
print(linear.weight)
Parameter containing:
tensor([[4.0496, 3.6883, 5.0904, 5.5787, 4.6238],
[6.3297, 6.1959, 4.6086, 5.1574, 6.2251]], requires_grad=True)
均匀分布初始化
linear = nn.Linear(5, 2)
nn.init.uniform_(linear.weight,0,10)
print(linear.weight)
Parameter containing:
tensor([[5.3156, 3.2887, 2.0559, 0.8858, 7.4100],
[9.8123, 1.7759, 1.9474, 5.4194, 5.7101]], requires_grad=True)
2、Xavier初始化(Glorot初始化)
适用于sigmoid和Tanh等激活函数,能有效缓解梯度消失或爆炸问题
import torch.nn as nn
linear = nn.Linear(5, 2)
nn.init.xavier_normal_(linear.weight)
print(linear.weight)
nn.init.xavier_uniform_(linear.weight)
print(linear.weight)
Parameter containing:
tensor([[ 0.1092, 0.6596, -0.2596, 0.1790, 0.1906],
[ 1.1577, 0.1663, 0.0516, 0.4451, -0.9941]], requires_grad=True)
Parameter containing:
tensor([[-0.3551, -0.0147, -0.5234, 0.4733, 0.1845],
[ 0.0142, 0.1118, -0.7389, 0.9132, 0.6893]], requires_grad=True)
3、He初始化(Kaiming)
主要适用于ReLU及其变体
linear = nn.Linear(5, 2)
nn.init.kaiming_normal_(linear.weight)
print(linear.weight)
nn.init.kaiming_uniform_(linear.weight)
print(linear.weight)
Parameter containing:
tensor([[ 0.2884, 0.4597, 0.9206, -0.9007, -1.4727],
[ 0.1024, 0.7552, 1.3354, -0.0632, 0.2416]], requires_grad=True)
Parameter containing:
tensor([[-0.2535, 0.0838, -1.0336, -0.2692, -0.2258],
[ 0.2634, -0.4902, 0.8401, -0.4683, 0.1186]], requires_grad=True)
十一、正则化dropout
随机失活dropout
import torch
import torch.nn as nn
x = torch.randint(1,10,(10,),dtype=torch.float)
print(x)
dropout = nn.Dropout(p = 0.2)
y = dropout(x)
print(y)
tensor([1., 7., 1., 8., 7., 7., 5., 7., 3., 6.])
tensor([ 0.0000, 8.7500, 1.2500, 10.0000, 0.0000, 8.7500, 0.0000, 0.0000,
3.7500, 7.5000])
十二、搭建神经网络
1、搭建神经网络
第 1 个隐藏层:使用 Xavier 正态分布初始化权重,激活函数使用 Tanh。
第 2 个隐藏层:使用 He 正态分布初始化权重,激活函数使用 ReLU。
输出层:按默认方式初始化,激活函数使用 Softmax。

import torch
import torch.nn as nn
class NN_model(nn.Module):
def __init__(self):
super().__init__()
self.linear1 = nn.Linear(3, 4)
nn.init.xavier_normal_(self.linear1.weight)
self.linear2 = nn.Linear(4, 4)
nn.init.kaiming_normal_(self.linear2.weight)
self.out = nn.Linear(4, 2)
def forward(self, x):
x = self.linear1(x)
x = torch.tanh(x)
x = self.linear2(x)
x = torch.relu(x)
x = self.out(x)
y = torch.softmax(x,dim = 1)
return y
if __name__ == '__main__':
x = torch.randn(10,3)
model = NN_model()
y_pred = model(x)
print("预测输出分类概率:",y_pred)
预测输出分类概率: tensor([[0.5959, 0.4041],
[0.3317, 0.6683],
[0.1820, 0.8180],
[0.5968, 0.4032],
[0.5942, 0.4058],
[0.5982, 0.4018],
[0.5165, 0.4835],
[0.6301, 0.3699],
[0.4951, 0.5049],
[0.5866, 0.4134]], grad_fn=<SoftmaxBackward0>)
2、查看模型参数
2.1、全部打出来
print(model.linear1.weight) print(model.linear1.bias) print(model.linear2.weight) print(model.linear2.bias) print(model.out.weight) print(model.out.bias)
2.2、for循环查找,调用model.parameters,但是不知道名称
for param in model.parameters():
print(param)
2.3、for循环,调用model.named_parameters
for name,param in model.named_parameters():
print(name)
print(param)
2.4、调用model.state_dict()查看参数字典
print(model.state_dict())
3、查看模型结构和参数数量

输出示例

4、使用Sequential定义模型
可以通过 torch.nn.Sequential 来构建模型,将各层按顺序传入。

import os
os.environ["KMP_DUPLICATE_LIB_OK"] = "TRUE"
import torch
import torch.nn as nn
from torchsummary import summary
x = torch.randn(10,3)
model = nn.Sequential(
nn.Linear(3,4),
nn.Tanh(),
nn.Linear(4,4),
nn.ReLU(),
nn.Linear(4,2),
nn.Softmax(dim=1)
)
def init_params(layer):
# 判断如果是线性层,就做参数初始化
if isinstance(layer, nn.Linear):
nn.init.xavier_uniform_(layer.weight)
nn.init.constant_(layer.bias, 0.01)
model.apply(init_params)
y_pred = model(x)
print("预测输出:",y_pred)
summary(model,(3,),batch_size=10,device='cpu')
预测输出: tensor([[0.4771, 0.5229],
[0.4563, 0.5437],
[0.7329, 0.2671],
[0.9581, 0.0419],
[0.7896, 0.2104],
[0.4530, 0.5470],
[0.4521, 0.5479],
[0.4652, 0.5348],
[0.4403, 0.5597],
[0.9639, 0.0361]], grad_fn=<SoftmaxBackward0>)
----------------------------------------------------------------
Layer (type) Output Shape Param #
================================================================
Linear-1 [10, 4] 16
Tanh-2 [10, 4] 0
Linear-3 [10, 4] 20
ReLU-4 [10, 4] 0
Linear-5 [10, 2] 10
Softmax-6 [10, 2] 0
================================================================
Total params: 46
Trainable params: 46
Non-trainable params: 0
----------------------------------------------------------------
Input size (MB): 0.00
Forward/backward pass size (MB): 0.00
Params size (MB): 0.00
Estimated Total Size (MB): 0.00
----------------------------------------------------------------
更多推荐


所有评论(0)