Computer >> 컴퓨터 >  >> 프로그램 작성 >> Python

PyTorch에서 로지스틱 회귀를 사용하여 필기 숫자 식별?

<시간/>

여기서는 PyTorch를 사용하여 CNN이 MNIST 데이터 세트를 사용하여 필기 숫자 분류기를 인식하도록 훈련할 것입니다.

MNIST는 손으로 쓴 숫자의 70,000개 이상의 레이블이 지정된 28*28 픽셀 회색조 이미지를 다루는 손으로 쓴 분류 작업에 널리 사용되는 데이터세트입니다. 데이터 세트에는 거의 60k 훈련 이미지와 10k 테스트 이미지가 포함되어 있습니다. 우리의 임무는 60k 훈련 이미지를 사용하여 모델을 훈련시킨 다음 10k 테스트 이미지에서 분류 정확도를 테스트하는 것입니다.

설치

먼저 터미널에서 다음을 실행하기 위해 MXNet 최신 버전이 필요합니다.

$pip mxnet 설치

그러면 다음과 같이 될 것입니다.

|
mxnet수집중Downloading https://files.pythonhosted.org/packages/60/6f/071f9ef51467f9f6cd35d1ad87156a29314033bbf78ad862a338b9eaf2e6.██30net-12 ███████████████████████████| 12.8MB 131kB/s요구 사항이 이미 충족됨:c:\python\python361\lib\site-packages의 numpy(mxnet에서) (1.16.0)graphviz 수집(mxnet에서)https://files.pythonhosted.org/packages/ 다운로드 1f/e2/ef2581b5b86625657afd32030f90cf2717456c1d2b711ba074bf007c0f1a/graphviz-0.10.1-py2.py3-none-any.1-py2.py3-none-any.whl.... 

둘째, 토치 및 토치비전 라이브러리가 필요합니다. pip를 사용하여 설치할 수 있는 위치가 아닌 경우

라이브러리 가져오기

가져오기 토치비전 가져오기

MNIST 데이터세트 로드

프로그램 작업을 시작하기 전에 MNIST 데이터 세트가 필요합니다. 이미지와 레이블을 메모리에 로드하고 이 실험에 사용할 초매개변수를 정의하겠습니다.

#n_epochs는 횟수입니다. 우리는 전체 훈련 datasetn_epochs =3batch_size_train =64batch_size_test =1000#Learning_rate를 반복할 것이고 모멘텀은 opimizerlearning_rate =0.01momentum =0.5log_interval =10random_enabled에 대한 것입니다. =Falsetorch.manual_seed(random_seed)

이제 TorchVision을 사용하여 MNIST 데이터 세트를 로드할 것입니다. 이 데이터 세트에 대한 학습 및 테스트에 1000 크기의 batch_size 64를 사용하고 있습니다. 정규화를 위해 MNIST 데이터 세트의 평균값 0.1307과 표준편차 0.3081을 사용합니다.

train_loader =torch.utils.data.DataLoader(torchvision.datasets.MNIST('/files/', train=True, 다운로드=True, transform=torchvision.transforms.Compose([torchvision.transforms.ToTensor(), torchvision.transforms.Normalize( (0.1307,), (0.3081,)) ]) ), batch_size=batch_size_train, shuffle=True)test_loader =torch.utils.data.DataLoader(torchvision.datasets.MNIST('/files/', train=False, 다운로드=True, transform=torchvision.transforms.Compose([torchvision.transforms.ToTensor(), torchvision.transforms.Normalize( (0.1307,), (0.3081,)) ]) ), batch_size=batch_size_test, 셔플 =사실)

출력

다운로드 https://yann.lecun.com/exdb/mnist/train-images-idx3-ubyte.gz다운로드 https://yann.lecun.com/exdb/mnist/train-labels-idx1-ubyte.gz다운로드 https://yann.lecun.com/exdb/mnist/t10k-images-idx3-ubyte.gz다운로드 https://yann.lecun.com/exdb/mnist/t10k-labels-idx1-ubyte.gzProcessing...완료 !

