在阅读这篇文章之前,请参考如下文章,有助于理解哦。
https
目录
张量操作
标量
如:1 是0维度
向量
如 (1,2,3,4,5),是1维度
张量
如[[1,2,3],[4.5.6]],是二维张量
读取图片数据作为张量
import os
data_dir = '../data/p1ch4/image-cats/'
filenames = [name for name in os.listdir(data_dir)
if os.path.splitext(name)[-1] == '.png']
for i, filename in enumerate(filenames):
img_arr = imageio.imread(os.path.join(data_dir, filename))
img_t = torch.from_numpy(img_arr)
img_t = img_t.permute(2, 0, 1)
img_t = img_t[:3]#Here we keep only the first three channels.Sometimes images also have an alpha channel indicating transparency, but our network only wants RGB input,[:3]是取得前三个值,[3:]是取得前三个以后的值
batch[i] = img_t
创建张量
x=torch.Tensor([1,2,3,4])#使用torch.Tensor创建的张量过大,使用torch.rand创建的张量符合正态分布,torch.rand_like(x,dtype=torch.long),创建#的形状是和X一样的
print(x.size()) #4
y=torch.unsqueeze(x,0) #对x的0维度进行扩充
print(y.size())#[1,4]
x=torch.Tensor([1,2,3,4])
z=torch.unsqueeze((x,1))
print(z.size(1))#[4,1]
x=torch.Tensor([[1,2,3,4]])
# 对x进行压缩
y=torch.squeeze(x,0)
print(y)#[1,2,3,4]
x=torch.rand(3,2)
y=torch.rand(3,2)
z_cat=torch.cat([x,y],0)#在行上进行拼接,torch.size:[6,2]
z_stack=torch.stack([x,y],0)#在行上进行堆叠,torch.size:[[3,2,2]]
张量与数组之间的转换
torch.from_numpy()# 将数组转换成张量,括号里面是数组
torch.numpy()#将张量转换成数组,其中tensor和numpy指向的是同一地址,一个值改变另外一个值也会改变
获取维度
x.size(0)# 获取x第0维度的值
x.shape()
张量运算
torch.mm(x,y)#将x与y相乘
数据正则化
1、将数据的范围编程(0,1)和(-1,1)之间的浮点数
batch = batch.float()
batch /= 255.0
2、计算平均值和标准偏差,
n_channels = batch.shape[1]
for c in range(n_channels):
mean = torch.mean(batch[:, c])
std = torch.std(batch[:, c])
batch[:, c] = (batch[:, c] - mean) / std
这里,我们只规范化了一批图像,因为我们没有还知道如何操作整个数据集
解决欠拟合
增加网络复杂度或者在模型中增加特征
解决过拟合
1、获取和使用更多的数据(数据增强)
2、正则化:就是将所有的W加起来取均值,使得参数更加平均,不会使得某些参数过强,出现过拟合
3、dropout:神经元之间相互连接,随机删除神经元,在test,valid是全连接
4、Earlystopping :每隔一段时间就喂验证数据给模型,假设三次正确率都不变或下降就停止训练模型
SGD优化
在pytorch使用tensorbord
pip install tensorboard
pip install tensorboardX
tensorboard --logdir logs
神经网络构建
定义一个NN
1、继承nn.Module()
2、实现forward()方法
import torch
import torch.nn as nn#包含NN设计模块接口,可用来定义和运行NN
import torch.nn.functional as F#包含NN使用常见函数,如Relu,pool,dropout这些没有学习参数的函数
import torchvision.models as model
from torchvision import datasets,transforms
class Net(nn.Module):
def __init__(self):
super(Net,self).__init__()
#定义以后需要用到的层
self.conv1=nn.Conv2d(1,6,3)#1为输入通道,6为输出通道,3为卷积核的大小
# 线性层
self.fc1=nn.Linear(1350,10)# 输入1350个特征,输出10个特征
self.rnn1=nn.LSTM
# 正向传播
def forward(self,x):
print(x.size())#(1,1,32,32),batch,channel,height,width
x=self.conv1(x)
x=F.relu(x)
print(x.size())#(1,6,30,30)
x=F.max_pool2d(x,(2,2))
x=F.relu(x)
print(x.size())#(1,6,15,15)
x=x.view(x.size()[0],-1)#-1是取第一个维度的值之后,第二个维度的值是后面三个维度的值相乘,即6*15*15=1350
print(x.size())#1350
x=self.fc1(x)
return x
加载数据集
# 加载训练数据集
train_loader=torch.utils.data.Dataloader(
datasets.MNIST('data',train=True,download=True),
transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize()]),# 输入值定在一个区间内,会增加训练的稳定性
batchsize=1,suffle=True#是否随数据进行打乱
)
# 加载测试数据集
test_loader=torch.utils.data.Dataloader(
datasets.MNIST('data',train=False,download=True),
transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize()]),# 输入值定在一个区间内,会增加训练的稳定性
batchsize=1,suffle=False#是否随数据进行打乱
)
调用模型
device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
net=Net()# 模型初始化
net=net.to(device)
print(net)# 打印模型的拓扑结构
#打印模型可学习的参数
for name,parameters in net.named_parameters():
print(name,':',parameters.size())
print(net.conv1.weight)#(6,1,3,3)
print(net.conv1.bias)#(6)
print(net.fc1.weight)#(10,1350)
print(net.fc1.bias)#(10)
# 调用模型
input=torch.randn(1,1,32,32)#对应forward的输入
out=net(input)# input从net中自动去找forward方法
print(out.size())#(1,10),1是batch,10是输出特征值
# 进行反向传播
#损失函数去定义梯度下降的路线
y=torch.arrange(0,10).view(1,10).float()
citerion=nn.MSELoss();
loss=citerion(out,y);
print(loss,iter());
# 优化器
import torch.optim
optimizer=torch.optim.SGD(net.parameters(),lr=0.01)
optimizer=net.zero_grad();
loss.backward()
optimizer.step()
将数据集送入模型
# 对模型训练
def train(model,device,train_loader,optimizer,epoch):
model.train()# 训练模式开启,开启dropout如果有dropout操作的化
for batch_idx,(data,target) in enumerate(train_loader):
data,target=data.to(device),target.to(device)
optimizer = net.zero_grad();
output=net(data)
loss=F.nll_loss(output.target)
loss.backward()
optimizer.step()
if((batch_idx+1)%30==0):
print()
# 对模型测试
def test(model,device,test_loader,optimizer,epoch):
model.eval()# 训练模式开启,开启dropout如果有dropout操作的化
for batch_idx,(data,target) in enumerate(test_loader):
data,target=data.to(device),target.to(device)
optimizer = net.zero_grad();
output=net(data)
loss=F.nll_loss(output.target)
loss.backward()
optimizer.step()
pred=output.max(1,keepdim=True)[1]#找到概率最大值的下标
if((batch_idx+1)%30==0):
print()
调用已经训练好的模型
# 怎么调用torchvision已经训练好的模型
net=model.resnet18(pretrained=True)#将参数也拿过来
# 冻结模型参数
for param in net.parameters():
param.requires_grad=False