优秀的编程知识分享平台

网站首页 > 技术文章 正文

走入TensorFlow模型卷积神经网络的世界

nanyue 2024-11-23 20:18:11 技术文章 1 ℃

在众多深度学习框架中,比如PyTorch、TensorFlow、MNN、Caffie等,PyTorch比较吃硬件性能,尤其在GPU显卡这块区分度非常大。

如果想做移动端识别程序,PyTorch明显不符合要求,与硬件性能强烈挂钩,如果移动端硬件配置不行,会造成用户体验极度不好。

而无差别适用于移动端的深度学习框架是TensorFlow Lite,就跟Android手机自带的数据库SQLite一样,与硬件配置无关,脱离硬件依赖。

而TensorFlow Lite是由TensorFlow模型转换导出的,本文介绍TensorFlow模型在卷积神经网络领域的应用。

一、TF描述卷积层

在TensorFlow中,卷积层通常是通过tf.keras.layers.Conv2D来实现的。下面我将用Python和TensorFlow的方式来描述如何定义一个基本的2D卷积层:

1. 导入必要的库

import tensorflow as tf

from tensorflow.keras import layers

2. 定义卷积层

# 创建一个卷积层实例

conv_layer = layers.Conv2D(

filters=32, # 输出的维度(即滤波器的数量)

kernel_size=(3, 3), # 滤波器的大小

strides=(1, 1), # 步长

padding='valid', # 填充方式:'valid'表示没有填充,'same'表示输出与输入同尺寸

activation='relu', # 激活函数

input_shape=(28, 28, 1) # 输入形状,例如对于MNIST数据集

)

3. 使用卷积层

假设我们有一个输入张量input_tensor,我们可以这样应用上面定义的卷积层:

# 假设输入张量

input_tensor = tf.random.normal([1, 28, 28, 1]) # 批次大小为1,灰度图像


# 应用卷积层

output_tensor = conv_layer(input_tensor)


print(output_tensor.shape)

这段代码定义了一个简单的2D卷积层,并将其应用于一个形状为(1, 28, 28, 1)的输入张量上,输出将是经过卷积操作后的结果。

二、TF描述批标准化

在TensorFlow中,批标准化(Batch Normalization)是一种常用的正则化技术,用于加速训练过程并提高模型性能。它通过对每个小批量的数据进行归一化处理,使得网络的中间输出具有零均值和单位方差。这有助于缓解梯度消失或爆炸的问题,并且使网络更加稳定。

1. 定义批标准化层

# 创建一个批标准化层实例

batch_norm_layer = layers.BatchNormalization(

axis=-1, # 要归一化的轴,默认为-1(最后一个轴)

momentum=0.99, # 动量值,用于计算移动平均值

epsilon=0.001, # 防止除以零的小常数

center=True, # 是否使用偏移项(β)

scale=True # 是否使用缩放项(γ)

)

2. 在模型中使用批标准化

通常情况下,批标准化层会与其他层一起组合成一个模型。例如,在卷积神经网络中:

model = tf.keras.Sequential([

layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),

layers.BatchNormalization(),

layers.MaxPooling2D((2, 2)),

layers.Flatten(),

layers.Dense(64, activation='relu'),

layers.BatchNormalization(),

layers.Dense(10, activation='softmax')

])


# 编译模型

model.compile(optimizer='adam',

loss='sparse_categorical_crossentropy',

metrics=['accuracy'])


# 查看模型结构

model.summary()

在这个例子中,我们在卷积层和全连接层之后分别添加了批标准化层,以提高模型的稳定性和性能。

三、TF描述池化

在TensorFlow中,池化(Pooling)是一种常用的下采样技术,用于减少特征图的空间尺寸,从而降低计算复杂度并提高模型的鲁棒性。常见的池化方法包括最大池化(Max Pooling)和平均池化(Average Pooling)。

1. 定义池化层

最大池化(Max Pooling)

# 创建一个最大池化层实例

max_pool_layer = layers.MaxPooling2D(

pool_size=(2, 2), # 池化窗口的大小

strides=(2, 2), # 步长

padding='valid' # 填充方式:'valid'表示没有填充,'same'表示输出与输入同尺寸

)

平均池化(Average Pooling)

# 创建一个平均池化层实例

avg_pool_layer = layers.AveragePooling2D(

pool_size=(2, 2), # 池化窗口的大小

strides=(2, 2), # 步长

padding='valid' # 填充方式:'valid'表示没有填充,'same'表示输出与输入同尺寸

)

2. 在模型中使用池化层

通常情况下,池化层会与其他层一起组合成一个模型。例如,在卷积神经网络中:

model = tf.keras.Sequential([

layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),

layers.MaxPooling2D((2, 2)), # 最大池化层

layers.Conv2D(64, (3, 3), activation='relu'),

layers.AveragePooling2D((2, 2)), # 平均池化层

layers.Flatten(),

layers.Dense(64, activation='relu'),

layers.Dense(10, activation='softmax')

])


# 编译模型

