【新闻】:机器学习炼丹术的粉丝的人工智能交流群已经建立,目前有目标检测、医学图像、时间序列等多个目标为技术学习的分群和水群唠嗑答疑解惑的总群,欢迎大家加炼丹兄为好友,加入炼丹协会。微信:cyx645016617.

参考目录:

目录

1 Keras卷积层

1.1 Conv2D

1.2 SeparableConv2D

1.3 Conv2DTranspose

1.3.1 去卷积的例子1

1.3.2 去卷积的例子2

2 Keras参数初始化

2.1 正态分布

2.2 均匀分布

2.3 截尾正态分布

2.4 常数

2.5 Xavier/Glorot

2.6 自定义初始化

3 Keras激活函数

3.1 relu

3.2 sigmoid

3.3 softmax

3.4 softplus

3.5 softsign

3.6 tanh

3.7 selu

4 Keras的L1/L2正则

4.1 L1/L2正则

4.2 自定义正则化

我们对Keras应该已经有了一个直观、宏观的认识了。现在,我们来系统的学习一下Keras的一些关于网络层的API,本文的主要内容是围绕卷积展开的,包含以下的内容:

不同类型的卷积层;

不同的参数初始化方式;

不同的激活函数;

增加L1/L2正则;

不同的池化层;

多个Normalization层;

其他的常用层。

本文内容较多,对于API的学习了解即可。

1 Keras卷积层

Keras的卷积层和PyTorch的卷积层,都包括1D、2D和3D的版本,1D就是一维的,2D是图像,3D是立体图像。这里就用最常见的2D图像来做讲解,1D和3D和2D基本相同,不多赘述。

1.1 Conv2D

先看Conv2D的所有参数:

tf.keras.layers.Conv2D(

filters,

kernel_size,

strides=(1, 1),

padding="valid",

data_format=None,

dilation_rate=(1, 1),

groups=1,

activation=None,

use_bias=True,

kernel_initializer="glorot_uniform",

bias_initializer="zeros",

kernel_regularizer=None,

bias_regularizer=None,

activity_regularizer=None,

kernel_constraint=None,

bias_constraint=None,

**kwargs

)

先看一个简单的例子:

import tensorflow as tf

input_shape = (4, 28, 28, 3)

x = tf.random.normal(input_shape)

y = tf.keras.layers.Conv2D(

filters=2,kernel_size=3,

activation='relu',padding='same'

)

print(y(x).shape)

(4, 28, 28, 2)

现在来看参数含义:

filter: 一个int整数,输出特征图的通道数;

kernel_size:一个int整数,卷积核大小;

strides:一个整数或者是(a,b)这样的list,表示卷积核是否跳步;

padding:'valid'表示没有padding,'same'表示输出和输入特征图的尺寸相同;只有这两种选择

data_format:'channels_last'或者是'channels_first'。默认是'channels_last',表示特征图的最后一个维度是通道,(batch_size, height, width, channels) ;如果选择了'channels_first'表示每一个样本的第一个维度是通道,所以特征图的格式和PyTorch的格式相同,(batch_size, channels, height, width)。

dilation_rate:碰撞卷积的设置,默认是1,1就是一般的卷积。需要注意的是dilation_rate和stride目前不支持同时不为1,换句话说,如果要膨胀卷积的话,那么stride必须是1;

groups;分组卷积;

activation:这个表示,可以直接在卷积层后面设置一个激活层,比方说'relu',这个在后面的章节会详细讲解目前Keras支持的所有激活层,如果什么都不填入,则不使用激活层

use_bias:一个bool参数,True表示使用bias,默认是True;

kernel_initializer:卷积核的初始化的方法,这个会在后面的章节详细讲解;

bias_initializer:偏置的初始化的方法,这个会在后面的章节详细讲解;

kernel_regularizer:卷积核的正则化的方法,在后面的章节会详细讲解;

bias_regularizer:偏置的正则化的方法,在后面的章节会详细讲解;

1.2 SeparableConv2D

Keras直接提供了深度可分离卷积层,这个层其实包含两个卷积层(了解深度可分离卷积的应该都知道这个吧),一层是depthwise,一层是pointwise。

这个SeparableConv2D的参数也很多,与Conv2D有很多重复的参数,就不多加赘述了:

tf.keras.layers.SeparableConv2D(

filters,

kernel_size,

strides=(1, 1),

padding="valid",

data_format=None,

dilation_rate=(1, 1),

depth_multiplier=1,

activation=None,

use_bias=True,

depthwise_initializer="glorot_uniform",

pointwise_initializer="glorot_uniform",

bias_initializer="zeros",

depthwise_regularizer=None,

pointwise_regularizer=None,

bias_regularizer=None,

activity_regularizer=None,

depthwise_constraint=None,

pointwise_constraint=None,

bias_constraint=None,

**kwargs

)

