当前位置: 代码迷 >> 综合 >> 深度学习入门demo mnist
  详细解决方案

深度学习入门demo mnist

热度:32   发布时间:2023-12-28 04:47:48.0

文章目录

  • 环境
  • 1、全连接层实现
  • 2、使用LeNet-5实现
    • 模型框架
    • 实现代码
    • 模型总结
  • 3、AlexNet
  • 模型框架
  • 模型实现
    • 模型总结
  • VGG
    • 模型总结

环境

python3.7
gpu: RTX3060
CUDA: 11.4
cudnn: 8.6
tensorflow-gpu: 2.5.0

1、全连接层实现

所有的网络层使用全连接层,有BN和dropout,无卷积部分。
流程:
额外实现:
one-hot编码、搭建顺序模型
主函数:
读取数据----->图片变为向量、label变为one-hot------->训练------>画图
代码:

import keras.layers
import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.layers import Dense, Dropout, Activation, BatchNormalization
import numpy as np
import matplotlib.pyplot as pltdef to_one_hot(label, nb_classes):sample_number = len(label)arr = np.zeros(shape=(sample_number, nb_classes))y = np.unique(label, nb_classes, return_inverse=True)for i, j in zip(range(sample_number), y[2]):arr[i, j] = 1return arrdef mol():model = tf.keras.Sequential()'''第一层'''model.add(Dense(512, activation='relu',input_shape=(784,)))model.add(BatchNormalization())model.add(Dropout(0.2))'''第二层'''model.add(Dense(512, activation='relu',kernel_initializer=tf.keras.initializers.he_normal(seed=64)))model.add(BatchNormalization())model.add(Dropout(0.2))'''第三层'''model.add(Dense(128, activation='relu',kernel_initializer=tf.keras.initializers.he_normal(seed=56)))model.add(BatchNormalization())model.add(Dropout(0.2))'''输出层'''model.add(Dense(10, activation='softmax'))return modelif __name__ == '__main__':(X_train, y_train), (X_test, y_test) = mnist.load_data()# print(X_train.shape) (60000, 28, 28)# print(X_test.shape) (10000, 28, 28)'''数据集的形状和标签进行处理:1、标签变成one-hot形式2、数据进行reshape'''y_train = to_one_hot(y_train, nb_classes=10)y_test = to_one_hot(y_test, nb_classes=10)X_train = X_train.reshape(60000, -1) # 需要转化为向量的形式X_test = X_test.reshape(10000, -1)model = mol()model.compile(loss=tf.keras.losses.categorical_crossentropy,metrics=tf.keras.metrics.categorical_accuracy,)hist = model.fit(X_train, y_train, epochs=10, batch_size=128,validation_data=(X_test, y_test),verbose=1,use_multiprocessing=True)print(hist.history)plt.figure(figsize=(10, 8))# 需要根据hist.history的参数去进行更改loss这些内容plt.plot(hist.history['loss'], label='train_loss') plt.plot(hist.history['categorical_accuracy'], label='train_accuracy')plt.plot(hist.history['val_loss'], label='train_loss')plt.plot(hist.history['val_categorical_accuracy'], label='train_accuracy')plt.legend()plt.grid()plt.show()

结果:
在这里插入图片描述

2、使用LeNet-5实现

LeNet-5中的5意思为该网络中卷积层和池化层一共为5层

模型框架

LeNet-5的模型框架:
在这里插入图片描述
图中红色为卷积层,绿色为最大池化层(下载样层),蓝色为全连接层。

实现代码

import keras.layers
import numpy as np
import tensorflow as tf
from tensorflow.keras.datasets import mnist
from tensorflow.keras.layers import Dense, Dropout, Activation, BatchNormalization
import utils''' 使用LeNet-5结构,其中卷积层和全连接层一共为5层 '''def LeNet():model = tf.keras.Sequential()'''第一层:卷积层'''model.add(keras.layers.Conv2D(filters=6, kernel_size=5, activation='sigmoid', input_shape=(28, 28, 1) # 一共有156个参数))'''第二层:MaxPooling层'''model.add(keras.layers.MaxPooling2D(pool_size=2, strides=2  # 本层没有参数 池化层只不过是一个特征提取的规则而已,不需要参数))'''第三层:卷积层'''model.add(keras.layers.Conv2D(filters=16, kernel_size=5, activation='sigmoid'))'''第四层:MaxPooling层'''model.add(keras.layers.MaxPooling2D(pool_size=2, strides=2))'''在进行全连接层之前,需要进行撑平'''model.add(keras.layers.Flatten())'''第五层:全连接层,sigmoid'''model.add(keras.layers.Dense(units=120, activation='sigmoid'))'''第六层:全连接层,sigmoid'''model.add(keras.layers.Dense(units=84, activation='sigmoid'))'''输出层:全连接层,softmax'''model.add(Dense(10, activation='softmax'))return modelif __name__ == '__main__':(X_train, y_train), (X_test, y_test) = mnist.load_data()# print(X_train.shape) (60000, 28, 28)# print(X_test.shape) (10000, 28, 28)### 第一步 数据转化成(样本数,长,宽,通道数)的形式 ###X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], X_train.shape[2], 1)).astype('float64')X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], X_test.shape[2], 1)).astype('float64')################# 第二步 进行标签转化y_train = utils.to_one_hot(y_train, nb_classes=10)y_test = utils.to_one_hot(y_test, nb_classes=10)model = LeNet()model.compile(loss=tf.keras.losses.categorical_crossentropy,metrics=tf.keras.metrics.categorical_accuracy)history = model.fit(X_train, y_train, epochs=10, batch_size=128,validation_data=(X_test, y_test), verbose=1, use_multiprocessing=True)print(history)

其中utils是自己写的一个工具文件,里面的to_one_hot函数实现如下:

# label直接传过来即可,nb_classes是总共有几类
def to_one_hot(label, nb_classes):# 获得样本数sample_number = len(label)# 0化矩阵arr = np.zeros(shape=(sample_number, nb_classes))# 为了防止重复,主要是np.unique函数的操作y = np.unique(label, nb_classes, return_inverse=True)for i, j in zip(range(sample_number), y[2]):arr[i, j] = 1return arr

模型总结

1、是卷积层在图像上首次使用
2、模型结构简单
3、池化层核大小为(2,2),步长为2.也就是经过池化层后图像大小减少为原来的一半

3、AlexNet

模型框架

Model: "sequential"
_________________________________________________________________
Layer (type)                 Output Shape              Param # 
=================================================================
conv2d (Conv2D)              (None, 55, 55, 96)        11712     
_________________________________________________________________
max_pooling2d (MaxPooling2D) (None, 18, 18, 96)        0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 18, 18, 256)       614656    
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 8, 8, 256)         0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 8, 8, 384)         885120    
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 8, 8, 384)         1327488   
_________________________________________________________________
conv2d_4 (Conv2D)            (None, 8, 8, 256)         884992    
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 3, 3, 256)         0         
_________________________________________________________________
flatten (Flatten)            (None, 2304)              0         
_________________________________________________________________
dense (Dense)                (None, 4096)              9441280   
_________________________________________________________________
dropout (Dropout)            (None, 4096)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 4096)              16781312  
_________________________________________________________________
dropout_1 (Dropout)          (None, 4096)              0         
_________________________________________________________________
dense_2 (Dense)              (None, 10)                40970     
=================================================================
Total params: 29,987,530
Trainable params: 29,987,530
Non-trainable params: 0
_________________________________________________________________
NoneProcess finished with exit code 0

