IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 基于深度强化学习的绘画智能体 代码分析 -> 正文阅读

[人工智能]基于深度强化学习的绘画智能体 代码分析

基于深度强化学习的绘画智能体 代码详解

Github源码链接

actor.py

  1. 导入库
import numpy as np
import torch
import torch.nn as nn
import torch.nn.functional as F
import torch.nn.utils.weight_norm as weightNorm

from torch.autograd import Variable
import sys

  1. 定义3*3的二维卷积模板
def conv3x3(in_planes, out_planes, stride=1):  
    return (nn.Conv2d(in_planes, out_planes, kernel_size=3, stride=stride, padding=1, bias=False))
  • nn.Conv2d()详解
    1.kernel_size:卷积核的大小,一般我们会使用5x5、3x3这种左右两个数相同的卷积核,因此这种情况只需要写kernel_size = 5这样的就行了。如果左右两个数不同,比如3x5的卷积核,那么写作kernel_size = (3, 5),注意需要写一个tuple,而不能写一个列表(list)。
    2.stride:步幅,卷积核两次卷积左上角点之间的距离;通俗讲就是卷积核每隔几个像素进行一次卷积操作
    3.padding:=0时,不填充,原图与卷积核进行卷积;=1时,在原图四边填充一行(一列),具体填充的数据由padding_mode控制,一般填0)
    4.bias:偏差,会在网络训练后向传播过程中,给输出加上一个学得的偏差
  1. 定义基础模块BasicBlock
class BasicBlock(nn.Module):
    expansion = 1
//定义两个3?33?3的卷积,然后进行BatchNorm2d(使得一批Batch满足均值为0,方差为1的分布)
    def __init__(self, in_planes, planes, stride=1):
        super(BasicBlock, self).__init__()
        self.conv1 = conv3x3(in_planes, planes, stride)
        self.bn1 = nn.BatchNorm2d(planes)
        self.conv2 = conv3x3(planes, planes)
        self.bn2 = nn.BatchNorm2d(planes)
        

//shortcut是为了防止梯度发散而跨越一个或多个层,允许梯度直接反向传播到更浅的层。
        self.shortcut = nn.Sequential() //输入和输出维度匹配的情况
        

//输入和输出维度不匹配的情况(需要借助conv+bn将输入尺寸降低)
        if stride != 1 or in_planes != self.expansion * planes:
            self.shortcut = nn.Sequential(
                (nn.Conv2d(in_planes, self.expansion*planes, kernel_size=1, stride=stride, bias=False)),
                nn.BatchNorm2d(self.expansion*planes)
            )

    def forward(self, x):
        out = F.relu(self.bn1(self.conv1(x)))//F是torch.nn.functional的别名,F.relu()将ReLU层添加到网络。  
        out = self.bn2(self.conv2(out))
        out += self.shortcut(x)
        out = F.relu(out)

        return out
        
def cfg(depth):
    depth_lst = [18, 34, 50, 101, 152]
    assert (depth in depth_lst), "Error : Resnet depth should be either 18, 34, 50, 101, 152"
    cf_dict = {
        '18': (BasicBlock, [2,2,2,2]),
        '34': (BasicBlock, [3,4,6,3]),
        '50': (Bottleneck, [3,4,6,3]),
        '101':(Bottleneck, [3,4,23,3]),
        '152':(Bottleneck, [3,8,36,3]),
    }

    return cf_dict[str(depth)]
  1. 定义Bottleneck模块。
class Bottleneck(nn.Module):
    expansion = 4
//这三层分别使用1?11?1 ,3?33?3,1?11?1的卷积模板,使用Bottleneck结构可以减少网络参数数量。
    def __init__(self, in_planes, planes, stride=1):
        super(Bottleneck, self).__init__()
        self.conv1 = (nn.Conv2d(in_planes, planes, kernel_size=1, bias=False))
        self.conv2 = (nn.Conv2d(planes, planes, kernel_size=3, stride=stride, padding=1, bias=False))
        self.conv3 = (nn.Conv2d(planes, self.expansion*planes, kernel_size=1, bias=False))
        self.bn1 = nn.BatchNorm2d(planes)
        self.bn2 = nn.BatchNorm2d(planes)
        self.bn3 = nn.BatchNorm2d(self.expansion*planes)

        self.shortcut = nn.Sequential()
        if stride != 1 or in_planes != self.expansion*planes:
            self.shortcut = nn.Sequential(
                (nn.Conv2d(in_planes, self.expansion*planes, kernel_size=1, stride=stride, bias=False)),
            )

    def forward(self, x):
        out = F.relu(self.bn1(self.conv1(x)))
        out = F.relu(self.bn2(self.conv2(out)))
        out = self.bn3(self.conv3(out))
        out += self.shortcut(x)
        out = F.relu(out)

        return out


  1. 定义整个残差网络
