PyTorchでcross-validation(交差検証。以下CV)する場合の実装例を参考として残しておきます。
まずは訓練時の実装例です。
from sklearn.model_selection import KFold
from statistics import mean
# 分割前のデータとして配列等をSeriesあるいはDataFrameに変換している
train_data = pd.Series(〜)
# fold毎のモデル、正解率、損失を格納する配列
nets, accs, losses = [], [], []
# n_splits分割(ここでは5分割)してCV
kf = KFold(n_splits=5, shuffle=True, random_state=2020)
for train_idx, valid_idx in kf.split(train_data):
# train_idx、valid_idxにはインデックスの値が格納されている
train = train_data.iloc[train_idx].reset_index(drop=True)
valid = train_data.iloc[valid_idx].reset_index(drop=True)
# train_one関数では実際の訓練が行われる
net, acc, loss = train_one(train, valid)
nets.append(net)
accs.append(acc)
losses.append(loss)
# CVの評価としてfold毎のvalidの結果を平均したものを使う(他にも手法はあるが)
print("oof acc: {:4f}".format(mean(accs)))
print("oof loss: {:4f}".format(mean(losses)))
次に推論時の実装例です。
# PyTorchを推論モードにする
with torch.no_grad():
for test_path in test_data:
img = Image.open(test_path)
_id = int(test_path.split('/')[-1].split('.')[0])
transform = ImageTransform(SIZE, MEAN, STD)
img = transform(img, phase='val')
img = img.unsqueeze(0)
img = img.to(DEVICE)
pred = 0.0
for i in range(5):
net = nets[i]
net.eval()
outputs = net(img)
preds = F.softmax(outputs, dim=1)[:, 1].tolist()
pred += preds[0]
id_list.append(_id)
# 確率の平均を算出
pred_list.append(pred / SPLITS)
cross-validationをすることで、しない場合に比べて計算量はk(=分割数)倍になりますが、モデルの評価がより確かなものになります。
参考まで。