模型实现

import numpy as np
import tensorflow as tf
from tensorflow.keras.datasets import mnist
import matplotlib.pyplot as pltimport utilsdef AlexNet():model = tf.keras.Sequential()model.add(tf.keras.layers.Conv2D(filters=96, kernel_size=11, strides=4, activation='relu') )model.add(tf.keras.layers.MaxPooling2D(pool_size=2, strides=3))model.add(tf.keras.layers.Conv2D(filters=256, kernel_size=5, padding='same', activation='relu'))model.add(tf.keras.layers.MaxPooling2D(pool_size=3, strides=2))model.add(tf.keras.layers.Conv2D(filters=384, kernel_size=3, padding='same', activation='relu'))model.add(tf.keras.layers.Conv2D(filters=384, kernel_size=3, padding='same', activation='relu'))model.add(tf.keras.layers.Conv2D(filters=256, kernel_size=3, padding='same', activation='relu'))model.add(tf.keras.layers.MaxPooling2D(pool_size=3, strides=2))model.add(tf.keras.layers.Flatten())model.add(tf.keras.layers.Dense(units=4096, activation='relu'))model.add(tf.keras.layers.Dropout(0.5))model.add(tf.keras.layers.Dense(units=4096, activation='relu'))model.add(tf.keras.layers.Dropout(0.5))model.add(tf.keras.layers.Dense(10, activation='softmax'))return modeldef get_data():(X_train, y_train), (X_test, y_test) = mnist.load_data()X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], X_train.shape[2], 1)).astype('float64')X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], X_test.shape[2], 1)).astype('float64')y_train = utils.to_one_hot(y_train, 10)y_test = utils.to_one_hot(y_test, 10)return X_train, X_test, y_train, y_testdef test_data(X_test, y_test, size):index = np.random.randint(0, X_test.shape[0], size=size)test = tf.image.resize_with_pad(X_test[index], target_height=277, target_width=277,)return test.numpy(), y_test[index]def train_data(X_train, y_train, size):index = np.random.randint(0, X_train.shape[0], size=size)train = tf.image.resize_with_pad(X_train[index], target_height=227, target_width=227,)return train.numpy(), y_train[index]if __name__ == '__main__':X_train, X_test, y_train, y_test = get_data()X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], X_test.shape[2], 1))X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], X_train.shape[2], 1))# 将图片转化为227*227大小 因为图片量太大,会导致显存容量不足,这里随机进行图片的选取X_train, y_train = train_data(X_train, y_train, size=256)X_test, y_test = test_data(X_test, y_test, size=128)y_train = utils.to_one_hot(y_train, 10)y_test = utils.to_one_hot(y_test, 10)# print(X_test.shape)# print(y_test)model = AlexNet()model.compile(loss=tf.keras.losses.categorical_crossentropy, metrics=tf.keras.metrics.categorical_accuracy,optimizer=tf.keras.optimizers.Adam(learning_rate=0.01))# print(model.summary())history = model.fit(X_train, y_train, epochs=3, batch_size=32, validation_split=0.1, use_multiprocessing=True)# utils.figure_plot(history)

模型总结

1、模型总共8层
2、5层卷积层,3层全连接层,除了最后输出层外,其余全连接层后面都有Dropout层
3、激活函数为relu和softmax,relu激活函数能够较好防止梯度爆炸,也能减少计算量
4、池化层核大小均为(3,3),步长为2

VGG

模型总结

1、模型结构很简单
2、网络层很深
3、卷积层的卷积核大小均为2
4、两个卷积加一个池化层

  相关解决方案