[ 深度学习初识- 实操笔记 ] 全连接神经网络-手写数字识别项目
深度学习初识
1. 神经网络
(1)感知机
一个神经元。
感知机接收多个输入信号,输出一个信号,与广义线性回归类似 ,即有Y = WX+B 。
广义线性回归中有核函数,在感知机中称为激活函数(提供非线性能力),在感知机中,激活函数常用 sigmoid函数。
广义线性回归和感知机算法的训练都是由梯度下降法,加上正则化降低损失的。
(2)多层神经网络 MLP
多个感知机,分布在多层神经网络上,即神经网络按一层一层构建,构成深度神经网络。深度神经网络的学习过程被称为深度学习。
模型可简单表示为:f…f(X,θ):即上一层的输出作为下一层的输入,第一层的结果称为一阶特征,第二层的结果称为二阶特征……层次越深,得到的特征就越抽象,网络就越聪明,但是层次越深,深度网络就存在梯度弥散和梯度暴涨的问题,即当层次越深,后面得到的梯度太大或太小,使得超出界限或特征消失。
第一层模型简单表示:f(WX) - W 为n行m列矩阵,代表这一层上有n个感知机,每个感知机有m个输入; X 为m行k列,即m个输入,k个输出。因此这一层有k个输出结果; f为激活函数。
第二层模型简单表示:f(f(WX)X) - f(WX)作为第二层的权重W,即第一层的输出,n行k列……
(3)激活函数
功能:激活每一个神经元,提供非线性能力。
Sigmoid/tanh 函数,这两个函数有饱和值,即在做深层神经网络的时候容易梯度弥散。
ReLU/Leaky ReLU,具有抗弥散能力,提供非线性能力的部分在拐点处(即原点),ReLU负轴为0,容易让神经元死掉,LeakyReLU为ReLU改进版。
(4)输出函数
神经网络的最后一层,输出范围具有限制,因此输出层的激活函数不同。
在多分类输出函数常用:softMax(x),损失loss为one-hot即每一个类别上的概率;当输出层要输出一个概率时候,常用sigmoid(x);当输出层不做改变时候,常用linear(x)……
2. 全连接神经网络
项目实例:手写数字识别项目
每一层的输出都与下一层的每个感知机相连。
Python+Pytorch代码实现:主要有三部分实现,数据部分data,网络模型构建net,网络训练train。
(1)数据部分data:
pytorch提供的数据处理库:
from torch.utils.data import Dataset
创建一个数据类继承Dataset:
def init(self,root,is_train = True):
主要用于初始化数据,载入/保存数据。可保存所有数据或者数据路径,这里保存数据路径,root 即为数据路径根地址。is_train 用来判断读取的为训练集还是测试集。
def len(self):
主要用来返回数据长度。
def getitem(self,index):
用来索引到每条数据,并处理每条数据。
数据展平:这里是因为每个像素作为一个输入。
数据归一化,标签/类别转换为one-hot编码。
class MNISTDataset(Dataset): def __init__(self, root, is_train=True): self.dataset = [] # 记录所有数据 sub_dir = "TRAIN" if is_train else "TEST" for tag in os.listdir(f"{root}/{sub_dir}"): img_dir = f"{root}/{sub_dir}/{tag}" for img_filename in os.listdir(img_dir): img_path = f"{img_dir}/{img_filename}" self.dataset.append((img_path, tag)) # 数据集有多少数据 def __len__(self): return len(self.dataset) # 每条数据的处理方式 def __getitem__(self, index): data = self.dataset[index] img_data = cv2.imread(data[0], cv2.IMREAD_GRAYSCALE) img_data = img_data.reshape(-1) #数据展平 img_data = img_data / 255 #归一化 #one_hot tag_one_hot = np.zeros(10) tag_one_hot[int(data[1])] = 1 return np.float32(img_data), np.float32(tag_one_hot)
(2)网络模型部分 net
pytorch提供的网络模型库:
from torch import nn
创建一个网络模型类继承nn.Module。
def init (self): 用来初始化网络组件
nn.Sequential(…)里面可放网络每层的运算。
下面的例子:输入层为784个像素点,第一层采用用ReLU为激活函数的线性模型,784个输入,100个输出。第二层即输出层,one-hot编码输出采用SoftMax为激活函数,上一层100个输入,10个输出(手写数字10个分类:1-10用one-hot编码输出10个概率结果,哪一位的概率最大,即为那一个分类)
def forward(self,x): x为输入矩阵NV (N张图片,每张图片V-784个像素)。输入的结果在sequential(x)组合组件中运算得到返回输出。
import torch from torch import nn class NetV(nn.Module): def __init__(self): super().__init__() self.sequential = nn.Sequential( nn.Linear(784, 100), nn.ReLU(), nn.Linear(100, 10), nn.Softmax() ) def forward(self, x): return self.sequential(x)
(3)训练部分train:
加载前面建好的数据库和网络库。
DataLoader库的功能是为训练数据/测试数据,分包训练。
optim库为优化模型。
tensorboard库提供将每轮训练的数据图表化显示的工具。(便于观察数据的变化,如损失,权重…)
import torch from day01.data import * from day01.net import * from torch.utils.data import DataLoader from torch import optim from torch.utils.tensorboard import SummaryWriter
def init(self,root):
加载训练数据,加载测试数据,创建模型,创建优化器。
self.test_dataloader = DataLoader(self.test_dataset, batch_size=100, shuffle=True)用DataLoader分包训练,每包100个数据。
(还可以加载上次训练的权重:
self.net.load_state_dict(torch.load("./checkpoint/2.t")))
def call(self):
以下面为例,最大轮次尽量设置毕竟大,可手动停止训练。
self.net.train()#模型初始化 y = self.net(imgs)#输入图片 作为模型训练 得到输出结果y loss = torch.mean((tags - y) ** 2) # 输出结果和正确结果做平方差取平均-损失 #优化器固定三步 self.opt.zero_grad()#梯度归零 loss.backward() self.opt.step()
import torch from day01.data import * from day01.net import * from torch.utils.data import DataLoader from torch import optim from torch.utils.tensorboard import SummaryWriter DEVICE = "cuda:0" class Train: def __init__(self, root): self.summaryWriter = SummaryWriter("./logs") # 加载训练数据 self.train_dataset = MNISTDataset(root, True) self.train_dataloader = DataLoader(self.train_dataset, batch_size=100, shuffle=True) # 加载测试数据 self.test_dataset = MNISTDataset(root, False) self.test_dataloader = DataLoader(self.test_dataset, batch_size=100, shuffle=True) # 创建模型 self.net = NetV() # self.net.load_state_dict(torch.load("./checkpoint/2.t")) self.net.to(DEVICE) # 创建优化器 self.opt = optim.Adam(self.net.parameters()) # 训练代码 def __call__(self): for epoch in range(100000): sum_loss = 0. for i, (imgs, tags) in enumerate(self.train_dataloader): imgs, tags = imgs.to(DEVICE), tags.to(DEVICE) self.net.train() y = self.net(imgs) loss = torch.mean((tags - y) ** 2) self.opt.zero_grad() loss.backward() self.opt.step() sum_loss += loss.cpu().detach().item() avg_loss = sum_loss / len(self.train_dataloader) sum_score = 0. test_sum_loss = 0. for i, (imgs, tags) in enumerate(self.test_dataloader): imgs, tags = imgs.to(DEVICE), tags.to(DEVICE) self.net.eval() test_y = self.net(imgs) test_loss = torch.mean((tags - test_y) ** 2) test_sum_loss += test_loss.cpu().detach().item() predict_tags = torch.argmax(test_y, dim=1) label_tags = torch.argmax(tags, dim=1) sum_score += torch.sum(torch.eq(predict_tags, label_tags).float()).cpu().detach().item() test_avg_loss = test_sum_loss / len(self.test_dataloader) score = sum_score / len(self.test_dataset) self.summaryWriter.add_scalars("loss", {"train_loss": avg_loss, "test_loss": test_avg_loss}, epoch) self.summaryWriter.add_scalar("score", score, epoch) print(epoch, avg_loss, test_avg_loss, score) torch.save(self.net.state_dict(), f"./checkpoint/{epoch}.t") if __name__ == '__main__': train = Train("../data/MNIST_IMG") train()
每轮训练后可保存权重
torch.save(self.net.state_dict(), f"./checkpoint/{epoch}.t"),便于下次运行或封装成pt包。
先设置gpu
DEVICE = "cuda:0"将数据和网络放入设置好的gpu,
to(DEVICE)进行运算 xianyu_blog 原创文章 4获赞 0访问量 118 关注 私信
- 神经网络与深度学习笔记——第1章 使用神经网络识别手写数字
- Python实现深度学习之-神经网络识别手写数字(更新中,更新日期:2017-07-12)
- 深度学习与神经网络实战:快速构建一个基于神经网络的手写数字识别系统
- 深度学习入门实践_十行搭建手写数字识别神经网络
- 神经网络与深度学习: 使用神经网络识别手写数字1
- 深度学习与TensorFlow实战(七)全连接网络基础—真实图片输出手写数字识别准确率
- 深度学习与TensorFlow实战(六)全连接网络基础—MNIST数据集输出手写数字识别准确率
- 【深度学习】笔记2_caffe自带的第一个例子,Mnist手写数字识别代码,过程,网络详解
- 【深度学习】笔记3_caffe自带的第一个例子,Mnist手写数字识别所使用的LeNet网络模型的详细解释
- 深度学习-传统神经网络使用TensorFlow框架实现MNIST手写数字识别
- python Tensorflow三层全连接神经网络实现手写数字识别
- 神经网络与深度学习 1.3 神经网络的架构 1.4 一个简单的分类手写数字的网络架构
- 【深度学习·笔记二】Matlab训练RCNN神经网络识别STOP路标
- 机器学习/深度学习个人进阶日志-基于Tensorflow的手写数字识别项目最终篇
- tensorflow 学习笔记7 普通神经网络实现mnist手写识别
- 机器学习深度学习基础笔记(2)——梯度下降之手写数字识别算法实现
- 【深度学习-学习笔记1】MNIST手写数字识别之MLP实现
- tensorflow 学习笔记12 循环神经网络RNN LSTM结构实现MNIST手写识别
- 深度学习笔记5torch实现mnist手写数字识别
- 深度学习框架Caffe学习笔记(2)-MNIST手写数字识别例程