coggle30天机器学习打卡之Pytorch篇

任务1 PyTorch张量计算与Numpy的转换

代码:

c = np.ones((3,3))
d = torch.from_numpy(c)
d.size()
d

结果:
在这里插入图片描述

任务2 PyTorch梯度计算和梯度下降过程

源码:

X = np.linspace(start=0, stop=100, num=10000)
y = 3*X + 4 + np.random.uniform(0, 1, size=(10000,))
X = torch.from_numpy(X)
X = X.to(torch.float32)
y = torch.from_numpy(y)
y = y.to(torch.float32)

w = Variable(torch.randn(1), requires_grad=True)
b = Variable(torch.randn(1), requires_grad=True)

prediction = w*X + b
plt.scatter(X.data.numpy(), y.data.numpy())
plt.plot(X.data.numpy(), prediction.data.numpy(), 'r-', lw=2)
plt.show()

for epoch in range(500):
    for i, (trn_x, trn_y) in enumerate(zip(X, y)):
        
        z = w * trn_x + b
        loss = torch.nn.functional.mse_loss(z, trn_y)
        loss.backward()
        w.data -= 1e-5*w.grad.data
        b.data -= 1e-5*b.grad.data
        l1 = w.grad.data.zero_()
        l2 = b.grad.data.zero_()
    if (epoch+1)%50 == 0:
        print(loss)

prediction = w*X + b
plt.scatter(X.data.numpy(), y.data.numpy())
plt.plot(X.data.numpy(), prediction.data.numpy(), 'r-', lw=2)
plt.show()

结果,从上往下分别是:拟合前,训练过程和拟合后:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

任务3 PyTorch全连接层原理和使用

class MyLinear(nn.Module):
    def __init__(self, input_features, output):
        super(Model, self).__init__()
        self.w = Parameter(torch.randn(output, input_features, requires_grad=True))
        self.b = Parameter(torch.randn(output, input_features, requires_grad=True))
        # 给模型添加parameter
        self.register_parameter('weight', self.w)
        self.register_parameter('bias', self.b)
    
    def forward(self, x):
        return self.w*x + self.b

ps.注意self.register_parameter,这个函数是给model.parameters()添加元素(model.parameters()是从一个字典逐步返回参数值),如果不添加,那么使用不了Pytorch自带的优化器。

Pytorchnn.Linear的使用(这里简单搭建一个只含全连接层的网络):

class Net(nn.Module):
    def __init__(self, input_features, output):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(input_features, 4)
        self.fc2 = nn.Linear(4, output)
    def forward(self, x):
        out = self.fc1(x)
        out = self.fc2(out)
        return out
model = Net(5, 3)
print(model)

在这里插入图片描述

任务4 PyTorchPyTorch激活函数原理和使用

实现源码:

def elu(x, alpha=1.0, inplace=False):
    # ELU(x)=max(0,x) + min(0,α∗(exp(x)−1))
    zeros = torch.zeros_like(x)
    left = torch.cat([x, zeros], dim=0)
    right = alpha * (torch.exp(x) - 1)
    right = torch.cat([zeros, right])

    result = torch.max(left, dim=0)[0] + torch.min(right, dim=0)[0]
    return result

def leaky_relu(x, negative_slope=0.01,inplace=False):
    # LeakyReLU(x) = max(0,x) + negative_slope∗min(0,x)
    zeros = torch.zeros_like(x)
    cat_mat = torch.cat([x, zeros], dim=0)

    result = torch.max(cat_mat, dim=0)[0] + negative_slope*torch.min(cat_mat, dim=0)[0]
    return result

def p_relu(x, num_parameters=1, init=0.25):
    # PReLU(x)=max(0,x)+a∗min(0,x)
    zeros = torch.zeros_like(x)
    cat_mat = torch.cat([x, zeros], dim=0)
    result = torch.max(cat_mat, dim=0)[0] + init*torch.min(cat_mat, dim=0)[0]
    return result

