[pytorch] 官网教程+注释

pytorch官网教程+注释

Classifier

import torch
import torchvision
import torchvision.transforms as transforms
transform = transforms.Compose(
    [transforms.ToTensor(),
     transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))])

trainset = torchvision.datasets.CIFAR10(root='./data', train=True,
                                        download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=3,
                                          shuffle=True, num_workers=2)

testset = torchvision.datasets.CIFAR10(root='./data', train=False,
                                       download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=3,
                                         shuffle=False, num_workers=2)

classes = ('plane', 'car', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')
Files already downloaded and verified
Files already downloaded and verified
import matplotlib.pyplot as plt
import numpy as np
def imshow(img):
    img = img/2 + 0.5 # 因为之前标准化的时候除以0.5就是乘以2,还减了0.5,所以回复原来的亮度值
    npimg = img.numpy()
    plt.imshow(np.transpose(npimg,(1,2,0))) # 转置根本的是改变索引顺序,即bgr转rgb
    plt.show()
dataiter = iter(trainloader)
images,labels = dataiter.next()
print(images.shape) #torch.Size([4, 3, 32, 32]) bchw
print(torchvision.utils.make_grid(images).shape) #torch.Size([3, 36, 138])
#imshow(torchvision.utils.make_grid(images)) # 以格子形式显示多张图片
#print(" ".join("%5s"% classes[labels[j]] for j in range(4)))
torch.Size([3, 3, 32, 32])
torch.Size([3, 36, 104])
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()
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):
        inputs,labels = data
        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("finished training")
[1, 2000] loss:1.468
[1, 4000] loss:1.410
[1, 6000] loss:1.378
[1, 8000] loss:1.363
[1,10000] loss:1.330
[1,12000] loss:1.299
[2, 2000] loss:1.245
[2, 4000] loss:1.217
[2, 6000] loss:1.237
[2, 8000] loss:1.197
[2,10000] loss:1.193
[2,12000] loss:1.196
finished training
dataiter = iter(testloader)
images,labels = dataiter.next()
imshow(torchvision.utils.make_grid(images))

outputs = net(images)
_,predicted = torch.max(outputs,1)
print("predicted"," ".join([classes[predicted[j]] for j in range(4)]))
predicted cat ship ship ship
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) # 等价于labels.size()[0]
        correct+= (predicted==labels).sum().item()
print("acc:{}%%".format(100*correct/total))
acc:56.96%%
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
print(device)
cpu
net.to(device)
Net(
  (conv1): Conv2d(3, 6, kernel_size=(5, 5), stride=(1, 1))
  (pool): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
  (conv2): Conv2d(6, 16, kernel_size=(5, 5), stride=(1, 1))
  (fc1): Linear(in_features=400, out_features=120, bias=True)
  (fc2): Linear(in_features=120, out_features=84, bias=True)
  (fc3): Linear(in_features=84, out_features=10, bias=True)
)

DataLoading And Processing

from __future__ import print_function,division
import os
import torch
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from torch.utils.data import Dataset,DataLoader
from torchvision import transforms,utils
import warnings
from skimage import io,transform
warnings.filterwarnings("ignore")
plt.ion()
landmarks_frame = pd.read_csv("data/faces/face_landmarks.csv") # name x y x y ...
#print(landmarks_frame.columns.tolist())
n = 65 # 第65个样本
img_name = landmarks_frame.iloc[n,0]# 第65个样本的文件名
#print(img_name)
#print(landmarks_frame.iloc[n,1:])
landmarks = landmarks_frame.iloc[n,1:].as_matrix()# 第65个样本的样本值向量
#如果不加上as_matrix的结果就是feature name + feature val,加了之后只有feature val
#print(landmarks)
landmarks = landmarks.astype('float').reshape(-1,2) # 两个一组,组成两列的矩阵
def show_landmarks(image,landmarks):
    plt.imshow(image)
    plt.scatter(landmarks[:,0],landmarks[:,1],s=10,marker='.',c='r')
    #plt.pause(0.001) # python 窗口用得着
plt.figure()
show_landmarks(io.imread(os.path.join("data/faces/",img_name)),landmarks)

# torch.utils.data.Dataset 是一个抽象类,我们的dataset需要继承这个类,才能对其进行操作
class FaceLandmarksDataset(Dataset):
    def __init__(self,csv_file,root_dir,transform=None):
        self.landmarks_frame = pd.read_csv(csv_file)
        self.root_dir = root_dir
        self.transform = transform
    def __len__(self):
        return len(self.landmarks_frame)
    def __getitem__(self,idx):
        img_name = os.path.join(
            self.root_dir,
            self.landmarks_frame.iloc[idx,0]
        )
        image = io.imread(img_name)
        landmarks = self.landmarks_frame.iloc[idx,1:].as_matrix()
        landmarks = landmarks.astype('float').reshape([-1,2])
        sample = {"image":image,"landmarks":landmarks}
        if self.transform:
            sample = self.transform(sample)
        return sample
