本文是利用pytorch自定义CNN网络系列的第三篇,主要介绍如何构建一个CNN网络,关于本系列的全文见这里

笔者的运行设备与软件:CPU (AMD Ryzen 5 4600U) + pytorch (1.13,CPU版) + jupyter;

本文所用到的资源:链接:https://pan.baidu.com/s/1WgW3IK40Xf_Zci7D_BVLRg 提取码:1212

1. 如何让构建一个CNN模型

构建模型的过程就是对CNN原理的代码实现,我们已经了解到CNN内部包含有卷积层、池化层、全连接层等网络层,模型的构建就是对这些层的实现以及链接。
CNN的模型的实现依赖pytorch中的torch.nn模块,而torch.nn.Module是所有模型的基类。需要注意的是,pytorch中没有“层”的概念,网络层也是基于基类torch.nn.Module实现的。直白而言,自定义CNN模型就是自定义一个类。我们知道CNN网络层可以根据功能,分为特征提取层(块)与全连接层(块),这种划分有利于直观理解。pytorch提供了多种容器实现“划分”,即torch.nn.Sequential类、torch.nn.Modulelist类、torch.nn.ModuleDict类等。综上,可以用下图简单示意CNN模型的构建。

2. nn.Sequential类

类别 区别
Sequential类 1)顺序性,各网络层之间严格按照顺序构建,我们在构建网络时,一定要注意前后网络层之间输入和输出数据之间的形状是否匹配;2)自带forward()函数:在nn.Sequetial的forward()函数里通过 for 循环依次读取每个网络层,执行前向传播运算。这使得我们我们构建的模型更加简洁。
Modulelist类 1)迭代性,常用于大量重复网络构建,通过 for 循环实现重复构建;2)内部无forward()函数。
ModuleDict类 1)索引性,常用于可选择的网络层;2)内部无forward()函数。

Sequential类、Modulelist类、ModuleDict类的基类也都是torch.nn.Module,构建简单的CNN模型Sequential类是比较适合的,这里只具体介绍Sequential类。Sequential类有三种“包装形式”,具体如下。
第一种

import torch.nn as nn
model = nn.Sequential(nn.Conv2d(3, 32, 5),
nn.ReLU(),
nn.Conv2d(32, 64, 5),
nn.ReLU())
print(model)
print(model[1])
'''
Sequential(
(0): Conv2d(3, 32, kernel_size=(5, 5), stride=(1, 1))
(1): ReLU()
(2): Conv2d(32, 64, kernel_size=(5, 5), stride=(1, 1))
(3): ReLU()
)
ReLU()
'''

注:这样做有一个问题,每一个层是没有名称,默认的是以0、1、2、3来命名,从上面的运行结果也可以看出。
第二种

import torch.nn as nn
from collections import OrderedDict
model = nn.Sequential(OrderedDict({'conv1':nn.Conv2d(3, 32, 5),
'relu1':nn.ReLU(),
'conv2':nn.Conv2d(32, 64, 5),
'relu2':nn.ReLU()}))
print(model)
print(model[1])
'''
Sequential(
(conv1): Conv2d(3, 32, kernel_size=(5, 5), stride=(1, 1))
(relu1): ReLU()
(conv2): Conv2d(32, 64, kernel_size=(5, 5), stride=(1, 1))
(relu2): ReLU()
)
ReLU()
'''

注:从上面的结果中可以看出,这个时候每一个层都有了自己的名称,但是此时需要注意,我并不能够通过名称直接获取层,依然只能通过索引index,即model[2] 是正确的,model["conv2"] 是错误的。这其实是由它的定义实现的,看上面的Sequenrial定义可知,只支持index访问。
第三种

import torch.nn as nn
model = nn.Sequential()
model.add_module('conv1',nn.Conv2d(3, 32, 5))
model.add_module('relu1',nn.ReLU())
model.add_module('conv2',nn.Conv2d(32, 64, 5))
model.add_module('relu2',nn.ReLU()) print(model)
print(model[1])
'''
Sequential(
(conv1): Conv2d(3, 32, kernel_size=(5, 5), stride=(1, 1))
(relu1): ReLU()
(conv2): Conv2d(32, 64, kernel_size=(5, 5), stride=(1, 1))
(relu2): ReLU()
)
ReLU()
'''

