手写数字识别项目实现
实现神经网络
根据参数绘制网络
- 方式1:单独存储每一层模型
- 方式2:self.layers = torch.nn.ModuleList
- 方式3:self.fc = torch.nn.Sequential
根据输入输出绘制网络
- 根据模型数据类型赋值权重
使用全连接拟合非线性
- 数据准备
- np创建非线性数据
- 数据转为张量
- 创建模型
- 迭代次数
- 学习率
- 网络初始化(Linear+ReLU)
- 损失函数初始化
- 训练模型
- x数据传入网络,获得输出out
- out和y输入损失函数,计算损失loss
- 梯度清零
- 反向传播
- 更新参数
- 测试数据
- 阻断跟踪,获得预期输出pred_out
- 绘图
- np数据绘制散点图
- 测试数据和pred_out绘图
- 显示图像
数据处理
- 下载数据 train_set = datasets.MNIST
- 获取图片和标签 img, label = train_set[0]
- 图像转为张量
- transforms.ToTensor()(img)
- 图像操作:缩放、水平/垂直翻转、裁剪…
- 组合以上操作:transforms.Compose
- tensor转为PIL:img = transforms.ToPILImage()(img)
- 显示图像
自定义数据集
- 确认数据类型
- 获取数据路径和标签
- 方式1:多层遍历
- 方式2:glob
- 根据数据路径读取数据
- 右切割,指定切割次数,获得图片读取路径和标签
- 存储图片路径和对应标签
- 改写
__len__
- 返回图片路径和对应标签的数据长度
- 改写
__getitem__
- 1.图像处理
- 获取图片路径和对应标签
- 根据图片路径读取图像
- 归一化处理
- 方式1:数据原值 / 数据最大值
- 方式2:transforms.ToTensor()
- 图像转为张量,注意类型设为float32
- 张量展平
- 2.标签处理
- 设定one-hot初始值:one_hot = torch.zeros(10)
- 根据标签赋值 获取的label是字符串类型 需要类型转换:one_hot[int(label)] = 1
- 3.返回图像张量和one-hot编码
手写识别网络搭建
- 自定义数据集
- 网络模型搭建
- 识别
- 准备数据
- 搭建模型
- 训练模型
- 测试模型
- 统计平均损失和准确率
推理预测
- 数据 img
- 静态图像
- 摄像头
- 数据预处理
- 归一化
- 尺度缩放
- 网络
- 初始化网络 net
- 加载参数
- 推理
- out = net(img)
版本对比
cnn_v1:LeNet5:2cnn+3fc,32*32
网络结构
self.cnn = nn.Sequential(
# 32 * 32 * 3 --> 28 * 28 * 6
nn.Conv2d(in_channels=3, out_channels=6, kernel_size=5),
nn.ReLU(),
# 28 * 28 * 6 --> 14 * 14 * 6
nn.MaxPool2d(2),
# 14 * 14 * 6 --> 10 * 10 * 16
nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5),
# 10 * 10 * 16 --> 5 * 5 * 16
nn.ReLU(),
nn.MaxPool2d(2),
# 5 * 5 * 16 --> 1 * 1 * 120
# nn.Conv2d(in_channels=16, out_channels=120, kernel_size=5),
)
self.fc = nn.Sequential(
# 5 * 5 * 16 --> 1 * 1 * 120
nn.Linear(400, 120),
nn.ReLU(),
# 1 * 1 * 120 --> 1 * 1 * 84
nn.Linear(120, 84),
nn.ReLU(),
# 1 * 1 * 84 --> 1 * 1 * 10
nn.Linear(84, 10),
nn.Softmax(dim=1),
)
可视化结果
cnn_v2:LeNet5:3cnn+2fc,32*32
网络结构
self.cnn = nn.Sequential(
# 32 * 32 * 3 --> 28 * 28 * 6
nn.Conv2d(in_channels=3, out_channels=6, kernel_size=5),
nn.ReLU(),
# 28 * 28 * 6 --> 14 * 14 * 6
nn.MaxPool2d(2),
# 14 * 14 * 6 --> 10 * 10 * 16
nn.Conv2d(in_channels=6, out_channels=16, kernel_size=5),
# 10 * 10 * 16 --> 5 * 5 * 16
nn.ReLU(),
nn.MaxPool2d(2),
# 5 * 5 * 16 --> 1 * 1 * 120
nn.Conv2d(in_channels=16, out_channels=120, kernel_size=5),
)
self.fc = nn.Sequential(
# 5 * 5 * 16 --> 1 * 1 * 120
# nn.Linear(400, 120),
nn.ReLU(),
# 1 * 1 * 120 --> 1 * 1 * 84
nn.Linear(120, 84),
nn.ReLU(),
# 1 * 1 * 84 --> 1 * 1 * 10
nn.Linear(84, 10),
nn.Softmax(dim=1),
)
可视化结果