自定义数据集的 CNN 训练产生了一个奇怪的结果

CNN training for custom dataset yields a weird result

提问人:Caleb Lee 提问时间:11/16/2023 最后编辑:halferCaleb Lee 更新时间:11/17/2023 访问量:32

问:

我正在尝试通过PyTorch的简单CNN将数据(速度谱面板;sgy文件)训练为坐标(速度结构配置文件;csv文件)。为了测试训练模型是否有效,我用 10 个带有标签的数据进行了测试。

但它产生了一个奇怪的结果:

纪元 1

失利: Nan [ 1/ 10]

测试错误: 精度:0.0%,平均损耗:nan

纪元 2

失利: Nan [ 1/ 10] 测试错误: 精度:0.0%,平均损耗:nan

...

纪元 10

失利: Nan [ 1/ 10] 测试错误: 精度:0.0%,平均损耗:nan

做!

如果我将“batch_size=1”更改为“batch_size=3”,它将显示以下错误:

纪元 1

失利: Nan [ 3/ 10]

-

RuntimeError 回溯(最近一次调用) <ipython-input-9-3c78b7430da0> 在 <细胞系中:144>() 145 print(f“Epoch {t+1}\n-------------------------------”) 146 train_loop(train_dataloader、模型、loss_fn、优化器) --> 147 test_loop(test_dataloader、型号、loss_fn) 148 打印(“完成!

<ipython-input-9-3c78b7430da0> in test_loop(test_dataloader, model, loss_fn) 135 pred = 模型(数据) 136 test_loss += loss_fn(pred, label).item() --> 137 正确 += (pred.argmax(1) == label).type(torch.float).sum().item() 138 139 test_loss /= num_batches

RuntimeError:张量 a (3) 的大小必须与非单例维度 1 的张量 b (40) 的大小匹配

如何更改我的代码以使训练有效?如何使我的代码无论“batch_size=”中的数字如何都能正常工作?

数据和标签如下所示:

print(data)
print(data.shape)

张量([[[0.0000, 0.0000, 1.0000, ..., 0.0184, 0.0348, 0.0492], [0.0000, 0.0000, 1.0000, ..., 0.0442, 0.0363, 0.0250], [0.0000, 0.0000, 1.0000, ..., 0.0564, 0.0388, 0.0295], ..., [1.0000, 0.9606, 0.8394, ..., 0.0093, 0.0152, 0.0153], [1.0000, 0.9524, 0.8419, ..., 0.0091, 0.0151, 0.0160], [1.0000, 0.9305, 0.8363, ..., 0.0093, 0.0146, 0.0157]]]) 炬。尺寸([1, 50, 200])

print(label)
print(label.shape)

张量([ 178., 1878., 822., 1814., 1375., 2162., 1669., 2304., 2065., 2736., 2528., 2780., 2836., 3008., 3396., 3490., 4013., 3518., 楠, 楠, 楠、楠、楠、楠、楠、�� 楠,楠,楠,楠,楠,�� dtype=torch.float64) 炬。尺寸([40])

完整的代码是:

# custom dataset  <- revised from "https://pytorch.org/tutorials/beginner/data_loading_tutorial.html"

import torch
from torch.utils.data import Dataset
import pandas as pd
import os
import segyio
import numpy as np

class cvspanel_dataset(Dataset):
    def __init__(self, csv_file, root_dir, transform=None):
        self.dv_label = pd.read_csv(csv_file)
        self.root_dir = root_dir
        self.transform = transform

    def __len__(self):
        return len(self.dv_label)

    def __getitem__(self, idx):
        if torch.is_tensor(idx):
            idx = idx.tolist()

        data_name = os.path.join(self.root_dir,
                                 self.dv_label.iloc[idx, 0])
        gth = segyio.open(data_name, ignore_geometry=True)
        data = gth.trace.raw[:]
        data = torch.tensor(data[:, :200])
        data = data.unsqueeze(0)
        arr = self.dv_label.iloc[idx, 1:]
        arr = np.asarray(arr)
        label = arr.astype('float').reshape(-1, 2)
        label = torch.tensor(label)
        label = label.view([-1, 1])
        label = label.squeeze()

        if self.transform:
            data = self.transform(data)
        if self.transform:
            label = self.transform(label)

        return data, label

train_dataset = cvspanel_dataset(csv_file='/content/drive/MyDrive/Colab Notebooks/research_data/synthetic_1D/d-v_label.csv',
                                 root_dir='/content/drive/MyDrive/Colab Notebooks/research_data/synthetic_1D/sgy_cvs_panel',
                                 transform=None)

test_dataset = cvspanel_dataset(csv_file='/content/drive/MyDrive/Colab Notebooks/research_data/synthetic_1D/d-v_label.csv',
                                 root_dir='/content/drive/MyDrive/Colab Notebooks/research_data/synthetic_1D/sgy_cvs_panel',
                                 transform=None)

# dataloader
batch_size = 1

train_dataloader = torch.utils.data.DataLoader(train_dataset,
                                           batch_size)
test_dataloader = torch.utils.data.DataLoader(test_dataset,
                                          batch_size)

# model building

import torch
import torch.nn as nn

class CNN(nn.Module):
    def __init__(self):
        super(CNN, self).__init__()
        self.layer1 = nn.Sequential(
            nn.Conv2d(in_channels=1, out_channels=32, kernel_size=17, stride=1, padding=3),
            nn.BatchNorm2d(32),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=10, stride=5, padding=0)
        )
        self.layer2 = nn.Sequential(
            nn.Conv2d(in_channels=32, out_channels=64, kernel_size=6, stride=1, padding=2),
            nn.BatchNorm2d(64),
            nn.ReLU(),
            nn.MaxPool2d(kernel_size=2, stride=3, padding=1)
        )
        self.fc1 = nn.Linear(in_features=64*3*13, out_features=512)
        self.drop = nn.Dropout(0.25)
        self.fc2 = nn.Linear(in_features=512, out_features=128)
        self.fc3 = nn.Linear(in_features=128, out_features=40)

    def forward(self, x):
        out = self.layer1(x)
        out = self.layer2(out)
        out1 = out.view(out.size(0), -1)
        out = self.fc1(out1)
        out = self.drop(out)
        out = self.fc2(out)
        out = self.fc3(out)
        return out

# hyperparameter

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

model = CNN();
model.to(device)

learning_rate = 0.001;

loss_fn = nn.CrossEntropyLoss();

optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate);

