PyTorch全连接ReLU网络
1.PyTorch的核心是两个主要特征:
• 一个n维张量,类似于numpy,但可以在GPU上运行
• 搭建和训练神经网络时的自动微分/求导机制
本文将使用全连接的ReLU网络作为运行示例。该网络将有一个单一的隐藏层,并将使用梯度下降训练,通过最小化网络输出和真正结果的欧几里得距离,来拟合随机生成的数据。
2.张量
2.1 热身: Numpy
在介绍PyTorch之前,将首先使用numpy实现网络。 Numpy提供了一个n维数组对象,以及许多用于操作这些数组的函数。Numpy是用于科学计算的通用框架; 对计算图、深度学习和梯度一无所知。然而,可以很容易地使用NumPy,手动实现网络的前向和反向传播,来拟合随机数据:

-- coding: utf-8 --

import numpy as np

N是批量大小; D_in是输入维度;

49/5000 H是隐藏的维度; D_out是输出维度。

N, D_in, H, D_out = 64, 1000, 100, 10

创建随机输入和输出数据

x = np.random.randn(N, D_in)
y = np.random.randn(N, D_out)

随机初始化权重

w1 = np.random.randn(D_in, H)
w2 = np.random.randn(H, D_out)

learning_rate = 1e-6
for t in range(500):
# 前向传递:计算预测值y
h = x.dot(w1)
h_relu = np.maximum(h, 0)
y_pred = h_relu.dot(w2)

# 计算和打印损失loss
loss = np.square(y_pred - y).sum()
print(t, loss)# 反向传播,计算w1和w2对loss的梯度
grad_y_pred = 2.0 * (y_pred - y)
grad_w2 = h_relu.T.dot(grad_y_pred)
grad_h_relu = grad_y_pred.dot(w2.T)
grad_h = grad_h_relu.copy()
grad_h[h < 0] = 0
grad_w1 = x.T.dot(grad_h)# 更新权重
w1 -= learning_rate * grad_w1
w2 -= learning_rate * grad_w2

2.2 PyTorch:张量
Numpy是一个很棒的框架,但不能利用GPU来加速其数值计算。 对于现代深度神经网络,GPU通常提供50倍或更高的加速,所以,numpy不能满足当代深度学习的需求。
在这里,先介绍最基本的PyTorch概念:
张量(Tensor):PyTorch的tensor在概念上与numpy的array相同: tensor是一个n维数组,PyTorch提供了许多函数,用于操作这些张量。任何希望使用NumPy执行的计算,也可以使用PyTorch的tensor来完成,可以认为是科学计算的通用工具。
与Numpy不同,PyTorch可以利用GPU加速其数值计算。要在GPU上运行Tensor, 在构造张量使用device参数把tensor建立在GPU上。
本文使用tensors将随机数据上训练一个两层的网络。和前面NumPy的例子类似,使用PyTorch的tensor,手动在网络中实现前向传播和反向传播:

-- coding: utf-8 --

import torch

dtype = torch.float
device = torch.device(“cpu”)

device = torch.device(“cuda:0”)#取消注释以在GPU上运行

N是批量大小; D_in是输入维度;

H是隐藏的维度; D_out是输出维度。

N, D_in, H, D_out = 64, 1000, 100, 10

#创建随机输入和输出数据
x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)

随机初始化权重

w1 = torch.randn(D_in, H, device=device, dtype=dtype)
w2 = torch.randn(H, D_out, device=device, dtype=dtype)

learning_rate = 1e-6
for t in range(500):
# 前向传递:计算预测y
h = x.mm(w1)
h_relu = h.clamp(min=0)
y_pred = h_relu.mm(w2)

# 计算和打印损失
loss = (y_pred - y).pow(2).sum().item()
print(t, loss)# Backprop计算w1和w2相对于损耗的梯度
grad_y_pred = 2.0 * (y_pred - y)
grad_w2 = h_relu.t().mm(grad_y_pred)
grad_h_relu = grad_y_pred.mm(w2.t())
grad_h = grad_h_relu.clone()
grad_h[h < 0] = 0
grad_w1 = x.t().mm(grad_h)# 使用梯度下降更新权重
w1 -= learning_rate * grad_w1
w2 -= learning_rate * grad_w2

