Coggle 30 日間の ML チェックイン タスク 1: 2 つの競合質問のデータ視覚化
タスク 1: 2 つのコンテストの質問のデータ視覚化
- 難易度/スコア: 低/1
パンチ内容:
- 出場者名:アップルドクター
- 竣工日:2023.6.6
- タスクの完了ステータス:
- 使用プログラミング言語:Python
- 実装された機能:
- 課題1のリンゴ病データの可視化方法:
- リンゴ病画像をロードし、画像とそのラベルを表示します。
- 課題2の建物検知データの可視化方法:
- 「吉林1号」の高解像度衛星リモートセンシング画像をロードして画像を表示します。
- 建物の変化を画像で視覚化します。
- 課題1のリンゴ病データの可視化方法:
背景紹介
このチェックイン タスクは、Coggle 30 日間の ML の最初のタスクであり、2 つの競合質問のデータ視覚化を完了する必要があります。問題 1 はリンゴの葉の病気の特定で、9 つの自然環境におけるリンゴの葉の病気の画像データが提供され、出場者はその画像とそのラベルを表示する必要があります。問題 2 は建物の変化の検出で、「吉林省 1 号」の高解像度衛星リモートセンシング画像がデータセットとして提供され、出場者は画像内の建物の変化を示す必要があります。
ミッション名 | 難易度・スコア |
---|---|
タスク 1: 2 つのコンテストの質問のデータ視覚化 | 低い/1 |
タスク 2: リンゴ病データの読み込みとデータ拡張 | 中/2 |
タスク 3: リンゴ病モデルのトレーニングと予測 | 中/2 |
タスク 4: リンゴ病モデルの最適化と多重トレーニング | 高/3 |
タスク 5: 建物検出データのロードとデータ拡張 | 高/2 |
タスク 6: 建物検出モデルのトレーニングと予測 | 中/2 |
タスク 7: 建物検出モデルの最適化とマルチフォールド トレーニング | 高/3 |
データセットの準備
まずサインアップしてデータセットをダウンロードします。練習試合のアドレスは次のとおりです。
問題 1: リンゴ病の画像認識
ラベル分布の視覚化
次に、リンゴ病データセットのラベルを視覚化して分析しました。まず、カテゴリごとのデータ量を計算し、ヒストグラムを使用してカテゴリ数の分布を示しました。
root = './datasets/apple'
classes_name = ['d1', 'd2', 'd3', 'd4', 'd5', 'd6', 'd7', 'd8', 'd9']
split = 1.0
train_path, val_path = [], []
class_counts = []
for cls in classes_name:
cls_path = glob.glob(f'{
root}/train/{
cls}/*')
class_counts.append(len(cls_path))
print(f"类别 {
cls} 数量为: {
len(cls_path)}")
# 计算训练集和验证集的数量
num_train = int(len(cls_path) * split)
num_val = len(cls_path) - num_train
# 随机选取80%的数据,存储到训练集列表中
train_path.extend(random.sample(cls_path, num_train))
# 将剩余的20%的数据存储到验证集列表中
val_path.extend(list(set(cls_path) - set(train_path)))
# 设置图表样式
plt.style.use('seaborn-whitegrid')
# 可视化类别数量
plt.bar(classes_name, class_counts)
plt.xlabel('Category')
plt.ylabel('Count')
plt.title('Category Count')
# 在每个柱子上方添加类别数量标签
for i in range(len(class_counts)):
plt.text(i, class_counts[i], class_counts[i], ha='center', va='bottom')
plt.xticks(rotation=45)
plt.show()
視覚化の結果から、リンゴ病データセットのラベル分布がアンバランスであることがわかります。このうち、サンプル数が 1,900 を超えるカテゴリが 3 つありますが、他のカテゴリはサンプルが 1,000 未満で、5 つのカテゴリでもサンプル数は 300 程度にすぎません。したがって、このデータセットのラベル分布には不均衡があります。
各カテゴリのデータ量統計は次のとおりです。
类别 d1 数量为: 292
类别 d2 数量为: 288
类别 d3 数量为: 2227
类别 d4 数量为: 238
类别 d5 数量为: 362
类别 d6 数量为: 260
类别 d7 数量为: 829
类别 d8 数量为: 1928
类别 d9 数量为: 3787
平均サイズを計算する
画像のサイズ特性を把握するために、すべての画像の平均サイズも計算しました。
total_width = 0
total_height = 0
num_images = len(train_path)
# 遍历训练集中的所有图像,求出它们的平均宽度和高度
for image_path in tqdm(train_path):
image = Image.open(image_path)
width, height = image.size
total_width += width
total_height += height
average_width = total_width / num_images
average_height = total_height / num_images
print("Average Image Size:")
print("Width:", average_width)
print("Height:", average_height)
計算された平均幅は 990、平均高さは 683 です。
Average Image Size:
Width: 990.6477328371365
Height: 683.6091469983352
各カテゴリの写真を視覚化する
各クラスの特徴をよりよく理解するために、各クラスの最初のいくつかの画像を示します。
num_images_per_category = 5
# 显示每个类别的前num_images_per_category张图像
for cls in classes_name:
cls_path = glob.glob(f'{
root}/train/{
cls}/*')[:num_images_per_category]
fig, axes = plt.subplots(1, num_images_per_category, figsize=(12, 2))
for i, image_path in enumerate(cls_path):
image = Image.open(image_path)
axes[i].imshow(image)
axes[i].axis('off')
plt.suptitle(f'Images for Category {
cls}')
plt.show()
上記の可視化結果から、各カテゴリの特徴を観察することができます。特にd2、d6カテゴリーではその特徴が最も顕著に表れます。d2 カテゴリーは黄色の葉を表しますが、d6 カテゴリーにはある程度の腐敗のある葉が含まれます。
問題 2: 建物の変更の検出
建物変化検出データセットには、Image1、Image2、label1 という 3 つのフォルダーがあります。
**元のイメージ:**デュアルテンポラル イメージは、R、G、B バンドを含む .tif 形式で保存されます。トレーニング セットとテスト セットの画像サイズは両方とも 512x512 ピクセルです。
**ラベル データ:** ラベルは単一チャネルの .png#pic_center 形式で保存され、各ピクセルのラベル値は数値で表され、「uint8」データ型を使用して保存されます。ラベル値はピクセルが変化したかどうかを示します。「0」は変化なし、「1」は変化を意味します。ラベルの寸法も 512x512 ピクセルです。
ラベル分布の視覚化
plt.figure(figsize=(12, 6))
bar_color = 'skyblue' # 柱状图颜色
bar_width = 0.8 # 柱状图宽度
# 绘制柱状图
bars = plt.bar(labels, counts, color=bar_color, width=bar_width)
# 在每个柱状图上方显示标签的数量
for bar in bars:
height = bar.get_height()
plt.text(bar.get_x() + bar.get_width() / 2, height, height,
ha='center', va='bottom', fontsize=8)
plt.xlabel('Pixel Label')
plt.ylabel('Count')
plt.title('Pixel Label Distribution')
plt.xticks(rotation=45, ha='right') # 旋转x轴标签
plt.tight_layout() # 调整布局以避免标签被裁剪
plt.show()
上記のコードにより、ラベル分布の可視化結果が得られます。図からわかるように、「0」は変化なし、「1」は変化を意味します。ピクセル ラベル「0」の数が「1」の数よりもはるかに多いことがわかります。具体的には、「0」の画素数は626,774,703個、「1」の画素数は28,585,297個となる。各画像のサイズは 512x512 ピクセルです。
リモートセンシング画像の可視化
Image1、Image2、label という 3 つの列が表示されます。
root = 'datasets/satellite/train'
image_folder1 = 'Image1'
image_folder2 = 'Image2'
label_folder = 'label1'
folder1_path = os.path.join(root, image_folder1)
folder2_path = os.path.join(root, image_folder2)
label_path = os.path.join(root, label_folder)
# 获取文件夹中的TIF图像文件列表
image_files1 = sorted([f for f in os.listdir(folder1_path) if f.endswith('.tif')])
image_files2 = sorted([f for f in os.listdir(folder2_path) if f.endswith('.tif')])
label_files = sorted([f for f in os.listdir(label_path) if f.endswith('.png')])
num_images = min(3, len(image_files1), len(image_files2), len(label_files))
fig, axes = plt.subplots(num_images, 3, figsize=(12, 6))
for i in range(num_images):
image_path1 = os.path.join(folder1_path, image_files1[i])
image_path2 = os.path.join(folder2_path, image_files2[i])
label_image_path = os.path.join(label_path, label_files[i])
image1 = Image.open(image_path1)
image2 = Image.open(image_path2)
label_image = Image.open(label_image_path)
axes[i, 0].imshow(image1)
axes[i, 0].axis('off')
axes[i, 0].set_title(f'{
image_files1[i]}')
axes[i, 1].imshow(image2)
axes[i, 1].axis('off')
axes[i, 1].set_title(f'{
image_files2[i]}')
axes[i, 2].imshow(label_image, cmap='gray')
axes[i, 2].axis('off')
axes[i, 2].set_title(f'{
label_files[i]}')
plt.tight_layout()
plt.show()