import os.path
from torch.utils.data import Dataset
root_dir = 'dataset/train' # 图片的间接根目录
label_dir = 'ants' # 图片的直接根目录
# Mydata类需要重写
class Mydata(Dataset):
def __init__(self,root_dir, label_dir):
self.root_dir= root_dir
self.label_dir=label_dir
self.path=os.path.join(self.root_dir,self.label_dir)#获取图片所在文件夹的路径
self.img_path=os.listdir(self.path) #用列表储存每一张图片的地址
def __getitem__(self, idx): #获取照片
img_name=self.img_path[idx] #读取照片名称信息
img_item_path=os.path.join(self.root_dir,self.label_dir,img_name)#合成路径,读取图片的具体相对路径和信息
label=self.label_dir
return img,label
def __len__(self):
return len(self.img_path)#获取列表长度,就是图片的数量
root_dir='dataset/train'
ants_label_dir='ants'
ants_dataset=Mydata(root_dir,ants_label_dir) #创建类
#相同的对象可以相加,构成新的数据集
1.绘制数据的图像
from torch.utils.tensorboard import SummaryWriter
writer=SummaryWriter('logs')
#writer.add_image()
for i in range(100): #循环画图,构建图像
writer.add_scalar('y=x',i,i) # 解析式,y内容,x内容
writer.close()
2.add_image的使用:
import numpy as np
from torch.utils.tensorboard import SummaryWriter
writer=SummaryWriter('logs')
image_path='图片路径'
img_PIL=Image.open(image_path) #pil形似打开图片,也可以opencv打开
img_array=np.array(img_PIL) #图片的矩阵化
print(type(img_array))
print(img_array.shape) #
writer.add_image('train',img_array,2,dataformats='HWC')
for i in range(100): #循环画图,构建图像
writer.add_scalar('y=x',i,i) # 解析式,y内容,x内容
writer.close()
transform的结构:指的是transform.py,就像一个大工具箱:
1.可以把普通的数据转化为 totensor数据类型,可以处理图片信息
transforms的用法:
tensor数据类型:
通过transform.ToTensor去解决俩个问题:
1.transform的使用方法:
2.Tensor数据类型的独特性?:张量形式。
为什么需要tensor的数据类型?
from torchvision import transforms
img=Image.open('图片路径')
writer=SummaryWriter('logs')
tensor1=transforms.ToTensor() #初始化totensor类
tensor_img=tensor1(img) #在类里面图片信息,将会返回tensor类型的图片数据
print(tensor_img) #输出tensor的数据类型,图片的张量表达式
writer.add_image('tensor_img',tensor_img) #添加图片,图片名称,图片内容
writer.close()
常见的transform模板:
输入; PIL Image.open()
输出: tensor ToTensor()
import torchvision
from torch.utils.tensorboard import SummaryWriter
dataset_transform=torchvision.transforms.Compose([torchvision.transforms.ToTensor()]) #图片·集体转化为张量形式
train_set=torchvision.datasets.MNIST(root='文件名',train=True,transform=dataset_transform,download=True)
test_set=torchvision.datasets.MNIST(root='',train=False,transform=dataset_transform,download=True)
# ROOT是储存的路径,train写True表示是训练集,Train写False是测试集,download表示是否下载)
writer=SummaryWriter('pa')
for i in range(10):
img,target=test_set[i]
writer.add_image('test',img,i)
加载数据集:
import torchvision
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
test_data=torchvision.datasets.MNIST('.da',train=False,transform=torchvision.transforms.ToTensor())#利用trainsforms把数据集的图片转化为totensor的张量形式,才能够把数据集喂入神经网络进行训练
test_loader=DataLoader(dataset=test_data,batch_size=64,shuffle=True,num_workers=0,drop_last=True) #drop_last写true是代表舍去不足64张照片,batch_size表示每一轮的读取照片数量是64,shuffle表示是否打乱数据随机选取,
#测试数据集致中和的第一张图片,返回照片以及对应的标签:
img,target=test_data[0]
print(img.shape)
print(target)
write=SummaryWriter('da')
for epoch in range(2):
step=0
for data in test_loader:
imgs,targets=data
write.add_image('epoch.{}'.format(epoch),imgs,step)
step+=1
write.close()
#在下一轮的神经网络的训练中,我们可以直接把imgs放入神经网络进行训练,imgs的形式必须是Totensor的张量形式!
前向传播对数据的处理:
import torch
import torch.nn as nn
import torch.nn.functional as f
class Mode(nn.Module): #继承神经网络
def __init__(self):
super().__init__() #固定代码格式
def forward(self,input):
output=input+1 #前向传播的处理方式
return output
niu=Mode()
x=torch.tensor(1.0) #传入神经网络的数值必须是张量
output=niu(x)
print(output)
import torchvision
import torch.nn as nn
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter
test_data=torchvision.datasets.MNIST('.da',train=False,transform=torchvision.transforms.ToTensor())
test_loader=DataLoader(dataset=test_data,batch_size=64,shuffle=True,num_workers=0,drop_last=True)
class niu(nn.Module):
def __init__(self):
super().__init__()
self.conv1=nn.Conv2d(in_channels=3,out_channels=6,kernel_size=3,stride=1,padding=0)
def forward(self,input):
x=self.conv1(input)#input的内容是rgb彩色图片(tensor形式)
return x
for data in test_loader:
imgs,label=data
output=niu(imgs) #类的实例化的同时,传入参数执行类的作用,并将作用结果返回给output储存
print(imgs.shape) #打印原图片的尺寸
print(output.shape)#打印卷积之后的尺寸
import torch
from torch import nn
from torch.nn import MaxPool2d #导入最大池化层
input=torch.tensor([[1,2,3,4,5],
[2,3,5,6,7],
[3,5,3,2,2],
[2,2,4,5,6]
[1,2,5,6,7]],dtype=torch.float32)#设置tensor数据,浮点型,整形否则会报错,
input=torch.reshape(input,(-1,1,5,5)) #input表示reshape的对象,-1表示自适应输入batch_size(一般都写-1),1表示通道数目,5,5表示张量的高度和宽度,,最大池化对尺寸的要求是四通道: {batch_size,通道数目,张量高度,张量宽度}
class niu(nn.Module):
def __init__(self):
super(niu, self).__init__()
self.max=nn.MaxPool2d(kernel_size=3,stride=1,padding=0,ceil_mode=True) #ceil写True的话,会保留更多的最大值,最大池化层的卷积核选为3*3
def forward(self,input):
output=self.max(input)
return output
ni=niu(input)
#可以试试dataloader可视化图像加载的过程
print(niu)
import torch
from torch import nn
from torch.nn import MaxPool2d #导入最大池化层
input=torch.tensor([[1,2,3,4,5],
[2,3,5,6,7],
[3,5,3,2,2],
[2,2,4,5,6]
[1,2,5,6,7]],dtype=torch.float32)#设置tensor数据,浮点型,整形否则会报错,
input=torch.reshape(input,(-1,1,5,5)) #input表示reshape的对象,-1表示自适应输入batch_size(一般都写-1),1表示通道数目,5,5表示张量的高度和宽度,,最大池化对尺寸的要求是四通道: {batch_size,通道数目,张量高度,张量宽度}
class niu(nn.Module):
def __init__(self):
super(niu, self).__init__()
self.relu=nn.ReLU()
def forward(self,input):
output=self.relu(input)
return output
ni=niu(input)
print(niu)
import torch
import torchvision
from torch.utils.data import DataLoader
from torch import nn
dataset=torchvision.datasets.MNIST('dd',train=False,transform=torchvision.transforms.ToTensor)
dataloader=Dataloader(dataset,batch_size=64)
class niu(nn.model):
def __init__(self):
super(niu, self).__init__()
self.liner=nn.linear(input,10) #将大量的数据缩减为10的张量线性结构
def forwar(self,input):
output=self.liner(input,10)
return output
for data in dataloader:
imgs,target=data
#output=torch.reshape(imgs,(1,1,1,-1 ))#-1自动计算
output=torch.flatten(imgs) #线性层展平数据,变成一行
output=niu(output)
from torch import nn
from torch.nn import Conv2d,Flatten,MaxPool2d,Linear,Sequential #导入线形层,池化层,卷积层,
class li(nn.Module):
def __init__(self):
super(li, self).__init__()
self.conv1=Conv2d(in_channels=3,out_channels=32,kernel_size=5,padding=2) #bgr图片·是三通道
self.maxpool1=MaxPool2d(2)#卷积核的大小是2
self.conv2=Conv2d(32,32,5,padding=2)
self.maxpool2=MaxPool2d(2)
self.conv3=Conv2d(32,64,5,padding=2)
self.maxpool3=MaxPool2d(2)
self.fla=Flatten()
self.linear1=Linear(1024,64) #把1024个元素的数据转化为64个数的元素
self.linear2=Linear(64,10) #全连接层结束
def forward(self,x): #传入参数x,并且卷积计算,实现卷积神经网络的基本流程
x=self.conv1(x)
x=self.maxpool1(x)
x=self.conv2(x)
x=self.maxpool2
x=self.conv3(x)
x=self.maxpool3
x=self.fla(x)
x=self.linear1(x)
x=self.linear2(x)
return x
from torch import nn
import torch
from torch.nn import Conv2d,Flatten,MaxPool2d,Linear,Sequential #导入线形层,池化层,卷积层,
class li(nn.Module):
def __init__(self):
super(li, self).__init__()
self.model=Sequential(
Conv2d(in_channels=3,out_channels=32,kernel_size=5,padding=2), #bgr图片·是三通道
MaxPool2d(2),#卷积核的大小是2
Conv2d(32,32,5,padding=2),
MaxPool2d(2),
Conv2d(32,64,5,padding=2),
MaxPool2d(2),
Flatten(), #展平数据
Linear(1024,64), #把1024个元素的数据转化为64个数的元素
Linear(64,10) #全连接层结束,最后输出10个数据量
) #使用Sequential函数仅需要写出卷积运算过程的流程函数即可,不需要赋值变量
def forward(self,x): #传入参数x,并且卷积计算,实现卷积神经网络的基本流程
x=self.model(x) #一行代码即可实现卷积的所有功能
return x
ll=li() #实例化
input=torch.ones(batch_size=64,input_channel=3,32,32) #创建64张3通道的图片,尺寸大小32*32
output=ll(input)
print(out.shape)
损失函数:“误差函数”
基本的损失函数使用代码例程
import torch
from torch.nn import L1Loss
input=torch.tensor([1,2,3],dtype=torch.float) #创建数据类型,必须是浮点数才可以,否则会报错
target=torch.tensor([1,2,5],dtype=torch.float)
input=torch.reshape(input,(1,1,1,3))#修改数据类型是 batch_size=1 channel=1 1*3 的张量数据
output=torch.reshape(target,(1,1,1,3)) #创建数据类型是 batch_size=1 channel=1 1*3 的张量数据
loss=L1Loss() #类的实例化
result=loss(input,output) #计算损失误差
print(result)
此损失函数应用于分类场景之中,在训练分类问题的时候,可以使用交叉熵损失函数
计算公式过于复杂,不必深究
loss=nn.CrossEntropyLoss()
loss_data=loss(input,target) #计算损失函数
loss.backward() #一行代码即可解决反向传播
# 设置损失函数
#设置反向传播
#设置学习速度等参数
#设置优化器,梯度清零,目的为了防止之前训练的梯度值影响下一轮训练的效果,因为每一轮的训练最合适的梯度都不同,因此有必要在每一轮训练前进行梯度清零
loss=nn.CrossEntroyLoss()
li=juan() #卷积网络实例化
optim=torch.optim.SGD(li.parameters(),lr=0.01) #设置优化器,实例化优化器的类,第一个参数是卷积神经网络类的实例化 名称.parameters(),第二个参数是学习速率
for data in data_loader:
imgs,target=data
optim.zero_grad() #先把之前的训练梯度值清零,避免影响后面
output=li(imgs) #训练网络
loss=loss(output,target) #计算损失值
loss.backward()#方向传播,自动优化,求解出每一个节点的梯度(此前梯度为0)
optim.step() #使用优化器,根据梯度值对模型的参数调优更新
model = torch.load('模型名称') #加载模型
#模型的保存方式有两种,下面是方式一
torch.save(卷积网络名称,'保存的名称.pth') #保存了网络的模型结构和参数。
#但是此方式的1加载,需要把卷积网络的代码也一起写上。
#以下是方式二:
torch.save(卷积网络名称.state_dict(),'保存的名称') #相当于把网络格式转化为字典型,把网络的要素及对应参数转化为一种字典的格式,官方推荐方式,方式二的模型加载不需要引入卷积网络代码
#方式二加载出来的东西比较奇怪,可以转化为原来的模型格式:代码如下L
网络名称.load_state_dict(torch.load('模型名称'))