深度学习和图像分类阶段分配和阶段总结

深度学习和图像分类阶段分配和阶段总结

深度学习任务

问题1:神经网络构建

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QhwMOh8z-1645955114250)(F:\Python学习\129黑马人工智能2.0课程\学习随笔\阶段4计算机视觉与图像处理\深度学习与CV随笔\第四章图像分类随笔\笔记图片\01.神经网络构建.jpg)]

问题1代码

# 导入工具包
import tensorflow as tf
from tensorflow.keras import layers
from tensorflow import keras

用function API构建

# 定义模型的输入
inputs = tf.keras.Input(shape=(784,),name="input")
# 四个隐层 
# 第一层 520,relu
x = tf.keras.layers.Dense(520, activation="relu",name="layer1")(inputs)
# 第二层 320 relu
x = tf.keras.layers.Dense(320,activation="relu",name="layer2")(x)
# 第三层 240 relu
x = tf.keras.layers.Dense(240,activation="relu",name="layer3")(x)
# 第四层 120 relu
x = tf.keras.layers.Dense(120,activation="relu",name="layer4")(x)
# 输出层 10 softmax
outputs = tf.keras.layers.Dense(10,activation="softmax",name="layer5")(x)
# 使用Model来创建模型,指明输入和输出
model = tf.keras.Model(inputs=inputs,outputs=outputs,name="my_model")
# 展示模型结果
model.summary()
Model: "my_model"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input (InputLayer)           [(None, 784)]             0         
_________________________________________________________________
layer1 (Dense)               (None, 520)               408200    
_________________________________________________________________
layer2 (Dense)               (None, 320)               166720    
_________________________________________________________________
layer3 (Dense)               (None, 240)               77040     
_________________________________________________________________
layer4 (Dense)               (None, 120)               28920     
_________________________________________________________________
layer5 (Dense)               (None, 10)                1210      
=================================================================
Total params: 682,090
Trainable params: 682,090
Non-trainable params: 0
_________________________________________________________________

通过sequential的方式进行构建

# 定义模型,包括5层
model = keras.Sequential(
[
    #第一层:神经元个数为520,激活函数为relu
    layers.Dense(520,activation="relu",name="layer1",input_shape=(1,784)),
    #第二层:神经元个数为320,激活函数为relu
    layers.Dense(320,activation="relu",name="layer2"),
    #第三层:神经元个数为240,激活函数为relu
    layers.Dense(240,activation="relu",name="layer3"),
    #第四层:神经元个数为120,激活函数为relu
    layers.Dense(120,activation="relu",name="layer4"),
    #第五层(输出层):神经元个数10个,激活函数为softmax
    layers.Dense(10,activation="softmax",name="layer5")
],
name="my_Sequential"
)
# 展示模型结果
model.summary()
# 模型展示
keras.utils.plot_model(model,show_layer_names=True)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DslMtgZc-1645955114251)(F:\Python学习\129黑马人工智能2.0课程\学习随笔\阶段4计算机视觉与图像处理\深度学习与CV随笔\第四章图像分类随笔\笔记图片\image-20220227100601475.png)]

通过model的子类构建

class MyModel(tf.keras.Model):
    #在init方法中定义网络层结构
    def __init__(self):
        super(MyModel,self).__init__()
        # 第一层:神经元个数:520,激活函数relu
        self.layer1 = tf.keras.layers.Dense(520,activation="relu",name="layer1",input_shape=(784,))
        # 第二层:神经元个数:320,激活函数:relu
        self.layer2 = tf.keras.layers.Dense(320,activation="relu",name="layer2")
        # 第三层:神经元个数:240,激活函数:relu
        self.layer3 = tf.keras.layers.Dense(240,activation="relu",name="layer3")
        # 第四层:神经元个数:120,激活函数:relu
        self.layer4 = tf.keras.layers.Dense(120,activation="relu",name="layer4")
        # 第五层:神经元个数:10,激活函数:softmax
        self.layer5 = tf.keras.layers.Dense(10,activation="softmax",name="layer5")
    
    # 在call方法中完成前向传播
    def call(self,inputs):
        x = self.layer1(inputs)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)
        return self.layer5(x)
    
# 实例化模型
model = MyModel()
# 设置一个输入,调用模型
x = tf.ones((1,784))
y=model(x)
model.summary()

