基于Pytorch实现CNN卷积神经网络-Mnist数据集

基于pytorch框架,采用神经网络和CNN网络实现Mnist数据集,该示例训练,相当于语言编程界的“hello world”入门程序。

文章目录

  • 前言
  • 一、Mnist数据模型简介
  • 二数据集的下载
    • 2.1网址下载
    • 2.2 基于pytorch框架自带模块加载
    • 2.3基于tensorflow自带框架加载(CNN)


前言

基于pytorch框架实现Mnist数据集,掌握机器学习中第一个“hello world”程序


一、Mnist数据模型简介

MNIST数据集是由0 到9 的数字图像构成的。它包含了60000张图片作为训练数据,10000张图片作为测试数据。每一张图片都有对应的标签数字。图片大小均为 28 * 28,单通道灰度图像(0~255)。
基于Pytorch实现CNN卷积神经网络-Mnist数据集_第1张图片
基于Pytorch实现CNN卷积神经网络-Mnist数据集_第2张图片

基于Pytorch实现CNN卷积神经网络-Mnist数据集_第3张图片

二数据集的下载

2.1网址下载

数据下载地址:http://yann.lecun.com/exdb/mnist/
基于Pytorch实现CNN卷积神经网络-Mnist数据集_第4张图片
下载后将文件放入相应的工作目录,然后进行加载:

'''
采用已经下载好的本地minist数据集进行训练
'''
data_path=Path('data')
path=data_path/'mnist'
path.mkdir(parents=True,exist_ok=True)
#url="http://yann.lecun.com/exdb/mnist/"
filename="mnist.pkl.gz"
if not (path/filename).exists():
    content=requests.get(filename).content
    (path/filename).open('wb').write(content)
#
with gzip.open((path/filename).as_posix(),'rb')as f:
    ((x_train,y_train),(x_valid,y_valid),_)=pickle.load(f,encoding='latin-1')
#784=28*28 黑白单通道
print(x_train.shape)
print(y_train.shape)
print(x_valid.shape)
print(y_valid.shape)
plt.imshow(x_train[0].reshape((28,28)),cmap='gray')
plt.show()

x_train,y_train,x_valid,y_valid=map(torch.tensor,(x_train,y_train,x_valid,y_valid))
n,c=x_train.shape

2.2 基于pytorch框架自带模块加载

from torchvision.datasets import mnist
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import torch
from torch import nn
transforms=transforms.Compose([transforms.ToTensor(),transforms.Normalize([0.5],[0.5])])
train_dataset=mnist.MNIST(
    root='./DATA',#下载数据,存放在DATA目录下
    train=True,#下载完成后告知默认的为训练集,如果为FALSE:则为测试集
    transform=transforms,
    download=True)

test_dataset=mnist.MNIST(
    root='./DATA',
    train=False,
    transform=transforms,
    download=True
)

print('length of train_data',len(train_dataset))
print('shape of train_data',train_dataset.data.shape)
print('Target shape of train_data',train_dataset.targets.shape)


print('length of train_data',len(test_dataset))
print('shape of train_data',test_dataset.data.shape)
print('Target shape of train_data',test_dataset.targets.shape)

#显示图片
data,targets=train_dataset.data[:6],train_dataset.targets[:6]
fig=plt.figure(figsize=(5,5))
for i in range(6):
    plt.subplot(2,3,(i+1))#子图从1开始,2行3列
    plt.tight_layout()#显示紧凑
    plt.imshow(data[i],cmap='gray')#以灰度图形式显示,去掉后可能为彩色
    plt.title('target:{}'.format(i))
    plt.xticks([])#去掉X坐标轴
    plt.yticks([])#去掉Y坐标轴
    plt.show()