face_dataset = FaceLandmarksDataset(csv_file='data/faces/face_landmarks.csv',root_dir='data/faces/')
fig = plt.figure()
for i in range(len(face_dataset)):
    sample = face_dataset[i]
    print(i,sample['image'].shape,sample['landmarks'].shape)
    ax = plt.subplot(1,4,i+1)
    #plt.tight_layout()
    ax.set_title("sample #{}".format(i))
    ax.axis("off")
    show_landmarks(**sample) #**为python 拆包,将dict拆解为x=a,y=b的格式
    if i==3:
        plt.show()
        break
0 (324, 215, 3) (68, 2)
1 (500, 333, 3) (68, 2)
2 (250, 258, 3) (68, 2)
3 (434, 290, 3) (68, 2)

class Rescale():
    def __init__(self,output_size):
        assert isinstance(output_size,(int,tuple)) # 必须是int或tuple类型,否则报错,要习惯用assert isinstance
        self.output_size = output_size
    def __call__(self,sample): # 这个类的对象是一个函数,所以定义call
        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: #给定一个size那就直接变成这个size
            new_h,new_w = output_size
        new_h,new_w = int(new_h),int(new_w)
        img = transform.resize(image,(new_h,new_w)) # 进行resize操作,调用的是skimage的resize,提供(h,w),跟opencv相反
        landmarks = landmarks * [new_w/w,new_h/h]# 相应的,landmark也要做转换
        return {"image":img,"landmarks":landmarks} # 返回dict
class RandomCrop():
    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] # 这里landmarks同样也需要做变换,之所以减去[left,top]是因为存储的是x,y对应的轴是w轴和h轴
        return {"image":image,"landmarks":landmarks}
class ToTensor():
    def __call__(self,sample):
        image,landmarks = sample['image'],sample['landmarks']
        image = image.transpose((2,0,1)) # transpose实质是reshape
        # skimage的shape [h,w,c]
        # torch的shape [c,h,w]
        return {"image":torch.from_numpy(image),"landmarks":torch.from_numpy(landmarks)}
scale = Rescale(256)
crop = RandomCrop(128)
composed = transforms.Compose([Rescale(256),RandomCrop(224)]) # 组合变换
fig = plt.figure()
sample = face_dataset[65]
for i,tsfrm in enumerate([scale,crop,composed]): # 三种变换
    transformed_sample = tsfrm(sample) # 应用其中之一
    ax = plt.subplot(1,3,i+1)
    plt.tight_layout()
    show_landmarks(**transformed_sample)
plt.show()

transformed_dataset = FaceLandmarksDataset(csv_file = 'data/faces/face_landmarks.csv',
                                           root_dir="data/faces/",
                                           transform=transforms.Compose(
                                               [
                                                   Rescale(256),
                                                   RandomCrop(224),
                                                   ToTensor()
                                               ])
                                          )
for i in range(len(transformed_dataset)):
    sample = transformed_dataset[i]
    print(i,sample['image'].size(),sample['landmarks'].size())
    if i==3:
        break
0 torch.Size([3, 224, 224]) torch.Size([68, 2])
1 torch.Size([3, 224, 224]) torch.Size([68, 2])
2 torch.Size([3, 224, 224]) torch.Size([68, 2])
3 torch.Size([3, 224, 224]) torch.Size([68, 2])
dataloader = DataLoader(transformed_dataset,batch_size=4,shuffle=True,num_workers=4) # 调用dataloader
def show_landmarks_batch(sample_batched):
    images_batch,landmarks_batch = sample_batched['image'],sample_batched['landmarks']
    batch_size = len(images_batch)
    im_size = images_batch.size(2) #这里的size是shape
    grid = utils.make_grid(images_batch) # 多张图变成一张图
    plt.imshow(grid.numpy().transpose(1,2,0)) # reshape到能用plt显示
    for i in range(batch_size):
        # 第i张图片的所有点的x,所有点的y,后面 + i*im_size是由于所有图像水平显示,所以需要水平有个偏移
        # 转numpy是因为torch类型的数据没办法scatter
        plt.scatter(landmarks_batch[i,:,0].numpy() + i*im_size,
                   landmarks_batch[i,:,1].numpy(),
                   s=10,marker='.',c='r')
        plt.title("batch from dataloader")
for i_batch,sample_batched in enumerate(dataloader):
    if i_batch ==3:
        plt.figure()
        show_landmarks_batch(sample_batched)
        plt.axis("off") # 关闭坐标系
        plt.ioff()
        plt.show()
        break
<built-in method size of Tensor object at 0x7f273f3bad38>

