Pytorch神经网络处理.mat格式Mnist数据

数据源提供的为.mat格式的数据,希望能够采用python的pytorch深度学习框架对其进行处理

此博客同时也写了一种对常规数据集进行读取的框架

以下为函数各个模块以及相应的说明(详细)

data_preprocess模块函数  

def dp():
      path = './mnist_lite.mat'  # 定义路径
      matr = io.loadmat(path)  # 关键步骤 采用io的loadmat包将数据读入缓存

      train_x = matr['train_x']  # 四个标签类型的数据为.mat中存储的形式
      train_y = matr['train_y']
      test_x = matr['test_x']
      test_y = matr['test_y']
'''
    原本数据shape为(784,6000), transpose 对于二维函数是将其转置,即6000个数据,784个信息点
'''
      train_x = torch.tensor(np.transpose(train_x))         
      train_x = train_x.to(torch.float32)  
      train_y = torch.tensor(np.transpose(train_y))  
      train_y = train_y.to(torch.float32)
      test_x = torch.tensor(np.transpose(test_x))
      test_x = test_x.to(torch.float32)
      test_y = torch.tensor(np.transpose(test_y))
      test_y = test_y.to(torch.float32)
      print(' train_x.shape:t',train_x.shape,'n',
            'train_y.shape:t',train_y.shape,'n',
            'test_x.shape:t',test_x.shape,'n',
            'test_y.shape:t',test_y.shape)

      train_x = train_x.reshape(6000,1,28,28)  # 将图像reshape为28*28的图像
      test_x = test_x.reshape(1000,1,28,28)

      return train_x, train_y, test_x, test_y

神经网络定义部分 Network模块 


class Net(nn.Module):

    def __init__(self):
        super(Net, self).__init__()
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=8, kernel_size=3, padding=1)
        self.conv2 = nn.Conv2d(in_channels=8, out_channels=16, kernel_size=3, padding=1)
        self.conv3 = nn.Conv2d(in_channels=16, out_channels=32, kernel_size=3, padding=1)
        self.m = nn.MaxPool2d(2, stride=2)
        self.fc = nn.Linear(28 * 28 * 2, 10)
        # self.initialize_weights()

    def forward(self, x):
        x = F.relu(self.conv1(x))
        # print("1",x.shape)
        x = self.m(x)
        # print("2",x.shape)
        x = F.relu(self.conv2(x))
        # print("3",x.shape)
        x = self.m(x)
        # print("4",x.shape)
        x = F.relu(self.conv3(x))
        # print("5",x.shape)
        x = torch.flatten(x, 1)  # flatten all dimensions except the batch dimension
        # print("6",x.shape)
        x = self.fc(x)
        # print("7",x.shape)
        # x = F.softmax(x, dim = 0)

        return x


net = Net()

对于神经网络的定义一些心得:

关于nn.conv2d()中的参数:

        第一层的输入图片样本in_channel的输入取决于图片的类型,RGB即为3,本项目的MNIST手写数据集为1通道数据所以为1,out_channel的大小取决于卷积核的数量,此时out_channel的大小为下一次卷积核的in_channel的大小

        对于pytorch,没有 padding = same 的设置,因此需要根据卷积核的大小,如果需要设置padding = same的情况下,如kernelsize设置为3时,padding设置为1,等价于 padding = same 的设置

关于nn.MaxPool2d()中的参数:

        kernel_size的设置是移动窗口的大小,这里stride的大小默认值是与窗口大小相同的

        每过一个最大池化层,信息点减少一半

关于torch.flatten()函数:

        在全连接层前采用flatten将所有信息点进行展开

特别注意:

        在后面采用的Loss标准如果采用了交叉熵判定标准的话,是已经有了softmax函数了,因此在网络最后的Sequential中不需要额外添加softmax函数

 训练部分train_process


import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.utils.data as data
import scipy.io as io
import numpy as np
import torch.optim as optim
import matplotlib.pyplot as plt
import data_preprocess
import Network