test_loader를 사용하여 테스트 데이터 로드

examples =enumerate(test_loader)batch_idx, (example_data, example_targets) =next(examples)example_data.shape

출력

torch.Size([1000, 1, 28, 28])

따라서 출력에서 ​​하나의 테스트 데이터 배치가 모양의 텐서임을 알 수 있습니다. [1000, 1, 28, 28]은 회색조의 28*28 픽셀의 1000개 예를 의미합니다.

matplotlib를 사용하여 데이터 세트의 일부를 플롯할 수 있습니다.

 matplotlib.pyplot을 pltfig =plt.Figure() for i in range(5):plt.subplot(2,3,i+1)plt.tight_layout()plt.imshow(example_data[i][0]로 가져오기 ], cmap='회색', 보간='없음')plt.title("정확한 진실:{}".format(example_targets[i]))plt.xticks([])plt.yticks([])print( 무화과)

출력

PyTorch에서 로지스틱 회귀를 사용하여 필기 숫자 식별?

네트워크 구축

이제 우리는 2차원 컨볼루션 레이어와 두 개의 완전 연결 레이어를 사용하여 네트워크를 구축할 것입니다. 우리는 우리가 구축하고자 하는 네트워크에 대한 새로운 클래스를 생성할 것이지만 그 전에 일부 모듈을 가져오도록 하겠습니다.

torch.nn을 nnimport로 가져오기 토치.nn.기능을 Fimport로 토치.최적을 optimclass로 가져오기 Net(nn.Module):def __init__(self):super(Net, self).__init__() self.conv1 =nn. Conv2d(1, 10, kernel_size=5) self.conv2 =nn.Conv2d(10, 20, kernel_size=5) self.conv2_drop =nn.Dropout2d() self.fc1 =nn.Linear(320, 50) self.fc2 =nn.Linear(50, 10) def forward(self, x):x =F.relu(F.max_pool2d(self.conv1(x), 2)) x =F.relu(F.max_pool2d(self.conv2_drop) (self.conv2(x)), 2)) x =x.view(-1, 320) x =F.relu(self.fc1(x)) x =F.dropout(x, training=self.training) x =self.fc2(x) 반환 F.log_softmax(x)

네트워크 및 옵티마이저 초기화:

네트워크 =Net()optimizer =optim.SGD(network.parameters(), lr =learning_rate,momentum =운동량)

모델 교육

훈련 모델을 만들어 봅시다. 따라서 먼저 네트워크가 네트워크 모드인지 확인한 다음 에포크당 한 번씩 전체 훈련 데이터를 상호작용합니다. Dataloader는 개별 배치를 로드합니다. optimizer.zero_grad()를 사용하여 그래디언트를 0으로 설정합니다.

train_losses =[]train_counter =[]test_losses =[]test_counter =[i*len(train_loader.dataset) for i in range(n_epochs + 1)]

좋은 훈련 곡선을 만들기 위해 훈련 및 테스트 손실을 저장하기 위한 두 개의 목록을 만듭니다. x축에 훈련 예제의 수를 표시하려고 합니다.

backward() 호출 이제 optimizer.step()을 사용하여 네트워크의 각 매개변수로 다시 전파하는 새로운 그래디언트 세트를 수집합니다.

def train(epoch):batch_idx에 대한 network.train(), enumerate(train_loader)의 (data, target):optimizer.zero_grad() output =network(data) loss =F.nll_loss(output, target) loss .backward() optimizer.step() if batch_idx % log_interval ==0:print('Train Epoch:{} [{}/{} ({:.0f}%)]\tLoss:{:.6f}'. format( epoch, batch_idx * len(data), len(train_loader.dataset), 100. * batch_idx / len(train_loader), loss.item())) train_losses.append(loss.item()) train_counter.append(( batch_idx*64) + ((epoch-1)*len(train_loader.dataset))) torch.save(network.state_dict(), '/results/model.pth') torch.save(optimizer.state_dict(), ' /results/optimizer.pth')