# Training  <- revised from "https://pytorch.org/tutorials/beginner/basics/optimization_tutorial.html"

def train_loop(train_dataloader, model, loss_fn, optimizer):
    size = len(train_dataloader.dataset)
    model.train()
    for batch, (data, label) in enumerate(train_dataloader):
        # Compute prediction and loss
        pred = model(data)
        loss = loss_fn(pred, label)

        # Backpropagation
        loss.backward()
        optimizer.step()
        optimizer.zero_grad()

        if batch % 100 == 0:
            loss, current = loss.item(), (batch + 1) * len(data)
            print(f"loss: {loss:>7f}  [{current:>5d}/{size:>5d}]")


def test_loop(test_dataloader, model, loss_fn):
    model.eval()
    size = len(test_dataloader.dataset)
    num_batches = len(test_dataloader)
    test_loss, correct = 0, 0

    with torch.no_grad():
        for data, label in test_dataloader:
            pred = model(data)
            test_loss += loss_fn(pred, label).item()
            correct += (pred.argmax(1) == label).type(torch.float).sum().item()

    test_loss /= num_batches
    correct /= size
    print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")

epochs = 10
for t in range(epochs):
    print(f"Epoch {t+1}\n-------------------------------")
    train_loop(train_dataloader, model, loss_fn, optimizer)
    test_loop(test_dataloader, model, loss_fn)
print("Done!")
PyTorch 数据集 conv-neural-network 自定义训练

评论


答: 暂无答案