问题2:特征图大小计算

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f4URV6Fw-1645955114253)(F:\Python学习\129黑马人工智能2.0课程\学习随笔\阶段4计算机视觉与图像处理\深度学习与CV随笔\第四章图像分类随笔\笔记图片\02.特征图大小计算.jpg)]

首先,关于这道题的计算方法有一个问题。上一课写的文章计算如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fbaYKFQE-1645955114253)(F:\Python学习\129黑马人工智能2.0课程\学习随笔\阶段4计算机视觉与图像处理\深度学习与CV随笔\第四章图像分类随笔\笔记图片\image-20220227103625915.png)]

注意上式有个+2P,这里带入这个公布发现不能能算出作业的结果,于是我找了一篇博客如下https://www.cnblogs.com/byugo/p/10634464.html,这里计算公式为n’= (n-k)/s+1,就不加那个2P了,这里不知道为啥,先留下这个问题,如果有朋友知道的话,真的麻烦您在评论区留言,感谢感谢!

问题2答案

  1. 首先输入的图像的高(height)为32,宽(weight)为32,通道数(D)为3,经过第一层卷积核大小(kernel_size)为5,步长(strides)为1的共6个卷积核进行卷积后,此时输出图像的大小为(32 – 5)/1 + 1 =28,输出图像的通道数则与卷积核的个数相同,所以输出图像大小为28 * 28 * 6
  2. 经过第一层池化层进行特征降维后,池化大小(pool_size)为2,步长为2,输出图像大小为(28 – 2 )/2 + 1 = 14,因为只有一个池化核,所以输出图像的通道数跟之前相同,此时输出图像大小为14 * 14 *6
  3. 经过第二层卷积层的时候,此时卷积核大小为5 * 5,步长为1,卷积核的个数为16,输出图像的大小为(14 – 5 )/1 + 1 = 10,通道数为16,此时输出图像大小为10 * 10 * 16
  4. 经过第二层池化层进行特征降维后,池化大小为2,步长为2,输出图像的长宽为(10 – 2 )/2 + 1 = 5,因为同样只有一个池化核,所以通道数依旧与之前相同,此时输出图像大小为5 * 5 * 16.

问题3:特征图计算

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZbpAqkn5-1645955114253)(F:\Python学习\129黑马人工智能2.0课程\学习随笔\阶段4计算机视觉与图像处理\深度学习与CV随笔\第四章图像分类随笔\笔记图片\03.特征图计算.jpg)]

问题3答案:

参考我之前写的博客:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P2t1rJMq-1645955114253)(F:\Python学习\129黑马人工智能2.0课程\学习随笔\阶段4计算机视觉与图像处理\深度学习与CV随笔\第四章图像分类随笔\笔记图片\image-20220227105511955.png)]

我在羊皮纸上写下了计算过程。字不好看,就凑合吧,哈哈哈哈!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9MyEQu92-1645955114255)(F:\Python学习\129黑马人工智能2.0课程\学习随笔\阶段4计算机视觉与图像处理\深度学习与CV随笔\第四章图像分类随笔\笔记图片\1.jpg)]

  1. 所以卷积后的特征图为:
    1 0
    4 -1
  2. RELU激活之后的特征图:大于0的为原值,小于0的置为0,所以激活函数处理后的特征图是:
    1 0
    4 0
  3. 这是最大池化层,所以取最大值,池化后的结果为4。

图像分类作业

问题:ResNet34

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RhRlOXWx-1645955114255)(F:\Python学习\129黑马人工智能2.0课程\学习随笔\阶段4计算机视觉与图像处理\深度学习与CV随笔\第四章图像分类随笔\笔记图片\01.resnet34.jpg)]

代码

import tensorflow as tf
from tensorflow.keras import layers,activations
from tensorflow import keras

建筑模型

# 构建残差块
class Residual(tf.keras.Model):
    #定义网络的层
    def __init__(self,num_channels,use_1x1conv=False,strides=1):
        super(Residual,self).__init__()
        #两个3x3的卷积层
        self.conv1=layers.Conv2D(num_channels,padding='same',kernel_size=3,strides=strides)
        self.conv2=layers.Conv2D(num_channels,padding='same',kernel_size=3)
        #判断是否使用1x1卷积层 来统一通道数
        if use_1x1conv==True:
            self.conv3=layers.Conv2D(num_channels,kernel_size=1,strides=strides)
        else:
            self.conv3=None
            
        #在每个卷积层后面都有一个BN层 标准化
        #这里定义网络层的次序 指的并不是模型里面各层之间的顺序  call方法里面前向传播的次序才决定模型里面个层的顺序
        self.bn1=layers.BatchNormalization()
        self.bn2=layers.BatchNormalization()

    
    #定义前向传播过程  决定模型里面各层之间的顺序
    def call(self,x):
        y=tf.keras.layers.Activation(activation='relu')(self.bn1(self.conv1(x)))
        y=self.bn2(self.conv2(y))
        
        if self.conv3:
            x=self.conv3(x)
        return tf.keras.layers.Activation(activation='relu')(y+x)
        
