代码来源——bilibiliup主肆十二-
这是我们下载后的代码
这是我们下载的代码
打开pycharm之后的project
images 目录主要是放置一些图片,包括测试的图片和ui界面使用的图片
models 目录下放置训练好的两组模型,分别是cnn模型和mobilenet的模型
results 目录下放置的是训练的训练过程的一些可视化的图,两个txt文件是训练过程中的输出,两个图是两个模型训练过程中训练集和验证集准确率和loss变化曲线
utils 是主要是我测试的时候写的一些文件,对这个项目没有实际的用途
get_data.py 爬虫程序,可以爬取百度的图片
window.py 是界面文件,主要是利用pyqt5完成的界面,通过上传图片可以对图片种类进行预测
testmodel.py 是测试文件,主要是用于测试两组模型在验证集上的准确率,这个信息你从results的txt的输出中也能获取
train_cnn.py 是训练cnn模型的代码
train_mobilenet.py 是训练mobilenet模型的代码
requirements.txt 是本项目需要的包
models:
CNN模型——浅层的网络
mobilenet——深层的网络:比较轻量,模型的层次也比较深
可以用Netron打开 github上搜索下载属于自己电脑版本的 我是windows
Conv2D表示的是卷积
MaxPooling2D表示的是池化
result:
热力图 下面以mobilenet的热力图为例
对角线是它的准确率
在大多数的类上都可以达到100%的准确率
以mobilenet的图为例
上面的图表示的是在训练过程中准确率的变化
下面的图表示的是在训练过程中损失函数的变化
横坐标epoch(时期)纵坐标accuracy(准确率)
蓝色曲线表示的是它的训练集
黄色曲线表示的是它的验证集
执行代码过程
1、train_cnn.py
2、train_mobilenet.py
3、test_model.py
4、window.py
5、
6、
代码介绍
data_split.py
是用来划分数据集
但是我们这里的果蔬的数据集是做了划分的‘
以我们下载的数据集为例
image_data是我们用来训练的数据集
test_image_data是用来测试的数据集
到时候我们就会分开来加载训练集以及测试集
train_scale=0.8, val_scale=0.2
指的是训练集和验证集所占的比例 分别是80%和20%
85行是原始数据的目录文件夹
86行是输入目标数据的文件夹
87行就会给我们划分出来这两个数据集
test_model.py
是用来测试我们这两个模型的
测试与训练的过程主要的不同点在于 测试的过程中我们直接加载模型就可以
调用evaluate去测它总体的一个准确率 就是P0指的高考
下面的代码会对分开的类别 因为我们有12个类 所以会对每个类单独测一个准确率出来
然后绘制成热力图的形式
test_real_labels = []
test_pre_labels = []
for test_batch_images, test_batch_labels in test_ds:
test_batch_labels = test_batch_labels.numpy()
test_batch_pres = model.predict(test_batch_images)
# print(test_batch_pres)
test_batch_labels_max = np.argmax(test_batch_labels, axis=1)
test_batch_pres_max = np.argmax(test_batch_pres, axis=1)
# print(test_batch_labels_max)
# print(test_batch_pres_max)
# 将推理对应的标签取出
for i in test_batch_labels_max:
test_real_labels.append(i)
for i in test_batch_pres_max:
test_pre_labels.append(i)
# break
# print(test_real_labels)
# print(test_pre_labels)
class_names_length = len(class_names)
heat_maps = np.zeros((class_names_length, class_names_length))
for test_real_label, test_pre_label in zip(test_real_labels, test_pre_labels):
heat_maps[test_real_label][test_pre_label] = heat_maps[test_real_label][test_pre_label] + 1
print(heat_maps)
heat_maps_sum = np.sum(heat_maps, axis=1).reshape(-1, 1)
# print(heat_maps_sum)
print()
heat_maps_float = heat_maps / heat_maps_sum
print(heat_maps_float)
# title, x_labels, y_labels, harvest
show_heatmaps(title="heatmap", x_labels=class_names, y_labels=class_names, harvest=heat_maps_float,
save_name="results/heatmap_mobilenet.png")
对角线表示的就是预测正确的概率
train_cnn.py
是用来训练cnn的模型代码
加载data_dir(训练集目录) test_data_dir(测试集目录)
按住ctrl 可以跳转到他具体的调用
"../data/vegetable_fruit/image_data"
这里的..表示的是上级目录
"../data/vegetable_fruit/test_image_data", 224, 224, 16
我们会把图片统一调成224*224的大小送入训练
16所表示的含义就是batchsize 就是说模型一次会送入16张图片
这样是为了防止模型的过拟合 另外可以保证模型训练的速度也可以快一些
model.compile(optimizer='sgd', loss='categorical_crossentropy', metrics=['accuracy'])
optimizer='sgd'使用的是随机梯度下降的一个优化器
loss='categorical_crossentropy'损失函数用的是一个交叉熵的一个损失函数
results下的两个图片文件就是由这个函数进行绘制的
训练的主函数是这样的
可以更改我们的训练周期次数 并且开始
每次训练完之后都会显示训练集与验证集的准确度和损失
train_mobilenet.py
是用来训练mobile的代码
跟上面一样都是先加载数据集 再加载模型
在这里我们把MobileNetV2的特征层拿过来
# 构建mobilenet模型
# 模型加载,指定图片处理的大小和是否进行迁移学习
def model_load(IMG_SHAPE=(224, 224, 3), class_num=12):
# 微调的过程中不需要进行归一化的处理
# 加载预训练的mobilenet模型
base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE,
include_top=False,
weights='imagenet')
# 将模型的主干参数进行冻结
base_model.trainable = False
model = tf.keras.models.Sequential([
# 进行归一化的处理
tf.keras.layers.experimental.preprocessing.Rescaling(1. / 127.5, offset=-1, input_shape=IMG_SHAPE),
# 设置主干模型
base_model,
# 对主干模型的输出进行全局平均池化
tf.keras.layers.GlobalAveragePooling2D(),
# 通过全连接层映射到最后的分类数目上
tf.keras.layers.Dense(class_num, activation='softmax')
])
model.summary()
# 模型训练的优化器为adam优化器,模型的损失函数为交叉熵损失函数
model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['accuracy'])
return model
optimizer='adam'优化器用的是比较高级的adam优化器 loss='categorical_crossentropy'损失函数用的是交叉熵的一个损失函数
跟上一个函数的区别就是mobilenet_fv.h5它的名字不一样
之后就会存在我们上面的models文件里
这上面两个模型运行完之后就会得到两个模型
window.py
是可视化界面的代码