深度学习零碎知识点

先给大家推荐一个学习tensorflow和keras的网址,基本上只要过一遍文档基本就可以拿下了:

https://tensorflow.google.cn/api_docs/python/tf/keras/Model

下面由浅入深的说几个初学深度学习遇到的坑:

关于Python:

  • 使用from package import
    item这种形式的时候,对应的item既可以是包里面的子模块(子包),或者包里面定义的其他名称,比如函数,类或者变量。
  • import语法会首先把item当作一个包定义的名称,如果没找到,再试图按照一个模块去导入。如果还没找到,恭喜,一个:exc:ImportError异常被抛出了。
  • 反之,如果使用形如import.tem.subitem.subsubitem这种导入形式,除了最后一项,都必须是包,而最后一项则可以是模块或者是包,但是不可以是类,函数或者变量的名字。

关于numpy:

1.区分三个点,无冒号,单冒号,双冒号:

  • a[…,2]:…表示遍历每行,2表示索引为2的所在列。
  • a[…,:2]:…表示遍历每行,:2表示索引为<2的0,1所在的列。
  • a[…,::2]:…表示遍历每行,2表示步长,选取多索引为0,2,4所在的列。
  • a[::-1]:表示取反,将所要输出的列表的固定维度取逆序。
import numpy
>>> a = numpy.array([[1,2,3,4,5],[6,7,8,9,10],[1,2,3,4,5],[6,7,8,9,10]])
>>> a
array([[ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10],
       [ 1,  2,  3,  4,  5],
       [ 6,  7,  8,  9, 10]])
>>> a[...,2]
array([3, 8, 3, 8])
>>> a[...,:2]
array([[1, 2],
       [6, 7],
       [1, 2],
       [6, 7]])
>>> a[...,::2]
array([[ 1,  3,  5],
       [ 6,  8, 10],
       [ 1,  3,  5],
       [ 6,  8, 10]])

2.关于tensorflow2.x版本中 .numpy() 的使用
在我们使用TensorFlow进行深度学习训练时,很多时候都是与Numpy数据打招呼,例如我们csv或者照片数据等。但是我们都知道,TensorFlow训练时都是使用Tensor来存储变量的,并且网络输出的结果也是Tensor。一般情况下我们不会感受到Numpy与Tensor之间的区别,因为TensorFlow网络在输入Numpy数据时会自动转换为Tensor来处理,由于2.x版本取消了session机制,开发人员可以直接执行 .numpy()方法转换tensor:

data_numpy = data_tensor.numpy()

不转换之前的print输出为tf.Tensor(1.0, shape=(), dtype=float32),转换后的输出为1.0

关于CNN

1.用7×7的卷积核和1×1的卷积核,以相同的步长下采样,二者有什么区别?
感受野不一样,7×7的滑窗大,提取区域也大。

2.pooling和用卷积核下采样的区别在哪里?
最直接的就是pooling和卷积的计算不一样,二者都会对feature map进行有效的信息提取,进行降维,pooling的好处在于计算量小,要么是max,要么是average,而conv的计算量大,但conv的好处在于可以交换通道间的信息,更有利于特征提取。

3.关于CNN输入图像尺寸要求
做一个简单的小总结:
1.由于有全连接层,因此如果不用预训练模型,就要保证自己的训练图像尺寸和预测图像尺相同;
2.如果用预训练模型,则自己的测试集输入图像尺寸必须和原模型训练尺寸相同;
3.如果迁移学习,把前面若干层权重固定,只训练后面包含全连接层的一部分网络层,即不是整体迁移,则不需要和原模型训练要求尺寸相同。

关于tensorflow

1.tensorflow中的数据类型
tensor有三个属性:数据,维度,数据类型,首先关于维度:维度要看张量的最左边有多少个左中括号,有n个,则这个张量就是n维张量。如下所示:

1    #维度为0的标量
[1,2,3]   #维度为1,一维向量
[[1,2],[3,4]]   #维度为2, 二维矩阵
[[[1,2],[3,4]],[[1,2],[3,4]]]   #维度为3,3维空间矩阵

在shape()的中括号中有多少个数字,就代表这个张量是多少维的张量。
2.关于tf.keras.metrics
在tensorflow2.x中我们进行模型编译的时候,会看到其中有一个参数是metrics,它用来在训练过程中监测一些性能指标,而这个性能指标是什么可以由我们来指定。性能评估函数类似于目标函数, 但是其评估结果不会用于训练
首先需要知道的是,如果是metrics下的一个类,那么它的实例化对象都有下面三个属性:

  • reset_states() 清除之前的计算结果,相当于复位重新开始计算
  • result() 计算并且返回结果
  • update_state() 将每一次更新的数据作为一组数据,这样在真正计算的时候会计算出每一组的结果,然后求多组结果的平均值。但并不会直接计算,计算还是在调用 result() 时完成
    - 在m.result() 会得到一个tensor的数据,再使用.numpy将它转化为numpy的数据
    下面是一个eg:
m = tf.keras.metrics.Accuracy() #新建一个实例化对象
m.update_state([1, 2, 3, 4], [0, 2, 3, 4]) #向对象中添加数据
m.result().numpy() 
#输出:0.75
m.reset_states() 
m = tf.keras.metrics.CategoricalAccuracy() 
_ = m.update_state([[0, 0, 1], [0, 1, 0]], [[0.1, 0.9, 0.8], 
                    [0.05, 0.95, 0]]) 
m.result().numpy() 
#输出:0.5
m = tf.keras.metrics.SparseCategoricalAccuracy() 
_ = m.update_state([[2], [1]], [[0.1, 0.9, 0.8], [0.05, 0.95, 0]]) 
m.result().numpy()
#输出:0.5

3.关于self.conv1 = Conv2D(32, 3, activation=‘relu’)和x = self.conv1(x)

前者是类的实例化对象,后者是对执行卷积操作,为什么在最后有(x)?这是tensorflow的一种特定写法,记住就行,其目的是:向卷积层中添加数据,然后返回一个输出,上面的两个形式也可以这样写:

  • x = Conv2D(32, 3, activation=‘relu’)(x)
    注:这和我们函数的输入是有所区别的,正常情况下,函数的输入都是放在括号内部,而这里有两个括号,其将类的实例化和添加数据合并到了一起,属于一种固定的写法。tensorflow官网中有详细说明:
    在这里插入图片描述

关于模型训练

在这里插入图片描述
如果只有CPU的话是一个串行过程,CPU首先载入图片并进行预处理,再进行训练,不断重复,如果用GPU的话,CPU只负责图片的读取及预处理过程,GPU就专心的对网络进行训练,CPU每读取一个batch,GPU就训练一个batch,耗时明显减少了很多。
为什么要使用tf.data.Dataset.from_tensor_slices()方法并行读取数据?
如果使用keras的数据生成器,在当前的版本中是无法使用多线程的,这就会导致效率很低,CPU读取并处理的时候花费了很长的时间,但是GPU运算只需要很短的时间,这样的话GPU很多时候就会处于一个空闲状态,并没有很好的利用GPU资源。如果使用多线程方法,CPU读取及预处理的时间就会大大缩短,GPU的占用率就会大大的提升,网咯的整个训练过程也会提升。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42308217/article/details/109983175