Pytorch、TensorFlow、Keras框架下使用卷积神经网络实现MNIST分类(附所有实现代码)

Pytorch、TensorFlow、Keras框架下使用卷积神经网络实现MNIST分类(附所有实现代码)

文章目录

    • Pytorch框架下搭建mnist分类卷积神经网络
    • TensorFlow框架下搭建mnist分类卷积神经网络
    • Keras框架下搭建mnist分类卷积神经网络

Pytorch框架下搭建mnist分类卷积神经网络

 创建CNN网络整体思路:

  1. 导入相关包;
  2. 设置超参数;
  3. 对数据进行处理,并加载数据;
  4. 创建CNN网络,包括卷积层、激活函数、最大池化层;
  5. 设置损失函数,优化器
  6. 训练模型
  7. 测试模型


 全部运行代码如下:

#基于Pytorch框架实现卷积神经网络的mnist分类
#Author J.A.
#Data 2022.2.8
#加入可视化内容

#导入相关包
import torch
import os
import torch.nn as nn
import torchvision
import matplotlib.pyplot as plt
from torch.utils.data import DataLoader
#设置超参数
epoch = 3
batch_size = 50
lr = 0.001
download_mnist = False     #因为已经下载过了

#进行数据处理
#首先判断是否已存在路径或者路径存在但是内容是否为空
if not(os.path.exists('./mnist/')) or not os.listdir('./mnist/'):
    download_mnist = True

train_data = torchvision.datasets.MNIST(
    root = './mnist/',
    train = True,
    transform = torchvision.transforms.ToTensor(),      #将其转变为tensor张量
    download = download_mnist,
)
#给出示例
print(train_data.train_data.size())     #(60000, 28, 28)
print(train_data.train_labels.size())   #(60000)
plt.imshow(train_data.train_data[0].numpy(), cmap = 'gray')
plt.title('%i' % train_data.train_labels[0])
plt.show()

#加载数据
train_loader = DataLoader(dataset = train_data, batch_size = batch_size, shuffle = True)
#挑选2500样本测试模型
test_data = torchvision.datasets.MNIST(root='./mnist/', train = False)
#利用unsqueeze()函数扩展维度将(2500,28,28)扩展为(2500,1,28,28)
test_x = torch.unsqueeze(test_data.test_data, dim = 1).type(torch.FloatTensor)[:2500] / 255.
test_y = test_data.test_labels[:2500]

#构建CNN模型,定义一个类
class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.Conv1 = nn.Sequential(         #输入尺寸维度(1,28,28)
            nn.Conv2d(
                in_channels = 1,            #灰度图像通道为1
                out_channels = 16,          #卷积核数量为16
                kernel_size = 5,            #卷积核尺寸 5*5
                stride = 1,                 #步长为1
                padding = 2,                #填充为2
            ),                              #当前维度(16,28,28)
            nn.ReLU(),                      #配置激活函数
            nn.MaxPool2d(kernel_size = 2),  #添加最大池化层
        )                                   #当前维度(16,14,14)】
        self.Conv2 = nn.Sequential(
            nn.Conv2d(16, 32, 5, 1, 2),     #当前维度尺寸(32,14,14)
            nn.ReLU(),
            nn.MaxPool2d(2),                #当前维度尺寸(32,7,7)
        )
        self.out = nn.Linear(32 * 7 * 7, 10)    #添加全连接层(1568,10)

    def forward(self, x):
        x = self.Conv1(x)
        x = self.Conv2(x)
        x = x.view(x.size(0), -1)
        output = self.out(x)
        return output, x                    #返回的x值用于后续可视化

#开始实例化函数
cnn = CNN()
#查看cnn结构
print(cnn)
#设置损失函数,优化器等
optimizer = torch.optim.Adam(cnn.parameters(), lr = lr)
loss_func = nn.CrossEntropyLoss()

#接下来配置可视化内容可忽略
from matplotlib import cm
try: from sklearn.manifold import TSNE; HAS_SK = True
except: HAS_SK = False; print('Please install sklearn for layer visualization')
def plot_with_labels(lowDWeights, labels):
    plt.cla()
    X, Y = lowDWeights[:, 0], lowDWeights[:, 1]
    for x, y, s in zip(X, Y, labels):
        c = cm.rainbow(int(255 * s / 9)); plt.text(x, y, s, backgroundcolor=c, fontsize=9)
    plt.xlim(X.min(), X.max()); plt.ylim(Y.min(), Y.max()); plt.title('Visualize last layer'); plt.show(); plt.pause(0.01)