3.自动求导
3.1 PyTorch:张量和自动求导
在上面的例子中,需要手动实现神经网络的前向和后向传递。手动实现反向传递,对于小型双层网络来说并不是什么大问 题,但对于大型复杂网络来说,很快就会变得非常繁琐。
但是,可以使用自动微分,来自动计算神经网络中的后向传递。 PyTorch中的 autograd包提供了这个功能。当使用autograd时,网络前向传播将定义一个计算图;图中的节点是tensor,边是函数, 这些函数是输出tensor到输入tensor的映射。这张计算图使得在网络中反向传播时,梯度的计算十分简单。
听起来很复杂,在实践中使用起来非常简单。 如果想计算某些的tensor的梯度,只需要在建立这个tensor时,加入这么一句:requires_grad=True。这个tensor上的任何PyTorch的操作都将构造一个计算图,从而允许稍后在图中执行反向传播。如果这个tensor x的requires_grad=True,那么反向传播之后x.grad将会是另一个张量,其为x关于某个标量值的梯度。
有时,可能希望防止PyTorch在requires_grad=True的张量执行某些操作时,构建计算图;例如,在训练神经网络时,通常不希望通过权重更新步骤进行反向传播。在这种情况下,可以使用torch.no_grad()上下文管理器来防止构造计算图。
下面使用PyTorch的Tensors和autograd来实现的两层的神经网络;不再需要手动执行网络的反向传播:

-- coding: utf-8 --

import torch

dtype = torch.float
device = torch.device(“cpu”)

device = torch.device(“cuda:0”)#取消注释以在GPU上运行

N是批量大小; D_in是输入维度;

H是隐藏的维度; D_out是输出维度。

N, D_in, H, D_out = 64, 1000, 100, 10

创建随机Tensors以保持输入和输出。

设置requires_grad = False表示不需要计算渐变

在向后传球期间对于这些Tensors。

x = torch.randn(N, D_in, device=device, dtype=dtype)
y = torch.randn(N, D_out, device=device, dtype=dtype)

为权重创建随机Tensors。

设置requires_grad = True表示想要计算渐变

在向后传球期间尊重这些张贴。

w1 = torch.randn(D_in, H, device=device, dtype=dtype, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, dtype=dtype, requires_grad=True)

learning_rate = 1e-6
for t in range(500):
# 前向传播:使用tensors上的操作计算预测值y;
# 由于w1和w2有requires_grad=True,涉及这些张量的操作将让PyTorch构建计算图,
# 从而允许自动计算梯度。由于不再手工实现反向传播,所以不需要保留中间值的引用。
y_pred = x.mm(w1).clamp(min=0).mm(w2)

# 使用Tensors上的操作计算和打印丢失。
# loss是一个形状为()的张量
# loss.item() 得到这个张量对应的python数值
loss = (y_pred - y).pow(2).sum()
print(t, loss.item())# 使用autograd计算反向传播。这个调用将计算loss对所有requires_grad=True的tensor的梯度。
# 这次调用后,w1.grad和w2.grad将分别是loss对w1和w2的梯度张量。
loss.backward()# 使用梯度下降更新权重。对于这一步,只想对w1和w2的值进行原地改变;不想为更新阶段构建计算图,
# 所以使用torch.no_grad()上下文管理器防止PyTorch为更新构建计算图
with torch.no_grad():w1 -= learning_rate * w1.gradw2 -= learning_rate * w2.grad# 反向传播后手动将梯度设置为零w1.grad.zero_()w2.grad.zero_()

3.2 PyTorch:定义新的自动求导函数
在底层,每一个原始的自动求导运算,实际上是两个在Tensor上运行的函数。其中,forward函数计算,从输入Tensors获得的输出Tensors。而backward函数接收输出Tensors,对于某个标量值的梯度,并且计算输入Tensors相对于该相同标量值的梯度。
在PyTorch中,可以很容易地通过定义torch.autograd.Function的子类,实现forward和backward函数,来定义自己的自动求导运算。之后,就可以使用这个新的自动梯度运算符了。然后,可以通过构造一个实例并像调用函数一样,传入包含输入数据的tensor调用,这样来使用新的自动求导运算。
这个例子中,自定义一个自动求导函数,来展示ReLU的非线性。并用实现的两层网络:
import torch