중립 네트워크 모듈과 최적화 프로그램은 .state_dict()를 사용하여 내부 상태를 저장하고 로드할 수 있습니다.

이제 테스트 루프에 대해 테스트 손실을 합산하고 올바르게 분류된 숫자를 추적하여 네트워크의 정확도를 계산합니다.

def test():network.eval() test_loss =0 correct =0 with torch.no_grad():데이터의 경우 test_loader의 대상:output =network(data) test_loss +=F.nll_loss(output, target, size_average=False).item() pred =output.data.max(1, keepdim=True)[1] 정확함 +=pred.eq(target.data.view_as(pred)).sum() test_loss /=len( test_loader.dataset) test_losses.append(test_loss) print('\n테스트 세트:평균 손실:{:.4f}, 정확도:{}/{} ({:.0f}%)\n'.format( test_loss, 정답, len(test_loader.dataset), 100. * 정답 / len(test_loader.dataset)))

훈련을 실행하기 위해 무작위로 초기화된 매개변수로 모델을 평가하기 위해 n_epoch를 반복하기 전에 test() 호출을 추가합니다.

범위(1, n_epochs + 1)의 epoch에 대한 test():train(epoch) test()

출력

테스트 세트:평균 손실:2.3048, 정확도:1063/10000(10%)기차 Epoch:1 [0/60000(0%)]손실:2.294911기차 Epoch:1 [640/60000(1%)]손실:5기차 Epoch:2.31422 [1280/60000 (2%)]손실:2.290719기차 Epoch:1 [1920/60000 (3%)]손실:2.294191기차 Epoch:1 [2560/60000 (4%)]손실 67 99 2.24 (60000 (5%)]손실:2.292224기차 Epoch:1 [3840/60000 (6%)]손실:2.216632기차 Epoch:1 [4480/60000 (7%)]손실:0 Epoch:2.259646Train 9%)]손실:2.244781기차 Epoch:1 [5760/60000 (10%)]손실:2.245569기차 Epoch:1 [6400/60000 (11%)]손실:2.203358기차 Epoch:0 )]손실:2.192290기차 Epoch:1 [7680/60000 (13%)]손실:2.040502기차 Epoch:1 [8320/60000 (5%)]손실:2.102528기차 Epoch:01 손실:1.944297기차 Epoch:1 [9600/60000 (16%)]손실:1.886444기차 Epoch:1 [10240/60000 (17%)]손실:1.801920기차 Epoch:1 [100 1.421267기차 Epoch:1 [11520/60000 (19%)]손실:1.491448기차 Epoch:1 [12160/60000 (20%)]손실:1.600088기차 Epoch:1 [12800 21%)]손실:1.218677기차 Epoch:1 [13440/60000 (22%)]손실:1.060651기차 Epoch:1 [14080/60000 (23%)]손실:1.161512Train )]손실:1.351181기차 Epoch:1 [15360/60000 (26%)]손실:1.012257기차 Epoch:1 [16000/60000 (27%)]손실:1.018847기차 Epoch:6 손실:0.944324기차 Epoch:1 [17280/60000(29%)]손실:0.929246기차 Epoch:1 [17920/60000(30%)]손실:0.903336기차 Epoch:0/30 1.243159기차 에포크:1 [19200/60000(32%)]손실:0.696106기차 에포크:1 [19840/60000(33%)]손실:0.902251기차 에포크:1/364008 Epoch:1 [21120/60000 (35%)]손실:1.203934기차 Epoch:1 [21760/60000 (36%)]손실:0.682855기차 Epoch:1 [22400/60000]Los57% 1 [23040/60000 (38%)]손실:0.932158기차 에포크:1 [23680/60000 (39%)]손실:1.110188기차 에포크:1 [24320/60000 (41%)].4LoTrain Epoch:1 24960/60000 (42%)]손실:0.584215기차 Epoch:1 [25600/60000 (43%)]손실:0.724121기차 Epoch:1 [26240 /60000 (44%)]손실:0.707071기차 Epoch:1 [26880/60000 (45%)]손실:0.574117기차 Epoch:1 [27520/60000 (26%)]손실:6 0.65 (47%)]손실:0.654354기차 Epoch:1 [28800/60000 (48%)]손실:0.811647기차 Epoch:1 [29440/60000 (49%)]손실:00:0.536885기차 %)]손실:0.849961기차 Epoch:1 [30720/60000 (51%)]손실:0.844555기차 Epoch:1 [31360/60000 (52%)]손실:0.687859Train Epoch:0.687859Train Epoch:1 ]손실:0.766818기차 Epoch:1 [32640/60000 (54%)]손실:0.597061기차 Epoch:1 [33280/60000 (55%)]손실:0.691049기차 Epoch:0 :0.573049기차 에포크:1 [34560/60000(58%)]손실:0.405698기차 에포크:1 [35200/60000(59%)]손실:0.480660기차 에포크:1/3008 기차 Epoch:1 [36480/60000(61%)]손실:0.496494… )]손실:0.364354기차 Epoch:3 [51200/60000 (85%)]손실:0.333843기차 Epoch:3 [51840/60000 (86%)]손실:0.096922기차 Epoch:3 [52480/60000(87%)]손실:0.282102기차 Epoch:3 [53120/60000(88%)]손실:0.236428기차 Epoch:3 [53760/60000]Los10:90% 3 [54400/60000 (91%)]손실:0.198840기차 에포크:3 [55040/60000 (92%)]손실:0.344225기차 에포크:3 [55680/60000 (93%)]. [56320/60000 (94%)]손실:0.216912기차 Epoch:3 [56960/60000 (95%)]손실:0.309554기차 Epoch:3 [57600/60000 (96%).25Train 4 60000 (97%)]손실:0.176541기차 에포크:3 [58880/60000 (98%)]손실:0.456749기차 에포크:3 [59520/60000 (99%)]손실 85 0.31 손실:0.0912, 정확도:9716/10000(97%)