参数详解:

depth_multiplier:depthwise卷积之后,一般会增多通道数。比方说输入通道是16个,那么输出通道数64个,然后再输入到pointwise卷积层。这个depth_multiplier就是depthwise卷积层的通道数的扩增系数,在上面的例子中这个扩增系数是4;

depthwise_initializer和pointwise_initializer不用多说,就是两个卷积层的卷积核的初始化的方法。

但是这个深度可分离卷积完全可以用一般的Conv2D来构建,所以其实在用到深度可分离卷积的时候,自己会重新构建一个这样的网络层

1.3 Conv2DTranspose

对于上采样,这种方法应该并不陌生。Transposed convolution有的时候也被称为Deconvolution去卷积

tf.keras.layers.Conv2DTranspose(

filters,

kernel_size,

strides=(1, 1),

padding="valid",

output_padding=None,

data_format=None,

dilation_rate=(1, 1),

activation=None,

use_bias=True,

kernel_initializer="glorot_uniform",

bias_initializer="zeros",

kernel_regularizer=None,

bias_regularizer=None,

activity_regularizer=None,

kernel_constraint=None,

bias_constraint=None,

**kwargs

)

参数详解:

output_padding:一个整数或者list,用来给输出的特征图增加一个padding的效果,默认是None,不添加padding;

对于去卷积,可能会比较生疏,这里多讲几个例子

1.3.1 去卷积的例子1

import tensorflow as tf

from tensorflow import keras

input_shape = (4, 28, 28, 3)

x = tf.random.normal(input_shape)

y = keras.layers.Conv2DTranspose(

filters=10,kernel_size=3,strides=1,padding='same')

print(y(x).shape)

(4, 28, 28, 10)

但是假如我们去掉了padding=‘same’

input_shape = (4, 28, 28, 3)

x = tf.random.normal(input_shape)

y = keras.layers.Conv2DTranspose(

filters=10,kernel_size=3,strides=1)

print(y(x).shape)

(4, 30, 30, 10)

这是因为去卷积的卷积核的中心是从原特征图的边界之外开始计算的。一个3乘3的卷积核,那么当卷积核的右下角与原特征图的左上角重合的时候,去卷积的就已经进行了一次运算,而一般的卷积是只有当卷积核的全部都与原特征图重合的时候,才进行计算的。(这里的讲解不太细致,因为之前在其他的文章中已经讲过去卷积的详细过程了)。

1.3.2 去卷积的例子2

现在把stride改成2

input_shape = (4, 28, 28, 3)

x = tf.random.normal(input_shape)

y = keras.layers.Conv2DTranspose(

filters=10,kernel_size=3,strides=2)

print(y(x).shape)

(4, 57, 57, 10)

假如加上padding='same'

input_shape = (4, 28, 28, 3)

x = tf.random.normal(input_shape)

y = keras.layers.Conv2DTranspose(

filters=10,kernel_size=3,strides=2,padding='same')

print(y(x).shape)

(4, 56, 56, 10)

所以一般情况下,使用的参数是strides=2,padding='same',这样特征图的尺寸就刚好放大一倍。

2 Keras参数初始化

把之前提到的简单的例子,增加卷积核和偏置的初始化:

import tensorflow as tf

input_shape = (4, 28, 28, 3)

initializer = tf.keras.initializers.RandomNormal(mean=0., stddev=1.)

x = tf.random.normal(input_shape)

y = tf.keras.layers.Conv2D(

filters=2,kernel_size=3,

activation='relu',padding='same',

kernel_initializer=initializer,

bias_initializer=initializer

)

print(y(x).shape)

(4, 28, 28, 2)

简单的说,就是先定义一个初始化器initializer,然后把这个初始化器作为参数传给Keras.Layers就行了。

2.1 正态分布

tf.keras.initializers.RandomNormal(mean=0.0, stddev=0.05, seed=None)

2.2 均匀分布

tf.keras.initializers.RandomUniform(minval=-0.05, maxval=0.05, seed=None)

2.3 截尾正态分布

tf.keras.initializers.TruncatedNormal(mean=0.0, stddev=0.05, seed=None)

基本和正态分布一样,但是如果随机的取值是在距离均值两个标准差的这个范围之外的,那么会重新取值。

换句话说,初始化的数值会被限制在均值正负两个标准差的范围内

2.4 常数