class MyReLU(torch.autograd.Function):
“”"
可以通过建立torch.autograd的子类来实现自定义的autograd函数,
并完成张量的正向和反向传播。
“”"
@staticmethod
def forward(ctx, x):
“”"
在正向传播中,接收到一个上下文对象和一个包含输入的张量;
必须返回一个包含输出的张量,
并且可以使用上下文对象来缓存对象,以便在反向传播中使用。
“”"
ctx.save_for_backward(x)
return x.clamp(min=0)

@staticmethod
def backward(ctx, grad_output):"""在反向传播中,接收到上下文对象和一个张量,其包含了相对于正向传播过程中产生的输出的损失的梯度。可以从上下文对象中检索缓存的数据,并且必须计算并返回与正向传播的输入相关的损失的梯度。"""x, = ctx.saved_tensorsgrad_x = grad_output.clone()grad_x[x < 0] = 0return grad_x

device = torch.device(‘cuda’ if torch.cuda.is_available() else ‘cpu’)

N是批大小; D_in 是输入维度;

H 是隐藏层维度; D_out 是输出维度

N, D_in, H, D_out = 64, 1000, 100, 10

产生输入和输出的随机张量

x = torch.randn(N, D_in, device=device)
y = torch.randn(N, D_out, device=device)

产生随机权重的张量

w1 = torch.randn(D_in, H, device=device, requires_grad=True)
w2 = torch.randn(H, D_out, device=device, requires_grad=True)

learning_rate = 1e-6
for t in range(500):
# 正向传播:使用张量上的操作来计算输出值y;
# 通过调用 MyReLU.apply 函数来使用自定义的ReLU
y_pred = MyReLU.apply(x.mm(w1)).mm(w2)

# 计算并输出loss
loss = (y_pred - y).pow(2).sum()
print(t, loss.item())# 使用autograd计算反向传播过程。
loss.backward()with torch.no_grad():# 用梯度下降更新权重w1 -= learning_rate * w1.gradw2 -= learning_rate * w2.grad# 在反向传播之后手动清零梯度w1.grad.zero_()w2.grad.zero_()

3.3 TensorFlow:静态图
PyTorch自动求导看起来非常像TensorFlow:这两个框架中,都定义计算图,使用自动微分来计算梯度。两者最大的不同就是TensorFlow的计算图是静态的,而PyTorch使用动态的计算图。
在TensorFlow中,定义计算图一次,然后重复执行这个相同的图,可能会提供不同的输入数据。而在PyTorch中,每一个前向通道定义一个新的计算图。
静态图的好处在于,可以预先对图进行优化。例如,一个框架可能要融合一些图的运算来提升效率,或者产生一个策略来将图分布到多个GPU或机器上。如果重复使用相同的图,那么在重复运行同一个图时,前期潜在的代价高昂的预先优化的消耗就会被分摊开。
静态图和动态图的一个区别是控制流。对于一些模型,希望对每个数据点执行不同的计算。例如,一个递归神经网络,可能对于每个数据点,执行不同的时间步数,这个展开(unrolling)可以作为一个循环来实现。对于一个静态图,循环结构要作为图的一部分。因此,TensorFlow提供了运算符(例如tf.scan)来把循环嵌入到图当中。对于动态图来说,情况更加简单:既然为每个例子即时创建图,可以使用普通的命令式控制流,来为每个输入执行不同的计算。
为了与上面的PyTorch自动梯度实例做对比,使用TensorFlow来拟合一个简单的2层网络:
import tensorflow as tf
import numpy as np

首先建立计算图(computational graph)

N是批大小;D是输入维度;

H是隐藏层维度;D_out是输出维度。

N, D_in, H, D_out = 64, 1000, 100, 10

为输入和目标数据创建placeholder;

