這是我參與8月更文挑戰的第4天,活動詳情查看: 8月更文挑戰html
合理的Train/Test集劃分會有效地減小under-fitting和over-fitting現象。以數字識別爲例,正常一個數據集咱們要劃分出來訓練部分和測設部分,以下圖所示python
左側橘色部分做爲訓練部分,神經網絡在該區域內不停地學習,將特徵轉入到函數中,學習好後獲得一個函數模型。隨後將上圖右面白色區域的測試部分導入到該模型中,進行accuracy和loss的驗證git
經過不斷地測試,查看模型是否調整到了一個最佳的參數,及結果是否發生了over-fitting現象markdown
# 訓練-測試代碼寫法
train_loader = torch.utils.data.DataLoader(
# 通常使用DataLoader函數來讓機器學習或測試
datasets.MNIST('../data', train=True, download=True,
# 使用 train=True 或 train=False來進行數據集的劃分
# train=True時爲訓練集,相反即爲測試集
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,),(0.3081,))
])),
batch_size=batch_size, shuffle=True)
test_loader = torch.utils.data.DataLoader(
datasets.MNIST('../data', train=False, download=True,
transform=transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,),(0.3081,))
])),
batch_size=batch_size, shuffle=True)
複製代碼
這裏注意,正常狀況下數據集是要有validation(驗證)集的,若沒有設置,即將test和val集合併爲一個了網絡
上面講解了如何對數據集進行劃分,那麼如何進行循環學習驗證測試呢?app
for epoch in range(epochs):
for batch_idx, (data, target) in enumerate(train_loader):
...
optimizer.zero_grad()
loss.backward()
optimizer.step()
if batch_idx % 100 == 0:
print('Train Epoch: {} [{} / {} ({:.0f}%)]\tLoss: {:.6f}'.format(
epoch, batch_idx * len(data), len(train_loadern.dataset),
100. * batch_idx / len(train_loader), loss.item()))
# 每次循環都查看一次是否發生了over-fitting
# 若是發生了over-fitting,咱們便將最後一次模型的狀態做爲最終的版本
test_loss = 0
correct = 0
for data, target in test_loader:
data = data.view(-1, 28*28)
pred = logits.data.max(1)[1]
correct += pred.eq(target.data).sum()
...
test_loss /= len(test_loader.dataset)
print('\nTest set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n'.format(
test_loss, correct, len(test_loader.dataset),
100. * correct / len(test_loader.dataset)))
複製代碼
以一個實際例子的Train Error和Test Error來舉例做圖dom
由圖看出在Training到第5次後,Test Error便達到一個較低的位置。然後隨着訓練次數的增長,Test Error逐漸增長,發生over-fitting現象。咱們將訓練次數在第5次的這個點叫作check-point機器學習
其實正常狀況下除了Train Set和挑選最佳參數的Test Set外,通常還要有Validation Set。Val Set代替Test Set的功能,而Test Set則要交給客戶,進行實際驗證的,正常狀況下Test Set是不加入到測試中的 函數
說個很具體的場景,就比方說Kaggle競賽中,比賽的主辦方給你訓練的數據集,通常咱們拿來都會本身分紅Train Set和Val Set兩部分,用Train Set訓練,Val Set挑選最佳參數,訓練好之後提交模型,此時主辦方會用它本身的數據集,即Test Set去測試你的模型,獲得一個Scorepost
從上面的過程能看出,Val Set能夠理解爲是從Train Set中拆出來的一部分,而與Test Set沒有關係
print('train:', len(train_db), 'test:', len(test_db))
# 首先先查看train和test數據集的數量,看看是否知足預訂的分配目標
train_db, val_db = torch.utils.data.random_split(train_db, [50000, 10000])
# 隨機分配法將數據分爲50k和10k的數量
train_loader = torch.utils.data.DataLoader(
train_db,
batch_size = batch_size, shuffle=True)
val_loader = torch.utils.data.DataLoader(
val_db,
batch_size = batch_size, shuffle=True)
複製代碼
可是這種訓練方式也會有一些問題,以下圖,假設總的數據量是70k
劃分完成以後,Test Set中的數據集是沒法使用的,這樣就只有50+10k的數據能夠用於學習
爲了增長學習的樣本,咱們能夠用K-fold cross-validation的方法,將這60k訓練了的樣本,再從新隨機劃分出50k的Train Set和10k的Val Set
白色部分爲新劃分的Val Set,兩個黃色部分加一塊爲Train Set。每進行一個epoch,便將新的Train Set給了網絡。這樣作的好處是使得數據集中的每個數據都有可能被網絡學習,防止網絡對相同的數據產生記憶
叫K-fold cross-validation的緣由在於,假設有60K的(Train+Val) Set可供使用,分紅了 份,每次取 份用來作train,另外 份用來作validation