Keras 中经常可以看到
K.image_data_format() == 'channels_first'
深度学习中 Flatten层 的作用 < GAP
Flatten层的实现在Keras.layers.core.Flatten()类中。
作用:
Flatten层用来将输入“压平”,即把多维的输入一维化,常用在从卷积层到全连接层的过渡。Flatten不影响batch的大小。
from keras.models import Sequential
from keras.layers.core import Flatten
from keras.layers.convolutional import Convolution2D
from keras.utils.vis_utils import plot_model
model = Sequential()
model.add(Convolution2D(64,3,3,border_mode="same",input_shape=(3,32,32)))
model.add(Flatten())
plot_model(model, to_file='Flatten.png', show_shapes=True)
为了更好的理解Flatten层作用,我把这个神经网络进行可视化如下图:
flatten层用来扁平参数用,一般用在卷积层与全链接层之间,可以从vgg16网络中可以看出,但是在后来的网络中用GlobalAveragePooling2D代替了flatten层,可以从vgg16与inceptionV3网络对比看出。从参数的对比可以看出,显然这种改进大大的减少了参数的使用量,避免了过拟合现象。
GlobalAveragePooling2D 层 全局池化层 还可以不在乎输入图像的大小
一般在全连接后会有**函数来做分类,假设这个**函数是一个多分类softmax,那么全连接网络的作用就是将最后一层卷积得到的feature map stretch成向量,对这个向量做乘法,最终降低其维度,然后输入到softmax层中得到对应的每个类别的得分。全连接层如此的重要,以至于全连接层过多的参数重要到会造成过拟合
在最后一个卷积层后,加上GAP 不管前面输出是多少 通过GAP后都变成了1*1*chinnal
所以就可以不在乎原始图像输入是多少,然后继续接下往下做
去掉fc层 换成GAP 我们叫全卷积神经网络 fully convlation network
在卷积层之后,用GAP替代FC全连接层。有两个有点:一是GAP在特征图与最终的分类间转换更加简单自然;二是不像FC层需要大量训练调优的参数,降低了空间参数会使模型更加健壮,抗过拟合效果更佳。
假设卷积层的最后输出是h × w × d 的三维特征图,具体大小为6 × 6 × 3,经过GAP转换后,变成了大小为 1 × 1 × 3 的输出值,也就是每一层 h × w 会被平均化成一个值。
GAP的使用一般在卷积层之后,输出层之前:
GAP GMP Flatten 对比
https://www.cnblogs.com/hutao722/p/10008581.html
对GAP的解释
https://www.jianshu.com/p/510072fc9c62
结论:
从本实验看出,在数据集有限的情况下,采用经典模型进行迁移学习时,GMP表现不太稳定,FC层由于训练参数过多,更易导致过拟合现象的发生,而GAP则表现稳定,优于FC层。当然具体情况具体分析,我们拿到数据集后,可以在几种方式中多训练测试,以寻求最优解决方案。
Tensorflow 写法
# detach original VGG fc layers and
# reconstruct your own fc layers serve for your own purpose
self.flatten = tf.reshape(pool5, [-1, 7*7*512])
self.fc6 = tf.layers.dense(self.flatten, 256, tf.nn.relu, name='fc6') #tf.layers.dense 可以一步建立最普通的隐藏层
self.out = tf.layers.dense(self.fc6, 1, name='out')
Dense层 == Fc
Dense即全连接层,逻辑上等价于这样一个函数:
权重W为m*n的矩阵.
输入x为n维向量.
**函数Activation.
偏置bias.
输出向量out为m维向量.
out=Activation(Wx+bias).
即一个线性变化加一个非线性变化产生输出.
为什么卷积层池化层玩需要将向量进行压缩,扁平
把分布式特征 representation 映射到样本标记空间
就是它把特征representation整合到一起,输出为一个值。
这样做,有一个什么好处?
就是大大减少特征位置对分类带来的影响。
举个简单的例子
从上图我们可以看出,猫在不同的位置,输出的 feature 值相同,但是位置不同。对于电脑来说,特征值相同,但是特征值位置不同,那分类结果也可能不一样,而这时全连接层 filter 的作用就相当于
喵在哪我不管 我只要喵
于是我让filter去把这个喵找到,实际就是把 feature map 整合成一个值:这个值大,哦,有喵;这个值小,那就可能没喵,和这个喵在哪关系不大了有没有,鲁棒性有大大增强了
因为空间结构特性被忽略了,所以全连接层不适合用于在方位上找 Pattern 的任务,比如 segmentation。
一些CNN网络最后为什么要有2个全连接层
写的太好了,生动,容易理解
https://blog.csdn.net/weixin_40903337/article/details/100074878
泰勒公式都知道吧,意思就是用多项式函数去拟合光滑函数。我们这里的全连接层中一层的一个神经元就可以看成一个多项式,我们用许多神经元去拟合数据分布,但是只用一层 fully-connected layer 有时候没法解决非线性问题,而如果有两层或以上 fully-connected layer 就可以很好地解决非线性问题了。
我们都知道,全连接层之前的作用是提取特征,全连接层的作用是分类
random.seed()
seed()方法改变随机数生成器的种子
当seed()没有参数时,每次生成的随机数是不一样的,而当seed()有参数时,每次生成的随机数是一样的,同时选择不同的参数生成的随机数也不一样
做图片分类任务时使用img_to_array。
image = cv2.imread(imagePath)
image = cv2.resize(image, (norm_size, norm_size))
image = img_to_array(image)
data.append(image)
img_to_array是keras下的一个方法,主要作用就是把numpy矩阵中的整数转换成浮点数。
训练和预测时Keras对图片读取处理方式不同,加入img_to_array会降低差距
网络性能影响挺大的,使用了以后val_acc与val_loss更加接近训练acc与loss
to_categorical()
# convert the labels from integers to vectors labels = to_categorical(labels, num_classes=CLASS_NUM)
to_categorical就是将类别向量转换为二进制(只有0和1)的矩阵类型表示。其表现为将原有的类别向量转换为独热编码的形式
to_categorical最为keras中提供的一个工具方法,从以上代码运行可以看出,将原来类别向量中的每个值都转换为矩阵里的一个行向量,从左到右依次是0,1,2,...8个类别。2表示为[0. 0. 1. 0. 0. 0. 0. 0. 0.],只有第3个为1,作为有效位,其余全部为0。
为什么要用one-hot编码
将离散型特征使用one-hot编码,确实会让特征之间的距离计算更加合理
用one-hot编码,是为了更合理地计算欧式距离
比如,有一个离散型特征,代表工作类型,该离散型特征,共有三个取值,不使用one-hot编码,其表示分别是x_1 = (1), x_2 = (2), x_3 = (3)。两个工作之间的距离是,(x_1, x_2) = 1, d(x_2, x_3) = 1, d(x_1, x_3) = 2。那么x_1和x_3工作之间就越不相似吗?显然这样的表示,计算出来的特征的距离是不合理。那如果使用one-hot编码,则得到x_1 = (1, 0, 0), x_2 = (0, 1, 0), x_3 = (0, 0, 1),那么两个工作之间的距离就都是sqrt(2).即每两个工作之间的距离是一样的,显得更合理
使用onehot的直接原因是现在多分类cnn网络的输出通常是softmax层,而它的输出是一个概率分布,从而要求输入的标签也以概率分布的形式出现,进而算交叉熵之类。
对于离散型特征,基于树的方法是不需要使用one-hot编码的,例如随机森林等。基于距离的模型,都是要使用one-hot编码,例如神经网络等。
在keras中model.fit_generator()和model.fit()有什么区别
https://blog.csdn.net/Hodors/article/details/97500808
首先Keras中的fit()函数传入的x_train和y_train是被完整的加载进内存的,当然用起来很方便,但是如果我们数据量很大,那么是不可能将所有数据载入内存的,必将导致内存泄漏,这时候我们可以用fit_generator函数来进行训练。
详细理解全连接层
这一步卷积一个非常重要的作用
就是把分布式特征representation映射到样本标记空间
就是它把特征representation整合到一起,输出为一个值
这样做,有一个什么好处?
就是大大减少特征位置对分类带来的影响
为什么全连接层可以实现分类
https://www.cnblogs.com/inception6-lxc/p/9939691.html
运行python3程序 出现如下错误
ModuleNotFoundError: No module named '__main__.model'; '__main__' is not a p
不知道原因
直接使用相对路径会出现问题
解决办法是不使用当前路径的 .
from automationtest_frame.output.logger import Logger
同时
1、把automationtest_frame 的上级路径放到系统path里
2、把autimation_frame的上级目录作为工程目录打开