tf.keras.initializers.Zeros()

tf.keras.initializers.Ones()

2.5 Xavier/Glorot

tf.keras.initializers.GlorotNormal(seed=None)

这个本质是一个截尾正态分布,但是GlorotNormal(又称Xavier),是一个以0为均值,标准差计算公式是:

std=2in+out−−−−−−−−√

是in和out表示输入和输出神经元数目的数目。如果是之前已经学习过或者看过我写的关于Xavier初始化的论文笔记的朋友,可能会发现论文中使用的是一个均匀分布而不是正态分布。

均匀分布的初始化如下:

tf.keras.initializers.GlorotUniform(seed=None)

这个均匀分布是我们讲的:

[−6in+out−−−−−−−−√,6in+out−−−−−−−−√]

这个Xavier方法,也是Keras默认的初始化的方法

2.6 自定义初始化

当然,Keras也是支持自定义初始化的方法的。

import tensorflow as tf

class ExampleRandomNormal(tf.keras.initializers.Initializer):

def init(self, mean, stddev):

self.mean = mean

self.stddev = stddev

def call(self, shape, dtype=None)`:

return tf.random.normal(

shape, mean=self.mean, stddev=self.stddev, dtype=dtype)

def get_config(self): # To support serialization

return {'mean': self.mean, 'stddev': self.stddev}

关键就是在__call__中返回一个和输入参数shape大小相同的一个tf张量就行了。

3 Keras激活函数

基本支持了所有的常见激活函数。在卷积层的参数activation中,可以输入relu,sigmoid,softmax等下面的字符串的形式,全部小写。

3.1 relu

tf.keras.activations.relu(x, alpha=0.0, max_value=None, threshold=0)

alpha就是斜率,如果是0.1,则变成leakyReLU;

max_value是ReLU的上界,如果是None则没有上界;

threshold是ReLU的下界,小于下界的都会被置0,一般默认是0.

3.2 sigmoid

tf.keras.activations.sigmoid(x)

函数方程:

sigmoid(x)=11+e−x

3.3 softmax

tf.keras.activations.softmax(x, axis=-1)

3.4 softplus

tf.keras.activations.softplus(x)

计算公式:

softplus(x)=log(ex+1)

3.5 softsign

tf.keras.activations.softsign(x)

计算公式:

softsign(x)=x|x|+1

3.6 tanh

tf.keras.activations.tanh(x)

计算公式:

tanh(x)=ex−e−xex+e−x

3.7 selu

tf.keras.activations.selu(x)

如果x>0,返回scale×x;

如果x<0,返回scale×α×(ex−1);

scale和α是事先设置的数值,alpha=1.67216214,scale=1.05070098

与elu激活函数类似,但是多了有个scale系数,selu=scale×elu

2017年的一篇论文提出selu,elu是2016年提出的

4 Keras的L1/L2正则

正则化就比较简单,不是L1就是L2,再或者两者都有。

4.1 L1/L2正则

from tensorflow.keras import layers

from tensorflow.keras import regularizers

layer = layers.Dense(

units=64,

kernel_regularizer=regularizers.l1_l2(l1=1e-5, l2=1e-4),

)

这里的正则化,可以使用:

tf.keras.regularizers.l1_l2(l1=1e-5, l2=1e-4)

tf.keras.regularizers.l2(1e-4)

tf.keras.regularizers.l1(1e-5)

关于L1和L2的计算细节:

L1:L1正则就是

loss=L1×sum(abs(x))

L2:L1正则就是

loss=L1×sum(x2)

4.2 自定义正则化

class MyRegularizer(tf.keras.regularizers.Regularizer):

def __init__(self, strength):
self.strength = strength def __call__(self, x):
return self.strength * tf.reduce_sum(tf.square(x)) def get_config(self):
return {'strength': self.strength}

这个实现的是L2正则的。其中的get_config是用来保存模型数据的,不要的话也没事,只是不能序列化的保存模型(不用使用config或者json来存储模型)。

人不可傲慢。

小白如何学习PyTorch】25 Keras的API详解(下)缓存激活,内存输出,并发解决的更多相关文章

  1. 百度地图API详解之事件机制,function“闭包”解决for循环和监听器冲突的问题:

    原文:百度地图API详解之事件机制,function"闭包"解决for循环和监听器冲突的问题: 百度地图API详解之事件机制 2011年07月26日 星期二 下午 04:06 和D ...

  2. 【小白学PyTorch】21 Keras的API详解(上)卷积、激活、初始化、正则

    [新闻]:机器学习炼丹术的粉丝的人工智能交流群已经建立,目前有目标检测.医学图像.时间序列等多个目标为技术学习的分群和水群唠嗑答疑解惑的总群,欢迎大家加炼丹兄为好友,加入炼丹协会.微信:cyx6450 ...

  3. 【小白学PyTorch】21 Keras的API详解(下)池化、Normalization层

    文章来自微信公众号:[机器学习炼丹术].作者WX:cyx645016617. 参考目录: 目录 1 池化层 1.1 最大池化层 1.2 平均池化层 1.3 全局最大池化层 1.4 全局平均池化层 2 ...

  4. linux命令学习笔记(25):linux文件属性详解

    Linux 文件或目录的属性主要包括:文件或目录的节点.种类.权限模式.链接数量.所归属的用户和用户组. 最近访问或修改的时间等内容.具体情况如下: 命令: ls -lih 输出: [root@loc ...

  5. Java8学习笔记(五)--Stream API详解[转]

    为什么需要 Stream Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念.它也不同于 StAX 对 ...

  6. hibernate学习(2)——api详解对象

    1   Configuration 配置对象 /详解Configuration对象 public class Configuration_test { @Test //Configuration 用户 ...

  7. 大数据学习笔记——Spark工作机制以及API详解

    Spark工作机制以及API详解 本篇文章将会承接上篇关于如何部署Spark分布式集群的博客,会先对RDD编程中常见的API进行一个整理,接着再结合源代码以及注释详细地解读spark的作业提交流程,调 ...

  8. jqGrid APi 详解

    jqGrid APi 详解 jqGrid皮肤 从3.5版本开始,jqGrid完全支持jquery UI的theme.我们可以从http://jqueryui.com/themeroller/下载我们所 ...

  9. Java 8 Stream API详解--转

    原文地址:http://blog.csdn.net/chszs/article/details/47038607 Java 8 Stream API详解 一.Stream API介绍 Java8引入了 ...

随机推荐

  1. Linux系统编程 —时序竞态

    时序竞态 什么是时序竞态?将同一个程序执行两次,正常情况下,前后两次执行得到的结果应该是一样的.但由于系统资源竞争的原因,前后两次执行的结果有可能得到不一样的结果,这个现象就是时序竞态. pause函 ...

  2. [VBA原创源代码] excelhome 对花名册进行分类

    最近在学习<菜鸟谈VBA最最基础入门<原创>>,其中第22节有一个VBA编程作业,实现对花名册进行分类. 自己花了点时间,自己丫丫学步,终于实现出来. 在原创聚集地cnblog ...

  3. three.js学习5_渲染器

    THREE.WebGLRenderer WebGL Render 用WebGL渲染出你精心制作的场景 介绍 在之前的介绍中, 已经介绍过场景, 相机, 光源, 有了这些后, 就可以形成一个可观的三维展 ...

  4. 最全总结 | 聊聊 Python 数据处理全家桶(配置篇)

    1.前言 在实际项目中,经常会接触到各种各样的配置文件,它可以增强项目的可维护性 常用配件文件的处理方式,包含:JSON.ini / config.YAML.XML 等 本篇文章,我们将聊聊 Pyth ...

  5. ECMASctipt6总结

    1.let 变量声明以及特性 声明变量 let a; let b, c, d; let e = 1; let f = 2, g = 3; 特性 1.不能重复声明 2.块级作用域  只在块级作用域有效 ...

  6. c#之task与thread区别及其使用

    如果需要查看更多文章,请微信搜索公众号 csharp编程大全,需要进C#交流群群请加微信z438679770,备注进群, 我邀请你进群! ! ! --------------------------- ...

  7. xxe 新手学习记录

    在做某题时遇到了xxe漏洞,学习+记录 这里因为环境暂时关了,现在复现不了,所以在网络上又找到了一些xxe题目环境 这里有 PikaChu靶场里的xxe环境,这个环境可以在BUUCTF里开,但是这里我 ...

  8. IPA的动态库注入+企业重签名过程

    [摘录]之前在进行iOS测试过程中由于要获取一定数据信息,因此需要对原本的安装包进行代码注入并且重新打包安装,因此就需要使用重签名策略,在此进行分享,希望大家可以使用其中的方法来运用到自身的项目中. ...

  9. const、define 和 static 的区别

    目录 define.const static define.const 在 C++ 中,const 和 define 都可以用来定义常量.但是这二者之间有很大的区别: define 的作用 用 def ...

  10. 正式班D7

    2020.10.13星期二 正式班D7 一.上节课复习 Linux发展 批处理系统 多道技术 分时操作系统 multics->Unix->minix->Linux(如Redhat.c ...