def relu(x, inplace=False):
    # ReLU(x)=max(0,x)
    zeros = torch.zeros_like(x)
    cat_mat = torch.cat([x, zeros], dim=0)
    result = torch.max(cat_mat, dim=0)[0]
    return result

def relu6(x, inplace=False):
    # ReLU6(x)=min(max(0,x),6)
    mat_zero = torch.zeros_like(x)

    x = torch.cat([x, mat_zero], dim=0)
    result = torch.max(x, dim=0)[0]
    result = torch.cat([torch.unsqueeze(result, dim=0), mat_zero+6], dim=0)
    result = torch.min(result, dim=0)[0]
    return result


def selu(x, inplace=True):
    # SELU(x) = scale∗(max(0, x) + min(0, α∗(exp(x)−1)))
    alpha = 1.6732632423543772848170429916717
    scale = 1.0507009873554804934193349852946

    zeros = torch.zeros_like(x)
    left = torch.cat([x, zeros], dim=0)

    right = alpha * (torch.exp(x) - 1)
    right = torch.cat([zeros, right])

    result = torch.max(left, dim=0)[0] + torch.min(right, dim=0)[0]
    result *= scale
    return result


def celu(x, alpha=1.0,inplace=False):
    if not alpha:
        raise Exception(f"{alpha}不能为0")

    # CELU(x)=max(0,x)+min(0,α∗(exp(x/α)−1))
    zeros = torch.zeros_like(x)
    left = torch.cat([x, zeros], dim=0)
    right = alpha * (torch.exp(x / alpha) - 1)
    right = torch.cat([zeros, right])

    result = torch.max(left, dim=0)[0] + torch.min(right, dim=0)[0]
    return result


def sigmoid(x):
    # Sigmoid(x) = 1 / (1 + exp(-x))
    return 1 / (1 + torch.exp(-1 * x))

def log_sigmoid(x):
    # LogSigmoid(x) = log(1 / (1 + exp(-x)))
    return torch.log(sigmoid(x))

def tanh(x):
    # Tanh(x) = (exp(x) - exp(-x)) / (exp(x) + exp(-x))
    # solution 1:
    # return torch.tanh(x)
    # solution 2:
    return (torch.exp(x) - torch.exp(-x)) / (torch.exp(x) + torch.exp(-x))


def tanh_shrink(x):
    return x - tanh(x)


def soft_plus(x, beta=1,threshold=20):
    #
    if not beta:
        raise
    return 1/beta*torch.log(1+torch.exp(beta*x))


def soft_shrink(x: Tensor, lambd=0.5):
    x.apply_(lambda x_: x_-lambd if x_ > lambd else x_+lambd if x_ < -lambd else 0)
    return x

任务5 PyTorch卷积层原理和使用

nn.Conv2d(            
in_channels=1,            
out_channels=32,            
kernel_size=5,            
stride=1,            
padding=2        
)

卷积层参数量计算方法:

总结一点就是:参数量=(filter size * 前一层特征图的通道数 )* 当前层filter数量+偏置数量
所以答案为: 5 × 5 × 1 × 32 + 32 = 832 5\times5\times1\times32+32=832 5×5×1×32+32=832
也可以使用相关库来查看:https://blog.csdn.net/qq_41979513/article/details/102369396

任务6 PyTorch常见的损失函数和优化器使用

任务7 PyTorch池化层和归一化层

实现两种2d pool,有两种方法:

max_pool = nn.MaxPool2d(kernel_size=3, stride=1, padding=0)
mean_pool = nn.AvgPool2d(kernel_size=3, stride=1, padding=0)
image = torch.randn(1, 3, 28, 28)
image.size()
max_pool(image).size()
mean_pool(image).size()

在这里插入图片描述
或者:

import torch.nn.functional as F
image = torch.randn(1, 3, 28, 28)
F.max_pool2d(image, kernel_size=3, stride=1, padding=0).size()
F.avg_pool2d(image, kernel_size=3, stride=1, padding=0).size()

在这里插入图片描述
ps.池化操作后输出的大小计算公式和卷积操作的一样。

