赞
踩
本节将介绍一种
只要学习过深度学习相关理论的人,都一定听说过名字叫做LeNet-5模型,它是深度学习三巨头只有Yann Lecun在1998年提出的一个CNN模型(很多人认为这是第一个具有实际应用价值的CNN模型)。在当年使用该模型可以很好地完成手写体数字的识别,而该模型所处理的手写体数字数据库称为MNIST。
MNIST全称是:Mixed National Institute of Standards and Technology databas,它包含70000张手写数字的灰度图片,每一张图片包含 28 X 28 个像素点。数据集被分为两部分,其中训练(mnist.train)集包括60000样本,测试集(mnist.test)包含10000样本。训练集又进一步封你为 55000 个样本用于训练,5000样本用于验证。下图是MNIST样本实例图。
MNIST数据集虽然经典,但也有问题。最主要的问题是,它太简单了!相对于现在动辄上百万个参数的“大”模型,MNIST数据集要小很多,且只是简单的十类问题,因此导致现有的模型在MNIST上的分类精度都超过了95%。为了更直观地观察不同算法间的性能差异,需要用一个更复杂一点的数据集,这时Fashion-MNIST出现了。
FashionMNIST是一个替代MNIST的图像数据集。 它是由一家德国科技公司(Zalando)整理提供。FashionMNIST 的大小、格式和训练集/测试集划分与原始的 MNIST 完全一致。60000/10000 的训练测试数据划分,28x28 的灰度图片。因此,能跑MNIST数据集的代码,只需稍加改动,就可以跑新的数据集。两个数据集的不同之处主要有两点,一是虽然两者都是以灰度图像呈现的,但MNIST呈现的是数字,背景设为0,前景设为1,FashionMNIST则是真正意义的灰度数据集。二是两者内容不同,前者被分类的是手写体数字,后者则是十类衣物服饰(分别是:T恤、裤子、套头衫、连衣裙、大衣、凉鞋、衬衫、运动鞋、包、短靴),其内容的复杂程度远高于手写体数字。下图是FashionMNIST的一个图示。
网上有很多基于FashionMNIST数据集的实例,在此就不再重复介绍。
本节实例选用的是中国版的MNIST,由英国纽卡斯尔大学整理并提供,我们不妨将其称为CHN-MNIST数据集。
该数据集共由100人书写,每人重复书写10遍,因此数据集样本数为1000组,每组包括15个汉字的数字,即“零、一、二、三、四、五、六、七、八、九、十、百、千、万、亿”,总样本数为15000。图像的分辨率为300*300。
对于这样一个简单的分类任务,不需要使用太复杂的网络,前面提到的LeNet-5足能胜任。
对于LeNet-5网络模型的介绍,网上一搜一大把,在此不再赘述,只贴出该模型的示意图,供大家参考。
下面将结合代码,一部分一部分的介绍具体的过程。
- import matplotlib.pyplot as plt
- import numpy as np
- import pandas as pd
- import torch
- import torch.nn as nn
- from PIL import Image
- from torch.utils.data import Dataset, DataLoader
- from tqdm import tqdm
由于是第一个例程,我们对所使用的扩展库详细加以介绍:
这一部分完成的是设置一些与模型训练有关的超参数。如下面代码所示:
- batch_size = 32 # 批次大小
- lr = 0.003 # 学习率
- epochs = 10 # 迭代轮数
- save_path = './best_model.pkl' # 模型保存路径
- device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') # 设备
各个参数的功能见注释,至于各个参数数值大小对最终结果的影响,将放在后续的章节介绍。其中最后一行是自动检测是否安装了cuda,如果是,则启动gpu加速。
这一部分完成的是设置一些与模型训练有关的超参数。如下面代码所示:
- class CustomDataset(Dataset):
- def __init__(self, k, l, csv_file='./chinese_mnist.csv'):
- self.df = pd.read_csv(csv_file)
-
- self.k = {'九': int(9), '十': int(10), '百': int(11), '千': int(12), '万': int(13), '亿': int(14), '零': int(0),
- '一': int(1), '二': int(2), '三': int(3), '四': int(4), '五': int(5), '六': int(6), '七': int(7),
- '八': int(8)}
-
- self.target = 'character'
- self.features = ['suite_id', 'sample_id', 'code', ]
-
- self.labels = np.asarray(self.df.iloc[:, 4])
-
- self.y = df[self.target]
- self.X = df.drop(self.target, axis=1)
-
- def __getitem__(self, idx):
- single_image_label = self.labels[idx]
-
- class_id = self.k[single_image_label]
-
- img = Image.open(f"./data/data/input_{self.X.iloc[idx, 0]}_{self.X.iloc[idx, 1]}_{self.X.iloc[idx, 2]}.jpg")
- img = np.array(img)
-
- return img, class_id
-
- def __len__(self):
- return len(self.X)
还需要对数据集进行一下预处理,便于后面的训练过程g
- # 1.构建索引到汉字的映射字典
- num2char = {int(9): '九', int(10): '十', int(11): '百',
- int(12): '千', int(13): '万', int(14): '亿',
- int(0): '零', int(1): '一', int(2): '二',
- int(3): '三', int(4): '四', int(5): '五',
- int(6): '六', int(7): '七', int(8): '八'}
-
- # 2.读取csv处理文件
- df = pd.read_csv('./chinese_mnist.csv', sep=',')
-
- # 3.处理数据
- train_df = df.groupby('value').apply(lambda x: x.sample(700, random_state=42)).reset_index(drop=True)
- x_train, y_train = train_df.iloc[:, :-2], train_df.iloc[:, -2]
-
- test_df = df.groupby('value').apply(lambda x: x.sample(300, random_state=42)).reset_index(drop=True)
- x_test, y_test = test_df.iloc[:, :-2], test_df.iloc[:, -2]
(未完,待续)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。