"""c++
分類器:網絡
@在神經網絡一節中,輸入數據都是隨機數據,這裏換爲真實的數據進行一個簡單的訓練;通常數據分爲圖像、文本、音視頻等。dom
對於圖像,Pillow,OpenCV等軟件包頗有用函數
對於音頻,請使用scipy和librosa等軟件包工具
對於文本,基於Python或Cython的原始加載,或者NLTK和SpaCy頗有用測試
@通常在c++中咱們會使用opencv進行圖像加載,至於加載的函數如loadimage或者imread都是由opencv提供的,在pytorch中也封裝了相似的優化
包,在torchvision中。這個包基本上有最多見的數據加載器;其中最多見的數據加載器包括:spa
torchvision.datasets和torch.utils.data.DataLoader;orm
@訓練圖像分類器常見步驟以下:視頻
使用如下命令加載和標準化CIFAR10訓練和測試數據集 torchvision
定義卷積神經網絡
定義損失函數
根據訓練數據訓練網絡
在測試數據上測試網絡
"""
import torch
#包含了目前流行的數據集,模型結構和經常使用的圖片轉換工具
import torchvision
"""
transforms有如下幾個主要功能:
Compose 組合多個功能步驟爲一個步驟;
CenterCrop 進行中心切割
RandomCrop 進行隨機切割
RandomHorizontalFlip 隨機水平翻轉
RandomSizedCrop 隨機剪切及重設大小
Pad 填充
Normalize 正規化
ToTensor 轉換爲pytorch支持的Tensor
ToPILImage 轉換爲PIL圖像
Lambda 使用lambd轉換器
"""
import torchvision.transforms as transforms # 主要用於圖像一些基本變換以及一些簡單格式封裝
"""
把一個取值範圍是[0,255]的PIL.Image或者shape爲(H,W,C)的numpy.ndarray,轉換成形狀爲[C,H,W],取值範圍是[0,1.0]的torch.FloadTensor;
給定均值:(R,G,B) 方差:(R,G,B),將會把Tensor正則化。即:Normalized_image=(image-mean)/std;
方差反應數據的偏離程度,標準差主要是利於咱們肉眼查看。
"""
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))])
# train爲True表示訓練集,爲False表示測試集;download表示是否從互聯網進行下載,transforms表示預處理方式,
# 主要目的是將這些如PIL形式數據轉成pytorch支持的;
trainset = torchvision.datasets.CIFAR10(root='./data',train=True,download=False,transform=transform)
#shuffle表示是否須要打亂數據。
trainloader = torch.utils.data.DataLoader(trainset,batch_size=4,shuffle=True,num_workers=0)
testset = torchvision.datasets.CIFAR10(root='./data',train=False,download=False,transform=transform)
testloader = torch.utils.data.DataLoader(testset,batch_size=4,shuffle=False,num_workers=0)
classes=('plane', 'car', 'bird', 'cat','deer', 'dog', 'frog', 'horse', 'ship', 'truck')
import matplotlib.pyplot as plt
import numpy as np
def imshow(img):
img = img/2+0.5
npimg = img.numpy()
plt.imshow(np.transpose(npimg,(1,2,0)))#進行軸對換
plt.show()
dataiter = iter(trainloader)#執行到此步驟失敗,須要將以前的num_workers改成0
images,labels = dataiter.next()#這裏注意指向的是第一個元素並不是下一個元素
imshow(torchvision.utils.make_grid(images))#網格顯示
print(' '.join('%5s'%classes[labels[j]] for j in range(4)))
#定義卷積神經網絡
import torch.nn as nn
import torch.nn.functional as F
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(3, 6, 5)
self.pool = nn.MaxPool2d(2, 2)
self.conv2 = nn.Conv2d(6, 16, 5)
self.fc1 = nn.Linear(16 * 5 * 5, 120)
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10)
def forward(self, x):
x = self.pool(F.relu(self.conv1(x)))
x = self.pool(F.relu(self.conv2(x)))
x = x.view(-1, 16 * 5 * 5)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
x = self.fc3(x)
return x
net = Net()
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
net.to(device)
#定義損失函數和優化器
import torch.optim as optim
criterion = nn.CrossEntropyLoss()
optimizer = optim.SGD(net.parameters(),lr=0.001, momentum=0.9)
#訓練網絡
for epoch in range(2):
running_loss = 0.0
for i ,data in enumerate(trainloader,0):# 0表明下標起始位置
#inputs,labels = data #使用CPU
inputs, labels = data[0].to(device), data[1].to(device)# 使用GPU
optimizer.zero_grad()
outputs = net(inputs)
loss = criterion(outputs,labels)
loss.backward()
optimizer.step()
running_loss += loss.item()
if i % 2000 == 1999:
print('[%d ,%5d] loss:%.3f'%(epoch+1,i+1,running_loss/2000))
running_loss =0.0
print('trainning finished')
#測試網絡
dataiter = iter(testloader)
images,labels = dataiter.next()
imshow(torchvision.utils.make_grid(images))
print('GroundTruth: ',' '.join('%5s'%classes[labels[j]] for j in range(4)))
outputs = net(images)
_,predicted = torch.max(outputs,1)#1表明返回最大元素在這一行的列索引
#整個數據集表現
correct = 0
total = 0
with torch.no_grad():
for data in testloader:
images,labels = data
outputs = net(images)
_,predicted = torch.max(outputs.data,1)
total += labels.size(0)
correct += (predicted==labels).sum().item()
print('正確率:%d %%'%(100*correct/total))
class_correct = list(0. for i in range(10))
class_total = list(0. for i in range(10))
with torch.no_grad():
for data in testloader:
images,labels = data
outputs = net(images)
_,predicted = torch.max(outputs,1)
c = (predicted==labels).squeeze()#壓縮
for i in range(4):
label = labels[i]
class_correct[label] += c[i].item()
class_total[label] += 1
for i in range(10):
print('%5s正確率:%2d %% '%(classes[i],100*class_correct[i]/class_total[i]))