CNN卷积神经网络(二)

一、卷积层

在 TensorFlow 中,既可以通过自定义权值的底层实现方式搭建神经网络,也可以直接调用现成的卷积层类的高层方式快速搭建复杂网络
 

1.2D卷积函数

在 TensorFlow 中, 通过 tf.nn.conv2d 函数可以方便地实现 2D 卷积运算。 tf.nn.conv2d基于输入𝑿: [b, ℎ, 𝑤, 𝑐𝑖𝑛] 卷积核𝑾: [𝑘, 𝑘, 𝑐𝑖𝑛, 𝑐𝑜𝑢𝑡] 进行卷积运算, 得到输出𝑶 [b,ℎ′, 𝑤′ ,𝑐𝑜𝑢𝑡] 其中𝑐𝑖𝑛表示输入通道数, 𝑐𝑜𝑢𝑡表示卷积核的数量, 也是输出特征图的通道数

import tensorflow as tf

x = tf.random.normal([2, 5, 5, 3]) # 模拟输入,3个通道,高宽为5
# 需要根据[k,k,cin,cout]格式创建 W 张量, 4 个 3x3 大小卷积核
w = tf.random.normal([3, 3, 3, 4])
# 步长为1 ,padding为0
out = tf.nn.conv2d(x, w, strides=1, padding=[[0, 0], [0, 0], [0, 0], [0, 0]])
# 根据[cout]格式创建偏置向量
b = tf.zeros([4])
# 在卷积输出上叠加偏置向量,它会自动 broadcasting 为[b,h',w',cout]
out = out + b
print(out)

padding 参数的设置格式为:padding=[[0,0],[上,下],[左,右],[0,0]], 上下左右各填充一个单位,则 padding 参数设置为[[0,0],[1,1],[1,1],[0,0]] 。通过设置参数 padding='SAME'、 strides=1 可以直接得到输入、 输出同大小的卷积层, 其中 padding 的具体数量由 TensorFlow 自动计算并完成填充操作。当𝑠 > 1时, 设置 padding='SAME'将使得输出高、 宽将成1/s倍减少
 

卷积神经网络层与全连接层一样,可以设置网络带偏置向量。 tf.nn.conv2d 函数是没有实现偏置向量计算的, 添加偏置只需要手动累加偏置张量即可。
 

2.卷积层类

通过卷积层类 layers.Conv2D 可以不需要手动定义卷积核𝑾和偏置𝒃张量,直接调用类实例即可完成卷积层的前向计算, 实现更加高层和快捷。 使用类方式会(在创建类时或 build 时)自动创建需要的权值张量和偏置向量等, 用户不需要记忆卷积核张量的定义格式,因此使用起来更简单方便,但是灵活性也略低。函数方式的接口需要自行定义权值和偏置等,更加灵活和底层

在新建卷积层类时,只需要指定卷积核数量参数 filters卷积核大小 kernel_size步长strides,填充 padding 等即可

创建 4 个3 × 3大小的卷积核的卷积层,步长为 1,padding 为'SAME':

layer = layers.Conv2D(4, kernel_size=4, strides=1, padding='SAME')

如果卷积核高宽不等,步长行列方向不等,此时需要将 kernel_size 参数设计为 tuple格式(𝑘ℎ ,𝑘𝑤) strides 参数设计为(𝑠ℎ, 𝑠𝑤)

创建 4 个3 × 大小的卷积核,竖直方向移动步长𝑠ℎ = 2,水平方向移动步长𝑠𝑤 = 1

layer = layers.Conv2D(4, kernel_size=[3, 4], strides=[2, 1], padding='SAME')

创建完成后,通过调用实例(的__call__方法)即可完成前向计算

# 创建卷积层类
layer = layers.Conv2D(4,kernel_size=3,strides=1,padding='SAME')
out = layer(x) # 前向计算
print(out.shape) # 输出张量的 shape

在类 Conv2D 中,保存了卷积核张量𝑾和偏置𝒃,可以通过类成员 trainable_variables直接返回𝑾和𝒃的列表。也可以直接调用类实例 layer.kernel、 layer.bias名访问𝑾和𝒃张量
 

二、池化层

池化层一般就是这几个类,用得最多的是MaxPool2D。 MaxPooling2D和MaxPool2D是一样的(stackoverflow说的)。

tf.keras.layers.MaxPool2D(
    pool_size=(2, 2), strides=None, 
    padding='valid', data_format=None, **kwargs
)

一种常用的池化层设定是感受野大小𝑘 = 2,步长𝑠 = 2,这样可以实现输出只有输入高宽一半的目的。但是一般会在下一个卷积层,卷积核的数量翻倍,为了弥补池化层压缩特征信息

三、BatchNorm层

在 TensorFlow 中,通过 layers.BatchNormalization()类可以非常方便地实现 BN 层。与全连接层、 卷积层不同, BN 层的训练阶段和测试阶段的行为不同,需要通过设置training 标志位来区分训练模式还是测试模式。

network = Sequential([
    layers.Conv2D(6, kernel_size=3, strides=1),
    layers.BatchNormalization(), # 插入BN层
    layers.MaxPool2D(pool_size=2, strides=2),
    layers.ReLU()
])

# 训练阶段
with tf.GradientTape() as tape:
    # 向前计算
    out = network(x, training=True)

# 测试阶段
for x, y in db_test: # 遍历测试集
    out = network(x, training=True)

 卷积层、 BN 层、 ReLU 层、池化层一度成为网络模型的标配单元块,通过堆叠 Conv-BN-ReLU-Pooling 方式往往可以获得不错的模型性能

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Super.Bear

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值