pytorch基本操作,pytorch的使用
PyTorch是基于Torch库的Python包,旨在加速深度学习应用。
PyTorch提供了一种类似于NumPy的抽象方法来刻画张量(或者多维数组),可以使用GPU来加速训练。
1.1 PyTorch张量
PyTorch的关键数据结构是张量,即多维数组。其功能类似于NumPy的ndarray对象。如下,我们可以使用火炬。张量()来创建张量。如果你需要一个NumPy兼容的表示,或者你想从一个现有的NumPy对象创建一个PyTorch张量,那么就非常简单了。
#构建二维pytorch张量
pytorch_tensor=火炬。张量(10,20,20)
print(type:,type(pytorch_tensor),和size:,pytorch_tensor.shape)
#将pytorch张量转换为numpy数组:
numpy _ tensor=py torch _ tensor . numpy()
print(type:,type(numpy_tensor),和size:,numpy_tensor.shape)
#将numpy数组转换为Pytorch张量:
pytorch_tensor=火炬。张量(数字张量)
print(type:,type(pytorch_tensor),和size:,pytorch_tensor.shape)
1.2 PyTorch与NumPy
PyTorch不是NumPy的简单替代品,但是它实现了许多NumPy函数。不便之处之一是它的命名规则。有时候和NumPy的命名方式大相径庭。让我们举几个例子来说明不同之处:
#张量创建
t=torch.rand(2,4,3,5)
a=np.random.rand(2,4,3,5)
#张量分割
a=t.numpy()
Pytorch _ slice=t [0,1: 3,4] #取t中的元素
numpy_slice=a[0,1:3,4]
屏蔽=t - 0.5
pytorch_masked=t[t 0]
numpy_masked=a[a 0]
#张量重塑
py torch _ shape=t . view([6,5,4])
numpy _ shape=a . shape([6,5,4])
1.3 PyTorch变量
PyTorch张量的简单包
帮助建立计算图表。
自动差异库的必要组成部分
将这些变量的梯度保存在。毕业生。
结构图:
图形和变量:在PyTorch中,神经网络将使用相互关联的变量作为计算图形。PyTorch允许通过代码构建计算图来构建网络模型;然后PyTorch会简化估计模型权重的过程,比如通过自动计算梯度。
例如,假设我们要建立一个两层模型,那么首先为输入和输出创建张量变量:
#将PyTorch张量包装成一个可变对象:
来自torch.autograd导入变量
导入torch.nn.functional as F
x=变量(torch.randn(4,1),requires_grad=False)
y=变量(torch.randn(3,1),requires_grad=False)
#我们将requirements _ grad设置为True,表明我们希望自动计算梯度,这将用于反向传播以优化权重。
#现在让我们定义权重:
w1=变量(torch.randn(5,4),requires_grad=True)
w2=变量(torch.randn(3,5),requires_grad=True)
#培训模式:
定义模型_向前(x):
返回F.sigmoid(w2 @ F.sigmoid(w1 @ x))
打印(w1)
打印(w1.data.shape)
打印(w1 . grad)#渐变渐变
输出是:
张量([[-0.8571,1.3199,-0.5086,0.7253),
[ 0.5370, 0.2830, -0.2245, -1.0154],
[-0.9083, -0.8636, 0.3927, 0.5870],
[ 0.2461, -0.0415, 1.9505, -0.1105],
[ 0.7191, -0.9653, 0.3059, -1.1343]])
火炬。大小([5,4])
没有人
1.4 PyTorch反向传播
我们有了输入和目标,模型权重,然后是训练模型的时候了。我们需要三个组件:
损失函数:描述我们模型的预测离目标有多远;
优化算法:用于更新权重;
反向传播步骤:
将torch.nn作为nn导入
将torch.optim作为optim导入
来自torch.autograd导入变量
导入torch.nn.functional as F
x=变量(torch.randn(4,1),requires_grad=False)
y=变量(torch.randn(3,1),requires_grad=False)
w1=变量(torch.randn(5,4),requires_grad=True)
w2=变量(torch.randn(3,5),requires_grad=True)
定义模型_向前(x):
返回F.sigmoid(w2@ F.sigmoid(w1@ x))
#损失函数:描述我们模型的预测离目标有多远;
判据=nn。MSELoss()
#优化算法:用于更新权重;
Optimizer=optim.sgd ([w1,w2],lr=0.001) #随机最速下降法(sgd)
#反向传播步骤:
对于范围(10)内的纪元:
损失=标准(model_forward(x),y)
Optimizer.zero_grad() #将以前的渐变清除为零。
失落。backward () #反向传播
Optimizer.step() #应用这些渐变
1.5 PyTorch CUDA接口
PyTorch的优点之一是它为张量和自动签名库提供了CUDA接口。有了CUDA GPU,不仅可以加速神经网络的训练和推理,还可以加速任何映射到PyTorch张量的工作量。
你可以打电话给火炬。CUDA.is_available()函数检查PyTorch中是否有可用的CUDA。
cuda _ GPU=torch . cuda . is _ available()
if (cuda_gpu):
打印(‘太好了,你有GPU了!’)
否则:
打印(‘生命短暂——考虑一下GPU吧!’)
如果你有GPU,之后。cuda(),用cuda加速代码就像调用一样简单。如果你打电话。张量上的cuda(),它会执行从CPU到CUDA GPU的数据迁移。如果你打电话。模型上的cuda(),它不仅会把所有的内存都搬到GPU上,还会把整个计算图映射到GPU上。
要将张量或模型复制回CPU,例如,要与NumPy交互,可以调用。cpu()。
cuda _ GPU=torch . cuda . is _ available()
if (cuda_gpu):
打印(‘太好了,你有GPU了!’)
否则:
打印(‘生命短暂——考虑一下GPU吧!’)
如果cuda_gpu:
x=x.cuda()
打印(类型(x.data))
否则:
x=x.cpu()
打印(类型(x.data))
让我们定义两个函数(训练函数和测试函数)来使用我们的模型执行训练和推理任务。代码也来自PyTorch官方教程,我们选择了训练/推理的所有必要步骤。
为了训练和测试网络,我们需要执行一系列可以直接映射到PyTorch代码的操作:
我们将模型转换为训练/推理模式;
我们通过在数据集上批量获取图像来迭代训练模型;
对于每一批图像,我们都要加载数据和标注,运行网络的正向步骤,获得模型输出;
我们定义损失函数,计算模型输出和每批目标之间的损失。
在训练时,我们将梯度初始化为零,并使用上一步定义的优化器和反向传播来计算所有与损失相关的分层梯度;
训练时,我们执行权重更新步骤。
进口火炬
将torch.nn作为nn导入
将torch.optim作为optim导入
来自torch.autograd导入变量
导入torch.nn.functional as F
x=变量(torch.randn(4,1),requires_grad=False)
y=变量(torch.randn(3,1),requires_grad=False)
w1=变量(torch.randn(5,4),requires_grad=True)
w2=变量(torch.randn(3,5),requires_grad=True)
定义模型_向前(x):
返回F.sigmoid(w2@ F.sigmoid(w1@ x))
#损失函数:描述我们模型的预测离目标有多远;
判据=nn。MSELoss()
#优化算法:用于更新权重;
Optimizer=optim.sgd ([w1,w2],lr=0.001) #随机最速下降法(sgd)
#反向传播步骤:
对于范围(10)内的纪元:
损失=标准(model_forward(x),y)
Optimizer.zero_grad() #将以前的渐变清除为零。
失落。backward () #反向传播
Optimizer.step() #应用这些渐变
cuda _ GPU=torch . cuda . is _ available()
if (cuda_gpu):
打印(‘太好了,你有GPU了!’)
否则:
打印(‘生命短暂——考虑一下GPU吧!’)
如果cuda_gpu:
x=x.cuda()
打印(类型(x.data))
否则:
x=x.cpu()
打印(类型(x.data))
定义训练(模型、时期、标准、优化器、数据加载器):
model.train()
对于batch_idx,枚举(data_loader)中的(data,target):
#enumerate()函数用于将遍历的数据对象(如列表、元组或字符串)组合成一个索引序列,
#同时列出数据和数据下标,一般用在for循环中。
如果cuda_gpu:
data,target=data.cuda(),target.cuda()
model.cuda()
数据,目标=变量(数据),变量(目标)
输出=模型(数据)
Optimizer.zero_grad() #将以前的渐变清除为零。
损失=标准(输出,目标)
Loss.backward() #应用这些渐变
optimizer.step()
if (batch_idx 1) % 400==0:
print( Train Epoch:{ }[{ }/{ }({: 0f } %)]\ t loss:{: 6f } 。格式(
epoch,(batch_idx 1) * len(data),len(data_loader.dataset),
100.* (batch_idx 1)/len(data_loader),loss.data[0])
定义测试(模型、时期、标准、数据加载器):
model.eval()#eval()函数用于执行字符串表达式并返回表达式的值。
#输出=模型(数据)
test_loss=0
正确=0
对于数据,数据加载器中的目标:
test_loss=标准(输出,目标)。数据[0]
pred=output.data.max(1)[1] #获取最大对数概率指标
正确=pred.eq(target.data).cpu().总和()
test_loss /=len(data_loader) #损失函数已经超过批量大小
ACC=correct/len(data _ loader。数据集)
打印( \n测试集:平均损耗:{:4f},准确度:{}/{} ({:0f}%)\n .格式(
test_loss,correct,len(data_loader.dataset),100 .* acc))
返回(acc,test_loss)
2.使用PyTorch进行数据分析
使用torch.nn库构建模型
使用火炬,亲笔签名库训练模型
将数据封装进torch.utils.data.Dataset库
使用NumPy接口连接你的模型、数据和你最喜欢的工具
在查看复杂模型之前,我们先来看个简单的:简单合成数据集上的线性回归,我们可以使用实例工具生成这样的合成数据集。
从sklearn.datasets导入make _回归
将海生的作为社交网站(Social Network Site的缩写)导入
进口熊猫作为螺纹中径
将matplotlib.pyplot作为血小板计数导入
sns.set()
x_train,y_train,W _ target=make _ regression(n _ samples=100,n_features=1,noise=10,coef=True)
df=pd .数据帧(data={ X :X _ train。ravel(), Y:y_train.ravel()})
sns.lmplot(x=X ,y=Y ,data=df,fit_reg=True)
plt.show()
x _火炬=火炬。浮动传感器(x_train)
y _火炬=火炬。浮动列车
y火炬=y火炬。查看(y _ torch。size()[0],1)
PyTorch的神经网络库中有大量有用的模块,其中一个就是线性模块。如名字所示,它对输入执行线性变换,即线性回归。
从sklearn.datasets导入make _回归
将海生的作为sns #seaborn导入能够快速的绘制图表
进口熊猫作为螺纹中径
将matplotlib.pyplot作为血小板计数导入
sns.set() #seaborn绘图命令
# x _火车为样本特征,y _火车为样本输出,W _目标为回归系数,共100个样本,每个样本一个特征
x_train,y_train,W _ target=make _ regression(n _ samples=100,n_features=1,noise=10,coef=True)
#make_regression:生成回归模型数据
# n _样本:生成样本数n _特征:样本特征数噪音:样本随机噪音系数:是否返回回归系数
df=pd .数据帧(data={ X :X _ train。ravel(), Y:y_train.ravel()})
#数据帧类似excel,是一种二维表,可以存放数值、字符串等
sns.lmplot(x=X ,y=Y ,data=df,fit_reg=True)# lmplot是用来绘制回归图的健康注册:是否显示拟合的直线
plt.show() #显示图像
x _火炬=火炬FloatTensor(x_train) #类型转换,将列表,numpy转化为张量
y _火炬=火炬。浮动列车
y火炬=y火炬。查看(y _ torch。size()[0],1) #view(n,m):排成n行m列
#PyTorch的神经网络库中有大量有用的模块,其中一个就是线性模块。
#如名字所示,它对输入执行线性变换,即线性回归。
类线性回归(火炬. nn .模块):
def __init__(self,input_size,output_size):
超级(线性回归,自我).__init__()#super():对继承自父类的属性进行初始化,用父类的初始化方法来初始化继承的属性
self.linear=torch.nn.Linear(输入大小,输出大小)
#torch.nn.Linear(输入特征,输出特征,偏差=真)对传入数据应用线性变换:y=Ax b
#参数:英寸_特性:每个输入样本的大小out _功能:每个输出样本的大小
向前定义(自身,x):
返回自线性(十)
型号=线性回归(1,1) #__init__中输入大小=1,输出大小=1
标准=火炬。nn。ms loss()#均方差损失函数
#构建一个【计算机】优化程序对象。这个对象能够保持当前参数状态并基于计算得到的梯度进行参数更新
优化器=火炬。optim。新币(型号。参数(),lr=0.1) #随机最速下降法(新加坡元)左后:学习率
对于范围(50)内的纪元:
数据,目标=变量(x_torch),变量(y _ torch)#变量变量
输出=模型(数据)
optimizer.zero_grad()#将先前的梯度清零
损失=标准(输出,目标)
loss.backward()#反向传播
optimizer.step()#应用这些梯度
预测=模型(变量(x _ torch))。数据。numpy()#拟合曲线
#现在我们可以打印出适合PyTorch的原始数据和线性回归。
Plt.plot (x _ train,y _ train, o ,label= originaldata) #原始数据点
Plt.plot (x _ train,predicted,label=拟合线)#拟合曲线
Plt.legend() #图片是默认格式。
Plt.show() #显示
为了转向更复杂的模型,我们将MNIST数据集下载到“datasets”文件夹中,并测试了PyTorch中可用的一些初始预处理。PyTorch有一个数据加载器和处理器,可以用于不同的数据集。数据集下载后,您可以随时使用它。您还可以将数据包加载到PyTorch tensor中,并创建自己的数据加载器类别。
批量是机器学习中的一个术语,指的是一次迭代中使用的训练样本的数量。批量大小可以是以下三种之一:
批处理模式:批处理大小等于整个数据集,所以迭代和历元值是一致的;
小批量模式:批量大小大于1,但小于整个数据集的大小。通常,数量可以是可被整个数据集整除的值。
随机模式:批量等于1。因此,梯度和神经网络参数应在每次采样后更新。
train _ loader=torch . utils . data . data loader(
数据集。MNIST(数据,训练=真,下载=真,转换=转换。撰写([
转变。ToTensor(),
转变。规格化((0.1307),(0.3081),)
])),
batch_size=batch_num_size,洗牌=真)
test _ loader=torch . utils . data . data loader(
Datasets.mnist (data ,train=false,transform=transforms . pose([# transforms . pose)将这两个步骤整合在一起。
转变。ToTensor(),
# tottensor()将形状为(H,W,C)的nump.ndarray或img转换为形状为(C,H,W)的张量,
#它将每个数值归一化为[0,1],其归一化方法很简单,除以255即可。
转变。规格化((0.1307),(0.3081),)
#Normalize():首先将输入规范化为(0,1),然后使用公式“(x-mean)/std”将每个元素分布到(-1,1)
])),
3.Pytorch中的LeNet卷积神经网络(CNN)
现在让我们从头开始创建第一个简单的神经网络。该网络执行图像分类并识别MNIST数据集中的手写数字。这是一个四层卷积神经网络(CNN),是分析MNIST数据集的常用架构。代码来自PyTorch官方教程,你可以在这里找到更多的例子(http://pytorch.org/tutorials/)。
我们将使用torch.nn库中的多个模块:
线性层:利用层的权重对输入张量进行线性变换;
Conv1和Conv2:卷积层,每层输出卷积核(小尺寸权张量)与相同尺寸输入区域的点积;
Relu:修改线性单位函数,逐元素使用激活函数Max (0,x);
池层:使用max运算对特定区域(通常为2x2像素)进行下采样;
Dropout2D:随机将输入张量的所有通道设置为零。当特征图具有强相关性时,dropout2D提高了特征图的独立性;
Soft:对N维输入张量应用log (Softmax (x))函数,以便输出介于0和1之间。
LeNet类(nn。模块):
def __init__(self):
超级(LeNet,self)。__init__()
Self.conv1=nn.conv2d (1,10,kernel _ size=5) #输入和输出通道数分别为1和10。
Self.conv2=nn.conv2d (10,20,kernel _ size=5) #输入和输出通道数分别为10和20。
self . con v2 _ drop=nn . drop out 2d()#随机选择输入通道,设置为0。
Self.fc1=nn。Linear(320,50) #输入向量大小和输出大小分别为320和50。
self.fc2=nn。线性(50,10)
向前定义(自身,x):
x=f . relu(f . max _ pool 2d(self . con v1(x),2)) #卷积-最大池层- relu
x=f . relu(f . max _ pool 2d(self . con v2 _ drop(self . con v2(x)),2)) #卷积-丢弃-最大池化- relu
X=x.view(-1,320) #view(n,m):排列成n行m列。
x=F.relu(self.fc1(x)) #fc - relu
x=F.dropout(x,训练=自我训练)#dropout
x=self.fc2(x)
return F.log_softmax(x,dim=1)
#创建LeNet类后,创建对象并将其移动到GPU:
model=LeNet()
Model.cuda()#如果没有GPU,用model.cpu()代替Model.cuda()
打印( MNIST网络模型:\n )
打印(模型)
输出:
MNIST _网络模型:
LeNet(
(conv1): Conv2d(1,10,kernel_size=(5,5),stride=(1,1))
(conv2): Conv2d(10,20,kernel_size=(5,5),stride=(1,1))
(conv2_drop): Dropout2d(p=0.5)
(fc1):线性(输入特征=320,输出特征=50,偏差=真)
(fc2):线性(输入特征=50,输出特征=10,偏差=真)
)
导入操作系统
将火炬. optim作为使最优化导入
从参考导入数据集、转换
来自火炬,亲笔签名导入变量
导入火炬. nn .功能为F
cuda _ GPU=torch。cuda。是否可用()
定义训练(模型、时期、标准、优化器、数据加载器):
model.train()
对于batch_idx,枚举(数据加载器)中的(数据,目标):
#enumerate()函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,
#同时列出数据和数据下标,一般用在为循环当中
如果cuda_gpu:
data,target=data.cuda(),target.cuda()
model.cuda()
数据,目标=变量(数据),变量(目标)
输出=模型(数据)
optimizer.zero_grad() #将先前的梯度清零
损失=标准(输出,目标)
loss.backward() #应用这些梯度
optimizer.step()
if (batch_idx 1) % 400==0:
print( Train Epoch:{ }[{ }/{ }({:0f } %)]\ t损失:{:6f } .格式(
epoch,(batch_idx 1) * len(data),len(data_loader.dataset),
100.* (batch_idx 1)/len(data_loader),loss.data[0])
定义测试(模型、时期、标准、数据加载器):
model.eval()#eval()函数用来执行一个字符串表达式,并返回表达式的值
test_loss=0
正确=0
对于数据,数据加载器中的目标:
如果cuda_gpu:
data,target=data.cuda(),target.cuda()
数据,目标=变量(数据),变量(目标)
输出=模型(数据)
test_loss=标准(输出,目标)。item() #items()将字典中的每个项分别做为元组,添加到一个列表中形成一个新的列表容器
pred=output.data.max(1)[1] #获取最大对数概率指标
正确=pred.eq(target.data).cpu().总和()
test_loss /=len(data_loader) #损失函数已经超过批量大小
ACC=correct/len(data _ loader。数据集)
打印( \n测试集:平均损耗:{:4f},准确度:{}/{} ({:0f}%)\n .格式(
test_loss,correct,len(data_loader.dataset),100 .* acc))
返回(acc,test_loss)
batch_num_size=64
#数据加载器数据加载器,结合了数据集和取样器,并且可以提供多个线程处理数据集
#在训练模型时使用到此函数,用来把训练数据分成多个小组,此函数每次抛出一组数据
#直至把所有的数据都抛出。就是做一个数据的初始化
#此函数的参数:
#数据集:包含所有数据的数据集
#批处理大小:每一小组所包含数据的数量
#随机播放:是否打乱数据位置,当为图雷时打乱数据,全部抛出数据后再次数据加载器时重新打乱
火车_装载机=火炬。utils。数据。数据加载器(
数据集MNIST(’数据,训练=真,下载=真,转换=转换。撰写([
转变ToTensor(),
转变。规格化((0.1307),(0.3081),)
])),
batch_size=batch_num_size洗牌=真)
test _ loader=火炬。utils。数据。数据加载器(
数据集MNIST(’数据,训练=假,转换=转换。撰写([#转换。构成把两个步骤整合到一起
转变ToTensor(),
#ToTensor()将形状为(高、低、中)的nump.ndarray或图片转为形状为(C、H、W)的张量,
#其将每一个数值归一化到[0,1],其归一化方法比较简单,直接除以255即可。
转变。规格化((0.1307),(0.3081),)
#Normalize():先将输入归一化到(0,1),再使用公式“(x-均值)/标准差",将每个元素分布到(-1,1)
])),
batch_size=batch_num_size洗牌=真)
LeNet类(nn .模块):
def __init__(self):
超级(莱内特,自我).__init__()
self.conv1=nn .Conv2d(1,10,kernel_size=5) #输入和输出通道数分别为一和10
self.conv2=nn .Conv2d(10,20,kernel_size=5) #输入和输出通道数分别为10和20
self.conv2_drop=nn .Dropout2d() #随机选择输入的信道,将其设为0
self.fc1=nn .线性(320,50) #输入的向量大小和输出的大小分别为320和50
self.fc2=nn .线性(50,10)
向前定义(自身,x):
x=f . relu(f . max _ pool 2d(self。con v1(x),2)) #卷积-最大池化层-雷鲁
x=f . relu(f . max _ pool 2d(self。con v2 _ drop(self。con v2(x)),2)) #卷积辍学最大池化-雷鲁
x=x.view(-1,320) #view(n,m):排成n行m列
x=F.relu(self.fc1(x)) #fc - relu
x=F.dropout(x,训练=自我训练)#辍学
x=self.fc2(x)
return F.log_softmax(x,dim=1)
#创建LeNet类后,创建对象并移至GPU:
model=LeNet()
如果cuda_gpu:
model.cuda()#没有国家政治保卫局。参见国家政治保卫局则用model.cpu()代替model.cuda()
打印(‘MNIST网络模型:\n )
打印(模型)
#要训练该模型,我们需要使用带动量的新币,学习率为0.01,动量为0.5。
判据=nn .交叉入口型()
optimizer=optim .新加坡元(模型参数(),lr=0.005,动量=0.9)
#仅仅需要5个纪元(一个世意味着你使用整个训练数据集来更新训练模型的权重)
#我们就可以训练出一个相当准确的LeNet模型。这段代码检查可以确定文件中是否已有预训练好的模型
#有则加载;无则训练一个并保存至磁盘
纪元=5
如果(OS。路径。是文件(预训/MNIST _ net。T7’):
打印("装载模型")
模型。load _ state _ dict(火炬。加载(预训练/MNIST _ net。T7 ,map_location=lambda storage,loc: storage))
acc,loss=test(模型,1,标准,测试加载器)
否则:
打印("培训模型")
对于范围内的时段(1,时段1):
训练(模型、时期、标准、优化器、训练加载器)
acc,loss=test(模型,1,标准,测试加载器)
torch.save(model.state_dict(), pretrained/MNIST_net.t7 )
若无预训练模型,输出:
培训模式
测试集:平均损失:0.1348,准确度:9578/10000 (0%)
测试集:平均损失:0.0917,准确度:9703/10000 (0%)
测试集:平均损失:0.0746,准确度:9753/10000 (0%)
测试集:平均损失:0.0659,准确度:9795/10000 (0%)
测试集:平均损失:0.0553,准确度:9828/10000 (0%)
现在我们来看下模型。首先,打印出该模型的信息。打印函数显示所有层(如拒绝传统社会的人被实现为一个单独的层)及其名称和参数。同样有一个迭代器在模型中所有已命名模块之间运行。当你具备一个包含多个「内部」模型的复杂深度神经网络时,这有所帮助。在所有已命名模块之间的迭代允许我们创建模型解析器,可读取模型参数、创建与该网络类似的模块。
打印(内部模型:)
对于idx,m in enumerate(型号。命名模块()):
打印(idx,-,m)
打印(-)
输出:
内部模型:
0 -( ,LeNet(
(conv1): Conv2d(1,10,kernel_size=(5,5),stride=(1,1))
(conv2): Conv2d(10,20,kernel_size=(5,5),stride=(1,1))
(conv2_drop): Dropout2d(p=0.5)
(fc1):线性(输入特征=320,输出特征=50,偏差=真)
(fc2):线性(输入特征=50,输出特征=10,偏差=真)
))
-
1 - (conv1 ,Conv2d(1,10,kernel_size=(5,5),stride=(1,1)))
-
2 - (conv2 ,Conv2d(10,20,kernel_size=(5,5),stride=(1,1)))
-
3 - (conv2_drop ,Dropout2d(p=0.5))
-
4 - (fc1 ,线性(输入特征=320,输出特征=50,偏差=真))
-
5 - (fc2 ,线性(输入特征=50,输出特征=10,偏差=真))
-
你可以使用cpu()方法将张量移至中央处理器(或确保它在那里)。或者,当国家政治保卫局。参见国家政治保卫局可用时(火炬. cuda .可用),使用cuda()方法将张量移至图形处理器。你可以看到张量是否在国家政治保卫局。参见国家政治保卫局上,其类型为火炬。cuda。飞人。如果张量在中央处理器上,则其类型为火炬。浮动服务员。
t=torch.rand(2,4,3,5)
print (type(t.cpu().数据))
如果torch.cuda.is_available():
打印(“Cuda可用")
打印(type(t.cuda().数据))
否则:
打印(“Cuda不可用")
输出:
班级火炬。张量
库达可用
班级火炬。张量
如果张量在中央处理器上,我们可以将其转换成NumPy数组,其共享同样的内存位置,改变其中一个就会改变另一个。
进口火炬
t=torch.rand(2,4,3,5)
如果torch.cuda.is_available():
尝试:
print(t.data.numpy())
除了RuntimeError作为e:
你不能将国家政治保卫局。参见国家政治保卫局张量转换为数组数组,你必须将你的权重tendor复制到中央处理器然后得到数组数组
print(type(t.cpu().data.numpy()))
打印(t . CPU()数据。numpy().形状)
打印(t . CPU()数据。numpy()).
现在我们了解了如何将张量转换成NumPy数组,我们可以利用该知识使用绘制精美的图表进行可视化!我们来打印出个卷积层的卷积滤波器。
导入操作系统
将火炬. optim作为使最优化导入
从参考导入数据集、转换
来自火炬,亲笔签名导入变量
导入火炬. nn .功能为F
cuda _ GPU=torch。cuda。是否可用()
定义训练(模型、时期、标准、优化器、数据加载器):
model.train()
对于batch_idx,枚举(数据加载器)中的(数据,目标):
#enumerate()函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,
#同时列出数据和数据下标,一般用在为循环当中
如果cuda_gpu:
data,target=data.cuda(),target.cuda()
model.cuda()
数据,目标=变量(数据),变量(目标)
输出=模型(数据)
optimizer.zero_grad() #将先前的梯度清零
损失=标准(输出,目标)
loss.backward() #应用这些梯度
optimizer.step()
if (batch_idx 1) % 400==0:
print( Train Epoch:{ }[{ }/{ }({:0f } %)]\ t损失:{:6f } .格式(
epoch,(batch_idx 1) * len(data),len(data_loader.dataset),
100.* (batch_idx 1)/len(data_loader),loss.data[0])
定义测试(模型、时期、标准、数据加载器):
model.eval()#eval()函数用来执行一个字符串表达式,并返回表达式的值
test_loss=0
正确=0
对于数据,数据加载器中的目标:
如果cuda_gpu:
data,target=data.cuda(),target.cuda()
数据,目标=变量(数据),变量(目标)
输出=模型(数据)
test_loss=标准(输出,目标)。item() #items()将字典中的每个项分别做为元组,添加到一个列表中形成一个新的列表容器
pred=output.data.max(1)[1] #获取最大对数概率指标
正确=pred.eq(target.data).cpu().总和()
test_loss /=len(data_loader) #损失函数已经超过批量大小
ACC=correct/len(data _ loader。数据集)
打印( \n测试集:平均损耗:{:4f},准确度:{}/{} ({:0f}%)\n .格式(
test_loss,correct,len(data_loader.dataset),100 .* acc))
返回(acc,test_loss)
batch_num_size=64
#数据加载器数据加载器,结合了数据集和取样器,并且可以提供多个线程处理数据集
#在训练模型时使用到此函数,用来把训练数据分成多个小组,此函数每次抛出一组数据
#直至把所有的数据都抛出。就是做一个数据的初始化
#此函数的参数:
#数据集:包含所有数据的数据集
#批处理大小:每一小组所包含数据的数量
#随机播放:是否打乱数据位置,当为图雷时打乱数据,全部抛出数据后再次数据加载器时重新打乱
火车_装载机=火炬。utils。数据。数据加载器(
数据集MNIST(’数据,训练=真,下载=真,转换=tr
ansforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=batch_num_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(
datasets.MNIST("data",train=False, transform=transforms.Compose([ #transforms.Compose把两个步骤整合到一起
transforms.ToTensor(),
#ToTensor()将shape为(H, W, C)的nump.ndarray或img转为shape为(C, H, W)的tensor,
#其将每一个数值归一化到[0,1],其归一化方法比较简单,直接除以255即可。
transforms.Normalize((0.1307,), (0.3081,))
#Normalize():先将输入归一化到(0,1),再使用公式”(x-mean)/std”,将每个元素分布到(-1,1)
])),
batch_size=batch_num_size, shuffle=True)
class LeNet(nn.Module):
def __init__(self):
super(LeNet,self).__init__()
self.conv1 = nn.Conv2d(1,10,kernel_size=5) #输入和输出通道数分别为1和10
self.conv2 = nn.Conv2d(10,20,kernel_size=5) #输入和输出通道数分别为10和20
self.conv2_drop = nn.Dropout2d() #随机选择输入的信道,将其设为0
self.fc1 = nn.Linear(320,50) #输入的向量大小和输出的大小分别为320和50
self.fc2 = nn.Linear(50,10)
def forward(self,x):
x = F.relu(F.max_pool2d(self.conv1(x),2)) #卷积--最大池化层--relu
x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)),2)) #卷积--dropout--最大池化--relu
x = x.view(-1, 320) #view(n,m):排成n行m列
x = F.relu(self.fc1(x)) #fc--relu
x = F.dropout(x, training=self.training) #dropout
x = self.fc2(x)
return F.log_softmax(x, dim=1)
#创建 LeNet 类后,创建对象并移至 GPU:
model = LeNet()
if cuda_gpu:
model.cuda()#没有GPU则用model.cpu()代替model.cuda()
print (MNIST_net model:\n)
print (model)
#要训练该模型,我们需要使用带动量的 SGD,学习率为 0.01,momentum 为 0.5。
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(model.parameters(),lr = 0.005, momentum = 0.9)
#仅仅需要 5 个 epoch(一个 epoch 意味着你使用整个训练数据集来更新训练模型的权重)
#我们就可以训练出一个相当准确的 LeNet 模型。这段代码检查可以确定文件中是否已有预训练好的模型
#有则加载;无则训练一个并保存至磁盘
epochs = 5
if (os.path.isfile(pretrained/MNIST_net.t7)):
print (Loading model)
model.load_state_dict(torch.load(pretrained/MNIST_net.t7, map_location=lambda storage, loc: storage))
acc, loss = test(model, 1, criterion, test_loader)
else:
print (Training model)
for epoch in range(1, epochs + 1):
train(model, epoch, criterion, optimizer, train_loader)
acc, loss = test(model, 1, criterion, test_loader)
torch.save(model.state_dict(), MNIST_net.t7)
t = torch.rand(2, 4, 3, 5)
if torch.cuda.is_available():
try:
print(t.data.numpy())
except RuntimeError as e:
"你不能将GPU张量转换为numpy数组,你必须将你的权重tendor复制到cpu然后得到numpy数组"
print(type(t.cpu().data.numpy()))
print(t.cpu().data.numpy().shape)
print(t.cpu().data.numpy())
data = model.conv1.weight.cpu().data.numpy()
print (data.shape)
print (data[:, 0].shape)
kernel_num = data.shape[0]
fig, axes = plt.subplots(ncols=kernel_num, figsize=(2*kernel_num, 2))
for col in range(kernel_num):
axes[col].imshow(data[col, 0, :, :], cmap=plt.cm.gray)
plt.show()
学习更多编程知识,请关注我的公众号:
代码的路
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。