卷积神经网络的一个示例实现如下所示:
class CNN(tf.keras.Model):
def __init__(self):
super().__init__()
self.conv1 = tf.keras.layers.Conv2D(
filters=32, # 卷积层神经元(卷积核)数目
kernel_size=[5, 5], # 感受野大小
padding='same', # padding策略(vaild 或 same)
activation=tf.nn.relu # 激活函数
)
self.pool1 = tf.keras.layers.MaxPool2D(pool_size=[2, 2], strides=2)
self.conv2 = tf.keras.layers.Conv2D(
filters=64,
kernel_size=[5, 5],
padding='same',
activation=tf.nn.relu
)
self.pool2 = tf.keras.layers.MaxPool2D(pool_size=[2, 2], strides=2)
self.flatten = tf.keras.layers.Reshape(target_shape=(7 * 7 * 64,))
self.dense1 = tf.keras.layers.Dense(units=1024, activation=tf.nn.relu)
self.dense2 = tf.keras.layers.Dense(units=10)
def call(self, inputs):
x = self.conv1(inputs) # [batch_size, 28, 28, 32]
x = self.pool1(x) # [batch_size, 14, 14, 32]
x = self.conv2(x) # [batch_size, 14, 14, 64]
x = self.pool2(x) # [batch_size, 7, 7, 64]
x = self.flatten(x) # [batch_size, 7 * 7 * 64]
x = self.dense1(x) # [batch_size, 1024]
x = self.dense2(x) # [batch_size, 10]
output = tf.nn.softmax(x)
return output
使用 Keras 中预定义的经典卷积神经网络结构
tf.keras.applications 中有一些预定义好的经典卷积神经网络结构,如 VGG16 、 VGG19 、 ResNet 、 MobileNet 等。我们可以直接调用这些经典的卷积神经网络结构(甚至载入预训练的参数),而无需手动定义网络结构。
例如,我们可以使用以下代码来实例化一个 MobileNetV2 网络结构:
model = tf.keras.applications.MobileNetV2()
当执行以上代码时,TensorFlow 会自动从网络上下载 MobileNetV2 网络的预训练权值,因此在第一次执行代码时需要具备网络连接。也可以通过将参数 weights 设置为 None 来随机初始化变量而不使用预训练权值。每个网络结构具有自己特定的详细参数设置,一些共通的常用参数如下:
input_shape :输入张量的形状(不含第一维的 Batch),大多默认为 224 × 224 × 3 。一般而言,模型对输入张量的大小有下限,长和宽至少为 32 × 32 或 75 × 75 ; include_top :在网络的最后是否包含全连接层,默认为 True ; weights :预训练权值,默认为 ‘imagenet’ ,即为当前模型载入在 ImageNet 数据集上预训练的权值。如需随机初始化变量可设为 None ; classes :分类数,默认为 1000。修改该参数需要 include_top 参数为 True 且 weights 参数为 None 。
以下展示一个例子,使用 MobileNetV2 网络在 tf_flowers 五分类数据集上进行训练(为了代码的简短高效,在该示例中我们使用了 TensorFlow Datasets 和 tf.data 载入和预处理数据)。同时将 classes 设置为 5,对应于 5 分类的数据集。
import tensorflow as tf
import tensorflow_datasets as tfds
num_epoch = 5
batch_size = 50
learning_rate = 0.001
dataset = tfds.load("tf_flowers", split=tfds.Split.TRAIN, as_supervised=True)
dataset = dataset.map(lambda img, label: (tf.image.resize(img, (224, 224)) / 255.0, label)).shuffle(1024).batch(batch_size)
model = tf.keras.applications.MobileNetV2(weights=None, classes=5)
optimizer = tf.keras.optimizers.Adam(learning_rate=learning_rate)
for e in range(num_epoch):
for images, labels in dataset:
with tf.GradientTape() as tape:
labels_pred = model(images, training=True)
loss = tf.keras.losses.sparse_categorical_crossentropy(y_true=labels, y_pred=labels_pred)
loss = tf.reduce_mean(loss)
print("loss %f" % loss.numpy())
grads = tape.gradient(loss, model.trainable_variables)
optimizer.apply_gradients(grads_and_vars=zip(grads, model.trainable_variables))
print(labels_pred)
参考资料
TensorFlow 模型建立与训练
|