# ResNet模块构建
# 同一个残差模块里面的残差块的通道数(卷积核个数),卷积核大小整个模型都是是一样的3x3,
class ResnetBlock(tf.keras.layers.Layer):
    # 定义所需的网络层
    def __init__(self, num_channels, num_res, first_block=False):
        super(ResnetBlock, self).__init__()
        # 定义list来存储残差块
        self.listLayers = []
        # 按照要求的一个模块里面的残差块数目 循环 生成模块
        for i in range(num_res):
            # 如果不是第一个模块 是其他模块的是第一个残差块 则这个残差块的步长度需要是2降维 而且要加1x1的卷积核统一通道数目
            # 因为本次模块的输入图片来自上各模块的输出 上个模块的卷积核个数和本模块不同 所以上个模块输出的图片通道数和本模块的卷积核个数不同
            # 在最后+x的时候 需要把输入的x转化成本模块的通道数
            if i == 0 and first_block == False:
                self.listLayers.append(
                    Residual(num_channels, use_1x1conv=True, strides=2))
            else:
                self.listLayers.append(Residual(num_channels))
    # 定义前向传播的过程
    def call(self, x):
        for layer in self.listLayers.layers:
            x = layer(x)
        return x
# 模型构建
class ResNet(tf.keras.Model):
    #定义各个层 其中先传入参数(每个模块里面的残差快个数) 整个模型可以改变每个模块残差块的个数 和残差块的卷积核个数 但保证每个模块里残差块的卷积核个数都一样
    def __init__(self,num_blocks):
        super(ResNet,self).__init__()
        #输入层 64个7x7大小卷积核的卷积层 步长度是2
        self.conv=layers.Conv2D(64,kernel_size=7,strides=2,padding='same')
        #BN层
        self.bn=layers.BatchNormalization()
        #激活函数
        self.relu=layers.Activation('relu')
        #池化
        self.mp=layers.MaxPool2D(pool_size=3,strides=2,padding='same')
        #几个串联的block模块(内含多个残差块)
        #每个残差模块里的残差块卷积核个数都相等=残差块里各卷积层卷积核个数
        self.res_block1=ResnetBlock(64,num_blocks[0],first_block=True)
        self.res_block2=ResnetBlock(128,num_blocks[1])
        self.res_block3=ResnetBlock(256,num_blocks[2])
        self.res_block4=ResnetBlock(512,num_blocks[3])
        #输出部分 首先全局平均池化层
        self.gap=layers.GlobalAveragePooling2D()
        #全连接层
        self.fc=layers.Dense(units=10,activation=tf.keras.activations.softmax)
        #定义前向传播过程
    def call(self,x):
        #输入部分的传输过程
        x=self.conv(x)
        x=self.bn(x)
        x=self.relu(x)
        x=self.mp(x)
        #残差模块部分传输过程
        x=self.res_block1(x)
        x=self.res_block2(x)
        x=self.res_block3(x)
        x=self.res_block4(x)
        # 输出部分的传输
        x=self.gap(x)
        x=self.fc(x)
        return x
        