注:model.add_module()函数输入的是集合,第一个是网络层名称,第二个是网络层。
补充torch.nn.Conv2d类的知识
上文中出现的nn.Conv2d类是二维卷积类,是最常用的卷积方式。和普通的类一样,它需要先实例化再使用。让我们构建一个只有一层二维卷积的神经网络,进而理解nn.Conv2d的使用。

import torch.nn as nn
class MyNet(nn.Module): def __init__(self):
super(MyNet, self).__init__()
self.conv2d = nn.Conv2d(in_channels=3,out_channels=64,kernel_size=3,stride=2,padding=1) def forward(self, x):
print(x.requires_grad)
x = self.conv2d(x)
return x net = MyNet()
print(net.conv2d.weight) #查看初始权重
print(net.conv2d.bias) #查看初始偏置

pytorch手册中的torch.nn.Conv2d类如下所示,前三个参数是必须要提供的:

需要注意的是,torch.nn.Conv2d并不需要提供初始权重和偏置,这是因为在nn模块中,pytorch对于卷积层的权重和偏置(如果需要偏置)初始化都是采用He初始化的,当然也可以手动进行初始化(这里不展开讲)。虽然pytorch自动初始化的参数,但我们可以通过torch.nn.Conv2d.weighttorch.nn.Conv2d.bias来查看卷积层的初始值。让我们来看一下各参数的意义:
in_channels---输入的四维张量[N, C, H, W]中的C,即输入图像的通道数(N为batch_size)。
out_channels---输出图像的通道数。在数值上它也是卷积核的种类数。
kernel_size---卷积核的尺寸,一般是3x3, 5x5这种奇数核,当核为nxn方阵时,记作kernel_size=n。当核为nxm矩阵时,记作kernel_size=(n, m)
stride---卷积核移动时的步长。
padding---边缘填充。
dilation---这个参数决定了是否采用空洞卷积,默认为1(不采用)。
groups---决定了是否采用分组卷积。
bias---即是否要添加偏置参数作为可学习参数的一个,默认为True。
padding_mode---padding的模式,默认采用零填充。

3. nn.Module类

本小节内容摘自:pytorch教程之nn.Module类详解——使用Module类来自定义模型_LoveMIss-Y的博客-CSDN博客

3.1. torch.nn.Module类简介

先来简单看一它的定义:

class Module(object):
def __init__(self):
def forward(self, *input): def add_module(self, name, module):
def cuda(self, device=None):
def cpu(self):
def __call__(self, *input, **kwargs):
def parameters(self, recurse=True):
def named_parameters(self, prefix='', recurse=True):
def children(self):
def named_children(self):
def modules(self):
def named_modules(self, memo=None, prefix=''):
def train(self, mode=True):
def eval(self):
def zero_grad(self):
def __repr__(self):
def __dir__(self):
'''
有一部分没有完全列出来
'''

我们在定义自已的网络的时候,需要继承nn.Module类,并重新实现构造函数__init__构造函数和forward这两个方法。但有一些注意技巧:
(1)一般把网络中具有可学习参数的层(如全连接层、卷积层等)放在构造函数__init__()中,当然也可以把不具有参数的层也放在里面;
(2)不具有可学习参数的层(如ReLU、dropout、BatchNormanation层)既可放在构造函数中,也可不放在构造函数中,如果不放在构造函数__init__里面,则在forward方法里面可以使用nn.functional来代替。
(3)forward方法是必须要重写的,它是实现模型的功能,实现各个层之间的连接关系的核心。
下面先看一个简单的例子。

import torch

class MyNet(torch.nn.Module):
def __init__(self):
super(MyNet, self).__init__() # 第一句话,调用父类的构造函数
self.conv1 = torch.nn.Conv2d(3, 32, 3, 1, 1)
self.relu1=torch.nn.ReLU()
self.max_pooling1=torch.nn.MaxPool2d(2,1) self.conv2 = torch.nn.Conv2d(3, 32, 3, 1, 1)
self.relu2=torch.nn.ReLU()
self.max_pooling2=torch.nn.MaxPool2d(2,1) self.dense1 = torch.nn.Linear(32 * 3 * 3, 128)
self.dense2 = torch.nn.Linear(128, 10) def forward(self, x):
x = self.conv1(x)
x = self.relu1(x)
x = self.max_pooling1(x)
x = self.conv2(x)
x = self.relu2(x)
x = self.max_pooling2(x)
x = self.dense1(x)
x = self.dense2(x)
return x model = MyNet()
print(model)
'''运行结果为:
MyNet(
(conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(relu1): ReLU()
(max_pooling1): MaxPool2d(kernel_size=2, stride=1, padding=0, dilation=1, ceil_mode=False)
(conv2): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(relu2): ReLU()
(max_pooling2): MaxPool2d(kernel_size=2, stride=1, padding=0, dilation=1, ceil_mode=False)
(dense1): Linear(in_features=288, out_features=128, bias=True)
(dense2): Linear(in_features=128, out_features=10, bias=True)
)
'''