当执行计算图时,他将会被真实的数据填充

x = tf.placeholder(tf.float32, shape=(None, D_in))
y = tf.placeholder(tf.float32, shape=(None, D_out))

为权重创建Variable并用随机数据初始化

TensorFlow的Variable在执行计算图时不会改变

w1 = tf.Variable(tf.random_normal((D_in, H)))
w2 = tf.Variable(tf.random_normal((H, D_out)))

前向传播:使用TensorFlow的张量运算计算预测值y。

注意这段代码实际上不执行任何数值运算;

只是建立了稍后将执行的计算图。

h = tf.matmul(x, w1)
h_relu = tf.maximum(h, tf.zeros(1))
y_pred = tf.matmul(h_relu, w2)

使用TensorFlow的张量运算损失(loss)

loss = tf.reduce_sum((y - y_pred) ** 2.0)

计算loss对于w1和w2的导数

grad_w1, grad_w2 = tf.gradients(loss, [w1, w2])

使用梯度下降更新权重。为了实际更新权重,需要在执行计算图时计算new_w1和new_w2。

注意,在TensorFlow中,更新权重值的行为是计算图的一部分;

但在PyTorch中,这发生在计算图形之外。

learning_rate = 1e-6
new_w1 = w1.assign(w1 - learning_rate * grad_w1)
new_w2 = w2.assign(w2 - learning_rate * grad_w2)

现在搭建好了计算图,所以开始一个TensorFlow的会话(session)来实际执行计算图。

with tf.Session() as sess:

# 运行一次计算图来初始化Variable w1和w2
sess.run(tf.global_variables_initializer())# 创建numpy数组来存储输入x和目标y的实际数据
x_value = np.random.randn(N, D_in)
y_value = np.random.randn(N, D_out)for _ in range(500):# 多次运行计算图。每次执行时,都用feed_dict参数,# 将x_value绑定到x,将y_value绑定到y,# 每次执行图形时都要计算损失、new_w1和new_w2;# 这些张量的值以numpy数组的形式返回。loss_value, _, _ = sess.run([loss, new_w1, new_w2], feed_dict={x: x_value, y: y_value})print(loss_value)

4.nn模块
4.1 PyTorch:nn
计算图和autograd是十分强大的工具,可以定义复杂的操作并自动求导;然而对于大规模的网络,autograd太过于底层。 在构建神经网络时,经常考虑将计算安排成层,其中一些具有可学习的参数,将在学习过程中进行优化。
TensorFlow里,有类似Keras,TensorFlow-Slim和TFLearn这种封装了底层计算图的高度抽象的接口,这使得构建网络十分方便。
在PyTorch中,包nn完成了同样的功能。nn包中定义一组大致等价于层的模块。一个模块接受输入的tesnor,计算输出的tensor,而且还保存了一些内部状态比如需要学习的tensor的参数等。nn包中也定义了一组损失函数(loss functions),用来训练神经网络。
这个例子中,用nn包实现两层的网络:

-- coding: utf-8 --

import torch

N是批大小;D是输入维度

H是隐藏层维度;D_out是输出维度

N, D_in, H, D_out = 64, 1000, 100, 10

#创建输入和输出随机张量
x = torch.randn(N, D_in)
y = torch.randn(N, D_out)

使用nn包将的模型定义为一系列的层。

nn.Sequential是包含其他模块的模块,并按顺序应用这些模块来产生其输出。

每个线性模块使用线性函数从输入计算输出,并保存其内部的权重和偏差张量。

在构造模型之后,使用.to()方法将其移动到所需的设备。

model = torch.nn.Sequential(
torch.nn.Linear(D_in, H),
torch.nn.ReLU(),
torch.nn.Linear(H, D_out),
)

nn包还包含常用的损失函数的定义;

在这种情况下,将使用平均平方误差(MSE)作为的损失函数。

设置reduction=‘sum’,表示计算的是平方误差的“和”,而不是平均值;

这是为了与前面手工计算损失的例子保持一致,

但是在实践中,通过设置reduction='elementwise_mean’来使用均方误差作为损失更为常见。