#实例化模型
mynet=ResNet([3,4,5,4])
print(mynet)
x=tf.random.uniform(shape=(1,224,224,1))
y=mynet(x)
mynet.summary()
<__main__.ResNet object at 0x0000029710D756A0>
Model: "res_net"
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
conv2d_102 (Conv2D)          multiple                  3200      
_________________________________________________________________
batch_normalization_93 (Batc multiple                  256       
_________________________________________________________________
activation (Activation)      multiple                  0         
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 multiple                  0         
_________________________________________________________________
resnet_block (ResnetBlock)   multiple                  223104    
_________________________________________________________________
resnet_block_1 (ResnetBlock) multiple                  1119360   
_________________________________________________________________
resnet_block_2 (ResnetBlock) multiple                  5649152   
_________________________________________________________________
resnet_block_3 (ResnetBlock) multiple                  17846784  
_________________________________________________________________
global_average_pooling2d (Gl multiple                  0         
_________________________________________________________________
dense_3 (Dense)              multiple                  5130      
=================================================================
Total params: 24,846,986
Trainable params: 24,830,730
Non-trainable params: 16,256
_________________________________________________________________

利用fashionmnist数据对网络进行训练

数据读取
import numpy as np
from tensorflow.keras.datasets import fashion_mnist
# 获取手写数字数据集
(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()
# 训练集数据维度的调整:N H W C
train_images = np.reshape(train_images,(train_images.shape[0],train_images.shape[1],train_images.shape[2],1))
# 测试集数据维度的调整:N H W C
test_images = np.reshape(test_images,(test_images.shape[0],test_images.shape[1],test_images.shape[2],1))
# 定义两个方法随机抽取部分样本演示
# 获取训练集数据
def get_train(size):
    # 随机生成要抽样的样本的索引
    index = np.random.randint(0, np.shape(train_images)[0], size)
    # 将这些数据resize成22*227大小
    resized_images = tf.image.resize_with_pad(train_images[index],224,224,)
    # 返回抽取的
    return resized_images.numpy(), train_labels[index]
# 获取测试集数据 
def get_test(size):
    # 随机生成要抽样的样本的索引
    index = np.random.randint(0, np.shape(test_images)[0], size)
    # 将这些数据resize成224*224大小
    resized_images = tf.image.resize_with_pad(test_images[index],224,224,)
    # 返回抽样的测试样本
    return resized_images.numpy(), test_labels[index]

# 获取训练样本和测试样本
train_images,train_labels = get_train(256)
test_images,test_labels = get_test(128)
模型编译
#优化器
optimizer=tf.keras.optimizers.SGD(learning_rate=0.01,momentum=0.9)
#模型编译
mynet.compile(optimizer=optimizer,loss='sparse_categorical_crossentropy',metrics=['accuracy'])
模型训练
# 模型训练:指定训练数据,batchsize,epoch,验证集
mynet.fit(train_images,train_labels,batch_size=128,epochs=3,verbose=1,validation_split=0.1)
Epoch 1/3
2/2 [==============================] - 33s 16s/step - loss: 3.4795 - accuracy: 0.1087 - val_loss: 93.5103 - val_accuracy: 0.0769
Epoch 2/3
2/2 [==============================] - 29s 14s/step - loss: 3.2747 - accuracy: 0.1261 - val_loss: 76.9233 - val_accuracy: 0.0769
Epoch 3/3
2/2 [==============================] - 26s 13s/step - loss: 2.7347 - accuracy: 0.3043 - val_loss: 65.8635 - val_accuracy: 0.1923
模型评估
mynet.evaluate(test_images,test_labels)
4/4 [==============================] - 3s 857ms/step - loss: 61.4498 - accuracy: 0.0703
[61.44978332519531, 0.0703125]
遇到问题:tensorflow 里面fashion_mnist下载失败(超时)的问题

下载自带的数据集太慢了,那么推荐从网上下载数据集,我直接分享到百度网盘

链接:https://pan.baidu.com/s/1YwN60rFsWy8SqGjrxsDVwA
提取码:cd69
下载之后移动到C盘C:\Users\LH.keras\datasets路径下。

阶段总结

学习了深度学习的内容后,感觉之前学过的神经网络的某些部分顿时豁然开朗。之前第一次学,真的是怀疑人生。 . . .一开始以为卷积神经网络会很复杂,但是看完之后觉得只要掌握其中的重要知识点就很容易掌握。所以当你遇到一个当时学不来,觉得难的知识点时,可以稍微发脾气,出去玩放松一下,但不能放弃,可以暂时跳过,继续学习后面的,等待以后的接触会有一种“暗中明明的另一个村庄”的感觉!

学习了图像分类后,感觉自己第一次进入了计算机视觉的大门。接下来,我将学习目标检测的内容。学习最重要的是坚持。为了完成项目,不断学习!

版权声明:本文为博主最白の白菜原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/qq_43966129/article/details/123167439

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
乘风的头像乘风管理团队
上一篇 2022年3月1日 下午3:36
下一篇 2022年3月1日 下午3:54

相关推荐