#超参数
train_batch_size=128
test_batch_size=54
#加载数据,可迭代对象
from torch.utils.data import DataLoader
from torch.nn import functional as F
train_loader=DataLoader(train_dataset,batch_size=train_batch_size,shuffle=True)
test_loader=DataLoader(test_dataset,batch_size=test_batch_size,shuffle=False)
#构建网络
class Net(nn.Module):
    def __init__(self,in_dim,n_hidden1,n_hidden2,out_dim):
        super(Net,self).__init__()
        self.layer1=nn.Sequential(nn.Linear(in_dim,n_hidden1),nn.BatchNorm1d(n_hidden1))
        self.layer2 = nn.Sequential(nn.Linear(n_hidden1, n_hidden2), nn.BatchNorm1d(n_hidden2))
        self.layer3 = nn.Sequential(nn.Linear(n_hidden2, out_dim))
    def forward(self,x):
        x=F.relu(self.layer1(x))
        x=F.relu(self.layer2(x))
        x=self.layer3(x)
        return x
model=Net(28*28,256,128,10)
print(model)

#定义损失函数和优化器
import torch.optim as optim
#超参数
learning_rate=0.01
momentum=0.5
criterion=nn.CrossEntropyLoss()
optimizer=optim.SGD(model.parameters(),lr=learning_rate,momentum=momentum)
#训练模型
num_epoches=10
device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device)
train_losses=[]
train_accs=[]
for epoch in range(num_epoches):
    train_loss=0
    train_acc=0
    for img,label in train_loader:
        img=img.to(device)
        label=label.to(device)
        img=img.view(img.size(0),-1)
        out=model(img)
        loss=criterion(out,label)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        train_loss+=loss.item()
        pred=out.argmax(dim=1)
        train_acc +=(pred==label).sum().item()/img.size(0)
    train_loss=train_loss/len(train_loader)
    train_acc=train_acc/len(train_loader)
    train_losses.append(train_loss)
    train_accs.append(train_acc)
    print('Epoch:{},Train loss:{},Train acc:{}'.format(epoch,train_losses,train_acc))

2.3基于tensorflow自带框架加载(CNN)

import tensorflow as tf
mnist=tf.keras.datasets.mnist
(x_train,y_train),(x_label,y_label)=mnist.load_data()
print(x_train.shape)
print(y_train.shape)
print(x_label.shape)
print(y_label.shape)
import os
save_dir='./MNIST_DATA/RAW/'
if os.path.exists(save_dir)is False:
    os.mkdir(save_dir)
import matplotlib.pyplot as plt
#显示前20张图片
for i in range(6):
    plt.subplot(2, 3, (i + 1))  # 子图从1开始,2行3列
    plt.tight_layout()  # 显示紧凑
    plt.imshow(x_train[i], cmap='gray')  # 以灰度图形式显示,去掉后可能为彩色
    plt.title('target:{}'.format(i))
    plt.xticks([])  # 去掉X坐标轴
    plt.yticks([])  # 去掉Y坐标轴
    plt.show()
'''
导入的训练集的shape为(60000,28,28)。若是全连接神经网络,
需要reshape为(60000,784);而卷积神经网络因为必须先进行卷积与池化运算,
所以必须保持图像的维数。所以reshape转换为(60000,28,28,1),即60000张图像,
每一张为28(宽)*28(高)*1(单色)。
'''
#数据处理,数据导入后预处理才能够输入模型进行训练
x_train=x_train.reshape(x_train.shape[0],28,28,1).astype('float32')
x_label=x_label.reshape(x_label.shape[0],28,28,1).astype('float32')
#标准化操作
x_train,x_label=x_train/255.0,x_label/255.0
#搭建模型
model=tf.keras.models.Sequential([
    tf.keras.layers.Conv2D(input_shape=(28,28,1),filters=16,kernel_size=(5,5),padding='same',activation='relu'),
    tf.keras.layers.MaxPool2D(pool_size=(2,2)),
    tf.keras.layers.Conv2D(filters=32,kernel_size=(3,3),padding='same',activation='relu'),
    tf.keras.layers.MaxPool2D(pool_size=(2,2)),
    tf.keras.layers.Dropout(0.25),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(128,activation='relu'),
    tf.keras.layers.Dropout(0.5),
    tf.keras.layers.Dense(10,activation='softmax')]
)

print(model.summary())

#训练模型
'''

'''
model.compile(loss='sparse_categorical_crossentropy',optimizer='adam',metrics=['accuracy'])
model.fit(x=x_train,y=y_train,validation_split=0.3,epochs=20,batch_size=100,verbose=2)

你可能感兴趣的:(pytorch,pytorch,神经网络,cnn)