深度学习训练营第二周

选题:彩色图片分类
难度:新手入门
语言:Python3、TensorFlow2
要求:

学习如何编写一个完整的深度学习程序
了解分类彩色图片会灰度图片有什么区别
测试集accuracy到达72%

一、 前期工作

1、导入数据

import tensorflow as tf
from tensorflow.keras import datasets,layers,models               #keras:指神经网络框架
import matplotlib.pyplot as plt

(train_images,train_labels),(test_images,test_labels) = datasets.cifar10.load_data()

2、归一化

  • 与第一周类似将像素值归一化到0-1
train_images,test_images = train_images/255.0,test_images/255.0

train_images.shape,test_images.shape,train_labels.shape

((50000, 32, 32, 3), (10000, 32, 32, 3), (50000, 1))

3、可视化图片

plt.figure(figsize=(20,10))
#根据结果,对图片编号对应分类进行标注
class_names = ['airplane', 'automobile', 'bird', 'cat', 'deer','dog', 'frog', 'horse', 'ship', 'truck']

for i in range(20):
    plt.subplot(5,10,i+1)
    plt.imshow(train_images[i])
    plt.yticks([])
    plt.xticks([])
    plt.xlabel(class_names[train_labels[i][0]])
    
plt.show()

深度学习训练营第二周_第1张图片

二、 构建CNN网络

根据相关理论,特征提取的误差主要来自两个方面:

(1)邻域大小受限造成的估计值方差增大;

(2)卷积层参数误差造成估计均值的偏移。

一般来说

mean-pooling能减小第一种误差(邻域大小受限造成的估计值方差增大),更多的保留图像的背景信息,

max-pooling能减小第二种误差(卷积层参数误差造成估计均值的偏移),更多的保留纹理信息。
Conv2D(): 卷积层,动态提取图片局部特征,tf.keras.layers.Conv2D(

  • input_shape = (高, 宽, 通道数), #仅在第一层有
  • filters = 卷积核个数,对应输出的维数
  • kernel_size = 卷积核尺寸,(n,k),如果为一个整数则宽和高相同
  • strides = 卷积横向和纵向的步长,如果为一个整数则横向和纵向相同
  • padding = ‘SAME’ or ‘VALID’,valid:表示不够卷积核大小的块,则丢弃;same表示不够卷积核大小的块就补0,所以输出和输入形状相同
  • activation = 激活函数
    )

Tips:反向传播算法

即,误差反向传播,建立在梯度下降基础上。
正向传播,输入信息经隐含层,逐步处理并传播至输出层,得到预测值,若与真实值不同,则计算损失函数
将该损失函数传入反向传播过程,逐层求出loss对各神经元权重的偏导,作为目标函数对权重梯度,并修改,直到误差达到期望
计算某一个系数对总误差的影响采用链式法则,主要该误差要将不同路径结果求和
系数更新公式为
在这里插入图片描述

Tips2:

与灰度图象不同,彩色图像通常有三个通道,即图像深度视为3,因此卷积核深度为3而灰度图为1,最终输出结果是将同一个卷积核对三个通道矩阵分别卷积后求和的结果

model = models.Sequential([                      #Sequential:顺序,制造一个容器
    layers.Conv2D(32,(3,3),activation = 'relu',input_shape=(32,32,3)),  #卷积层1,3*3
    layers.MaxPool2D((2,2)),   #池化层
    layers.Conv2D(64,(3,3),activation='relu'),
    layers.MaxPool2D((2,2)),
    layers.Flatten(),
    layers.Dense(64,activation='relu'), #全连接层提取特征
    layers.Dense(10,activation='softmax')
    
])            
model.summary()

Model: “sequential”


Layer (type) Output Shape Param #

conv2d (Conv2D) (None, 30, 30, 32) 896

max_pooling2d (MaxPooling2D (None, 15, 15, 32) 0
)

conv2d_1 (Conv2D) (None, 13, 13, 64) 18496

max_pooling2d_1 (MaxPooling (None, 6, 6, 64) 0
2D)

flatten (Flatten) (None, 2304) 0

dense (Dense) (None, 64) 147520

dense_1 (Dense) (None, 10) 650

=================================================================
Total params: 167,562
Trainable params: 167,562
Non-trainable params: 0


三、编译

model.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])

四、训练模型

history = model.fit(train_images,train_labels,epochs=10,validation_data=(test_images,test_labels))

