文章目录
- 环境
- 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、两个卷积加一个池化层