model.compile(optimizer='adam',

loss='sparse_categorical_crossentropy',

metrics=['accuracy'])


# 查看模型结构

model.summary()

在这个例子中,我们在卷积层之后分别添加了最大池化层和平均池化层,以减少特征图的空间尺寸并提高模型的鲁棒性。

四、TF描述舍弃

在TensorFlow中,舍弃(Dropout)是一种常用的正则化技术,用于防止过拟合。通过在训练过程中随机丢弃一部分神经元的输出,Dropout 可以增强模型的泛化能力。下面详细介绍如何在TensorFlow中使用 Dropout 层。

1. 定义 Dropout 层

# 创建一个 Dropout 层实例

dropout_layer = layers.Dropout(rate=0.5) # rate 表示丢弃的概率

2. 在模型中使用 Dropout 层

通常情况下,Dropout 层会与其他层一起组合成一个模型。例如,在卷积神经网络中:

model = tf.keras.Sequential([

layers.Conv2D(32, (3, 3), activation='relu', input_shape=(28, 28, 1)),

layers.MaxPooling2D((2, 2)),

layers.Dropout(0.5), # Dropout 层

layers.Conv2D(64, (3, 3), activation='relu'),

layers.MaxPooling2D((2, 2)),

layers.Flatten(),

layers.Dense(64, activation='relu'),

layers.Dropout(0.5), # Dropout 层

layers.Dense(10, activation='softmax')

])


# 编译模型

model.compile(optimizer='adam',

loss='sparse_categorical_crossentropy',

metrics=['accuracy'])


# 查看模型结构

model.summary()

在这个例子中,我们在卷积层和全连接层之后分别添加了 Dropout 层,以提高模型的泛化能力和防止过拟合。

五、实际案例

通过引入cifar10数据集,加载数据集,引入卷积神经网络完成模型训练,完整代码如下:

完整代码:


import tensorflow as tf

import os

import numpy as np

from matplotlib import pyplot as plt

from tensorflow.keras.layers import Conv2D, BatchNormalization, Activation, MaxPool2D, Dropout, Flatten, Dense

from tensorflow.keras import Model

np.set_printoptions(threshold=np.inf)


cifar10 = tf.keras.datasets.cifar10

(x_train, y_train), (x_test, y_test) = cifar10.load_data()

x_train, x_test = x_train / 255.0, x_test / 255.0


cvpath= 'E:/代码Git/pythonProject1/chapter08'

class Baseline(Model):

def __init__(self):

super(Baseline, self).__init__()

self.c1 = Conv2D(filters=6, kernel_size=(5, 5), padding='same')

self.b1 = BatchNormalization()

self.a1 = Activation('relu')

self.p1 = MaxPool2D(pool_size=(2,2), strides=2, padding='same')

self.d1 = Dropout(0.2)

self.flatten = Flatten()

self.f1 = Dense(128, activation='relu')

self.d2 = Dropout(0.2)

self.f2 = Dense(10, activation='softmax')


def call(self, x):

x = self.c1(x)

x = self.b1(x)

x = self.a1(x)

x = self.p1(x)

x = self.d1(x)

x = self.flatten(x)

x = self.f1(x)

x = self.d2(x)

y = self.f2(x)

return y


model = Baseline()

model.compile(optimizer='adam',

loss = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=False),

metrics=['sparse_categorical_accuracy'])

checkpoint_save_path = cvpath+'/checkpoint/Baseline.ckpt'

if os.path.exists(checkpoint_save_path+'.index'):

print('---------load the model--------------')

model.load_weights(checkpoint_save_path)

cp_callback = tf.keras.callbacks.ModelCheckpoint(filepath=checkpoint_save_path,

save_weights_only=True,

save_best_only=True)

history = model.fit(x_train, y_train, batch_size=32, epochs=5, validation_data=(x_test, y_test), validation_freq=1,

callbacks=[cp_callback])

model.summary()

file=open(cvpath+'/weights.txt','w')

for v in model.trainable_variables:

file.write(str(v.name)+'\t')

file.write(str(v.shape)+'\n')

file.write(str(v.numpy())+'\n')

file.close()

############################ close ###################################################

acc = history.history['sparse_categorical_accuracy']

val_acc = history.history['val_sparse_categorical_accuracy']

loss = history.history['loss']

val_loss = history.history['val_loss']

plt.subplot(1,2,1)

plt.plot(acc, label='Training Accuracy')

plt.plot(val_acc, label='Validation Accuracy')

plt.title('Training And Validation Accuracy')

plt.legend()

plt.subplot(1,2,2)

plt.plot(loss, label='Training Loss')

plt.plot(val_loss, label='Validation Loss')

plt.title('Training and Validation Loss')

plt.legend()

plt.show()


右键运行程序:

首先下载cifar10数据集,下载过程略

采用断点续存,逐步保存训练过程,查看结果:

中间如果报出文件夹不存在,需要创建对应文件夹和文件。

更多大模型深度学习内容欢迎关注博主,持续更新。

Tags:

最近发表
标签列表