
2025.03.03
Chapter 6. Transfer Learning
41. 식물잎의 사진으로 질병분류 - 파일정리42. 식물잎의 사진으로 질병분류 - 학습하기주 의
병든 작물잎 사진을 이용한 분류문제
kaggle에서 좋은 평가를 받은 코드로 해설. 좀 어려울 수 있지만.. 세미나 느낌으로 접근..
데이터는
kaggle에도 있고, 강사님이 공유해주신google Drive에서도 받을 수 있었다.

colab에서 압축푸는 것..

- 폴더이름을 이용해서
class_list생성

test,train,validation데이터를 나눌 폴더 생성

- 폴더 추가생성하기


처음에 원본 데이터가 저장되어 있는
dataset폴더 내 각각의 폴더에서, 사진데이터를splitted폴더로 복사해야 한다.
다만, 전체를 일괄복사가 아닌,train(60%), test(20%), val(20%)정도로 나누어서 이동복사 한다.
import math
for cls in classes_list:
path = os.path.join(origin_dataset_dir, cls)
fnames = os.listdir(path)
# 각 폴더안에 있는 파일의 목록이 저장된다.
# Sick_plant 폴더안에 dataset 폴더안에 Apple_Applt_scab 폴더 안의
# image(1).JPG... 파일들의 이름이 fnames에 저장된다.
# 위 폴더는 fnames에는 첫 반복문에서 630개의 이름이 저장된다 (list 형태태)
train_size = math.floor(len(fnames) * 0.6)
test_size = math.floor(len(fnames) * 0.2)
val_size = math.floor(len(fnames) * 0.2)
# 630개 중에서 60%는 train data로, 나머지 각 20% 씩 test, val 데이터로 사용
# size만 설정
# math.floor = 주어진 숫자보다 작거나 같은 가장 큰 정수 반환
'''train 데이터 복사사'''
train_fnames = fnames[:train_size]
print('Train size (',cls,') : ', len(train_fnames))
for fname in train_fnames:
scr = os.path.join(path, fname)
# train으로 사용한 사진파일 경로
dst = os.path.join(os.path.join(train_dir, cls), fname)
# splitted 폴더에 train 폴더에 apple.. 폴더에 파일이름으로 경로생성
shutil.copyfile(scr, dst)
# scr 경로파일을 dst로 복사
# src(원본 파일)에서 dst(대상 파일)로 파일 내용을 그대로 복사합니다.
'''val 데이터 복사사'''
val_fnames = fnames[train_size:(val_size + train_size)]
# 60부터 80까지 해서 20개가 선택된다 (20%)
print('val size (',cls,') : ', len(val_fnames))
for fname in val_fnames:
scr = os.path.join(path, fname)
# train으로 사용한 사진파일 경로
dst = os.path.join(os.path.join(val_dir, cls), fname)
# splitted 폴더에 train 폴더에 apple.. 폴더에 파일이름으로 경로생성
shutil.copyfile(scr, dst)
# scr 경로파일을 dst로 복사
# src(원본 파일)에서 dst(대상 파일)로 파일 내용을 그대로 복사합니다.
'''test 데이터 복사사'''
test_fnames = fnames[(val_size + train_size):(val_size + test_size + train_size)]
print('test size (',cls,') : ', len(test_fnames))
for fname in test_fnames:
scr = os.path.join(path, fname)
# train으로 사용한 사진파일 경로
dst = os.path.join(os.path.join(test_dir, cls), fname)
# splitted 폴더에 train 폴더에 apple.. 폴더에 파일이름으로 경로생성
shutil.copyfile(scr, dst)
# scr 경로파일을 dst로 복사
# src(원본 파일)에서 dst(대상 파일)로 파일 내용을 그대로 복사합니다.

train, test, val 폴더에 사진파일이 지정된 크기(개수)만큼 저장되는 것을 알 수 있다.
- 관련 모듈, 라이브러리 import
GPU사용 설정

batch-size가 클수록 속도가 개선된다. 다만, GPU 메모리 내에서 크게할 수 있다.

🔹 ImageFolder의 역할
- DataLoader -> batch 학습 적용하기 위한..
num_workers는 GPU 또는 CPU 사용갯수 지정


- 너무 길어서 코드자체 복사.
- class 정의
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(3, 32, 3, padding=1)
self.pool = nn.MaxPool2d(2,2)
self.conv2 = nn.Conv2d(32, 64, 3, padding=1)
self.conv2 = nn.Conv2d(64, 64, 3, padding=1)
self.fc1 = nn.Linear(4096, 512)
# 64 X 64 를 2X2 pooling -> 32, 16, 8
# (8 X 8) X 64 (출력채널널) = 4096
self.fc2 = nn.Linear(512, 33)
# 512는 그냥 잡은듯
# 33는 폴더 숫자. 즉, class 숫자.
def forward(self, x):
x = self.conv1(x)
x = F.relu(x)
x = self.pool(x)
x = F.dropout(x, p=0.25, training=self.training)
# training = self.training 은 model.train() 때만 사용하겟다는 의미
x = self.conv2(x)
x = F.relu(x)
x = self.pool(x)
x = F.dropout(x, p=0.25, training=self.training)
x = self.conv3(x)
x = F.relu(x)
x = self.pool(x)
x = F.dropout(x, p=0.25, training=self.training)
x = x.view(-1, 4096)
x = self.fc1(x)
x = F.relu(x)
x = F.dropout(x, p=0.25, training=self.training)
x = self.fc2(x)
return F.log_softmax(x, dim=1)

- train하는 것도 함수로 만들기

- 전체과정 함수로 설정


--------------------- epoch 30 ----------------------
train Loss : 0.0270, Accuracy : 99.32 %
val Loss : 0.2267, Accuracy : 93.08 %
Completed in 0m 43s