loss_fn = torch.nn.MSELoss(reduction=‘sum’)

learning_rate = 1e-4
for t in range(500):
# 前向传播:通过向模型传入x计算预测的y。
# 模块对象重载了__call__运算符,所以可以像函数那样调用。
# 这么做相当于向模块传入了一个张量,然后返回了一个输出张量。
y_pred = model(x)

 # 计算并打印损失。# 传递包含y的预测值和真实值的张量,损失函数返回包含损失的张量。
loss = loss_fn(y_pred, y)
print(t, loss.item())# 反向传播之前清零梯度
model.zero_grad()# 反向传播:计算模型的损失对所有可学习参数的导数(梯度)。
# 在内部,每个模块的参数存储在requires_grad=True的张量中,
# 因此这个调用将计算模型中所有可学习参数的梯度。
loss.backward()# 使用梯度下降更新权重。
# 每个参数都是张量,所以可以像以前那样可以得到的数值和梯度
with torch.no_grad():for param in model.parameters():param -= learning_rate * param.grad

4.2 PyTorch:optim
到目前为止,已经通过手动改变,包含可学习参数的张量,来更新模型的权重。对于随机梯度下降(SGD/stochastic gradient descent)等简单的优化算法来说,这不是一个很大的负担,但在实践中,经常使用AdaGrad、RMSProp、Adam等更复杂的优化器,来训练神经网络。
import torch

N是批大小;D是输入维度

H是隐藏层维度;D_out是输出维度

N, D_in, H, D_out = 64, 1000, 100, 10

产生随机输入和输出张量

x = torch.randn(N, D_in)
y = torch.randn(N, D_out)

使用nn包定义模型和损失函数

model = torch.nn.Sequential(
torch.nn.Linear(D_in, H),
torch.nn.ReLU(),
torch.nn.Linear(H, D_out),
)
loss_fn = torch.nn.MSELoss(reduction=‘sum’)

使用optim包定义优化器(Optimizer)。Optimizer将会为更新模型的权重。

这里使用Adam优化方法;optim包还包含了许多别的优化算法。

Adam构造函数的第一个参数告诉优化器应该更新哪些张量。

learning_rate = 1e-4
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

for t in range(500):

# 前向传播:通过像模型输入x计算预测的y
y_pred = model(x)# 计算并打印loss
loss = loss_fn(y_pred, y)
print(t, loss.item())# 在反向传播之前,使用optimizer将要更新的所有张量的梯度清零(这些张量是模型可学习的权重)
optimizer.zero_grad()# 反向传播:根据模型的参数计算loss的梯度
loss.backward()# 调用Optimizer的step函数使所有参数更新
optimizer.step()

4.3 PyTorch:自定义nn模块
有时候,需要指定比现有模块序列更复杂的模型;对于这些情况,可以通过继承nn.Module并定义forward函数,这个forward函数可以使用其他模块或者其他的自动求导运算,来接收输入tensor,产生输出tensor。
在这个例子中,用自定义Module的子类构建两层网络:
import torch

class TwoLayerNet(torch.nn.Module):
def init(self, D_in, H, D_out):
“”"
在构造函数中,实例化了两个nn.Linear模块,并将作为成员变量。
“”"
super(TwoLayerNet, self).init()
self.linear1 = torch.nn.Linear(D_in, H)
self.linear2 = torch.nn.Linear(H, D_out)

def forward(self, x):"""在前向传播的函数中,接收一个输入的张量,也必须返回一个输出张量。可以使用构造函数中定义的模块以及张量上的任意的(可微分的)操作。"""h_relu = self.linear1(x).clamp(min=0)y_pred = self.linear2(h_relu)return y_pred

N是批大小; D_in 是输入维度;

H 是隐藏层维度; D_out 是输出维度

N, D_in, H, D_out = 64, 1000, 100, 10

产生输入和输出的随机张量

x = torch.randn(N, D_in)
y = torch.randn(N, D_out)

通过实例化上面定义的类来构建的模型。

model = TwoLayerNet(D_in, H, D_out)

构造损失函数和优化器。

SGD构造函数中对model.parameters()的调用,

