pytorch

中文文档

简单网络的建立

数据的加载

import torch
import torch.nn as nn
import torch.optim as optim
from torch.optim import lr_scheduler
import numpy as np
import torchvision
from torchvision import datasets, models, transforms
import matplotlib.pyplot as plt
import time
import os
import copy
#数据处理
data_transforms = {
    'train': transforms.Compose([
        transforms.RandomResizedCrop(224),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
    'val': transforms.Compose([
        transforms.Resize(256),
        transforms.CenterCrop(224),
        transforms.ToTensor(),
        transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
    ]),
}

data_dir = 'data/hymenoptera_data'
#加载处理后数据
image_datasets = {x: datasets.ImageFolder(os.path.join(data_dir, x),
                                          data_transforms[x])
                  for x in ['train', 'val']}
#创建数据加载器,每次往网络输入batch数据
dataloaders = {x: torch.utils.data.DataLoader(image_datasets[x], batch_size=4,
                                             shuffle=True, num_workers=4)
              for x in ['train', 'val']}
dataset_sizes = {x: len(image_datasets[x]) for x in ['train', 'val']}
class_names = image_datasets['train'].classes

device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

数据的显示

def imshow(inp, title=None):
    """Imshow for Tensor."""
    inp = inp.numpy().transpose((1, 2, 0))
    mean = np.array([0.485, 0.456, 0.406])
    std = np.array([0.229, 0.224, 0.225])
    inp = std * inp + mean
    inp = np.clip(inp, 0, 1)
    plt.imshow(inp)
    if title is not None:
        plt.title(title)
    plt.pause(0.001)  # pause a bit so that plots are updated


# Get a batch of training data
#迭代器和迭代对象  迭代器有next()方法,可迭代对象有列表等
#可通过iter()方法将可迭代对象变成迭代器,同时注意yield()方法
inputs, classes = next(iter(dataloaders['train']))

# Make a grid from batch将batch在一张图上显示
out = torchvision.utils.make_grid(inputs)

imshow(out, title=[class_names[x] for x in classes])

建立训练模型

#使用models下载vgg16神经网络,是CNN卷积网络中的一种,比较小,也好用
fmodel = models.vgg16(pretrained = True)
#冻结预训练网络中的参数,因为我们并不想更新这一部分的参数
for param in fmodel.parameters():
    param.require_grad = False
from collections import OrderedDict

# 定义一个新的classifier,其中包含3个全连接隐藏层,层之间使用ReLU函数进行激活,最后输出使用LogSoftMax函数,因为这是一个多分类。
classifier = nn.Sequential(OrderedDict([
                            ('fc1',nn.Linear(25088,4096)),
                             ('relu1',nn.ReLU()),
                             ('fc2',nn.Linear(4096,1000)),
                             ('relu2',nn.ReLU()),
                             ('fc3',nn.Linear(1000,102)),
                             ('output',nn.LogSoftmax(dim=1))
]))
# 替换
fmodel.classifier = classifier
# 使用Negative Log Likelihood Loss作为误差函数
criterion = nn.NLLLoss()

# 使用Adam作为优化器,并且只对分类器的参数进行优化,也可以使用SDG,ADAM具有动量优化效果,设置学习速率为0.01,
optimizer = optim.Adam(fmodel.classifier.parameters(),lr=0.001
def accuracy_test(model,dataloader):
    correct = 0
    total = 0
    model.cuda() # 将模型放入GPU计算,能极大加快运算速度
    with torch.no_grad(): # 使用验证集时关闭梯度计算
        for data in dataloader:
           
            images,labels = data
            images,labels = images.to('cuda'),labels.to('cuda')

            outputs = model(images)
            _, predicted = torch.max(outputs.data,1) 
            # torch.max返回输出结果中,按dim=1行排列的每一行最大数据及他的索引,丢弃数据,保留索引
            total += labels.size(0)
            
            correct += torch.sum(predicted==labels.data)
            #将预测及标签两相同大小张量逐一比较各相同元素的个数
    print('the accuracy is {:.4f}'.format(correct/total))
def deep_learning (model,trainloader,epochs,print_every,criterion,optimizer,device):
    epochs = epochs #设置学习次数
    print_every = print_every
    steps = 0
    model.to(deive)
    
    for e in range(epochs):
        running_loss = 0
        for ii , (inputs,labels) in enumerate(trainloader):
            steps += 1
            inputs,labels = inputs.to(device),labels.to(device)
            optimizer.zero_grad() # 优化器梯度清零
            
            # 前馈及反馈
            outputs = model(inputs) #数据前馈,正向传播
            loss = criterion(outputs,labels) # 输出误差
            loss.backward() #误差反馈
            optimizer.step() #优化器更新参数
            
            running_loss += loss.item()
            
            if steps % print_every == 0:
                #test the accuracy
               
                
                print('EPOCHS : {}/{}'.format(e+1,epochs),
                      'Loss : {:.4f}'.format(running_loss/print_every))
                accuracy_test(model,validloader)
deep_learning(fmodel,trainloader,3,40,criterion,optimizer,'cuda')
accuracy_test(testloader)
from PIL import Image # 使用image模块导入图片

def process_image(image):
    ''' 对图片进行缩放,建材,标准化,并输出一个NUMPY数组
    '''
    
     
    #调整图片大小
    pic = Image.open(image)
    if pic.size[0] < pic.size[1]:
        ratio = float(256) / float(pic.size[0])
    else:
        ratio = float(256) / float(pic.size[1])
    
    new_size = (int(pic.size[0]*ratio),int(pic.size[1]*ratio)) 
    
    pic.thumbnail(new_size) # 缩放为等长等宽
    
    #从图片中心抠出224 *224 的图像
    
    pic = pic.crop([pic.size[0]/2-112,pic.size[1]/2-112,pic.size[0]/2+112,pic.size[1]/2+112])
    
    #将图片转化为numpy数组
    mean = [0.485,0.456,0.406]
    std = [0.229,0.224,0.225]
    np_image = np.array(pic)
    np_image = np_image/255
    
    for i in range(2):          # 使用和训练集同样的参数对图片进行数值标准化
        
        np_image[:,:,i] -= mean[i]
        np_image[:,:,i] /= std[i]
    
    np_image = np_image.transpose((2,0,1))  #PyTorch 要求颜色通道为第一个维度,但是在 PIL 图像和 Numpy 数组中是第三个维度,所以调整
    np_image = torch.from_numpy(np_image) # 转化为张量
    np_image = np_image.float()
    print(np_image.type)
    return np_image
def predict(image_path, model, topk=5):
    ''' 预测图片.
    '''
    img = process_image(image_path)
    img = img.unsqueeze(0)   # 将图片多增加一维
    result = model(img.cuda()).topk(topk)
    probs= []
    classes = []
    a = result[0]     # 返回TOPK函数截取的排名前列的结果列表a
    b = result[1].tolist() #返回TOPK函数截取的排名前列的概率索引列表b
    
    for i in a[0]:
        probs.append(torch.exp(i).tolist())  #将结果转化为实际概率
    for n in b[0]:
        classes.append(str(n+1))      # 将索引转化为实际编号
    
    return(probs,classes)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,904评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,581评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,527评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,463评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,546评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,572评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,582评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,330评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,776评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,087评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,257评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,923评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,571评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,192评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,436评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,145评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352