注意:上面的是将所有的层都放在了构造函数__init__里面,但是只是定义了一系列的层,各个层之间到底是什么连接关系并没有,而是在forward里面实现所有层的连接关系,当然这里依然是顺序连接的。下面再来看一下一个例子:

import torch
import torch.nn.functional as F class MyNet(torch.nn.Module):
def __init__(self):
super(MyNet, self).__init__() # 第一句话,调用父类的构造函数
self.conv1 = torch.nn.Conv2d(3, 32, 3, 1, 1)
self.conv2 = torch.nn.Conv2d(3, 32, 3, 1, 1) self.dense1 = torch.nn.Linear(32 * 3 * 3, 128)
self.dense2 = torch.nn.Linear(128, 10) def forward(self, x):
x = self.conv1(x)
x = F.relu(x)
x = F.max_pool2d(x)
x = self.conv2(x)
x = F.relu(x)
x = F.max_pool2d(x)
x = self.dense1(x)
x = self.dense2(x)
return x model = MyNet()
print(model)
'''运行结果为:
MyNet(
(conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(conv2): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(dense1): Linear(in_features=288, out_features=128, bias=True)
(dense2): Linear(in_features=128, out_features=10, bias=True)
)
'''

注意:此时,将没有训练参数的层没有放在构造函数里面了,所以这些层就不会出现在model里面,但是运行关系是在forward里面通过nn.functional的方法实现的(nn.Xxx和nn.functional.xxx的区别详见PyTorch 中,nn 与 nn.functional 有什么区别? - 知乎)。
总结:所有放在构造函数__init__里面的层的都是这个模型的“固有属性”。

3.2. torch.nn.Module类的多种实现

上面是为了一个简单的演示,但是Module类是非常灵活的,可以有很多灵活的实现方式,下面将一一介绍。

通过Sequential类来包装层

所谓的包装,就是将几个层包装在一起作为一个大的层(块),前面已经介绍了Sequential类的三种实现方式,这里取一种方式演示。

import torch.nn as nn

class MyNet(nn.Module):
def __init__(self):
super(MyNet, self).__init__()
self.conv_block = nn.Sequential(
nn.Conv2d(3, 32, 3, 1, 1),
nn.ReLU(),
nn.MaxPool2d(2))
self.dense_block = nn.Sequential(
nn.Linear(32 * 3 * 3, 128),
nn.ReLU(),
nn.Linear(128, 10)
)
# 在这里实现层之间的连接关系,其实就是所谓的前向传播
def forward(self, x):
conv_out = self.conv_block(x)
res = conv_out.view(conv_out.size(0), -1)
out = self.dense_block(res)
return out model = MyNet()
print(model)
'''运行结果为:
MyNet(
(conv_block): Sequential(
(0): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU()
(2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(dense_block): Sequential(
(0): Linear(in_features=288, out_features=128, bias=True)
(1): ReLU()
(2): Linear(in_features=128, out_features=10, bias=True)
)
)
'''

几个常用Module类方法

Sequenrial类实现了整数索引,故而可以使用model[index] 这样的方式获取一个曾,但是Module类并没有实现整数索引,不能够通过整数索引来获得层,那该怎么办呢?它提供了几个主要的方法,如下:

def children(self):

def named_children(self):

def modules(self):

def named_modules(self, memo=None, prefix=''):

'''
注意:这几个方法返回的都是一个Iterator迭代器,故而通过for循环访问,当然也可以通过next
'''
  1. model.children()方法