plt.ion()

#开始训练模型
for epoch in range(epoch):                                  #迭代模型
    for step, (b_x, b_y) in enumerate(train_loader):        #将train_loader数据传入模型
        output = cnn(b_x)[0]
        loss = loss_func(output,b_y)                        #计算损失值
        optimizer.zero_grad()                               #优化器梯度置零
        loss.backward()                                     #反向传播,计算梯度
        optimizer.step()                                    #更新梯度值

        #打印结果值
        if step % 50 == 0:
            test_output, last_layer = cnn(test_x)
            pred_y = torch.max(test_output, 1)[1].data.numpy()  #输出最大值,()里边1表示每一行取最大值,
            # 其次[1]表示对于取得结果取其索引也就是对应下标为1的数组
            accuracy = float((pred_y == test_y.data.numpy()).astype(int).sum()) / float(test_y.size(0))
            print('Epoch:', epoch, '|train loss: %.4f' %loss.data.numpy(), '|test accuracy: %.2f' % accuracy)
            if HAS_SK:
                # Visualization of trained flatten layer (T-SNE)
                tsne = TSNE(perplexity=30, n_components=2, init='pca', n_iter=5000)
                plot_only = 500
                low_dim_embs = tsne.fit_transform(last_layer.data.numpy()[:plot_only, :])
                labels = test_y.numpy()[:plot_only]
                plot_with_labels(low_dim_embs, labels)
plt.ioff()
#打印10个测试数据集中的数据
test_output, _ = cnn(test_x[:10])
pred_y = torch.max(test_output, 1)[1].data.numpy()
print(pred_y, 'Prediction Number')
print(test_y[:10].numpy(),'Real Number')

 运行结果以及可视化内容如下:
Pytorch、TensorFlow、Keras框架下使用卷积神经网络实现MNIST分类(附所有实现代码)_第1张图片
Pytorch、TensorFlow、Keras框架下使用卷积神经网络实现MNIST分类(附所有实现代码)_第2张图片
Pytorch、TensorFlow、Keras框架下使用卷积神经网络实现MNIST分类(附所有实现代码)_第3张图片

