今天分享的学习内容主要是完整构建神经网络,
包括:训练、测试、损失函数呀,计算精度呀,等等~
用到的框架就是torch
在这里我也是对自己做一个学习记录,如果不符合大家的口味,大家划走就可以啦
可能没有什么文字或者原理上的讲解,基本上都是代码,但是我还是想说,如果基础不是很好,认认真真敲一遍,会有不一样的感受!
正片开始:
目录
内容一:神经网络优化器
内容二:完整模型训练
内容三:GPU训练
内容四:测试模型
# 损失函数反向传播
# 反向传播通过梯度来更新参数,使得loss损失最小
import torch
import torchvision
from torch import nn
from torch.nn import Linear, Conv2d, MaxPool2d, Flatten, Sequential
from torch.utils.data import DataLoaderdataset = torchvision.datasets.CIFAR10("dataset", train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size = 64, drop_last=True)class net(nn.Module):def __init__(self):super(net, self).__init__()self.model = Sequential(Conv2d(in_channels = 3, out_channels = 32, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Conv2d(in_channels = 32, out_channels = 32, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Conv2d(in_channels = 32, out_channels = 64, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Flatten(),Linear(1024, 64),Linear(64, 10))def forward(self, x):x = self.model(x)return xmodel = net()
print(model)
loss = nn.CrossEntropyLoss()
epoch = 0for data in dataloader:imgs, targets = dataoutput = model(imgs) result = loss(output, targets) # 计算实际输出与目标输出的差距result.backward() # 计算出来的 loss 值有 backward 方法属性,反向传播来计算每个节点的更新的参数。这里查看网络的属性 grad 梯度属性刚开始没有,反向传播计算出来后才有,后面优化器会利用梯度优化网络参数。 # print(result)# print(epoch)epoch = epoch + 1
内容一:神经网络优化器
import torch
import torchvision
from torch import nn
from torch.nn import Linear, Conv2d, MaxPool2d, Flatten, Sequential
from torch.utils.data import DataLoaderdataset = torchvision.datasets.CIFAR10("dataset", train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size = 64, drop_last=True)class net(nn.Module):def __init__(self):super(net, self).__init__()self.model = Sequential(Conv2d(in_channels = 3, out_channels = 32, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Conv2d(in_channels = 32, out_channels = 32, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Conv2d(in_channels = 32, out_channels = 64, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Flatten(),Linear(1024, 64),Linear(64, 10))def forward(self, x):x = self.model(x)return xmodel = net()
print(model)
loss = nn.CrossEntropyLoss()
optim = torch.optim.SGD(model.parameters(), lr = 0.01)for epoch in range(5):running_loss = 0.0for data in dataloader:imgs, targets = dataoutput = model(imgs) result_loss = loss(output, targets) # 计算实际输出与目标输出的差距optim.zero_grad() # 梯度清零result_loss.backward() # 反向传播 计算损失函数的梯度optim.step() # 根据梯度 对网络的参数进行调试running_loss = running_loss + result_lossprint(result_loss) # 对这一轮所有误差的总和import torch
import torchvision
from torch import nn
from torch.nn import Linear, Conv2d, MaxPool2d, Flatten, Sequential
from torch.utils.data import DataLoaderdataset = torchvision.datasets.CIFAR10("dataset", train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size = 64, drop_last=True)class net(nn.Module):def __init__(self):super(net, self).__init__()self.model = Sequential(Conv2d(in_channels = 3, out_channels = 32, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Conv2d(in_channels = 32, out_channels = 32, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Conv2d(in_channels = 32, out_channels = 64, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Flatten(),Linear(1024, 64),Linear(64, 10))def forward(self, x):x = self.model(x)return xmodel = net()
print(model)
loss = nn.CrossEntropyLoss()
optim = torch.optim.SGD(model.parameters(), lr = 0.01)
scheduler = torch.optim.lr_scheduler.StepLR(optim, step_size = 5, gamma = 0.1) # 每过 step_size 更新一次优化器,更新是学习率为原来的学习率的的 0.1 倍 for epoch in range(5):running_loss = 0.0for data in dataloader:imgs, targets = dataoutput = model(imgs) result_loss = loss(output, targets) # 计算实际输出与目标输出的差距optim.zero_grad() # 梯度清零result_loss.backward() # 反向传播 计算损失函数的梯度optim.step() # 根据梯度 对网络的参数进行调试scheduler.step() # 学习率太小了,所以20个轮次后,相当于没走多少running_loss = running_loss + result_lossprint(result_loss) # 对这一轮所有误差的总和
内容二:完整模型训练
import torch
import torchvision
from torch import nn
from torch.nn import Linear, Conv2d, MaxPool2d, Flatten, Sequential
from torch.utils.data import DataLoaderdataset = torchvision.datasets.CIFAR10("dataset", train=False, transform=torchvision.transforms.ToTensor(), download=True)
dataloader = DataLoader(dataset, batch_size = 64, drop_last=True)class net(nn.Module):def __init__(self):super(net, self).__init__()self.model = Sequential(Conv2d(in_channels = 3, out_channels = 32, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Conv2d(in_channels = 32, out_channels = 32, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Conv2d(in_channels = 32, out_channels = 64, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Flatten(),Linear(1024, 64),Linear(64, 10))def forward(self, x):x = self.model(x)return xmodel = net()
print(model)
loss = nn.CrossEntropyLoss()
optim = torch.optim.SGD(model.parameters(), lr = 0.01)
scheduler = torch.optim.lr_scheduler.StepLR(optim, step_size = 5, gamma = 0.1) # 每过 step_size 更新一次优化器,更新是学习率为原来的学习率的的 0.1 倍 for epoch in range(5):running_loss = 0.0for data in dataloader:imgs, targets = dataoutput = model(imgs) result_loss = loss(output, targets) # 计算实际输出与目标输出的差距optim.zero_grad() # 梯度清零result_loss.backward() # 反向传播 计算损失函数的梯度optim.step() # 根据梯度 对网络的参数进行调试scheduler.step() # 学习率太小了,所以20个轮次后,相当于没走多少running_loss = running_loss + result_lossprint(result_loss) # 对这一轮所有误差的总和import torch
import torchvision
from torch import nn
from torch.nn import Linear, Conv2d, MaxPool2d, Flatten, Sequential
from torch.utils.data import DataLoaderclass net(nn.Module):def __init__(self):super(net, self).__init__()self.model = Sequential(Conv2d(in_channels = 3, out_channels = 32, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Conv2d(in_channels = 32, out_channels = 32, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Conv2d(in_channels = 32, out_channels = 64, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Flatten(),Linear(1024, 64),Linear(64, 10))def forward(self, x):x = self.model(x)return xtrain_data = torchvision.datasets.CIFAR10("dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True)
test_data = torchvision.datasets.CIFAR10("dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True) train_dataloader = DataLoader(train_data, batch_size = 64)
test_dataloader = DataLoader(test_data, batch_size = 64)model = net()loss_fn = nn.CrossEntropyLoss()optimer = torch.optim.SGD(model.parameters(), lr = 0.01)total_train_step = 0
total_test_step = 0epoch = 3for i in range(epoch):print('--------the {} epoch for train--------'.format(i+1))model.train() # 当网络中有dropout层、batchnorm层时,这些层能起作用for data in train_dataloader:imgs, targets = datatrain_result = model(imgs)loss_train = loss_fn(train_result, targets)# 优化器模型调优optimer.zero_grad()loss_train.backward()optimer.step()total_train_step = total_train_step + 1if total_train_step % 100 == 0:print('the current step eopch {}, the train loss is {}'.format(total_train_step, loss_train)) # 方式一 获得Loss# print('the current train eopch {}, the train loss is {}'.format(total_train_step, loss_train.item())) # 方式二 获得Lossmodel.eval() # 当网络中有dropout层、batchnorm层时,这些层不能起作用total_test_loss = 0total_accuracy = 0with torch.no_grad():for data in test_dataloader:imgs, targets = datatest_result = model(imgs)loss_test = loss_fn(test_result, targets)total_test_loss = total_test_loss + loss_test.item()accuracy = (test_result.argmax(1) == targets).sum()total_accuracy = total_accuracy + accuracyprint('the all test loss is {}'.format(total_test_loss))print('the accuracy rate is {}'.format(total_accuracy / len(test_data)))total_test_step = total_test_step + 1torch.save(model, 'result/model_{}.pth'.format(i)) # 保存每一轮训练后的结果#torch.save(model.state_dict(),"model_{}.path".format(i)) # 保存方式二print('model is saved')
内容三:GPU训练
import torch
import torchvision
from torch import nn
from torch.nn import Linear, Conv2d, MaxPool2d, Flatten, Sequential
from torch.utils.data import DataLoader# 定义训练的设备
#device = torch.device("cpu")
#device = torch.device("cuda") # 使用 GPU 方式一
#device = torch.device("cuda:0") # 使用 GPU 方式二
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")class net(nn.Module):def __init__(self):super(net, self).__init__()self.model = Sequential(Conv2d(in_channels = 3, out_channels = 32, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Conv2d(in_channels = 32, out_channels = 32, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Conv2d(in_channels = 32, out_channels = 64, kernel_size = 5, stride = 1, padding = 2),MaxPool2d(kernel_size = 2, ceil_mode = True),Flatten(),Linear(1024, 64),Linear(64, 10))def forward(self, x):x = self.model(x)return xtrain_data = torchvision.datasets.CIFAR10("dataset",train=True,transform=torchvision.transforms.ToTensor(),download=True)
test_data = torchvision.datasets.CIFAR10("dataset",train=False,transform=torchvision.transforms.ToTensor(),download=True) train_dataloader = DataLoader(train_data, batch_size = 64)
test_dataloader = DataLoader(test_data, batch_size = 64)model = net()
model = model.to(device)loss_fn = nn.CrossEntropyLoss()
loss_fn = loss_fn.to(device)optimer = torch.optim.SGD(model.parameters(), lr = 0.01)total_train_step = 0
total_test_step = 0epoch = 30for i in range(epoch):print('--------the {} epoch for train--------'.format(i+1))model.train() # 当网络中有dropout层、batchnorm层时,这些层能起作用for data in train_dataloader:imgs, targets = dataimgs = imgs.to(device) # 也可以不赋值,直接 imgs.to(device)targets = targets.to(device) # 也可以不赋值,直接 targets.to(device)train_result = model(imgs)loss_train = loss_fn(train_result, targets)# 优化器模型调优optimer.zero_grad()loss_train.backward()optimer.step()total_train_step = total_train_step + 1if total_train_step % 100 == 0:print('the current step eopch {}, the train loss is {}'.format(total_train_step, loss_train)) # 方式一 获得Loss# print('the current train eopch {}, the train loss is {}'.format(total_train_step, loss_train.item())) # 方式二 获得Lossmodel.eval() # 当网络中有dropout层、batchnorm层时,这些层不能起作用total_test_loss = 0total_accuracy = 0with torch.no_grad():for data in test_dataloader:imgs, targets = datatest_result = model(imgs.to(device))loss_test = loss_fn(test_result, targets.to(device))total_test_loss = total_test_loss + loss_test.item()accuracy = (test_result.argmax(1) == targets.to(device)).sum()total_accuracy = total_accuracy + accuracyprint('the all test loss is {}'.format(total_test_loss))print('the accuracy rate is {}'.format(total_accuracy / len(test_data)))total_test_step = total_test_step + 1torch.save(model, 'result/model_{}.pth'.format(i)) # 保存每一轮训练后的结果#torch.save(model.state_dict(),"model_{}.path".format(i)) # 保存方式二print('model is saved')
内容四:测试模型
import torchvision
import torch
from PIL import Image
from torch import nndevice = torch.device("cuda")image_path = 'dataset/1.jpg'
image = Image.open(image_path) # PIL类型的Image
image = image.convert("RGB") # 4通道的RGBA转为3通道的RGB图片
print(image)transform = torchvision.transforms.Compose([torchvision.transforms.Resize((32, 32)),torchvision.transforms.ToTensor()])image = transform(image)
print(image.shape)# model = torch.load('result/model_20.pth', map_location = torch.device('cpu'))
model = torch.load('result/model_29.pth')
print(model)image = torch.reshape(image, (1, 3, 32, 32)) # 转为四维,符合网络输入需求
model.eval()
with torch.no_grad():result = model(image.to(device))result = model(image.to(device))
print(result)
print(result.argmax(1)) # 概率最大类别的输出
注:上述内容参考b站up主“我是土堆”的视频!!!