import torch.nn as nn
from collections import OrderedDict
class MyNet(nn.Module):
def __init__(self):
super(MyNet, self).__init__()
self.conv_block=torch.nn.Sequential()
self.conv_block.add_module("conv1",torch.nn.Conv2d(3, 32, 3, 1, 1))
self.conv_block.add_module("relu1",torch.nn.ReLU())
self.conv_block.add_module("pool1",torch.nn.MaxPool2d(2)) self.dense_block = torch.nn.Sequential()
self.dense_block.add_module("dense1",torch.nn.Linear(32 * 3 * 3, 128))
self.dense_block.add_module("relu2",torch.nn.ReLU())
self.dense_block.add_module("dense2",torch.nn.Linear(128, 10)) def forward(self, x):
conv_out = self.conv_block(x)
res = conv_out.view(conv_out.size(0), -1)
out = self.dense_block(res)
return out model = MyNet() for i in model.children():
print(i)
print(type(i)) # 查看每一次迭代的元素到底是什么类型,实际上是 Sequential 类型,所以有可以使用下标index索引来获取每一个Sequenrial 里面的具体层 '''运行结果为:
Sequential(
(conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(relu1): ReLU()
(pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
<class 'torch.nn.modules.container.Sequential'>
Sequential(
(dense1): Linear(in_features=288, out_features=128, bias=True)
(relu2): ReLU()
(dense2): Linear(in_features=128, out_features=10, bias=True)
)
<class 'torch.nn.modules.container.Sequential'>
'''
  1. model.named_children()方法
for i in model.named_children():
print(i)
print(type(i)) # 查看每一次迭代的元素到底是什么类型,实际上是 返回一个tuple,tuple 的第一个元素是 '''运行结果为:
('conv_block', Sequential(
(conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(relu1): ReLU()
(pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
))
<class 'tuple'>
('dense_block', Sequential(
(dense1): Linear(in_features=288, out_features=128, bias=True)
(relu2): ReLU()
(dense2): Linear(in_features=128, out_features=10, bias=True)
))
<class 'tuple'>
'''

总结:

  • model.children()和model.named_children()方法返回的是迭代器;
  • model.children()每一次迭代返回的元素是Sequential类;
  • model.named_children()每一次迭代返回的元素是元组类型,元组的第一个元素是名称,第二个元素就是对应的层或者是Sequential。
  1. model.modules()方法
for i in model.modules():
print(i)
print("==================================================")
'''运行结果为:
MyNet(
(conv_block): Sequential(
(conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(relu1): ReLU()
(pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(dense_block): Sequential(
(dense1): Linear(in_features=288, out_features=128, bias=True)
(relu2): ReLU()
(dense2): Linear(in_features=128, out_features=10, bias=True)
)
)
==================================================
Sequential(
(conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(relu1): ReLU()
(pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
==================================================
Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
==================================================
ReLU()
==================================================
MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
==================================================
Sequential(
(dense1): Linear(in_features=288, out_features=128, bias=True)
(relu2): ReLU()
(dense2): Linear(in_features=128, out_features=10, bias=True)
)
==================================================
Linear(in_features=288, out_features=128, bias=True)
==================================================
ReLU()
==================================================
Linear(in_features=128, out_features=10, bias=True)
==================================================
'''
  1. model.named_modules()方法
for i in model.named_modules():
print(i)
print("==================================================")
'''运行结果是:
('', MyNet(
(conv_block): Sequential(
(conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(relu1): ReLU()
(pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(dense_block): Sequential(
(dense1): Linear(in_features=288, out_features=128, bias=True)
(relu2): ReLU()
(dense2): Linear(in_features=128, out_features=10, bias=True)
)
))
==================================================
('conv_block', Sequential(
(conv1): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(relu1): ReLU()
(pool1): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
))
==================================================
('conv_block.conv1', Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1)))
==================================================
('conv_block.relu1', ReLU())
==================================================
('conv_block.pool1', MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False))
==================================================
('dense_block', Sequential(
(dense1): Linear(in_features=288, out_features=128, bias=True)
(relu2): ReLU()
(dense2): Linear(in_features=128, out_features=10, bias=True)
))
==================================================
('dense_block.dense1', Linear(in_features=288, out_features=128, bias=True))
==================================================
('dense_block.relu2', ReLU())
==================================================
('dense_block.dense2', Linear(in_features=128, out_features=10, bias=True))
==================================================
'''

总结:

  • model.modules()model.named_modules()方法返回的是迭代器iterator;
  • model的modules()方法和named_modules()方法都会将整个模型的所有构成(包括包装层、单独的层、自定义层等)由浅入深依次遍历出来,只不过modules()返回的每一个元素是直接返回的层对象本身,而named_modules()返回的每一个元素是一个元组,第一个元素是名称,第二个元素才是层对象本身。
  • 如何理解children和modules之间的这种差异性。注意pytorch里面不管是模型、层、激活函数、损失函数都可以当成是Module的拓展,所以modules和named_modules会层层迭代,由浅入深,将每一个自定义块block、然后block里面的每一个层都当成是module来迭代。而children就比较直观,就表示的是所谓的“孩子”,所以没有层层迭代深入。

4. 创建一个CNN模型

import torch.nn as nn

class MyNet(nn.Module):
def __init__(self):
super(MyNet, self).__init__()
self.conv1=nn.Sequential(nn.Conv2d(3, 32, 3, 1, 1),
nn.ReLU(),
nn.MaxPool2d(2))
self.conv2=nn.Sequential(nn.Conv2d(32, 64, 3, 1, 1),
nn.ReLU(),
nn.MaxPool2d(2))
self.conv3=nn.Sequential(nn.Conv2d(64, 64, 3, 1, 1),
nn.ReLU(),
nn.MaxPool2d(2))
self.dense=nn.Sequential(nn.Linear(64*3*3, 128),
nn.ReLU(),
nn.Linear(128, 10))
def forward(self, x):
conv1_out = self.conv1(x)
conv2_out = self.conv2(conv1_out)
conv3_out = self.conv3(conv2_out)
res = conv3_out.view(conv3_out.size(0), -1)
return self.dense(res) model=MyNet()
print(model)
'''
MyNet(
(conv1): Sequential(
(0): Conv2d(3, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU()
(2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(conv2): Sequential(
(0): Conv2d(32, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU()
(2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(conv3): Sequential(
(0): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
(1): ReLU()
(2): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)
)
(dense): Sequential(
(0): Linear(in_features=576, out_features=128, bias=True)
(1): ReLU()
(2): Linear(in_features=128, out_features=10, bias=True)
)
)
'''

5. 参考内容

  1. pytorch教程之nn.Module类详解——使用Module类来自定义模型_LoveMIss-Y的博客-CSDN博客
  2. [PyTorch 学习笔记] 3.1 模型创建步骤与 nn.Module
  3. pytorch教程之nn.Sequential类详解——使用Sequential类来自定义顺序连接模型_LoveMIss-Y的博客-CSDN博客
  4. Pytorch的nn.Conv2d()详解_风雪夜归人o的博客-CSDN博客

利用pytorch自定义CNN网络(三):构建CNN模型的更多相关文章

  1. MINIST深度学习识别:python全连接神经网络和pytorch LeNet CNN网络训练实现及比较(三)

    版权声明:本文为博主原创文章,欢迎转载,并请注明出处.联系方式:460356155@qq.com 在前两篇文章MINIST深度学习识别:python全连接神经网络和pytorch LeNet CNN网 ...

  2. 数据挖掘入门系列教程(十二)之使用keras构建CNN网络识别CIFAR10

    简介 在上一篇博客:数据挖掘入门系列教程(十一点五)之CNN网络介绍中,介绍了CNN的工作原理和工作流程,在这一篇博客,将具体的使用代码来说明如何使用keras构建一个CNN网络来对CIFAR-10数 ...

  3. 【深度学习系列】用PaddlePaddle和Tensorflow实现经典CNN网络Vgg

    上周我们讲了经典CNN网络AlexNet对图像分类的效果,2014年,在AlexNet出来的两年后,牛津大学提出了Vgg网络,并在ILSVRC 2014中的classification项目的比赛中取得 ...

  4. [论文解读]CNN网络可视化——Visualizing and Understanding Convolutional Networks

    概述 虽然CNN深度卷积网络在图像识别等领域取得的效果显著,但是目前为止人们对于CNN为什么能取得如此好的效果却无法解释,也无法提出有效的网络提升策略.利用本文的反卷积可视化方法,作者发现了AlexN ...

  5. 【深度学习系列】用PaddlePaddle和Tensorflow实现经典CNN网络AlexNet

    上周我们用PaddlePaddle和Tensorflow实现了图像分类,分别用自己手写的一个简单的CNN网络simple_cnn和LeNet-5的CNN网络识别cifar-10数据集.在上周的实验表现 ...

  6. tensorflow构建CNN模型时的常用接口函数

    (1)tf.nn.max_pool()函数 解释: tf.nn.max_pool(value, ksize, strides, padding, data_format='NHWC', name=No ...

  7. 数据挖掘入门系列教程(十一点五)之CNN网络介绍

    在前面的两篇博客中,我们介绍了DNN(深度神经网络)并使用keras实现了一个简单的DNN.在这篇博客中将介绍CNN(卷积神经网络),然后在下一篇博客中将使用keras构建一个简单的CNN,对cifa ...

  8. 07_利用pytorch的nn工具箱实现LeNet网络

    07_利用pytorch的nn工具箱实现LeNet网络 目录 一.引言 二.定义网络 三.损失函数 四.优化器 五.数据加载和预处理 六.Hub模块简介 七.总结 pytorch完整教程目录:http ...

  9. Keras如何构造简单的CNN网络

    1. 导入各种模块 基本形式为: import 模块名 from 某个文件 import 某个模块 2. 导入数据(以两类分类问题为例,即numClass = 2) 训练集数据data 可以看到,da ...

  10. Tensorflow在CIFAR-10构建CNN

    使用Tensorflow在CIFAR-10二进制数据集上构建CNN 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 Tensorflow机器学习实战指南 利用Tensorflow读取 ...

随机推荐

  1. 大米cms爆破后台及支付逻辑漏洞

    又找到个网站挖洞,我来康康. 大米手机是个什么鬼手机??看一下吧 这个支付页面好熟悉,可能存在支付逻辑漏洞,咱们用burp改个包看看. 先支付一个看看 把包里那个=1改成0试试~ 证实确实存在支付逻辑 ...

  2. 2021-06-13:如果一个节点X,它左树结构和右树结构完全一样,那么我们说以X为头的树是相等树。给定一棵二叉树的头节点head,返回head整棵树上有多少棵相等子树。

    2021-06-13:如果一个节点X,它左树结构和右树结构完全一样,那么我们说以X为头的树是相等树.给定一棵二叉树的头节点head,返回head整棵树上有多少棵相等子树. 福大大 答案2021-06- ...

  3. 2021-12-01:给定一个正数数组arr,代表每个人的体重。给定一个正数limit代表船的载重,所有船都是同样的载重量。 每个人的体重都一定不大于船的载重。 要求: 1, 可以1个人单独一搜船;

    2021-12-01:给定一个正数数组arr,代表每个人的体重.给定一个正数limit代表船的载重,所有船都是同样的载重量. 每个人的体重都一定不大于船的载重. 要求: 1, 可以1个人单独一搜船: ...

  4. Python竖版大屏 | 用pyecharts开发可视化的奇妙探索!

    你好!我是@马哥python说,一枚10年程序猿‍,正在试错用pyecharts开发可视化大屏的非常规排版. 以下,我用8种ThemeType展示的同一个可视化数据大屏. 1.SHINE主题 2.LI ...

  5. v8 study

    v8环境搭建看这里 现在的v8采用的是Ignition(JIT生成) + TurboFan(优化) v8调试 安装pwngdb git clone https://github.com/pwndbg/ ...

  6. 自定义 coding.net 静态网站域名

    点击文章左下角 "阅读原文",预览本文章的示例站点. 在上一篇文章<使用 coding.net 发布你的个人博客>,我们介绍了怎么在 coding.net 部署个人的静 ...

  7. 【Python&GIS】根据像素坐标计算图片某点的地理/投影坐标

            又是掉头发的一天,今天的任务是通过图片中心点的地理坐标以及图片中某点的像素坐标(即这个点位于图片中的x,y坐标)计算该点的地理/投影坐标.经过一整天的搜索,发现网上并没有这方面的教程. ...

  8. RT_Device

    以上图片来自网页,非原创

  9. Java 网络编程 —— RMI 框架

    概述 RMI 是 Java 提供的一个完善的简单易用的远程方法调用框架,采用客户/服务器通信方式,在服务器上部署了提供各种服务的远程对象,客户端请求访问服务器上远程对象的方法,它要求客户端与服务器端都 ...

  10. 【HMS Core】Android Studio安装Toolkit登录报错{"httpCode":500,"errorCode":"00012005"...

    [问题描述] 在Android Studio安装Toolkit插件,安装后登录,报错 ​ ​ [问题分析] 此种情况一般是由于开发者账户未实名造成的 [解决方案] 1.检查开发者账户是否实名,登录联盟 ...