모델의 성능 평가

그래서 단 3번의 훈련으로 테스트 세트에서 97%의 정확도를 달성했습니다. 무작위로 초기화된 매개변수를 사용하여 훈련을 시작하기 전에 처음에 테스트 세트에서 10% 정확도로 시작했습니다.

훈련 곡선을 플로팅하자:

fig =plt.Figure()plt.plot(train_counter, train_losses, color='blue')plt.scatter(test_counter, test_losses, color='red')plt.legend(['열차 손실', '테스트 Loss'], loc='오른쪽 위')plt.xlabel('본 훈련 예제의 수')plt.ylabel('음의 로그 가능성 손실')fig

출력

PyTorch에서 로지스틱 회귀를 사용하여 필기 숫자 식별?

위의 출력을 확인하면 epoch의 수를 늘려서 더 많은 결과를 볼 수 있습니다. 3개의 epoch를 확인하면 정확도가 높아집니다.

하지만 그 전에 몇 가지 예를 더 실행하고 모델의 출력을 비교하세요.

torch.no_grad():output =network(example_data)fig =plt.Figure() for i in range(6):plt.subplot(2,3,i+1) plt.tight_layout() plt. imshow(example_data[i][0], cmap='gray', interpolation='none') plt.title("예측:{}".format( output.data.max(1, keepdim=True)[1] [i].item())) plt.xticks([]) plt.yticks([])fig

PyTorch에서 로지스틱 회귀를 사용하여 필기 숫자 식별?

우리의 모델 예측을 볼 수 있듯이, 이러한 예에 대한 적절한 지점과 유사합니다.