Pytorch中的數(shù)據(jù)轉(zhuǎn)換Transforms與DataLoader方式
DataLoader
DataLoader是一個(gè)比較重要的類,它為我們提供的常用操作有:
batch_size
(每個(gè)batch的大小)shuffle
(是否進(jìn)行shuffle操作)num_workers
(加載數(shù)據(jù)的時(shí)候使用幾個(gè)子進(jìn)程)
import torch as t import torch.nn as nn import torch.nn.functional as F import torch ''' 初始化網(wǎng)絡(luò) 初始化Loss函數(shù) & 優(yōu)化器 進(jìn)入step循環(huán): 梯度清零 向前傳播 計(jì)算本次Loss 向后傳播 更新參數(shù) ''' class LeNet(nn.Module): ? ? def __init__(self): ? ? ? ? super(LeNet, 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) ? ? ? ? return x if __name__ == "__main__": ? ? net = LeNet() ? ? # #########訓(xùn)練網(wǎng)絡(luò)######### ? ? from torch import optim ? ? # from torchvision.datasets import MNIST ? ? import ?torchvision ? ? import numpy ? ? from torchvision import transforms ? ? from torch.utils.data import DataLoader ? ? # 初始化Loss函數(shù) & 優(yōu)化器 ? ? loss_fn = nn.CrossEntropyLoss() ? ? optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9) ? ? # transforms = transforms.Compose([]) ? ? DOWNLOAD = False ? ? BATCH_SIZE = 32 ? ? transform = transforms.Compose([ ? ? ? ? transforms.ToTensor() ? ? ]) ? ? #transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) ?# 歸一化 ? ? train_dataset = torchvision.datasets.MNIST(root='./', train=True, transform=transform, download=DOWNLOAD) ? ? test_dataset = torchvision.datasets.MNIST(root='./data/mnist', ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? train=False, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? transform=torchvision.transforms.ToTensor(), ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? download=True) ? ? ? ? train_loader = DataLoader(dataset=train_dataset, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? batch_size=BATCH_SIZE, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? shuffle=True) ? ? test_loader = DataLoader(dataset=test_dataset, batch_size=BATCH_SIZE) ? ? for epoch in range(200): ? ? ? ? running_loss = 0.0 ? ? ? ? for step, data in enumerate(train_loader): ? ? ? ? ? ? ? inputs, labels = data ? ? ? ? ? ? inputs, labels = t.autograd.Variable(inputs), t.autograd.Variable(labels) ? ? ? ? ? ? # inputs = torch.from_numpy(inputs).unsqueeze(1) ? ? ? ? ? ? # labels = torch.from_numpy(numpy.array(labels)) ? ? ? ? ? ? # 梯度清零 ? ? ? ? ? ? optimizer.zero_grad() ? ? ? ? ? ? # forward ? ? ? ? ? ? outputs = net(inputs) ? ? ? ? ? ? # backward ? ? ? ? ? ? loss = loss_fn(outputs, labels) ? ? ? ? ? ? loss.backward() ? ? ? ? ? ? # update ? ? ? ? ? ? optimizer.step() ? ? ? ? ? ? running_loss += loss.item() ? ? ? ? ? ? if step % 10 == 9: ? ? ? ? ? ? ? ? print("[{0:d}, {1:5d}] loss: {2:3f}".format(epoch + 1, step + 1, running_loss / 2000)) ? ? ? ? ? ? ? ? running_loss = 0. ? ? print("Finished Training") ? ?# save the trained net ? ? torch.save(net, 'net.pkl') ? ? # load the trained net ? ? net1 = torch.load('net.pkl') ? ? # test the trained net ? ? correct = 0 ? ? total = 1 ? ? for images, labels in test_loader: ? ? ? ? preds = net(images) ? ? ? ? predicted = torch.argmax(preds, 1) ? ? ? ? total += labels.size(0) ? ? ? ? correct += (predicted == labels).sum().item() ? ? accuracy = correct / total ? ? print('accuracy of test data:{:.1%}'.format(accuracy))
數(shù)據(jù)變換(Transform)
實(shí)例化數(shù)據(jù)庫(kù)的時(shí)候,有一個(gè)可選的參數(shù)可以對(duì)數(shù)據(jù)進(jìn)行轉(zhuǎn)換,滿足大多神經(jīng)網(wǎng)絡(luò)的要求輸入固定尺寸的圖片,因此要對(duì)原圖進(jìn)行Rescale或者Crop操作,然后返回的數(shù)據(jù)需要轉(zhuǎn)換成Tensor。
數(shù)據(jù)轉(zhuǎn)換(Transfrom)發(fā)生在數(shù)據(jù)庫(kù)中的__getitem__操作中。
class Rescale(object): ? ? """Rescale the image in a sample to a given size. ? ? Args: ? ? ? ? output_size (tuple or int): Desired output size. If tuple, output is ? ? ? ? ? ? matched to output_size. If int, smaller of image edges is matched ? ? ? ? ? ? to output_size keeping aspect ratio the same. ? ? """ ? ? def __init__(self, output_size): ? ? ? ? assert isinstance(output_size, (int, tuple)) ? ? ? ? self.output_size = output_size ? ? def __call__(self, sample): ? ? ? ? image, landmarks = sample['image'], sample['landmarks'] ? ? ? ? h, w = image.shape[:2] ? ? ? ? if isinstance(self.output_size, int): ? ? ? ? ? ? if h > w: ? ? ? ? ? ? ? ? new_h, new_w = self.output_size * h / w, self.output_size ? ? ? ? ? ? else: ? ? ? ? ? ? ? ? new_h, new_w = self.output_size, self.output_size * w / h ? ? ? ? else: ? ? ? ? ? ? new_h, new_w = self.output_size ? ? ? ? new_h, new_w = int(new_h), int(new_w) ? ? ? ? img = transform.resize(image, (new_h, new_w)) ? ? ? ? # h and w are swapped for landmarks because for images, ? ? ? ? # x and y axes are axis 1 and 0 respectively ? ? ? ? landmarks = landmarks * [new_w / w, new_h / h] ? ? ? ? return {'image': img, 'landmarks': landmarks} class RandomCrop(object): ? ? """Crop randomly the image in a sample. ? ? Args: ? ? ? ? output_size (tuple or int): Desired output size. If int, square crop ? ? ? ? ? ? is made. ? ? """ ? ? def __init__(self, output_size): ? ? ? ? assert isinstance(output_size, (int, tuple)) ? ? ? ? if isinstance(output_size, int): ? ? ? ? ? ? self.output_size = (output_size, output_size) ? ? ? ? else: ? ? ? ? ? ? assert len(output_size) == 2 ? ? ? ? ? ? self.output_size = output_size ? ? def __call__(self, sample): ? ? ? ? image, landmarks = sample['image'], sample['landmarks'] ? ? ? ? h, w = image.shape[:2] ? ? ? ? new_h, new_w = self.output_size ? ? ? ? top = np.random.randint(0, h - new_h) ? ? ? ? left = np.random.randint(0, w - new_w) ? ? ? ? image = image[top: top + new_h, ? ? ? ? ? ? ? ? ? ? ? left: left + new_w] ? ? ? ? landmarks = landmarks - [left, top] ? ? ? ? return {'image': image, 'landmarks': landmarks} class ToTensor(object): ? ? """Convert ndarrays in sample to Tensors.""" ? ? def __call__(self, sample): ? ? ? ? image, landmarks = sample['image'], sample['landmarks'] ? ? ? ? # swap color axis because ? ? ? ? # numpy image: H x W x C ? ? ? ? # torch image: C X H X W ? ? ? ? image = image.transpose((2, 0, 1)) ? ? ? ? return {'image': torch.from_numpy(image), ? ? ? ? ? ? ? ? 'landmarks': torch.from_numpy(landmarks)}
torchvision 包的介紹
torchvision 是PyTorch中專門用來處理圖像的庫(kù),這個(gè)包中有四個(gè)大類。
torchvision.datasets torchvision.models torchvision.transforms torchvision.utils
torchvision.datasets
torchvision.datasets 是用來進(jìn)行數(shù)據(jù)加載的,PyTorch團(tuán)隊(duì)在這個(gè)包中幫我們提前處理好了很多很多圖片數(shù)據(jù)集。
MNIST、COCO、Captions、Detection、LSUN、ImageFolder、Imagenet-12、CIFAR、STL10、SVHN、PhotoTour
import torchvision from torch.utils.data import DataLoader DOWNLOAD = False BATCH_SIZE = 32 transform = transforms.Compose([ ? ? transforms.ToTensor() ]) #transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) ?# 歸一化 train_dataset = torchvision.datasets.MNIST(root='./', train=True, transform=transform, download=DOWNLOAD) train_loader = DataLoader(dataset=train_dataset, ? ? ? ? ? ? ? ? ? ? ? ? ?batch_size=BATCH_SIZE, ? ? ? ? ? ? ? ? ? ? ? ? ?shuffle=True)
torchvision.models
torchvision.models 中為我們提供了已經(jīng)訓(xùn)練好的模型,加載之后,可以直接使用。包含以下模型結(jié)構(gòu)。
AlexNet、VGG、ResNet、SqueezeNet、DenseNet、MobileNet
import torchvision.models as models resnet18 = models.resnet18(pretrained=True) alexnet = models.alexnet(pretrained=True)
torchvision.transforms
transforms提供了一般圖像的轉(zhuǎn)化操作類
# 圖像預(yù)處理步驟 transform = transforms.Compose([ ? ? transforms.Resize(96), # 縮放到 96 * 96 大小 ? ? transforms.ToTensor(), ? ? transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) # 歸一化 ])
Transforms支持的變化
__all__ = ["Compose", "ToTensor", "PILToTensor", "ConvertImageDtype", "ToPILImage", "Normalize", "Resize", "Scale", ? ? ? ? ? ?"CenterCrop", "Pad", "Lambda", "RandomApply", "RandomChoice", "RandomOrder", "RandomCrop", ? ? ? ? ? ?"RandomHorizontalFlip", "RandomVerticalFlip", "RandomResizedCrop", "RandomSizedCrop", "FiveCrop", "TenCrop", ? ? ? ? ? ?"LinearTransformation", "ColorJitter", "RandomRotation", "RandomAffine", "Grayscale", "RandomGrayscale", ? ? ? ? ? ?"RandomPerspective", "RandomErasing", "GaussianBlur", "InterpolationMode", "RandomInvert", "RandomPosterize", ? ? ? ? ? ?"RandomSolarize", "RandomAdjustSharpness", "RandomAutocontrast", "RandomEqualize"]
from PIL import Image # from torch.utils.tensorboard import SummaryWriter from torchvision import transforms from torch.autograd import Variable from torchvision.transforms import functional as F tensor數(shù)據(jù)類型 # 通過transforms.ToTensor去看兩個(gè)問題 img_path = "./k.jpg" img = Image.open(img_path) # writer = SummaryWriter("logs") tensor_trans = transforms.ToTensor() tensor_img = tensor_trans(img) tensor_img1 = F.to_tensor(img) print(tensor_img.type(),tensor_img1.type()) print(tensor_img.shape) ''' transforms.Normalize使用如下公式進(jìn)行歸一化: channel=(channel-mean)/std(因?yàn)閠ransforms.ToTensor()已經(jīng)把數(shù)據(jù)處理成[0,1],那么(x-0.5)/0.5就是[-1.0, 1.0]) ''' # writer.add_image("Tensor_img", tensor_img) # writer.close()
將輸入的PIL.Image重新改變大小成給定的size,size是最小邊的邊長(zhǎng)。
舉個(gè)例子,如果原圖的height>width,那么改變大小后的圖片大小是(size*height/width, size)。
### class torchvision.transforms.Scale(size, interpolation=2) ```python from torchvision import transforms from PIL import Image crop = transforms.Scale(12) img = Image.open('test.jpg') print(type(img)) print(img.size) croped_img=crop(img) print(type(croped_img)) print(croped_img.size)
對(duì)PIL.Image進(jìn)行變換
class torchvision.transforms.Compose(transforms)
將多個(gè)transform組合起來使用。
class torchvision.transforms.Normalize(mean, std)
給定均值:(R,G,B) 方差:(R,G,B),將會(huì)把Tensor正則化。即:Normalized_image=(image-mean)/std。
class torchvision.transforms.RandomSizedCrop(size, interpolation=2)
先將給定的PIL.Image隨機(jī)切,然后再resize成給定的size大小。
class torchvision.transforms.RandomCrop(size, padding=0)
切割中心點(diǎn)的位置隨機(jī)選取。size可以是tuple也可以是Integer。
class torchvision.transforms.CenterCrop(size)
將給定的PIL.Image進(jìn)行中心切割,得到給定的size,size可以是tuple,(target_height, target_width)。size也可以是一個(gè)Integer,在這種情況下,切出來的圖片的形狀是正方形。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
python 實(shí)現(xiàn)logging動(dòng)態(tài)變更輸出日志文件名
這篇文章主要介紹了python 實(shí)現(xiàn)logging動(dòng)態(tài)變更輸出日志文件名的案例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-03-03使用Pycharm(Python工具)新建項(xiàng)目及創(chuàng)建Python文件的教程
這篇文章主要介紹了使用Pycharm(Python工具)新建項(xiàng)目及創(chuàng)建Python文件的教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04快速部署 Scrapy項(xiàng)目scrapyd的詳細(xì)流程
這篇文章主要介紹了快速部署 Scrapy項(xiàng)目scrapyd的詳細(xì)流程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09使用批處理腳本自動(dòng)生成并上傳NuGet包(操作方法)
這篇文章主要介紹了使用批處理腳本自動(dòng)生成并上傳NuGet包的操作方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11解決Django后臺(tái)ManyToManyField顯示成Object的問題
今天小編就為大家分享一篇解決Django后臺(tái)ManyToManyField顯示成Object的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-08-08