class ResNet(nn.Module):
    def __init__(self, num_inputs, depth, num_outputs):
        super(ResNet, self).__init__()
        self.in_planes = 64

        block, num_blocks = cfg(depth)

        self.conv1 = conv3x3(num_inputs, 64, 2)
        self.bn1 = nn.BatchNorm2d(64)
        self.layer1 = self._make_layer(block, 64, num_blocks[0], stride=2)
        self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)
        self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)
        self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)
        self.fc = nn.Linear(512, num_outputs)


//_make_layer方法作用是生成多个卷积层,形成一个大的模块。
    def _make_layer(self, block, planes, num_blocks, stride):
        strides = [stride] + [1]*(num_blocks-1)
        layers = []

        for stride in strides:
            layers.append(block(self.in_planes, planes, stride))
            self.in_planes = planes * block.expansion

        return nn.Sequential(*layers)

   
 def forward(self, x): 
        x = F.relu(self.bn1(self.conv1(x))) 
        x = self.layer1(x)
        x = self.layer2(x)
        x = self.layer3(x)
        x = self.layer4(x)
        x = F.avg_pool2d(x, 4) //平均池化
        x = x.view(x.size(0), -1) //将特征图转换为一个1维的向量,-1是说这个参数由另一个参数确定, 比如矩阵在元素总数一定的情况下,确定列数就能确定行数,要保证能够相乘,在矩阵乘法之前就要把x调到正确的size 
        x = self.fc(x)
        x = torch.sigmoid(x) //将值映射到0-1之间
        return x

关于残差网络(Resnet)的理解

网络深度是影响深度卷积神经网络性能的一大因素,但是研究者发现当网络不断加深时,训练的结果并不好。这不是因为过拟合,因为过拟合的话应该是训练集上结果好,测试集不好,但深度网络出现的现象是训练集上的效果就不好。而且这种现象还会随着深度加深而变差。这并不符合逻辑,因为深层网络在训练时,可以是在浅层网络的函数上加上一个恒等变换。而深层网络显然没有把这种恒等变换学习到。因此,提出了Resnet。
在单纯的前向传播基础上深度残差网络增加了跃层连接(Skip Connection)。实践表明,深度残差网路可以有效地改善“深度”网络的性能。

参考知乎上的解释
A,B,C,D 为四个不同的网络块,箭头代表"数据流"
这里我们以上图为例简单解释为什么看似简单的操作能够解决深度网络中梯度消失的问题:

假设网络输入为 x x x ,从 A A A D D D经历两次前向传播以及一次Skip Connection,

根据后向传播的链式法则,
在这里插入图片描述

在这里插入图片描述

所以:

在这里插入图片描述

此时,即使在A-B-C的后向传播中出现梯度衰减的情况,D处的梯度依然能够直接传递到A,也即是实现了梯度的跨层传播。

以及为了深入了解,再引用下简书上一个的回答
在这里插入图片描述

F是求和前网络映射,H是从输入到求和后的网络映射。
比如把5映射到5.1,那么引入残差前是F’(5)=5.1,引入残差后是H(5)=5.1, H(5)=F(5)+5, F(5)=0.1。这里的F’和F都表示网络参数映射,引入残差后的映射对输出的变化更敏感。比如s输出从5.1变到5.2,映射F’的输出增加了1/51=2%,而对于残差结构输出从5.1到5.2,映射F是从0.1到0.2,增加了100%。明显后者输出变化对权重的调整作用更大,所以效果更好。残差的思想都是去掉相同的主体部分,从而突出微小的变化,看到残差网络我第一反应就是差分放大器。

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-07-22 14:10:48  更:2021-07-22 14:11:39 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/4 15:33:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码