net = Network.Net()  # 网络定义在Network.py文件中
Epoch = 10
BATCH_SIZE = 128  # 批训练的数据个数
# 先转换成 torch 能识别的 Datasettorch_dataset = data.TensorDataset(train_x, train_y)

# 把 dataset 放入 DataLoader

train_x, train_y, test_x, test_y = data_preprocess.dp()
print(train_x.shape,train_y.shape)
torch_dataset = data.TensorDataset(train_x, train_y)  # 生成TensorDataset

loader = data.DataLoader(
    dataset = torch_dataset,      # torch TensorDataset format
    batch_size = BATCH_SIZE,      # mini batch size
    shuffle = True               # 要不要打乱数据 (打乱比较好)
)

# loss 画图预备
loss_record = []
bc_record = []
step_ = 0

loss_record_mean = []
epoch_record = []
step__ = 0

# Accuracy 画图预备
accuracy_record = []
_bc_record = []
_step_ = 0

accuracy_record_mean = []
_epoch_record = []
_step__ = 0


optimizer = optim.SGD(net.parameters(), lr=0.05, momentum=0.9)  
criterion = nn.CrossEntropyLoss()
optimizer.zero_grad()

for epoch in range(Epoch):
    print('............','Epoch:',epoch,'............')
    loss_sum = 0
    acc_sum = 0
    num = 0
    for step, (batch_x, batch_y) in enumerate(loader): #每一步loader释放一小批数据用来学习
        train_predict_y = net(batch_x)
        loss = criterion(train_predict_y.float(), batch_y.float())
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        # print('parameter updating')

        output = torch.argmax(train_predict_y, dim=1, keepdim=False)  


        # print(output)  
        label = torch.argmax(batch_y, dim=1, keepdim=False)

'''
        这里判断Accuracy的思路为比较预测输出的最大值的索引即第几类与groud_truth是否相等
        因为数组形式相同,因此取最大索引值的方式相同
'''
        # print(label)
        # print('..........output...............',output)
        # print('..........label...............',label)
        acc = output[output == label].shape[0] / output.shape[0]  # 计算正确率
        # print(output[output==label])
        acc_sum = acc_sum + acc

        loss_sum = loss_sum + loss
        num = num + 1

        # loss for batch
        loss_record.append(loss.detach())  # y 坐标
        bc_record.append(step_)    # 每次加了大约 47 次
        step_ = step_ + 1

        # acc for batch
        accuracy_record.append(acc)
        _bc_record.append(_step_)
        _step_ = _step_ + 1

    print('Loss:', (loss_sum / num).detach())
    print("Accuracy:", acc_sum / num)

    loss_record_mean.append((loss_sum / num).detach())  # 每一次epoch训练结束之后的 Loss 取的是一个均值  如果取点的话就是一共eoch个点
    epoch_record.append(step__)
    step__ = step__ + 47

    accuracy_record_mean.append((acc_sum / num))   # 每一次epoch训练结束之后的 Accuracy 取的是一个均值
    _epoch_record.append(_step__)
    _step__ = step__ + 47 # 之前一个batch循环训练完后除以内层batch训练的次数

# 测试集的正确率进行检验


# 画图

fig_list = torch.Tensor(loss_record).numpy()
fig_mean = torch.Tensor(loss_record_mean).numpy()

对于训练网络部分的一些心得:

        首先需要将输入数据X和预测输出数据y_hat组合为TensorDataset,才能将数据存储入pytorch数据迭代器的Dataloader中

        使用argmax提取出train_y 和 labels的最大值所在的索引进行判别,以此判定出accuracy的大小

        将画图的张量采用.detach()函数,返回的张量的requires_grad为false

关于画图:

        在每一个批结束后进行点的绘制,Loss和Accuracy在每一小次迭代后都进行值的存储

最终运行情况:

 

 

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>