title = "24.4.14.temporal.2015"
train_df = pd.read_csv("./dataFrame/a_train_df.csv",encoding="utf-8")
valid_df = pd.read_csv("./dataFrame/a_valid_df.csv",encoding="utf-8")
test_df = pd.read_csv("./dataFrame/2015년_CT검사결과.csv",encoding="utf-8")
train_df,valid_df,test_df = change_dir(train_df,valid_df,test_df)
train_df, test_df, valid_df, df_minT, df_maxT = t_score_normalization(train_df,valid_df,test_df)
train_loader, _ = get_dataloader(train_df, bone_resize=32, mode='train')
valid_loader, _ = get_dataloader(valid_df, bone_resize=32,mode='valid')
test_loader, _ = get_dataloader(test_df, bone_resize=32,mode='valid')
device = torch.device("cuda")
model = densenet_custom.DenseNet3D_32_1by1_split_detach_reg().to(device)
class_counts = [3, 1 , 2] # 각 클래스에 대한 샘플 수를 리스트로 제공합니다.
total_samples = sum(class_counts)
class_weights = [total_samples / class_counts[i] for i in range(len(class_counts))]
class_weights_tensor = torch.tensor(class_weights).to(device)
# 손실 함수에 클래스 가중치 적용
loss_function = torch.nn.CrossEntropyLoss(weight=class_weights_tensor)
# loss_function = torch.nn.CrossEntropyLoss().to(device)
L1loss_function = torch.nn.L1Loss().to(device)
mse_loss_function = torch.nn.MSELoss().to(device)
optimizer = optim.Adam(model.parameters(), lr=1e-4, weight_decay=1e-5)
num_epochs = 200
이제 여기서 학습을 하기 위해서 들어온다면 chagne_dir은 csv에서 저장된 경로에서 pt를 불러오도록 할 때 경로 설정이라고 생각하면 됨.
이 후 각 프레임에서 t_score를 확인하도록 함.
def t_score_normalization(train_df,valid_df,test_df):
df = pd.concat([train_df,test_df,valid_df])
df_minT = df["T score"].min()
df_maxT = df["T score"].max()
df["T score1"] = (df["T score"] - df["T score"].min() )/(df["T score"].max()-df["T score"].min())
train_df["T score1"] = (train_df["T score"] - df["T score"].min() )/(df["T score"].max()-df["T score"].min())
test_df["T score1"] = (test_df["T score"] - df["T score"].min() )/(df["T score"].max()-df["T score"].min())
valid_df["T score1"] = (valid_df["T score"] - df["T score"].min() )/(df["T score"].max()-df["T score"].min())
return train_df, test_df, valid_df, df_minT, df_maxT
여기를 보면 알 수 있듯이 0~1로 스케일링 하는 과정이라고 생각하면 됨.
이제 [get_dataloader] 함수를 보면
def get_dataloader(df, bone_resize, mode ='valid'):
if mode == 'valid':
dataset = CTDataset(df, bone_resize = bone_resize)
loader = DataLoader(dataset, batch_size = 1)
elif mode == 'train':
dataset = CTDataset(df, bone_resize = bone_resize)
loader = DataLoader(dataset, batch_size = 32, shuffle = True)
return loader, dataset
이런식으로 구성되어 있는데 여기서 CTDataset, DataLoader를 보면서 한 번 확인해보자.
<CTDataset>
class CTDataset(Dataset):
def __init__(self, df, bone_resize, num_classes=3, device=torch.device('cuda')):
self.df = df
self.img_pt_path = df.nii_128_path
self.bone_path = df.otsu_path
self.label = df[df.columns[-num_classes-3:-3]].values
self.T = df["T score"].values
self.person = df['환자번호'].values
self.device = device
self.mean = 0
self.std = 0.1
self.bone_resize = bone_resize
self.noise = torch.tensor((np.random.normal(0, 0.1, (1,128,128,128))),dtype=torch.float).to(device)
self.WC = 400
self.WW = 1800
self.lwin = self.WC - self.WW/2
self.rwin = self.WC + self.WW/2
def __len__(self):
return len(self.df)
def __getitem__(self, idx):
bone_data = torch.load(self.bone_path.iloc[idx])
bone_data = torch.tensor(bone_data, device=self.device).float()
bone_data = bone_data.to(self.device)
bone_data = bone_data.unsqueeze(0)
bone_data = nn.functional.interpolate(bone_data.unsqueeze(0), size=(self.bone_resize,\\
self.bone_resize,self.bone_resize),mode='trilinear')
bone_data[bone_data>0] = -1
bone_data[bone_data==0] = 1
bone_data[bone_data==-1] = 0
bone_data = bone_data.squeeze(0)
pt_data = torch.load(self.img_pt_path.iloc[idx])
pt_data = torch.tensor(pt_data, device=self.device).float()
pt_data = pt_data.to(self.device)
pt_data = pt_data.unsqueeze(0)
pt_data = torch.permute(pt_data,(0,3,2,1)) # c,h,w,d -> c,d,h,w
pt_data[pt_data < self.lwin] = self.lwin
pt_data[pt_data > self.rwin] = self.rwin
pt_data -= pt_data.min()
pt_data /= pt_data.max()
label = self.label[idx]
T = self.T[idx] # T score
person = self.person[idx]
return pt_data, bone_data ,label,T