将包含模型的一部分,即两个nn.Linear模块的可学习参数。

loss_fn = torch.nn.MSELoss(reduction=‘sum’)
optimizer = torch.optim.SGD(model.parameters(), lr=1e-4)
for t in range(500):
# 前向传播:通过向模型传递x计算预测值y
y_pred = model(x)

#计算并输出loss
loss = loss_fn(y_pred, y)
print(t, loss.item())# 清零梯度,反向传播,更新权重
optimizer.zero_grad()
loss.backward()
optimizer.step()

4.4 PyTorch:控制流和权重共享
作为动态图和权重共享的一个例子,实现了一个非常奇怪的模型:一个全连接的ReLU网络,在每一次前向传播时,隐藏层的层数为随机1到4之间的数,这样可以多次重用相同的权重来计算。
因为这个模型可以使用普通的Python流控制来实现循环,并且可以通过在定义转发时,多次重用同一个模块,来实现最内层之间的权重共享。
利用Mudule的子类很容易实现这个模型:
import random
import torch

class DynamicNet(torch.nn.Module):
def init(self, D_in, H, D_out):
“”"
在构造函数中,构造了三个nn.Linear实例,将在前向传播时被使用。
“”"
super(DynamicNet, self).init()
self.input_linear = torch.nn.Linear(D_in, H)
self.middle_linear = torch.nn.Linear(H, H)
self.output_linear = torch.nn.Linear(H, D_out)

def forward(self, x):"""对于模型的前向传播,随机选择0、1、2、3,并重用了多次计算隐藏层的middle_linear模块。由于每个前向传播构建一个动态计算图,可以在定义模型的前向传播时使用常规Python控制流运算符,如循环或条件语句。在这里,还看到,在定义计算图形时多次重用同一个模块是完全安全的。这是Lua Torch的一大改进,因为Lua Torch中每个模块只能使用一次。"""h_relu = self.input_linear(x).clamp(min=0)for _ in range(random.randint(0, 3)):h_relu = self.middle_linear(h_relu).clamp(min=0)y_pred = self.output_linear(h_relu)return y_pred

N是批大小;D是输入维度

H是隐藏层维度;D_out是输出维度

N, D_in, H, D_out = 64, 1000, 100, 10

产生输入和输出随机张量

x = torch.randn(N, D_in)
y = torch.randn(N, D_out)

实例化上面定义的类来构造的模型

model = DynamicNet(D_in, H, D_out)

构造的损失函数(loss function)和优化器(Optimizer)。

用平凡的随机梯度下降训练这个奇怪的模型是困难的,所以使用了momentum方法。

criterion = torch.nn.MSELoss(reduction=‘sum’)
optimizer = torch.optim.SGD(model.parameters(), lr=1e-4, momentum=0.9)
for t in range(500):

# 前向传播:通过向模型传入x计算预测的y。
y_pred = model(x)# 计算并打印损失
loss = criterion(y_pred, y)
print(t, loss.item())# 清零梯度,反向传播,更新权重
optimizer.zero_grad()
loss.backward()
optimizer.step()

