这目录
深度学习及图像分类阶段作业与阶段总结
深度学习作业
问题1:神经网络构建
问题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)
通过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:特征图大小计算
首先这题计算方式有个疑问,以前上课写过的文章计算如下:
注意上式有个+2P,这里带入这个公布发现不能能算出作业的结果,于是我找了一篇博客如下https://www.cnblogs.com/byugo/p/10634464.html,这里计算公式为n’= (n-k)/s+1,就不加那个2P了,这里不知道为啥,先留下这个问题,如果有朋友知道的话,真的麻烦您在评论区留言,感谢感谢!
问题2答案
-
首先输入的图像的高(height)为32,宽(weight)为32,通道数(D)为3,经过第一层卷积核大小(kernel_size)为5,步长(strides)为1的共6个卷积核进行卷积后,此时输出图像的大小为(32 - 5)/1 + 1 =28,输出图像的通道数则与卷积核的个数相同,所以输出图像大小为28 * 28 * 6
-
经过第一层池化层进行特征降维后,池化大小(pool_size)为2,步长为2,输出图像大小为(28 - 2 )/2 + 1 = 14,因为只有一个池化核,所以输出图像的通道数跟之前相同,此时输出图像大小为14 * 14 *6
-
经过第二层卷积层的时候,此时卷积核大小为5 * 5,步长为1,卷积核的个数为16,输出图像的大小为(14 - 5 )/1 + 1 = 10,通道数为16,此时输出图像大小为10 * 10 * 16
-
经过第二层池化层进行特征降维后,池化大小为2,步长为2,输出图像的长宽为(10 - 2 )/2 + 1 = 5,因为同样只有一个池化核,所以通道数依旧与之前相同,此时输出图像大小为5 * 5 * 16.
问题3:特征图计算
问题3答案:
参考之前写过的博客:
我在演草纸上写出运算过程,字不好看,凑合凑合吧,哈哈哈哈哈哈!
-
所以卷积后的特征图是:
1 0
4 -1
-
RELU激活之后的特征图:大于0的为原值,小于0的置为0,所以激活函数处理后的特征图是:
1 0
4 0
-
这是最大池化层,所以取最大值,池化后的结果为4。
图像分类作业
问题:ResNet34
代码
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路径下。
阶段总结
学完深度学习方面的内容,感觉之前学习的神经网络一些不懂得地方都突然豁然开朗,之前第一次学习真的是怀疑人生。。。。一开始认为卷积神经网络会很复杂,但是看完之后,认为只要掌握他里面的重要知识点,就会很容易掌握。所以当遇到当时学习的时候不会的,感觉很难的知识点时,可以稍微发一点脾气,出去玩放松放松,但是不能放弃,可以先暂时跳过,继续学习后面的,等未来再次接触时会有“柳暗花明又一村”的感觉!
学习完图像分类,感觉像是初入计算机视觉的大门,接下来我将学习目标检测方面的内容,学习重要的是坚持,为了完成毕设,坚持学习下去!