任务8 使用PyTorch搭建VGG网络

学习链接:https://zhuanlan.zhihu.com/p/263527295

  • 步骤1:理解VGG网络的原理。
  • 步骤2:使用pytorch搭建VGG网络模型。
  • 步骤3:打印出VGG 11层模型 每层特征图的尺寸,以及参数量

论文地址(推荐第一个地址):

论文中各种VGG结构如下图:
Table 1: ConvNet configurations (shown in columns). The depth of the configurations increases from the left (A) to the right (E), as more layers are added (the added layers are shown in bold). The convolutional layer parameters are denoted as “conv〈receptive field size〉-〈number of channels〉”. The ReLU activation function is not shown for brevity.
在这里插入图片描述
从上图可以看出,除A-LRNC两列外,其余列的每行的卷积层都是一样的,所以我会分开两部分来复现,接下来看看一些细节,例如stridepadding
在这里插入图片描述
开始复现:

import torch.nn as nn
import torch.nn.functional as F
from typing import List
# 第一部分
class VGG(nn.Module):
    def __init__(self, arch: List[int], num_classes=1000):
        super(VGG, self).__init__()
        self.in_channels = 3
        self.conv_pool1 = self.make_layer(64, arch[0])
        self.conv_pool2 = self.make_layer(128, arch[1])
        self.conv_pool3 = self.make_layer(256, arch[2])
        self.conv_pool4 = self.make_layer(512, arch[3])
        self.conv_pool5 = self.make_layer(512, arch[4])
        self.fc1 = nn.Linear(7*7*512, 4096)
        self.fc2 = nn.Linear(4096, 4096)
        self.fc3 = nn.Linear(4096, num_classes)

    def make_layer(self, output_channels, num):
        layers = []
        for _ in range(num):
            layers.append(nn.Conv2d(self.in_channels, output_channels,
                                    kernel_size=3, stride=1, padding=1))
            layers.append(nn.ReLU())
            self.in_channels = output_channels
        layers.append(nn.MaxPool2d(kernel_size=2, stride=2))
        return nn.Sequential(*layers)


    def forward(self, x):
        out = self.conv_pool1(x)
        out = self.conv_pool2(out)
        out = self.conv_pool3(out)
        out = self.conv_pool4(out)
        out = self.conv_pool5(out)
        out = out.view(out.size(0), -1)
        out = self.fc1(out)
        out = F.relu(out)
        out = self.fc2(out)
        out = F.relu(out)
        out = self.fc3(out)
        return F.softmax(out)

def VGG_11():
    return VGG([1, 1, 2, 2, 2], num_classes=1000)

def VGG_13():
    return VGG([1, 1, 2, 2, 2], num_classes=1000)

def VGG_16():
    return VGG([2, 2, 3, 3, 3], num_classes=1000)

def VGG_19():
    return VGG([2, 2, 4, 4, 4], num_classes=1000)

打印出VGG 11层模型 每层特征图的尺寸,以及参数量:
在这里插入图片描述

任务9 使用PyTorch搭建ResNet网络

学习链接:https://zhuanlan.zhihu.com/p/263526658

  • 步骤1:理解ResNet网络的原理。
  • 步骤2:使用pytorch搭建ResNet网络模型。
  • 步骤3:打印出ResNet 18模型 每层特征图的尺寸,以及参数量

任务10 使用PyTorch完成Fashion-MNIST分类

学习链接:https://github.com/masoudrostami/Fashion-MNIST-using-PyTorch/blob/main/MNIST%20Fashion%20Project.ipynb

  • 步骤1:搭建4层卷积 + 2层全连接的分类模型。
  • 步骤2:在训练过程中记录下每个epoch的训练集精度和测试集精度

任务11:使用PyTorch完成人脸关键点检测

数据集下载
示例

  • 步骤1:搭建4层卷积 + 2层的模型完成关键点回归。
  • 步骤2:使用resnet18预训练模型完成关键点回归
