一. 工具说明及要求
Pycharm
python ( version < 3.11 )
tensorflow
openCV
numpy
matplotlib
二.训练前工作
训练数据集介绍
数据集: IOS-Lab-数字手写体数据
数据集组成: 40张图,每张图中0-9数字各20个
数据集处理 (核心过程)
(1) openCV读取图片
cv2.imread()
(2) openCV切割图片统一大小
numpy数组操作 + cv2.resize()
(3) openCV处理图片
cv2.cvtColor()
cv2.medianBlur()
cv2.Sobel()
cv2.adaptiveThreshold()
cv2.bitwise_not()
cv2.erode()
# 等等
(4) 图片规则命名
eg: 数字-男女-第几位-第几个
(5) 图片存储
cv2.imwrite()
三.模型训练(关键过程)(伪代码)
(1) 加载图片
listdir = os.listdir(imagePath) # 获取目录下所有图片 (实际上是图的名词)
for imageName in listdir: # 遍历每张图
loadLabel # 获取图片label
cv2.imread(imageName) # 加载图片
cv2.resize() # 图片转为统一大小
# 存储 img 与 对应label 用列表存储
temp = np.array([img, labelSex], dtype=object) # 拼接图片
temp = temp.transpose()
np.random.shuffle(temp) # 打乱图片
# img 与 label 分割
return img , label
(2)转为tensorflow所需格式
def preprocess(x, y):
x = tf.cast(x, dtype=tf.float32) / 255.
y = tf.cast(y, dtype=tf.int32)
y = tf.one_hot(y, depth=2) # depth 为 label的个数 eg:0-9 共10个 男女 共2个
return x, y
# 分割 训练集 与 验证集 (2个哦)
db = tf.data.Dataset.from_tensor_slices((x, y))
db = db.map(preprocess).shuffle(num).batch(batchSize) # 像素处理 打乱 分批次
sample = next(iter(db))
(3) 定义模型(下扩展)
class myModel(keras.Model):
def __init__(self):
super(myModel, self).__init__():
# 你的模型
def call(self, inputs):
# 模型链接
(4) 训练模型
network = myModel()
network.compile(optimizer=optimizers.Adam(learning_rate=0.001), # 学习率
loss=tf.losses.CategoricalCrossentropy(from_logits=True), # 损失
metrics=['accuracy']
)
history = network.fit(db, epochs=60, validation_data=ds_val, validation_freq=1)
# db 数据 epoch 次数 validation_data 验证集 validation_freq 验证频率
network.evaluate(ds_val)
network.summary() # 打印网络结构
(5) 预测数据
pred = network.predict(x) # 预测
(6) 可视化
acc = history.history['accuracy']
val_acc = history.history['val_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()
四.模型选择
对于3.3中模型的定义,这里列举案例,大家可自行组合。(具体参数可自行百度)
class MyModel(keras.Model):
def __init__(self):
super(MyModel, self).__init__()
self.c1 = layers.Conv2D(filters=6, kernel_size=(5, 5), padding='same') # 卷积层
self.b1 = layers.BatchNormalization() # BN层
self.a1 = layers.Activation('relu') # 激活层
self.p1 = layers.MaxPool2D(pool_size=(2, 2), strides=2, padding='same') # 池化层
self.d1 = layers.Dropout(0.2) # dropout层
self.flatten = layers.Flatten()
# 下面是全连接层
self.fc1 = MyDense(1176, 256)
self.fc2 = MyDense(256, 128)
self.fc3 = MyDense(128, 64)
self.fc4 = MyDense(64, 32)
# 最终变成 输出维度为 10 与 Y的 one_hot 相关
self.fc5 = MyDense(32, 10)
def call(self, inputs, training=None):
# 运行了 上面构造函数中的 Dense
x = self.c1(inputs)
x = self.b1(x)
x = self.a1(x)
x = self.p1(x)
x = self.d1(x)
x = self.flatten(x)
x = self.fc1(x)
# 激活函数用 relu (改变映射)
# 因为每次卷积后数据就不在是 规定范围内的数据
# 所以我们要给它调整回去 不然 后果我不知道 但是肯定差了
x = tf.nn.relu(x)
x = self.fc2(x)
x = tf.nn.relu(x)
x = self.fc3(x)
x = tf.nn.relu(x)
x = self.fc4(x)
x = tf.nn.relu(x)
x = self.fc5(x)
return x
大家自定义层时一定要按照 CBAPD的组合(D一定要有 D前需要flatten())
各层介绍(具体可自行百度):
卷积层(Conv2D):
用于在图像、视频等二维数据上进行卷积操作,提取输入数据的特征信息。
批标准层(BN):
深度神经网络中常用的一种层,用于解决梯度消失和梯度爆炸等问题,加速网络训练和提高泛化能力。
激活层(Activation):
sigmoid函数 relu函数
池化层(Pooling):
通常用于降低输入数据的空间维度,减少参数数量,控制过拟合等。在卷积神经网络(Convolutional Neural Network, CNN)中,池化层通常紧跟在卷积层之后,用于压缩卷积层的输出。
全连接层(Dense):
它是一种多层神经网络,它将输入层的节点与输出层的节点完全连接起来