有料,有料,微信搜索 【K同学啊】 关注这个分享干货的博主。
本文 GitHub https://github.com/kzbkzb/Python-AI 已收录,有 Python、深度学习的资料以及我的系列文章。
大家好,我是「K同学啊 」!
前几天翻译了一篇讲十大CNN结构的文章(「多图」图解10大CNN架构),原作者思路十分清晰,从时间线上,将近年来CNN发展过程中一些比较重要的网络模型做了一一介绍。我发现其中好像有几个网络模型并没有在《深度学习100例》出现,接下一段时间我将围绕这些网络模型进行实战讲解。
在90年代,由于支持向量机(Support Vecotr Machine,SVM)等算法的发展,深度学习的发展受到了很大的阻碍(尽管Geoffery Hinton在1986年发明的BP算法(Backpropagation)解决了神经网络的非线性分类学习的问题,但梯度消失的问题没有得到很好的解决)。但Yann LeCun等人坚持不懈,依然在该领域苦苦研究。1998年,Yann LeCun提出了LeNet-5网络。LeNet-5被誉为是卷积神经网络的“Hello Word”,足以见其重要性。
LeNet-5 是最简单的架构之一。它有 2 个卷积层和 3 个全连接层(LeNet-5 中的“5”——神经网络的名称通常来自于它们所具有的卷积层和全连接层的数量)。我们现在所知道的平均池化层被称为子采样层,它具有可训练的权重。这个架构有大约60,000 个参数。
刊物
我的环境:
来自专栏:《深度学习100例》
如果你是一名深度学习小白可以先看看我这个专门为你写的专栏:《小白入门深度学习》
如果使用的是CPU可以忽略这步
import tensorflow as tf
gpus = tf.config.list_physical_devices("GPU")
if gpus:
gpu0 = gpus[0] #如果有多个GPU,仅使用第0个GPU
tf.config.experimental.set_memory_growth(gpu0, True) #设置GPU显存用量按需使用
tf.config.set_visible_devices([gpu0],"GPU")
from tensorflow import keras
from tensorflow.keras import datasets, layers, models
import os,PIL
import tensorflow as tf
import matplotlib.pyplot as plt
# 支持中文
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
#隐藏警告
import warnings
warnings.filterwarnings('ignore')
(train_images, train_labels), (test_images, test_labels) = datasets.cifar10.load_data()
# 将像素的值标准化至0到1的区间内。
train_images, test_images = train_images / 255.0, test_images / 255.0
train_images.shape,test_images.shape,train_labels.shape,test_labels.shape
((50000, 32, 32, 3), (10000, 32, 32, 3), (50000, 1), (10000, 1))
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer','dog', 'frog', 'horse', 'ship', 'truck']
plt.figure(figsize=(20,10))
for i in range(40):
plt.subplot(5,10,i+1)
plt.xticks([])
plt.yticks([])
plt.grid(False)
plt.imshow(train_images[i], cmap=plt.cm.binary)
plt.xlabel(class_names[train_labels[i][0]])
plt.show()
batch = 32
model = keras.Sequential([
# 卷积层1
keras.layers.Conv2D(6, 5), # 使用6个5*5的卷积核对单通道32*32的图片进行卷积,结果得到6个28*28的特征图
keras.layers.MaxPooling2D(pool_size=2, strides=2), # 对28*28的特征图进行2*2最大池化,得到14*14的特征图
keras.layers.ReLU(), # ReLU激活函数
# 卷积层2
keras.layers.Conv2D(16, 5), # 使用16个5*5的卷积核对6通道14*14的图片进行卷积,结果得到16个10*10的特征图
keras.layers.MaxPooling2D(pool_size=2, strides=2), # 对10*10的特征图进行2*2最大池化,得到5*5的特征图
keras.layers.ReLU(), # ReLU激活函数
# 卷积层3
keras.layers.Conv2D(120, 5), # 使用120个5*5的卷积核对16通道5*5的图片进行卷积,结果得到120个1*1的特征图
keras.layers.ReLU(), # ReLU激活函数
# 将 (None, 1, 1, 120) 的下采样图片拉伸成 (None, 120) 的形状
keras.layers.Flatten(),
# 全连接层1
keras.layers.Dense(84, activation='relu'), # 32*84
# 全连接层2
keras.layers.Dense(10, activation='softmax') # 32*10
])
model.build(input_shape=(batch, 32, 32, 3))
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
conv2d (Conv2D) (32, 28, 28, 6) 456
_________________________________________________________________
max_pooling2d (MaxPooling2D) (32, 14, 14, 6) 0
_________________________________________________________________
re_lu (ReLU) (32, 14, 14, 6) 0
_________________________________________________________________
conv2d_1 (Conv2D) (32, 10, 10, 16) 2416
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (32, 5, 5, 16) 0
_________________________________________________________________
re_lu_1 (ReLU) (32, 5, 5, 16) 0
_________________________________________________________________
conv2d_2 (Conv2D) (32, 1, 1, 120) 48120
_________________________________________________________________
re_lu_2 (ReLU) (32, 1, 1, 120) 0
_________________________________________________________________
flatten (Flatten) (32, 120) 0
_________________________________________________________________
dense (Dense) (32, 84) 10164
_________________________________________________________________
dense_1 (Dense) (32, 10) 850
=================================================================
Total params: 62,006
Trainable params: 62,006
Non-trainable params: 0
_________________________________________________________________
model.compile(optimizer='adam',
loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
metrics=['accuracy'])
epochs = 20
history = model.fit(train_images, train_labels, epochs=epochs,
validation_data=(test_images, test_labels))
Epoch 1/20
1563/1563 [==============================] - 23s 14ms/step - loss: 1.8339 - accuracy: 0.3194 - val_loss: 1.4007 - val_accuracy: 0.4835
Epoch 2/20
1563/1563 [==============================] - 21s 13ms/step - loss: 1.3719 - accuracy: 0.5025 - val_loss: 1.3414 - val_accuracy: 0.5132
Epoch 3/20
1563/1563 [==============================] - 21s 13ms/step - loss: 1.2513 - accuracy: 0.5491 - val_loss:
......
Epoch 18/20
1563/1563 [==============================] - 25s 16ms/step - loss: 0.7382 - accuracy: 0.7391 - val_loss: 1.1993 - val_accuracy: 0.6142
Epoch 19/20
1563/1563 [==============================] - 24s 15ms/step - loss: 0.7124 - accuracy: 0.7442 - val_loss: 1.2107 - val_accuracy: 0.6104
Epoch 20/20
1563/1563 [==============================] - 23s 15ms/step - loss: 0.6981 - accuracy: 0.7543 - val_loss: 1.1922 - val_accuracy: 0.6148
plt.imshow(test_images[1])
import numpy as np
pre = model.predict(test_images)
print(class_names[np.argmax(pre[1])])
ship
acc = history.history['accuracy']
val_acc = history.history['val_accuracy']
loss = history.history['loss']
val_loss = history.history['val_loss']
epochs_range = range(epochs)
plt.figure(figsize=(12, 4))
plt.subplot(1, 2, 1)
plt.plot(epochs_range, acc, label='Training Accuracy')
plt.plot(epochs_range, val_acc, label='Validation Accuracy')
plt.legend(loc='lower right')
plt.title('Training and Validation Accuracy')
plt.subplot(1, 2, 2)
plt.plot(epochs_range, loss, label='Training Loss')
plt.plot(epochs_range, val_loss, label='Validation Loss')
plt.legend(loc='upper right')
plt.title('Training and Validation Loss')
plt.show()
作为早期的网络模型,LeNet-5的不足(过拟合)也在这里体现出来了,也正是这些不完美才有了CNN后面的发展。
Seaborn 是一个画图库,它基于 Matplotlib 核心库进行了更高阶的 API 封装,可以让你轻松地画出更漂亮的图形。Seaborn 的漂亮主要体现在配色更加舒服、以及图形元素的样式更加细腻。
from sklearn.metrics import confusion_matrix
import seaborn as sns
import pandas as pd
# 定义一个绘制混淆矩阵图的函数
def plot_cm(labels, predictions):
# 生成混淆矩阵
conf_numpy = confusion_matrix(labels, predictions)
# 将矩阵转化为 DataFrame
conf_df = pd.DataFrame(conf_numpy, index=class_names ,columns=class_names)
plt.figure(figsize=(8,7))
sns.heatmap(conf_df, annot=True, fmt="d", cmap="BuPu")
plt.title('混淆矩阵@K同学啊',fontsize=15)
plt.ylabel('真实值',fontsize=14)
plt.xlabel('预测值',fontsize=14)
val_pre = []
val_label = []
#这里可以取部分验证数据生成混淆矩阵
for image, label in zip(test_images[:200], test_labels[:200]):
# 需要给图片增加一个维度
img_array = tf.expand_dims(image, 0)
# 使用模型预测图片
prediction = model.predict(img_array)
val_pre.append(class_names[np.argmax(prediction)])
val_label.append(class_names[label[0]])
plot_cm(val_label, val_pre)
深度学习新人必看:《小白入门深度学习》
往期精彩-卷积神经网络篇:
往期精彩-循环神经网络篇:
往期精彩-生成对抗网络篇:
本文选自专栏:《深度学习100例》
先赞后看,再收藏,养成好习惯!