편집 기록

편집 기록
  • 프로필 nowp님의 편집
    날짜2020.03.06

    CNN 학습


    #!/usr/bin/env python
    # coding: utf-8
    
    # In[30]:
    
    
    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    
    import torch.optim as optim
    from torch.utils.data import DataLoader
    
    import torchvision
    import torchvision.transforms as transforms
    
    
    # In[31]:
    
    
    import visdom
    
    vis = visdom.Visdom()
    vis.close(env="main")
    
    
    # In[32]:
    
    
    def value_tracker(value_plot, value, num):
        '''num, loss_value, are Tensor'''
        vis.line(X=num,
                 Y=value,
                 win = value_plot,
                 update='append'
                 )
    
    
    # In[33]:
    
    
    #device = 'cuda' if torch.cuda.is_available() else 'cpu'
    device = 'cpu'
    print(device)
    
    torch.manual_seed(2020)
    if device =='cuda':
        torch.cuda.manual_seed_all(2020)
    
    
    # In[34]:
    
    
    train_data_mean = [0.5, 0.5, 0.5]
    train_data_std = [0.5, 0.5, 0.5]
    
    
    # In[35]:
    
    
    transform_train = transforms.Compose([
        transforms.RandomCrop(16, padding=4),
        transforms.ToTensor(),
        #transforms.Normalize(train_data_mean, train_data_std)
    ])
    
    transform_test = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize(train_data_mean, train_data_std)
    ])
    
    trainset = torchvision.datasets.ImageFolder(root='C:/Users/beomseokpark/Desktop/CNN/train_data_processed',
                                                transform=transform_train)
    trainloader = torch.utils.data.DataLoader(trainset, batch_size=128,
                                              shuffle=True, num_workers=0)
    
    testset = torchvision.datasets.ImageFolder(root='C:/Users/beomseokpark/Desktop/CNN/test_data_processed',
                                                transform=transform_test)
    testloader = torch.utils.data.DataLoader(testset, batch_size=128,
                                             shuffle=False, num_workers=0)
    
    
    # In[36]:
    
    
    import torchvision.models.resnet as resnet
    
    
    # In[37]:
    
    
    conv1x1=resnet.conv1x1
    Bottleneck = resnet.Bottleneck
    BasicBlock= resnet.BasicBlock
    
    
    # In[38]:
    
    
    class ResNet(nn.Module):
    
        def __init__(self, block, layers, num_classes=1000, zero_init_residual=False):
            super(ResNet, self).__init__()
            self.inplanes = 16
            self.conv1 = nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1,
                                   bias=False)
            self.bn1 = nn.BatchNorm2d(16)
            self.relu = nn.ReLU(inplace=True)
            #self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
    
            self.layer1 = self._make_layer(block, 16, layers[0], stride=1)
            self.layer2 = self._make_layer(block, 32, layers[1], stride=1)
            self.layer3 = self._make_layer(block, 64, layers[2], stride=2)
            self.layer4 = self._make_layer(block, 128, layers[3], stride=2)
    
            self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
            self.fc = nn.Linear(128 * block.expansion, num_classes)
    
            for m in self.modules():
                if isinstance(m, nn.Conv2d):
                    nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                elif isinstance(m, nn.BatchNorm2d):
                    nn.init.constant_(m.weight, 1)
                    nn.init.constant_(m.bias, 0)
    
            if zero_init_residual:
                for m in self.modules():
                    if isinstance(m, Bottleneck):
                        nn.init.constant_(m.bn3.weight, 0)
                    elif isinstance(m, BasicBlock):
                        nn.init.constant_(m.bn2.weight, 0)
    
        def _make_layer(self, block, planes, blocks, stride=1):
            downsample = None
            if stride != 1 or self.inplanes != planes * block.expansion:
                downsample = nn.Sequential(
                    conv1x1(self.inplanes, planes * block.expansion, stride),
                    nn.BatchNorm2d(planes * block.expansion),
                )
    
            layers = []
            layers.append(block(self.inplanes, planes, stride, downsample))
            self.inplanes = planes * block.expansion
            for _ in range(1, blocks):
                layers.append(block(self.inplanes, planes))
    
            return nn.Sequential(*layers)
    
        def forward(self, x):
            x = self.conv1(x)
            x = self.bn1(x)
            x = self.relu(x)
            #x = self.maxpool(x)
    
            x = self.layer1(x)
            x = self.layer2(x)
            x = self.layer3(x)
            x = self.layer4(x)
    
            x = self.avgpool(x)
            x = x.view(x.size(0), -1)
            x = self.fc(x)
    
            return x
    
    
    # In[39]:
    
    
    resnet18 = ResNet(resnet.BasicBlock, [2, 2, 2, 2], 4, True).to(device)
    resnet50 = ResNet(resnet.Bottleneck, [3, 4, 6, 3], 4, True).to(device) 
    
    
    # In[40]:
    
    
    criterion = nn.CrossEntropyLoss().to(device)
    #optimizer = torch.optim.SGD(resnet50.parameters(), lr = 0.005, momentum = 0.9, weight_decay=5e-4)#default = lr 0.1
    optimizer = torch.optim.Adam(resnet50.parameters(), lr=0.05)
    lr_sche = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=1)#default = gamma 0.5
    
    
    # In[41]:
    
    
    loss_plt = vis.line(Y=torch.Tensor(1).zero_(),opts=dict(title='loss_tracker', legend=['loss'], showlegend=True))
    acc_plt = vis.line(Y=torch.Tensor(1).zero_(),opts=dict(title='Accuracy', legend=['Acc'], showlegend=True))
    
    
    # In[42]:
    
    
    def acc_check(net, test_set, epoch, save=1):
        correct = 0
        total = 0
        with torch.no_grad():
            for data in test_set:
                images, labels = data
                images = images.to(device)
                labels = labels.to(device)
                outputs = net(images)
    
                _, predicted = torch.max(outputs.data, 1)
    
                total += labels.size(0)
                correct += (predicted == labels).sum().item()
    
        acc = (100 * correct / total)
        print('Accuracy of the network on test images: %d %%' % acc)
        if save:
            torch.save(net.state_dict(), "C:/Users/beomseokpark/Desktop/CNN/model/ResNet_epoch_{}_acc_{}.pth".format(epoch, int(acc)))
        return acc
    
    
    # In[43]:
    
    
    print(len(trainloader))
    epochs = 50
    
    for epoch in range(epochs):
    
        running_loss = 0.0
        lr_sche.step()
        for i, data in enumerate(trainloader, 0):
            inputs, labels = data
            inputs = inputs.to(device)
            labels = labels.to(device)
    
            optimizer.zero_grad()
    
            outputs = resnet50(inputs)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()
    
            running_loss += loss.item()
            if i % 30 == 29:
                value_tracker(loss_plt, torch.Tensor([running_loss/30]), torch.Tensor([i + epoch*len(trainloader) ]))
                print('[%d, %5d] loss: %.3f' %
                      (epoch + 1, i + 1, running_loss / 30))
                running_loss = 0.0
    
        acc = acc_check(resnet50, testloader, epoch, save=1)
        value_tracker(acc_plt, torch.Tensor([acc]), torch.Tensor([epoch]))
    
    
    print('Finished Training')
    
    
    # In[ ]:
    
    
    correct = 0
    total = 0
    
    with torch.no_grad():
        for data in testloader:
            images, labels = data
            images = images.to(device)
            labels = labels.to(device)
            outputs = resnet50(images)
    
            _, predicted = torch.max(outputs.data, 1)
    
            total += labels.size(0)
    
            correct += (predicted == labels).sum().item()
    
    print('Accuracy of the network on test images: %d %%' % (
        100 * correct / total))
    

    이미지

    다음과 같은 암석 박편 데이터셋을 수집하여 4개의 클래스로 구별하는 코드를 ResNet으로 구현해보았는데, 정확도가 너무 나오지 않네요.

    학습이 잘 되지 않는데 데이터셋이 학습시키기 어려운 것인가요?

    이 정도 난이도의 데이터셋 같은 경우 어느정도의 정확도가 나와야 정상인지 궁금합니다.

  • 프로필 박범석님의 편집
    날짜2020.03.06

    CNN 학습


    #!/usr/bin/env python
    # coding: utf-8
    
    # In[30]:
    
    
    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    
    import torch.optim as optim
    from torch.utils.data import DataLoader
    
    import torchvision
    import torchvision.transforms as transforms
    
    
    # In[31]:
    
    
    import visdom
    
    vis = visdom.Visdom()
    vis.close(env="main")
    
    
    # In[32]:
    
    
    def value_tracker(value_plot, value, num):
        '''num, loss_value, are Tensor'''
        vis.line(X=num,
                 Y=value,
                 win = value_plot,
                 update='append'
                 )
    
    
    # In[33]:
    
    
    #device = 'cuda' if torch.cuda.is_available() else 'cpu'
    device = 'cpu'
    print(device)
    
    torch.manual_seed(2020)
    if device =='cuda':
        torch.cuda.manual_seed_all(2020)
    
    
    # In[34]:
    
    
    train_data_mean = [0.5, 0.5, 0.5]
    train_data_std = [0.5, 0.5, 0.5]
    
    
    # In[35]:
    
    
    transform_train = transforms.Compose([
        transforms.RandomCrop(16, padding=4),
        transforms.ToTensor(),
        #transforms.Normalize(train_data_mean, train_data_std)
    ])
    
    transform_test = transforms.Compose([
        transforms.ToTensor(),
        transforms.Normalize(train_data_mean, train_data_std)
    ])
    
    trainset = torchvision.datasets.ImageFolder(root='C:/Users/beomseokpark/Desktop/CNN/train_data_processed',
                                                transform=transform_train)
    trainloader = torch.utils.data.DataLoader(trainset, batch_size=128,
                                              shuffle=True, num_workers=0)
    
    testset = torchvision.datasets.ImageFolder(root='C:/Users/beomseokpark/Desktop/CNN/test_data_processed',
                                                transform=transform_test)
    testloader = torch.utils.data.DataLoader(testset, batch_size=128,
                                             shuffle=False, num_workers=0)
    
    
    # In[36]:
    
    
    import torchvision.models.resnet as resnet
    
    
    # In[37]:
    
    
    conv1x1=resnet.conv1x1
    Bottleneck = resnet.Bottleneck
    BasicBlock= resnet.BasicBlock
    
    
    # In[38]:
    
    
    class ResNet(nn.Module):
    
        def __init__(self, block, layers, num_classes=1000, zero_init_residual=False):
            super(ResNet, self).__init__()
            self.inplanes = 16
            self.conv1 = nn.Conv2d(3, 16, kernel_size=3, stride=1, padding=1,
                                   bias=False)
            self.bn1 = nn.BatchNorm2d(16)
            self.relu = nn.ReLU(inplace=True)
            #self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
    
            self.layer1 = self._make_layer(block, 16, layers[0], stride=1)
            self.layer2 = self._make_layer(block, 32, layers[1], stride=1)
            self.layer3 = self._make_layer(block, 64, layers[2], stride=2)
            self.layer4 = self._make_layer(block, 128, layers[3], stride=2)
    
            self.avgpool = nn.AdaptiveAvgPool2d((1, 1))
            self.fc = nn.Linear(128 * block.expansion, num_classes)
    
            for m in self.modules():
                if isinstance(m, nn.Conv2d):
                    nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')
                elif isinstance(m, nn.BatchNorm2d):
                    nn.init.constant_(m.weight, 1)
                    nn.init.constant_(m.bias, 0)
    
            if zero_init_residual:
                for m in self.modules():
                    if isinstance(m, Bottleneck):
                        nn.init.constant_(m.bn3.weight, 0)
                    elif isinstance(m, BasicBlock):
                        nn.init.constant_(m.bn2.weight, 0)
    
        def _make_layer(self, block, planes, blocks, stride=1):
            downsample = None
            if stride != 1 or self.inplanes != planes * block.expansion:
                downsample = nn.Sequential(
                    conv1x1(self.inplanes, planes * block.expansion, stride),
                    nn.BatchNorm2d(planes * block.expansion),
                )
    
            layers = []
            layers.append(block(self.inplanes, planes, stride, downsample))
            self.inplanes = planes * block.expansion
            for _ in range(1, blocks):
                layers.append(block(self.inplanes, planes))
    
            return nn.Sequential(*layers)
    
        def forward(self, x):
            x = self.conv1(x)
            x = self.bn1(x)
            x = self.relu(x)
            #x = self.maxpool(x)
    
            x = self.layer1(x)
            x = self.layer2(x)
            x = self.layer3(x)
            x = self.layer4(x)
    
            x = self.avgpool(x)
            x = x.view(x.size(0), -1)
            x = self.fc(x)
    
            return x
    
    
    # In[39]:
    
    
    resnet18 = ResNet(resnet.BasicBlock, [2, 2, 2, 2], 4, True).to(device)
    resnet50 = ResNet(resnet.Bottleneck, [3, 4, 6, 3], 4, True).to(device) 
    
    
    # In[40]:
    
    
    criterion = nn.CrossEntropyLoss().to(device)
    #optimizer = torch.optim.SGD(resnet50.parameters(), lr = 0.005, momentum = 0.9, weight_decay=5e-4)#default = lr 0.1
    optimizer = torch.optim.Adam(resnet50.parameters(), lr=0.05)
    lr_sche = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=1)#default = gamma 0.5
    
    
    # In[41]:
    
    
    loss_plt = vis.line(Y=torch.Tensor(1).zero_(),opts=dict(title='loss_tracker', legend=['loss'], showlegend=True))
    acc_plt = vis.line(Y=torch.Tensor(1).zero_(),opts=dict(title='Accuracy', legend=['Acc'], showlegend=True))
    
    
    # In[42]:
    
    
    def acc_check(net, test_set, epoch, save=1):
        correct = 0
        total = 0
        with torch.no_grad():
            for data in test_set:
                images, labels = data
                images = images.to(device)
                labels = labels.to(device)
                outputs = net(images)
    
                _, predicted = torch.max(outputs.data, 1)
    
                total += labels.size(0)
                correct += (predicted == labels).sum().item()
    
        acc = (100 * correct / total)
        print('Accuracy of the network on test images: %d %%' % acc)
        if save:
            torch.save(net.state_dict(), "C:/Users/beomseokpark/Desktop/CNN/model/ResNet_epoch_{}_acc_{}.pth".format(epoch, int(acc)))
        return acc
    
    
    # In[43]:
    
    
    print(len(trainloader))
    epochs = 50
    
    for epoch in range(epochs):
    
        running_loss = 0.0
        lr_sche.step()
        for i, data in enumerate(trainloader, 0):
            inputs, labels = data
            inputs = inputs.to(device)
            labels = labels.to(device)
    
            optimizer.zero_grad()
    
            outputs = resnet50(inputs)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()
    
            running_loss += loss.item()
            if i % 30 == 29:
                value_tracker(loss_plt, torch.Tensor([running_loss/30]), torch.Tensor([i + epoch*len(trainloader) ]))
                print('[%d, %5d] loss: %.3f' %
                      (epoch + 1, i + 1, running_loss / 30))
                running_loss = 0.0
    
        acc = acc_check(resnet50, testloader, epoch, save=1)
        value_tracker(acc_plt, torch.Tensor([acc]), torch.Tensor([epoch]))
    
    
    print('Finished Training')
    
    
    # In[ ]:
    
    
    correct = 0
    total = 0
    
    with torch.no_grad():
        for data in testloader:
            images, labels = data
            images = images.to(device)
            labels = labels.to(device)
            outputs = resnet50(images)
    
            _, predicted = torch.max(outputs.data, 1)
    
            total += labels.size(0)
    
            correct += (predicted == labels).sum().item()
    
    print('Accuracy of the network on test images: %d %%' % (
        100 * correct / total))
    

    이미지

    다음과 같은 암석 박편 데이터셋을 수집하여 4개의 클래스로 구별하는 코드를 ResNet으로 구현해보았는데, 정확도가 너무 나오지 않네요ㅠㅠ

    학습이 잘 되지 않는데 데이터셋이 학습시키기 어려운 것인가요?

    이 정도 난이도의 데이터셋 같은 경우 어느정도의 정확도가 나와야 정상인지 궁금합니다.