专业名词
参数和超参数
参数
:模型
f(x,θ)
中
θ
称为模型的参数,可以通过优化算法进行学习
超参数
:用来定义模型结构或优化策略
batch_size 批处理
每次处理的数据数量
epoch 轮次
把一个数据集,循环运行几轮
transforms变换
主要将图片转换为tensor,旋转图片,以及正则化
normalize 正则化
模型出现过拟合现象时,降低模型复杂度
卷积层
:由卷积核构建,卷积核简称为卷积,也称为滤波器,卷积的大小可以在实际需要时自定义其长和宽(1×1、3×3、5×5)
池化层
:对图片进行压缩(降采样)的一种方法,如max_pooling,average_pooling等
激活层
:激活函数的作用是在所有隐藏层之间添加一个激活函数,这样的输出就是一个非线性函数,因而神经网络的表达能力更加强大
损失函数
:在深度学习中,损失反映模型最后预测结果与实际真值之间的差距,可以用来分析训练过程的好坏、模型是否收敛等,例如:均方损失、交叉熵损失等。
具体代码
# 加载必要库
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
# 定义超参数
BATCH_SIZE = 128
DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
EPOCHS = 10
# 构建pipeline(transforms),对图像做处理
pipeline = transforms.Compose([
# 将图像转换为tensor格式
transforms.ToTensor(),
# 正则化 模型过拟合时降低模型复杂度
transforms.Normalize((0.1307, ), (0.3081, ))
])
# 下载、加载数据集MNIST
train_set = datasets.MNIST("data", train=True, transform=pipeline, download=True)
test_set = datasets.MNIST("data", train=False, transform=pipeline, download=True)
train_loader = DataLoader(train_set, batch_size=BATCH_SIZE, shuffle=True)
test_loader = DataLoader(test_set, batch_size=BATCH_SIZE, shuffle=True)
'''
# 显示MNIST中的图片
with open("./data/MNIST/raw/train-image-idx3-ubyte", "rb") as f
file = f.read()
image1 = [int(str(item).encode('ascii'), 16) for item in file[16:16+784]]
print(image1)
import cv2
import numpy as np
image_np = np.array(image1, dtype=np.unit8).reshape(28,28,1)
print(image_np.shape)
cv2.imwrite("digit.jpg", image_np)
'''
# 构建网络模型
class Net(nn.Module):
def __init__(self):
super().__init__()
# 灰度图片通道数为1, 输出通道数为10,kernel为5
self.conv1 = nn.Conv2d(1, 10, 5)
# 输入通道10,输出通道20,kernel为3
self.conv2 = nn.Conv2d(10, 20, 3)
# 输入通道2000,输出通道500
self.fc1 = nn.Linear(2000, 500)
# 输入通道500,输出通道10
self.fc2 = nn.Linear(500, 10)
def forward(self, x):
# batch_size * 通道1 * 28 * 28
input_size = x.size(0)
# 输入:batch * 1 * 28 * 28 输出:batch * 10 * 24 * 24
x = self.conv1(x)
# 保持shape不变,输出batch * 10 * 24 * 24
x = F.relu(x)
# 输入batch * 10 * 24 * 24 输出:batch * 10 * 12 * 12
x = F.max_pool2d(x, 2, 2)
# 输出batch * 20 * 10 * 10
x = self.conv2(x)
x = F.relu(x)
# 展平
x = x.view(input_size, -1)
# 全连接层
# 输入batch * 2000,输出batch * 500
x = self.fc1(x)
# 模型表达更加充分,保持shape不变
x = F.relu(x)
# 输入batch * 500 输出:batch * 10
x = self.fc2(x)
# 计算分类后,每个数字的概率值
output = F.log_softmax(x, dim=1)
return output
# 定义模型和优化器,优化模型参数
net = Net().to(DEVICE)
# 更新模型的参数
optimizer = optim.Adam(net.parameters())
# 定义训练方法
def train_model(model, device, dataset, optimizers, epochs):
# 模型训练
model.train()
for batch_index, (data, target) in enumerate(dataset):
# 部署到DEVICE上
data, target = data.to(device), target.to(device)
# 梯度初始化为0
optimizers.zero_grad()
# 训练后的结果
output = model(data)
# 计算交叉熵损失
loss = F.cross_entropy(output, target)
# 找到概率值最大的下标
pred = output.max(1, keepdim=True)
# 反向传播
loss.backward()
# 参数优化
optimizers.step()
if batch_index % 3000 == 0:
print("Train Epoch: {} \t Loss : {:.6f}".format(epochs, loss.item()))
# 定义测试方法
def test_model(model, device, dataset):
# 模型验证
model.eval()
# 正确率
correct = 0.0
# 测试损失
test_loss = 0.0
with torch.no_grad(): # 不会计算梯度,也不会进行反向传播
for data, target in dataset:
# 部署到device上
data, target = data.to(device), target.to(device)
# 测试数据
output = model(data)
# 计算测试损失
test_loss += F.cross_entropy(output, target).item()
# 找到概率最大的下标
pred = output.max(1, keepdim=True)[1]
# pred = torch.max(output, dim=1)
# pred = output.argmax(dim=1)
# 累积正确的值
correct += pred.eq(target.view_as(pred)).sum().item()
# 计算测试损失值
test_loss /= len(dataset.dataset)
print("Test -- Average loss: {:.4f}, Accuracy: {:.3f} \n".
format(test_loss, 100 * correct / len(dataset.dataset)))
if __name__ == '__main__':
# 开始训练,输出预测结果
for epoch in range(1, EPOCHS + 1):
train_model(net, DEVICE, train_loader, optimizer, epoch)
test_model(net, DEVICE, test_loader)
官方MNIST 模型及训练、测试方法
# Pytorch官网mnist
# 导入库
import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision import transforms, datasets
from torch.utils.data import DataLoader
import torch.optim as optim
# 定义超参数
BATCH_SIZE = 64
EPOCHS = 10
DEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
# pipeline
pipeline = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,))
])
# 下载、加载数据集
train_data = datasets.MNIST('data', train=True, transform=pipeline, download=True)
test_data = datasets.MNIST('data', train=False, transform=pipeline, download=True)
train_loader = DataLoader(train_data, batch_size=BATCH_SIZE, shuffle=True)
test_loader = DataLoader(test_data, batch_size=BATCH_SIZE, shuffle=True)
# 定义神经网络
class Net(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(1, 32, 3, 1)
self.conv2 = nn.Conv2d(32, 64, 3, 1)
self.dropout1 = nn.Dropout(0.25)
self.dropout2 = nn.Dropout(0.5)
self.fc1 = nn.Linear(9216, 128)
self.fc2 = nn.Linear(128, 10)
def forward(self, x):
x = self.conv1(x)
x = F.relu(x)
x = self.conv2(x)
x = F.relu(x)
x = F.max_pool2d(x, 2)
x = self.dropout1(x)
x = torch.flatten(x, 1)
x = self.fc1(x)
x = self.dropout2(x)
x = self.fc2(x)
output = F.log_softmax(x, dim=1)
return output
# 定义神经网络及优化器
net = Net().to(DEVICE)
optimizer = optim.Adadelta(net.parameters())
# 定义训练函数
def train_model(model, device, dataset, optimizers, epochs):
model.train()
for batch_index, (data, target) in enumerate(dataset):
optimizers.zero_grad()
data, target = data.to(device), target.to(device)
output = net(data)
loss = F.nll_loss(output, target)
loss.backward()
optimizers.step()
if batch_index % 100 == 0:
print('Train Epoch: {} \t loss: {:.6f}'.format(epochs, loss))
# 定义测试函数
def test_model(model, device, dataset):
model.eval()
test_loss = 0.0
correct = 0.0
with torch.no_grad():
for data, target in dataset:
data, target = data.to(device), target.to(device)
output = model(data)
test_loss += F.nll_loss(output, target, reduction='sum').item() # sum up batch loss
pred = output.argmax(dim=1, keepdim=True) # get the index of the max log-probability
correct += pred.eq(target.view_as(pred)).sum().item()
test_loss /= len(dataset.dataset)
print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.2f}%)\n'.format(
test_loss, correct, len(dataset.dataset), 100. * correct / len(dataset.dataset)
))
if __name__ == '__main__':
for epoch in range(1, EPOCHS + 1):
train_model(net, DEVICE, train_loader, optimizer, epoch)
test_model(net, DEVICE, test_loader)
版权声明:本文为jiangyangll原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。