原文地址:https://www.cnblogs.com/aoru45/p/10668250.html

时间: 2024-12-07 14:02:56

[pytorch] 官网教程+注释的相关文章

Django学习笔记 官网教程纠正 代码

原文: Django学习笔记 官网教程纠正 代码 Django学习笔记 4.模板初学中,照书例django book 出现以下异常 raise ImportError("Settings cannot be imported, because environment variable %s is undefined." % ENVIRONMENT_VARIABLE) ImportError: Settings cannot be imported, because environmen

Java Web框架-----------------------struts2(官网教程版HelloWorld)

Java Web框架------------------struts2(官网教程版HelloWorld) 我们都知道Struts是Java Web 常用的三大框架之一,另外还有Spring.Hibernate.学习Struts很有必 要!那么怎么学习呢?我的建议是: 1.对于英语能力还可以的人,学技术我们要从官网文档学起,再结合中文别人所写的论文.博客,视频 等.这样可以达到事半功倍的效果. 2.对于阅读英语稍微吃力的人,我们可以下载有道词典,再来本计算机专业英语书,不懂就查,但是, 我们决不能

Unity 官网教程 -- Multiplayer Networking

教程网址:https://unity3d.com/cn/learn/tutorials/topics/multiplayer-networking/introduction-simple-multiplayer-example?playlist=29690 1. 新建一个3D工程,在菜单 "File"  - "Save Scenes" ,保存场景为 "Main".注意,保存的文件放在Assets目录下. 2.菜单"GameObject&

RabbitMQ官网教程---路由

(使用python客户端pika 0.9.8) 在前面的教程中我们构建了一个简单的日志系统.我们可以给许多接收者广播日志消息. 在这个教程中我们将添加一个特性给它-我们将订阅仅仅一种消息子集成为可能.例如,我们可以指挥仅仅错误消息到日志文件(保存到磁盘空间),它任然可以在控制台打印所有的日志消息. 绑定 在前面的例子中我们已经创建了绑定,你可以重新调用像这样的代码: channel.queue_bind(exchange=exchange_name, queue=queue_name) 绑定是e

RabbitMQ官网教程---发布/订阅

(使用python客户端pika 0.9.8) 在前面的教程中我们创建了一个工作队列.假设在一个工作队列后面是每一个被传递给正确的工作者的任务.在这部分中我们将做一些完全不同的事情--我们将给多个消费者传递一个消息.这种模式被称为"发布/订阅". 为了阐明这个模式,我们将构建一个简单的日志系统.它将由两个程序构成--第一个将发出日志消息并且第二个将接收并且打印它们. 在我们的日志系统中每个运行的接收程序副本将获得这个消息.用这种方式我们将可以运行一个接收器并且直接日志到磁盘:而且同时我

RabbitMQ官网教程---主题

(使用python客户端pika 0.9.8) 在前面的教程中我们提高了我们的日志系统.我们使用一个direct类型的exchange代替使用一个fanout类型的exchange的虚拟广播,获取一个可选的接收日志. 尽管使用direct类型的exchange提高了我们的系统,但是它任然是有限的-它不基于多个判断标准路由. 在我们的日志系统中,我们也许想不仅订阅基于严重程度的日志,而且还有基于源的生产日志.你也许从unix的syslog工具中知道了这个概念,它基于严重程度路由日志和设施. 那将给

Gatling官网教程翻译之Advanced Tutorial

高级教程 在这一部分,我们假设读者已经完成了前面Quickstart的学习部分.而且你已经有了一个基础的simulation. 我们在这一部分将通过一系列的重构,向读者介绍更多Gatling的高级用法和DSL结构. 回顾下已有的Simulation: 1 package computerdatabase 2 import io.gatling.core.Predef._ 3 import io.gatling.http.Predef._ 4 import scala.concurrent.dur

Postman 官网教程,重点内容,翻译笔记,

json格式的提交数据需要添加:Content-Type :application/x-www-form-urlencoded,否则会导致请求失败 1. 创建 + 测试: 创建和发送任何的HTTP请求,请求可以保存到历史中再次执行2. Organize: 使用Postman Collections为更有效的测试及集成工作流管理和组织APIs3. document: 依据你创建的Clollections自动生成API文档,并将其发布成规范的格式4. collarorate: 通过同步连接你的tea

scrapy1_官网教程

https://scrapy-chs.readthedocs.io/zh_CN/0.24/intro/tutorial.html 本篇文章主要介绍如何使用编程的方式运行Scrapy爬虫. 在开始本文之前,你需要对 Scrapy 有所熟悉,知道 Items.Spider.Pipline.Selector 的概念.如果你是 Scrapy 新手,想了解如何用Scrapy开始爬取一个网站,推荐你先看看官方的教程.