PyTorch全连接ReLU网络相关推荐

  1. 不要再纠结卷积的公式啦!0公式深度解析全连接前馈网络与卷积神经网络

    Hello~你们的小夕终于吐泡泡了-前几天小夕又加班赶project啦,拖了好几天,都快患上拖稿焦虑症了_(:з」∠)_ 关于卷积神经网,小夕就不从卷积讲啦.以前不止一个粉丝问我卷积神经网络中卷积的意 ...

  2. 不要再纠结卷积的公式啦!0公式深度解析全连接前馈网络与卷积神经网络!

    文章转载自订阅号「夕小瑶的卖萌屋」中的文章<不要再纠结卷积的公式啦!0公式深度解析全连接前馈网络与卷积神经网络>. Hello~你们的小夕终于吐泡泡了-前几天小夕又加班赶project啦, ...

  3. 深度之眼Pytorch打卡(十三):Pytorch全连接神经网络部件——线性层、非线性激活层与Dropout层(即全连接层、常用激活函数与失活 )

    前言   无论是做分类还是做回归,都主要包括数据.模型.损失函数和优化器四个部分.数据部分在上一篇笔记中已经基本完结,从这篇笔记开始,将学习深度学习模型.全连接网络MLP是最简单.最好理解的神经网络, ...

  4. 基于Pytorch全连接神经网络实现多分类

    (一)计算机视觉工具包的介绍 为了方便开发者应用,PyTorch专门开发了一个视觉工具包torchvision,主要包含以下三个部分: 1.models models提供了深度学习中各种经典的神经网络 ...

  5. 深度学习之利用TensorFlow实现简单的全连接层网络(MNIST数据集)

    Tensorflow是一个基于数据流编程(Dataflow Programming)的符号数学系统,被广泛应用于各类机器学习(Machine Learning)算法的编程实现,其前身是谷歌的神经网络算 ...

  6. FCN全连接卷积网络(5)--Fully Convolutional Networks for Semantic Segmentation阅读(相关工作部分)

    相关工作 相关工作 1.重新设计和微调现有的分类模型来指导语义分割的密集预测内容. 2.虽然进去已有研究团队将卷积网络应用到密集预测任务当中,但是这些方面存在着一些不足,入感知范围有限.需要传统方法进 ...

  7. FCN全连接卷积网络(3)--Fully Convolutional Networks for Semantic Segmentation阅读(摘要部分)

    1.摘要 1.1逐句理解一下: Convolutional networks are powerful visual models that yield hierarchies of features ...

  8. FCN全连接卷积网络(4)--Fully Convolutional Networks for Semantic Segmentation阅读(引言部分)

    引言 引言部分翻译 总结 1.卷积网络推动了视觉识别的发展. 2.早前的卷积网络运用当中,将每个像素标记为封闭对象或一个某个类别,这样的做法存在缺点.也就是传统的卷积网络存在缺点. 3.实验证明,端到 ...

  9. FCN全连接卷积网络(2)--读论文的过程理解

    阅读论文的步骤: 首先,理解论文的各部分组成 1.摘要 对论文的高度概括,是论文的门面,在上网找论文的时候大家一般是先看摘要部分.所以,我们写论文的时候,摘要部分也要反复推敲. 2.引言 主要是大方向 ...

最新文章

  1. ArcGIS Engine开发-TOCControl中实现图层的拖放
  2. 哥调的不是车,是寂寞
  3. python画圆简单代码-Python 用turtle实现用正方形画圆的例子
  4. BigData预处理(完整步骤)
  5. GMapbook中文版上线
  6. laravel 检测sql_在Laravel PHP应用程序中轻松进行面部检测
  7. 华农专业课计算机基础,华南农业大学期末考试大学计算机基础试卷.doc
  8. leetcode - 967. 连续差相同的数字(集合、递归、动态规划)
  9. 青云oracle,青云oracle工具下载
  10. php PHP命令行脚本接收传入参数的三种方式
  11. VS 2022 SVN 插件
  12. 苹果ipad9和华为matepad11选哪个好
  13. python实现isprime函数_Python语言的isPrime函数 - python
  14. html中css字体颜色设置,css样式字体设置宋体 css中font字体颜色怎么设置
  15. 计算机一级网址打不开怎么办,电脑唯独一个网址打不开怎么解决
  16. 几个串口通信协议的整理
  17. pyflink执行任务问题总结
  18. EXCEL密码破解/破解工作表保护密码(详细图文教程)
  19. 三年级下册分数计算机题,三年级下册数学卷子题
  20. 在学习JavaScript的过程

热门文章

  1. 关于新技术的引入原则 ——从零开始学架构
  2. jenkins+sonarqube流水线脚本模板
  3. 2022-2028年中国体育用品行业投资分析及前景预测报告(全卷)
  4. linux watch命令
  5. 人要懂得放下已经发生,却又无法改变的事情
  6. 难忘的一天——装操作系统(二)
  7. linux配置java环境变量(详细)
  8. 左神讲算法——异或的高级操作(两数交换+经典面试题)
  9. Linux 内核,30 年C 语言将升级至 C11
  10. ARM系列处理器和架构