Epoch 1/10
1563/1563 - 37s 22ms/step - loss: 1.4751 - accuracy: 0.4729 - val_loss: 1.2133 - val_accuracy: 0.5764
Epoch 2/10
1563/1563- 29s 19ms/step - loss: 1.1154 - accuracy: 0.6101 - val_loss: 1.0410 - val_accuracy: 0.6333
Epoch 3/10
1563/1563- 32s 20ms/step - loss: 0.9889 - accuracy: 0.6554 - val_loss: 0.9828 - val_accuracy: 0.6562
Epoch 4/10
1563/1563 - 31s 20ms/step - loss: 0.9118 - accuracy: 0.6839 - val_loss: 0.9593 - val_accuracy: 0.6695
Epoch 5/10
1563/1563 - 29s 19ms/step - loss: 0.8490 - accuracy: 0.7051 - val_loss: 0.9274 - val_accuracy: 0.6776
Epoch 6/10
1563/1563- 30s 19ms/step - loss: 0.7962 - accuracy: 0.7212 - val_loss: 1.0031 - val_accuracy: 0.6605
Epoch 7/10
1563/1563 - 31s 20ms/step - loss: 0.7539 - accuracy: 0.7363 - val_loss: 0.9010 - val_accuracy: 0.6927
Epoch 8/10
1563/1563 - 33s 21ms/step - loss: 0.7157 - accuracy: 0.7486 - val_loss: 0.9414 - val_accuracy: 0.6831
Epoch 9/10
1563/1563- 32s 20ms/step - loss: 0.6773 - accuracy: 0.7624 - val_loss: 0.9776 - val_accuracy: 0.6772
Epoch 10/10
1563/1563 - 32s 20ms/step - loss: 0.6494 - accuracy: 0.7714 - val_loss: 0.9521 - val_accuracy: 0.6868

六、模型评估

import matplotlib.pyplot as plt

plt.plot(history.history['accuracy'],label='accuracy')
plt.plot(history.history['val_accuracy'],label='val_accuracy')
plt.xlabel('Epoch')
plt.ylabel('accuracy')
plt.legend(loc='lower right')

test_loss,test_acc = model.evaluate(test_images,test_labels,verbose=2)
print(test_acc)

深度学习训练营第二周_第2张图片
0.6868000030517578
显然模型预测准确率过低,需要对模型进行优化

七 模型优化

实验2 添加新的卷积层

model2 = models.Sequential([
    layers.Conv2D(32,(3,3),padding='same',activation = 'relu',input_shape=(32,32,3)),   #为了防止卷积过多使得图像边缘消失,padding=‘same'
    layers.MaxPool2D((2,2)),   
    layers.Conv2D(64,(3,3),padding='same',activation='relu'),
    layers.MaxPool2D((2,2)),
    layers.Conv2D(128,(3,3),activation='relu',padding='valid'),
    layers.Flatten(),
    layers.Dense(128,activation='relu'), 
    layers.Dense(10,activation='softmax')])

model2.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])
history = model2.fit(train_images,train_labels,epochs=10,validation_data=(test_images,test_labels))
plt.plot(history.history['accuracy'],label='accuracy')
plt.plot(history.history['val_accuracy'],label='val_accuracy')
plt.xlabel('Epoch')
plt.ylabel('accuracy')
plt.legend(loc='lower right')

test_loss,test_acc = model2.evaluate(test_images,test_labels,verbose=2)

深度学习训练营第二周_第3张图片
可见测试集准确率已经达到72%,但训练集超过90%考虑是否存在过拟合

实验3 添加新的卷积层,并添加dropout层防止过拟合

我们一般在网络的最开始和结束的时候使用全连接层,而hidden layers则是网络中的卷积层。所以一般情况,在全连接层部分,采用较大概率的dropout而在卷积层采用低概率或者不采用dropout。

model3 = models.Sequential([
    layers.Conv2D(32,(3,3),padding='same',activation = 'relu',input_shape=(32,32,3)),   #为了防止卷积过多使得图像边缘消失,padding=‘same'
    layers.MaxPool2D((2,2)),   
    layers.Conv2D(64,(3,3),padding='same',activation='relu'),
    layers.MaxPool2D((2,2)),
    layers.Conv2D(128,(3,3),activation='relu',padding='valid'),
    layers.Flatten(),
    layers.Dense(128,activation='relu'),
    layers.Dropout(0.2),#该方法常用于全连接层部分
    layers.Dense(10,activation='softmax')])

model3.compile(optimizer='adam',
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=['accuracy'])
history = model3.fit(train_images,train_labels,epochs=10,validation_data=(test_images,test_labels))

Epoch 10/10
1563/1563 52s 33ms/step - loss: 0.4802 - accuracy: 0.8274 - val_loss: 0.8817 - val_accuracy: 0.7297

plt.plot(history.history['accuracy'],label='accuracy')
plt.plot(history.history['val_accuracy'],label='val_accuracy')
plt.xlabel('Epoch')
plt.ylabel('accuracy')
plt.legend(loc='lower right')

test_loss,test_acc = model3.evaluate(test_images,test_labels,verbose=2)

深度学习训练营第二周_第4张图片
第三次实验结果,测试集准确率接近73%,训练集为82.7%,相对来说过拟合的情况明显减弱

七、模型预测

plt.imshow(test_images[5])

深度学习训练营第二周_第5张图片

import numpy as np

pre = model3.predict(test_images)
print(class_names[np.argmax(pre[5])])

313/313 [==============================] - 3s 9ms/step
frog

总结

针对模型准确率不足的情况可以通过适当添加卷积层得到比较好的解决,但有可能导致模型过拟合,此时通过在模型开头或是结尾添加dropout层的方法得到一定的改善

你可能感兴趣的:(深度学习,神经网络,python)