torch.Size([60000, 28, 28])
torch.Size([60000])
CNN(
  (Conv1): Sequential(
    (0): Conv2d(1, 16, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (1): ReLU()
    (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (Conv2): Sequential(
    (0): Conv2d(16, 32, kernel_size=(5, 5), stride=(1, 1), padding=(2, 2))
    (1): ReLU()
    (2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  )
  (out): Linear(in_features=1568, out_features=10, bias=True)
)
Epoch: 0 |train loss: 2.3102 |test accuracy: 0.15
Epoch: 0 |train loss: 0.5123 |test accuracy: 0.80
...
Epoch: 2 |train loss: 0.0223 |test accuracy: 0.98
Epoch: 2 |train loss: 0.0308 |test accuracy: 0.98
[7 2 1 0 4 1 4 9 5 9] Prediction Number
[7 2 1 0 4 1 4 9 5 9] Real Number

Process finished with exit code 0

TensorFlow框架下搭建mnist分类卷积神经网络

 在TensorFlow框架下搭建神经网络思路步骤如下:

  1. 导入相关包;
  2. 定义学习率、批处理大小;
  3. 数据预处理;
  4. 构建两层CNN模型(卷积层、激活函数、池化层);
  5. 定义损失函数,优化器、模型评估指标;
  6. 构建图会话;
  7. 运行模型;

 全部示例代码如下:

#基于TensorFlow框架实现卷积神经网络的mnist分类
#Author J.A.
#Data 2022.2.7
#加入可视化内容

#导入相关包
import tensorflow as tf
#引入mnist数据集
from tensorflow.examples.tutorials.mnist import input_data
import numpy as np
import matplotlib.pyplot as plt

#定义一个随机种子
tf.set_random_seed(1)
np.random.seed(1)

#定义批处理集大小,学习率
batch_size = 50
lr = 0.001

#加载mnist数据集,并选择为one-hot编码
mnist = input_data.read_data_sets('./mnist', one_hot = True)
test_x = mnist.test.images[:2500]
test_y = mnist.test.labels[:2500]

#画图示例
print(mnist.train.images.shape) #(55000,28*28)
print(mnist.train.labels.shape) #(55000,10)
plt.imshow(mnist.train.images[0].reshape(28,28),cmap='gray')
plt.title('%i' % np.argmax(mnist.train.labels[0]))
plt.show()
#加载数据以及预处理
tf_x = tf.placeholder(tf.float32,[None,28*28]) / 255.   #placeholder插入值
image = tf.reshape(tf_x,[-1,28,28,1])                   #[batch,heigth,width,channel]
tf_y = tf.placeholder(tf.int32,[None,10])               #输入y

#构建CNN模型
#网络第一层
Conv1 = tf.layers.conv2d(               #此时特征维度(28,28,1)
    inputs = image,
    filters = 16,
    kernel_size = 5,
    strides = 1,
    padding = 'same',                   #padding为same时,不改变特征图长宽
    activation = tf.nn.relu
)                                       #此时特征维度(28,28,16)
Pool1 = tf.layers.max_pooling2d(
    Conv1,
    pool_size=2,
    strides=2,
)                                       #此时特征维度(14,14,16)
#网络第二层
Conv2 = tf.layers.conv2d(Pool1, 32, 5, 1, 'same',activation=tf.nn.relu)     #此时特征维度(14,14,32)
Pool2 = tf.layers.max_pooling2d(Conv2, 2, 2)                     #此时特征维度(7,7,32)
flatten = tf.reshape(Pool2, [-1, 7*7*32])                        #加入全连接层维度为(1568)
output =  tf.layers.dense(flatten, 10)                           #输出层维度(10)

#定义损失函数以及优化器
loss = tf.losses.softmax_cross_entropy(onehot_labels = tf_y, logits = output)
train_op = tf.train.AdamOptimizer(lr).minimize(loss)

#定义评估指标
accuracy = tf.metrics.accuracy(     #return(acc, update_op),and create 2 local variables
    labels =tf.argmax(tf_y, axis = 1), predictions = tf.argmax(output, axis = 1),)[1]

#构建图,Session会话
sess = tf.Session()
#此处的local_variables_initializer()是为了accuracy_op
init_op = tf.group(tf.global_variables_initializer(), tf.local_variables_initializer())
sess.run(init_op)           #初始化图的变量

#构建模型可视化(可忽略)
from matplotlib import cm
try: from sklearn.manifold import TSNE; HAS_SK = True
except: HAS_SK = False; print('\nPlease install sklearn for layer visualization\n')
def plot_with_labels(lowDWeights, labels):
    plt.cla(); X, Y = lowDWeights[:, 0], lowDWeights[:, 1]
    for x, y, s in zip(X, Y, labels):
        c = cm.rainbow(int(255 * s / 9)); plt.text(x, y, s, backgroundcolor=c, fontsize=9)
    plt.xlim(X.min(), X.max()); plt.ylim(Y.min(), Y.max()); plt.title('Visualize last layer'); plt.show(); plt.pause(0.01)
plt.ion()
#运行模型
for step in range(800):
    b_x, b_y = mnist.train.next_batch(batch_size)
    _, loss_ = sess.run([train_op, loss], {tf_x: b_x, tf_y: b_y})
    if step % 50 == 0:
        accuracy_, flatten_representation = sess.run([accuracy, flatten], {tf_x: test_x, tf_y: test_y})
        print('Step:', step, '|train loss: %.4f' % loss_, '|test accuracy: %.2f' % accuracy_)

        if HAS_SK:
            # Visualization of trained flatten layer (T-SNE)
            tsne = TSNE(perplexity=30, n_components=2, init='pca', n_iter=5000);
            plot_only = 800
            low_dim_embs = tsne.fit_transform(flatten_representation[:plot_only, :])
            labels = np.argmax(test_y, axis=1)[:plot_only];
            plot_with_labels(low_dim_embs, labels)
plt.ioff()

#在测试集中打印10个预测值
test_output = sess.run(output, {tf_x: test_x[:10]})
pred_y  = np.argmax(test_output, 1)
print(pred_y, 'prediction number')
print(np.argmax(test_y[:10], 1), 'real number')

 其运行结果以及可视化结果如下:
Pytorch、TensorFlow、Keras框架下使用卷积神经网络实现MNIST分类(附所有实现代码)_第4张图片

Pytorch、TensorFlow、Keras框架下使用卷积神经网络实现MNIST分类(附所有实现代码)_第5张图片

Pytorch、TensorFlow、Keras框架下使用卷积神经网络实现MNIST分类(附所有实现代码)_第6张图片

(55000, 784)
(55000, 10)
Step: 0 |train loss: 2.2956 |test accuracy: 0.13
Step: 50 |train loss: 0.3620 |test accuracy: 0.47
...
Step: 650 |train loss: 0.0490 |test accuracy: 0.87
Step: 700 |train loss: 0.0273 |test accuracy: 0.88
Step: 750 |train loss: 0.0909 |test accuracy: 0.88
[7 2 1 0 4 1 4 9 5 9] prediction number
[7 2 1 0 4 1 4 9 5 9] real number

Process finished with exit code 0

Keras框架下搭建mnist分类卷积神经网络

 思路:

  1. 创建数据部分,包括数据预处理,数据的训练集、测试集划分;
  2. 创建CNN的重要组成部分,创建神经网络,Sequential(),然后通过model.add()添加卷积层、激活函数、最大池化层,之后添加全连接层等等
  3. 定义优化器、模型配置等等
  4. 运行模型
  5. 评估模型

 全部代码如下:

'''
#基于Keras实现卷积神经网络的mnist分类
#Author J.A.
#Data 2022.2.6
#在Tensorflow下实现Keras

#导入相关包
import numpy as np
#设置随机种子
np.random.seed(2022)
from tensorflow.keras.datasets import mnist        #从Keras的datasets库导入mnist数据集
#from tensorflow.keras.utils import np_utils
from tensorflow.python.keras.utils.np_utils import to_categorical
from tensorflow.keras.models import Sequential
#引入Keras模型框架以及卷积层、激活函数、池化层、全连接层等
from tensorflow.keras.layers import Dense, Activation, Convolution2D, MaxPool2D,Flatten
from tensorflow.keras.optimizers import Adam

#training X.shape为(60000,28*28), Y.shape(60000,)
#test X.shape为(10000,28*28),Y.shape(10000,)

(X_train, y_train),(X_test, y_test) = mnist.load_data()         #载入数据

#对数据进行最简单的处理
#对训练集数据进行预处理,(-1是指smaple数据,-1指全部数据,1是指一维图像,
# 28*28是指数据大小()/255进行均值处理)
X_train = X_train.reshape(-1,1,28,28) / 255.
X_test = X_test.reshape(-1,1,28,28) / 255.

#将其转变为ONE-Hot编码
y_train = to_categorical(y_train, num_classes = 10)
y_test = to_categorical(y_test, num_classes = 10)
#创建CNN模型
model = Sequential()
#添加卷积层、激活函数、池化层等
# Conv layer1
model.add(Convolution2D(
    batch_input_shape=(None, 1, 28, 28),
    filters = 32,        #卷积核数量
    kernel_size = 5,    #卷积核大下
    strides = 1,        #步长
    padding = 'same',   #降维操作
    data_format = 'channels_first',
))      #维度关系   (32,28,28)
model.add(Activation('relu'))
model.add(MaxPool2D(
    pool_size = 2,       #卷积核大下
    strides = 2,         #步长
    padding = 'same',    #降维操作
    data_format = 'channels_first',
))      #维度关系(32,14,14)
# Conv layer2
model.add(Convolution2D(64, 5, strides = 1, padding = 'same',data_format='channels_first'))
#维度关系(64, 14, 14)
model.add(Activation('relu'))
model.add(MaxPool2D(2,2,'same',data_format='channels_first'))
#维度关系(64,7,7)

#添加全连接层1
model.add(Flatten())    #维度关系64*7*7=3136, output shape(1024)
model.add(Dense(1024))
model.add(Activation('relu'))
#添加全连接层2
model.add(Dense(10))    #维度关系(10)
model.add(Activation('softmax'))

#定义优化器
adam = Adam(lr = 1e-4)
#模型配置
model.compile(optimizer = adam,
              loss = 'categorical_crossentropy',
              metrics = ['accuracy'])
print('Training------------Begin!!!')
#运行模型
model.fit(X_train, y_train, epochs = 1, batch_size = 64,)
print('\nTesting----------Begin!!!')
#评估模型
loss, accuracy = model.evaluate(X_test, y_test)
#打印运行结果
print('\ntest loss: ', loss)
print('\ntest accuracy: ', accuracy)

 基于Keras的mnist数据集分类运行结果如下:

10000/10000 [==============================] - 3s 296us/sample - loss: 0.0853 - acc: 0.9752

test loss:  0.08534580951035023

test accuracy:  0.9752

Process finished with exit code 0

你可能感兴趣的:(机器学习算法,pytorch,cnn,tensorflow)