个人主页
GitHub地址
文件主入口为 classifier_collection.py。以下出现的代码片断若无说明都来自该程序。
深度学习或机器学习一般处理步骤:
本实验图像分类由以下几个过程组成:
数据分析代码在 tool/analyze.py
里
模块导入:
# coding:UTF-8
import pandas as pd
import warnings
warnings.filterwarnings("ignore")
import seaborn as sns
import matplotlib.pyplot as plt
sns.set(style="white", color_codes=True)
bone = pd.read_csv(r'C:\Users\Yauno\Downloads\rsna-bone-age\boneage-training-dataset.csv')
bone.head()
print(bone.head()) # 打印前5排数据
id boneage male
0 1377 180 False
1 1378 12 False
2 1379 94 False
3 1380 120 True
4 1381 82 False
# 男女各年龄分布图
csv_data = pd.DataFrame(bone)
bone_x, bone_male_y_dict, bone_female_y_dict = [], {}, {}
for i in range(len(csv_data)):
bone_age = csv_data['boneage'][i]
is_male = csv_data['male'][i]
# print(is_male)
if bone_age not in bone_x:
bone_x.append(bone_age)
if is_male == True:
bone_male_y_dict[bone_age] = bone_male_y_dict.get(bone_age, 0) + 1
else:
bone_female_y_dict[bone_age] = bone_female_y_dict.get(bone_age, 0) + 1
# print(bone_male_y_dict)
# print(bone_female_y_dict)
bone_x.sort()
bone_male_y, bone_female_y = [], []
# print(bone_x)
for i in bone_x:
bone_male_y.append(bone_male_y_dict.get(i, 0))
bone_female_y.append(bone_female_y_dict.get(i, 0))
# print(len(bone_x) == len(bone_male_y))
fig, (axs1, axs2) = plt.subplots(1, 2, figsize=(15,15))
axs1.scatter(bone_x, bone_male_y, color="k")
axs1.set_title('male')
axs1.set_xlabel('bone_age')
axs1.set_ylabel('total')
axs2.scatter(bone_x, bone_female_y, color="red")
axs2.set_title('female')
axs2.set_xlabel('bone_age')
axs2.set_ylabel('total')
plt.show()
由上图可以看到大部分年龄段图片数量很少,不仅会降低精确度,还会影响后面k-flod划分训练集。至于为什么会影响,后面说。
# 箱图+数据分布散点图
ax = sns.boxplot(x="male", y="boneage", data=bone)
ax = sns.stripplot(x="male", y="boneage", data=bone, jitter=True, edgecolor="gray")
plt.show()
由上面分析结果可以看出各年龄段数据分布严重不均衡,所以在划分训练集的时候要考虑到训练集必须包括所有年龄段。
数据抽取的原接口程序为 tool/get_data.py
返回的数据类型看原接口,每个训练集与验证集文件夹下都对应着标签标签名为 labels.txt。由于数据中的分类不是从0开始,所以在数据抽取过程中对分类进行重新编号,最后得到的分类编号在 input_para['lables_output']
下面。
这里的几个输入输出路径不用讲,要讲的为:
原接口程序 tool/pic_data_augmentation.py
参数讲解:
{pic_name:class}
, 标签名对应着分类ignore
参数为 True
时,则程序会忽略 threshed
参数,每张图片将会被固定扩充max_gen张这里数据处理使用 \unet
文件下的程序进行处理
在一般机器学习或深度学习中数据处理又称数据清洗,主要是对数据进行检查偏差并处理缺失值与噪音。在本次分类处理中,即对数据进行去噪处理。去噪处理可以简单使用低通滤波进行去噪,但更为实际的是提取感兴趣区域:分割。
主要用法见unet分割代码。
k-fold:将数据划分为k份, 每次训练k-1份数据,用训练好的模型对剩下1份数据进行验证,也称交叉验证。在一般使用单个模型训练时可以通过这种方法找到更好地模型及参数。在本次分类中用于对集成学习中基础学习器的训练。
集成学习主要有三种:bagging, boosting, stacking。
如图,将划分为5折的数据按1-4组合,共有5总组合方式(有啥疑问的联系我),如图中trainingdata的五列。假设我们有5个不同的神经网络模型,首先用一个神经网络模型如图中的Model1, 对5组数训练数据进行训练,每个组训练数据又分为5份(这是由于每组训练数据是由5折数据组合的),每组数据4分作为训练集,用模型Model1训练4分数据然后对剩下一分进行预测,依次这样经过五次训练后就能得到同一个神经网络模型的5个不同训练结果,并且所有数据都被预测了一次(黄色)。这里的绿色表示对待测试数据集(testdata)进行预测,每一个网络模型的5个不同结果都对同一testdata进行预测,最后加权求平均获得一个新的待预测数据。5个不同的神经网络模型对每一个训练数据都会进行预测,所以每个训练集(trainingdata)可以得到5个不同的预测结果(train_prediction, 每个图片可以得到5个不同的预测分类结果,这里的分类并咩有经过argmax,而是一个一维数组),而待预测的数据也会有5个不同的预测结果(test_prediction)。通过模型融合将训练数据预测结果train_prediction作为新的训练数据,可以训练出新的模型,这样就可以对待预测数据test_prediction进行最终的预测。
原接口 tool/disposal_data.py
, 最后生成k-fold个文件,每个文件下又分为train和test,对应上图中的蓝色数据集与黄色数据集。每次训练时对train文件夹的数据进行训练,对test文件下的数据进行预测。对待预测数据(testdata)的预测放到后面。
train_split_name
对应不用修改,若要使用微调则将checkpoint_path
参数填为微调模型文件路径
8,9步合在一起运行,最终获得对测试集的预测结果
模型训练的时候没有进行参数选择,参数选择一般有三种方法:
几乎所有方法都不能保证达到全局最优,因为深度学习本身就不一定能够达到全局最优
融合模型选用分类模型,有随机森林,GBDT, XGBDT, ExtraTrees, AdaBoost,BaggingClassifier, LogisticRegression,GaussianNB…