# 导入相关库
import os, sys, codecs, glob
from PIL import Image, ImageDraw
import numpy as np
import pandas as pd
import cv2

import torch
torch.backends.cudnn.benchmark = False
import torchvision.models as models
import torchvision.transforms as transforms
import torchvision.datasets as datasets
import torch.nn as nn
import torch.nn.functional as F
import torch.optim as optim
from torch.autograd import Variable
from torch.utils.data.dataset import Dataset

from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = 'all'
import time
import random

接下来定义和创建Dataset类数据集

# 定义
class MyDataset(Dataset):
    def __init__(self, img, keypoint, transform=None):
        self.img = img
        self.transform = transform
        self.keypoint = keypoint

    def __getitem__(self, index):
        img = Image.fromarray(self.img[:, :, index]).convert('RGB')
        
        if self.transform is not None:
            img = self.transform(img)
        
        return img, self.keypoint[index] / 96.0   # 除以96是为了归一化

    def __len__(self):
        return self.img.shape[-1]

接着导入相关数据:
在这里插入图片描述
其中test.npy暂时用不到,要有fillna,因为标签有空值。

imgs_trans = transforms.Compose([transforms.ToTensor(),])

train_dataset = MyDataset(train_img[:, :, :-500], train_df.values[:-500], imgs_trans)
train_loader = torch.utils.data.DataLoader(
    train_dataset, batch_size=10, shuffle=True, num_workers=5
)

val_dataset = MyDataset(train_img[:, :, -500:], train_df.values[-500:], imgs_trans)
val_loader = torch.utils.data.DataLoader(
    val_dataset, batch_size=10, shuffle=False, num_workers=5
)

定义自己的模型,四层卷积核两层全连接:


class Model(nn.Module):
    def __init__(self):
        self.conv1 = nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3)  #94
        self.conv2 = nn.Conv2d(in_channels=32, out_channels=64, kernel_size=3)  #92
        self.conv3 = nn.Conv2d(in_channels=64, out_channels=128, kernel_size=3)  #90
        self.conv4 = nn.Conv2d(in_channels=128, out_channels=64, kernel_size=3)  # 88
        self.fc1 = nn.Linear(64*88*88, 128)
        self.fc2 = nn.Linear(128, 8)
        super(Model, self).__init__()
        
    def forward(self, x):        
        x = self.conv1(x)
        x = F.relu(x)
        x = self.conv2(x)
        x = F.relu(x)
        x = self.conv3(x)
        x = F.relu(x)
        x = self.conv4(x)
        x = F.relu(x)
        x = x.view(x.size(0), -1)
        x = self.fc1(x)
        x = F.relu(x)
        x = self.fc2(x)
        x = F.relu(x)
        return feat
from tqdm import tqdm
from sklearn.metrics import mean_absolute_error

def train(train_dat, model, criterion, optimizer, epoch):
    model.train()

    for i, (input, target) in enumerate(tqdm(train_dat)):
        input = Variable(input).float().cuda()
        target = Variable(target).float().cuda()

        output = model(input, target)
        loss = criterion(output, target)
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    print(f"train dataset's loss: {loss.data}")

            
def evaluate(val_dat, net):
    net.eval()
    
    val_preds = []
    with torch.no_grad():
        end = time.time()
        for i, (input, target) in enumerate(tqdm(val_dat)):
            input = input.float().cuda()
            target = target.float().cuda()
            output = net(input)
            val_preds.append(output.data)
    val_loss = mean_absolute_error(torch.cat(val_preds)*96, train_df.values[-500:])
    print(f"valid dataset's loss: {val_loss}")

model = XunFeiNet().cuda()
criterion = nn.MSELoss().cuda()
optimizer = torch.optim.Adam(model.parameters(), 0.001)
scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.85)

for epoch in range(1):
    print('Epoch: ', epoch)

    train(train_loader, model, criterion, optimizer, epoch)
    
    evaluate(val_loader, model)
    scheduler.step()

任务12 使用PyTorch搭建对抗生成网络

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值