• 残差神经网络就是基于残差块的一个深度神经网络。 2. 代码 这篇博客理论涉及较少，主要是代码，在CIFAIR10数据集上，实现一个浅层的残差神经网络用于分类。 import torch import torch.nn as nn import ...
1. 残差块

输入X，经过两次次卷积，一次ReLU，得到F(X)，在将X与F(X)相加，在经过一个ReLU，即为最后的结果。残差神经网络就是基于残差块的一个深度神经网络。

2. 代码

这篇博客理论涉及较少，主要是代码，在CIFAIR10数据集上，实现一个浅层的残差神经网络用于分类。

import torch
import torch.nn as nn
import torchvision
import torchvision.transforms as transforms

device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(torch.cuda.is_available())

num_epochs = 100
batch_size = 100
learning_rate = 0.001

transform = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.RandomCrop(32),
transforms.ToTensor()
])

train_datatset = torchvision.datasets.CIFAR10(root='../../data/',
train=True,
transform=transform,
)

test_datatset = torchvision.datasets.CIFAR10(root='../../data/',
train=False,
transform=transforms.ToTensor()
)

dataset=train_datatset,
batch_size=batch_size,
shuffle=True
)

dataset=test_datatset,
batch_size=batch_size,
shuffle=True
)

for i, (images, labels) in enumerate(train_loader):
break

print(images.shape)

def conv3x3(in_channels, out_channels, stride=1):
return nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False)

class ResidualBlock(nn.Module):
def __init__(self, in_channels, out_channels, stride=1, downsample=None):
super(ResidualBlock, self).__init__()
self.conv1 = conv3x3(in_channels, out_channels, stride)
self.bn1 = nn.BatchNorm2d(out_channels)
self.relu = nn.ReLU(inplace=True)
self.conv2 = conv3x3(out_channels, out_channels)
self.bn2 = nn.BatchNorm2d(out_channels)
self.downsample = downsample

def forward(self, x):
residual = x
out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn2(out)
if self.downsample:
residual = self.downsample(x)
out += residual
out = self.relu(out)
return out

class ResNet(nn.Module):
def __init__(self, block, layers, num_classes=10):
super(ResNet, self).__init__()
self.in_channels = 16
self.conv = conv3x3(3, 16)
self.bn = nn.BatchNorm2d(16)
self.relu = nn.ReLU(inplace=True)
self.layer1 = self.make_layer(block, 16, layers[0])
self.layer2 = self.make_layer(block, 32, layers[1], 2)
self.layer3 = self.make_layer(block, 64, layers[2], 2)
self.avg_pool = nn.AvgPool2d(8)
self.fc = nn.Linear(64, num_classes)

def make_layer(self, block, out_channels, blocks, stride=1):
downsample = None
if(stride != 1) or (self.in_channels != out_channels):
downsample = nn.Sequential(
conv3x3(self.in_channels, out_channels, stride=stride),
nn.BatchNorm2d(out_channels)
)
layers = []
layers.append(block(self.in_channels, out_channels, stride, downsample))
self.in_channels = out_channels
for i in range(1, blocks):
layers.append(block(self.in_channels, out_channels))
return nn.Sequential(*layers)

def forward(self, x):
out = self.conv(x)
out = self.bn(out)
out = self.relu(out)
out = self.layer1(out)
out = self.layer2(out)
out = self.layer3(out)
out = self.avg_pool(out)
out = out.view(out.size(0), -1)
out = self.fc(out)
return out

model = ResNet(ResidualBlock, [2, 2, 2]).to(device)

criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

def update_lr(optimizer, lr):
for param_group in optimizer.param_groups:
param_group['lr'] = lr

curr_lr = learning_rate
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
images = images.to(device)
labels = labels.to(device)

outputs = model(images)
loss = criterion(outputs, labels)

loss.backward()
optimizer.step()

if (i+1)%100 == 0:
print("Epoch[{}/{}], Step[{}/{}] Loss: {:.4f}"
.format(epoch+1, num_epochs, i+1, total_step, loss.item()))

if(epoch+1) % 20 == 0:
curr_lr /= 3
update_lr(optimizer, curr_lr)

model.eval()
correct = 0
total = 0
for images, labels in test_loader:
images = images.to(device)
labels = labels.to(device)
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()

print("Accuracy of the model on the test images:{}%" .format(100* correct / total))

torch.save(model.state_dict(), 'resnet.ckpt')


展开全文
• 残差神经网络 残差神经网络产生的原因：为了更好的神经网络效果，研究人员想到了深层神经网络，即在浅层神经网络的基础上加更多的神经网络层，但是因为过拟合等的原因深层网络可能准确率还不如浅层网络，尽管误差值...
残差神经网络
残差神经网络产生的原因：为了更好的神经网络效果，研究人员想到了深层神经网络，即在浅层神经网络的基础上加更多的神经网络层，但是因为过拟合等的原因深层网络可能准确率还不如浅层网络，尽管误差值差不多，所以研究人员想到了添加恒等映射网络层，即数据在通过该层时输入和输出一样，这样结果再差也不会差过浅层网络。
然而激活函数很难拟合y=x这个函数，所以研究人员想到了将单元的输入直接与单元输出加在一起，然后再激活，即残差单元可以以跳层连接的形式实现。那么期望的输出：H(x)=F(x)+x，F(x)就是输入x经过残差模块计算的结果。
例子
import torch
import torch.nn as nn
import torch.utils.data as Data
import torchvision
import torchvision.transforms as transforms

# 判断是否启用GPU计算
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')

# 超参数
EPOCHS = 80              # 批处理的次数
BATCH_SIZE = 100         # 批处理时，每次提取的数据个数
LR = 0.001               # 学习效率

# 图像预处理
transform = transforms.Compose([
transforms.RandomHorizontalFlip(),  # 随机水平翻转，概率为0.5
transforms.RandomCrop(32),          # 给定大小的图片的随机剪辑
transforms.ToTensor()               # 转化数据类型为tensor
])

# 训练集、测试集加载
train_data = torchvision.datasets.MNIST(
root='./mnist',
train=True,
transform=transform,
)
test_data = torchvision.datasets.MNIST(root='./mnist/', train=False,  transform=transform)

# 残差模块的定义
class Residual_Block(nn.Module):
def __init__(self, i_channel, o_channel, stride=1, down_sample=None):
super(Residual_Block, self).__init__()
self.conv1 = nn.Conv2d(in_channels=i_channel,
out_channels=o_channel,
kernel_size=3,
stride=stride,
bias=False)
# BatchNorm2d(）对小批量3d数据组成的4d输入进行批标准化操作
# 主要为了防止神经网络退化
self.bn1 = nn.BatchNorm2d(o_channel)
self.relu = nn.ReLU(inplace=True)
self.conv2 = nn.Conv2d(in_channels=o_channel,
out_channels=o_channel,
kernel_size=3,
stride=1,
bias=False)
self.bn2 = nn.BatchNorm2d(o_channel)
self.down_sample = down_sample

def forward(self, x):
residual = x
out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn2(out)

# 将单元的输入直接与单元输出加在一起
if self.down_sample:
residual = self.down_sample(x) # 下采样
out += residual
out = self.relu(out)

return out

class ResNet(nn.Module):
def __init__(self, block, layers, num_classes=10):
super(ResNet, self).__init__()
self.in_channels = 16
self.conv = nn.Conv2d(in_channels=1, out_channels=16, kernel_size=3, stride=1, padding=1, bias=False)
self.bn = nn.BatchNorm2d(16)
self.relu = nn.ReLU(inplace=True)
self.layer1 = self.make_layer(block, 16, layers[0])
self.layer2 = self.make_layer(block, 32, layers[0], 2)
self.layer3 = self.make_layer(block, 64, layers[1], 2)
self.avg_pool = nn.AvgPool2d(8)
self.fc = nn.Linear(64, num_classes)

def make_layer(self, block, out_channels, blocks, stride=1):
# blocks=layers,残差模块的数量
down_sample = None
# 判断是否in_channels(输入)与(输出)是否在同一维度
# 即输入的3d数据的长宽高与输出的数据的长宽高是否一样
if (stride != 1) or (self.in_channels != out_channels):
# 如果不一样就转换一下维度
down_sample = nn.Sequential(
nn.Conv2d(self.in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False),
nn.BatchNorm2d(out_channels)
)

layers = []
layers.append(block(self.in_channels, out_channels, stride, down_sample))
self.in_channels = out_channels
for i in range(1, blocks):
layers.append(block(out_channels, out_channels))
return nn.Sequential(*layers)  # 添加所有残差块

def forward(self, x):
out = self.conv(x)
out = self.bn(out)
out = self.relu(out)
out = self.layer1(out)
out = self.layer2(out)
out = self.layer3(out)
out = self.avg_pool(out)
out = out.view(out.size(0), -1)
out = self.fc(out)

return out

model = ResNet(Residual_Block, [2, 2, 2, 2]).to(device)

# 计算误差与
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=LR)

# 用于更新学习率
def update_lr(optimizer, lr):
for param_group in optimizer.param_groups:
param_group['lr'] = lr

# 训练
curr_lr = LR
for epoch in range(EPOCHS):
for i, (images, labels) in enumerate(train_loader):
# 将数据放入GPU
images = images.to(device)
labels = labels.to(device)

outputs = model(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()

if (i + 1) % 100 == 0:
print("Epoch [{}/{}],step[{}/{}] Loss:{:.4f}"
.format(epoch + 1, EPOCHS, i + 1, total_step, loss.item()))

# 降低学习速度
if (epoch + 1) % 20 == 0:  # 每过20个Epoch，学习率就会下降
curr_lr /= 3
update_lr(optimizer, curr_lr)

# 测试
model.eval()
correct = 0
total = 0
for images, labels in test_loader:
images = images.to(device)
labels = labels.to(device)
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()

print('accuracy of the model on the test images: {}%'
.format(100 * correct / total))


效果
训练开始

最后的准确率在99.32%左右
总结
残差神经网络的出现是为了解决梯度爆炸、梯度弥散和神经网络退化的问题。
在介绍RNN中提到过梯度爆炸与梯度弥散的问题，在RNN中是通过LSTM即长短期记忆法解决的。在介绍批标准化中也提到神经网络退化的问题，是通过BatchNorm1d()函数来解决的。
而残差网络像是LSTM与批标准化的结合，LSTM与残差网络的差别在于门控机制，可以认为是在时间维上引入了门控的残差连接。


展开全文
• import torch from torch import nn import torch.nn.functional as F import torchvision class ResnetbasicBlock(nn.Module): def __int__(self,in_channels,out_channels): super().__init__() ...


import torch
from torch import nn
import torch.nn.functional as F
import torchvision

class ResnetbasicBlock(nn.Module):
def __int__(self,in_channels,out_channels):
super().__init__()
self.conv1 == nn.Conv2d(in_channels,out_channels,kernel_size=3,padding=1,bias=False )
self.bn1 =  nn.BatchNorm2d(out_channels)
self.conv2 == nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1, bias=False)
self.bn1 = nn.BatchNorm2d(out_channels)

def forward(self,x):
residual = x
out = self.conv1(x)
out = F.relu(self.bn1(out),inplace=True)
out = self.conv2(out)
out = self.bn2(out)
#最关键一步 F(x)+x
out += residual
#将out激活输出
return F.relu(out)

model = ResnetbasicBlock()




展开全文
• 这次我们来聊一下残差神经网络的实现。这是咱们国内大神何凯明当年在CVPR上荣获一等奖的作品。它通过相等输入输出维度之间的恒等映射，高维度向低维度的下采样等方法构造残差块，对于很深的网络降低了学习难度，同时...
开篇
这次我们来聊一下残差神经网络的实现。这是咱们国内大神何凯明当年在CVPR上荣获一等奖的作品。它通过相等输入输出维度之间的恒等映射，高维度向低维度的下采样等方法构造残差块，对于很深的网络降低了学习难度，同时由于是恒等映射，我们在求解梯度的时候也相对轻松很多。
这也引入了一个新的方法去解决梯度爆炸或者梯度消失的问题，除了使用Batch Normalization和RELU以外，我们也可以构建残差块生成ResNet。

这里我们不介绍ResNet的主要原理，大家可以下载ResNet论文自己阅读，或者看一些介绍原理的博客，建议学完基础原理再回来看实现方法，因为这种实现方法其实是论文的一种复现。我们开始吧。
ResNet残差神经网络
库的引入
import torch
import torch.nn as nn
import torchvision
import torchvision.transforms as transforms

设备配置及超参数的定义
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

num_epochs = 80
batch_size = 100
learning_rate = 0.001
定义图像预处理的操作
这里就有需要用到很多我们transforms库中的函数了
transform = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.RandomCrop(32),
transforms.ToTensor()])
Compose表示一个集合，这个图像预处理操作包括内部的内容：
1.图像填充
2.图像随机垂直旋转
3.图像随即剪切
4.图像转变为张量
数据集的引入与加载
这次我们不再使用mnist数据集，而是使用CIFAR10数据集。这是多伦多大学的数据集，内部图片都是32*32的3通道彩色图片，基本都是外部世界的真是物品，某种程度上来说比MNIST好得多。大家可以去http://www.cs.toronto.edu/~kriz/cifar.html找到这个数据集。
train_dataset = torchvision.datasets.CIFAR10(root='../../data/',
train=True,
transform=transform,

test_dataset = torchvision.datasets.CIFAR10(root='../../data/',
train=False,
transform=transforms.ToTensor())

batch_size=batch_size,
shuffle=True)

batch_size=batch_size,
shuffle=False)
定义一个卷积核为3*3，步长为1，填充长度也为1的卷积函数
def conv3x3(in_channels, out_channels, stride=1):
return nn.Conv2d(in_channels, out_channels, kernel_size=3,
stride=stride, padding=1, bias=False)
这个函数的定义主要是为了方便之后的调用，再使用的时候就不需要写很长一块了
残差块类的定义
class ResidualBlock(nn.Module):
def __init__(self, in_channels, out_channels, stride=1, downsample=None):
super(ResidualBlock, self).__init__()
self.conv1 = conv3x3(in_channels, out_channels, stride)
self.bn1 = nn.BatchNorm2d(out_channels)
self.relu = nn.ReLU(inplace=True)
self.conv2 = conv3x3(out_channels, out_channels)
self.bn2 = nn.BatchNorm2d(out_channels)
self.downsample = downsample

def forward(self, x):
residual = x
out = self.conv1(x)
out = self.bn1(out)
out = self.relu(out)
out = self.conv2(out)
out = self.bn2(out)
# 下采样
if self.downsample:
residual = self.downsample(x)
out += residual
out = self.relu(out)
return out

残差块是残差神经网络中很重要的一块，我们的核心都在里面。
我们可以看到残差块先是经过一个3*3的卷积神经网络，然后经过Batch Normalization函数进行标准化，然后经过RELU激活函数，再经过卷积网络和Batch Normalization。最后就是我们残差映射，如果downsample不为None，则我们应该从低维进行下采样，加到out上，如果为None,即两个维度相同，则直接加上恒等映射的x.
下面我们会说这个downsample到底什么样子。
残差网络的定义
class ResNet(nn.Module):
def __init__(self, block, layers, num_classes=10):
super(ResNet, self).__init__()
self.in_channels = 16
self.conv = conv3x3(3, 16)
self.bn = nn.BatchNorm2d(16)
self.relu = nn.ReLU(inplace=True)
# 构建残差块,恒等映射
# in_channels == out_channels and stride = 1 所以这里我们构建残差块,没有下采样
self.layer1 = self.make_layer(block, 16, layers[0], stride=1)
# 不构建残差块,进行了下采样
# layers中记录的是数字,表示对应位置的残差块数目
self.layer2 = self.make_layer(block, 32, layers[1], 2)
# 不构建残差块,进行了下采样
self.layer3 = self.make_layer(block, 64, layers[2], 2)
self.avg_pool = nn.AvgPool2d(8)
self.fc = nn.Linear(64, num_classes)

def make_layer(self, block, out_channels, blocks, stride=1):
downsample = None
if (stride != 1) or (self.in_channels != out_channels):
downsample = nn.Sequential(
conv3x3(self.in_channels, out_channels, stride=stride),
nn.BatchNorm2d(out_channels))
layers = []
layers.append(block(self.in_channels, out_channels, stride, downsample))
# 当out_channels = 32时,in_channels也变成32了
self.in_channels = out_channels
# blocks是残差块的数目
# 残差块之后的网络结构,是out_channels->out_channels的
# 可以说,make_layer做的是输出尺寸相同的所有网络结构
# 由于输出尺寸会改变,我们用make_layers去生成一大块对应尺寸完整网络结构
for i in range(1, blocks):
layers.append(block(out_channels, out_channels))
return nn.Sequential(*layers)

def forward(self, x):
out = self.conv(x)
out = self.bn(out)
out = self.relu(out)
# layer1是三块in_channels等于16的网络结构，包括三个恒等映射
out = self.layer1(out)
# layer2包括了16->32下采样,然后是32的三个恒等映射
out = self.layer2(out)
# layer3包括了32->64的下采样,然后是64的三个恒等映射
out = self.layer3(out)
out = self.avg_pool(out)
# 全连接压缩
# out.size(0)可以看作是batch_size
out = out.view(out.size(0), -1)
out = self.fc(out)
return out


这就是我们的核心部分，我们可以看到，残差网络本身要先经过Conv3*3->Batch Normalization->RELU。然后才是我们的三层残差块。
我们主要来看我们的make_layers函数:
函数内部给出了何时进行下采样。如果步长不为1或者输入维度不等于输出维度的时候进行下采样，否则进行恒等映射。什么意思呢？
在layer1处，当我们的输入维度是16时，输出维度也是16，此时我们需要进行恒等映射，然后将out_channels设置为16.然后在layer2处，由于输入维度变成了32，我们就需要从32向16维度进行下采样，即会从16维度的残差块引出一条线进入32维度。然后out_channels = 32了,32维度残差块内部进行恒等映射。到了layer3我们又要从32维度的残差块下采样到64维度，然后out_channels=64，我们在64内部进行恒等映射。
这里面的参数layers[0],layer[1],layers[2]表示的是各个维度残差块的数目。
定义模型
# [2,2,2]表示的是不同in_channels下的恒等映射数目
model = ResNet(ResidualBlock, [2, 2, 2]).to(device)
损失函数的定义
criterion = nn.CrossEntropyLoss()
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
设置一个通过优化器更新学习率的函数
def update_lr(optimizer, lr):
for param_group in optimizer.param_groups:
param_group['lr'] = lr
训练模型更新学习率
total_step = len(train_loader)
curr_lr = learning_rate
for epoch in range(num_epochs):
for i, (images, labels) in enumerate(train_loader):
images = images.to(device)
labels = labels.to(device)

# Forward pass
outputs = model(images)
loss = criterion(outputs, labels)

# Backward and optimize
loss.backward()
optimizer.step()

if (i + 1) % 100 == 0:
print("Epoch [{}/{}], Step [{}/{}] Loss: {:.4f}"
.format(epoch + 1, num_epochs, i + 1, total_step, loss.item()))

if (epoch + 1) % 20 == 0:
curr_lr /= 3
update_lr(optimizer, curr_lr)
测试模型并保存
model.eval()
correct = 0
total = 0
for images, labels in test_loader:
images = images.to(device)
labels = labels.to(device)
outputs = model(images)
_, predicted = torch.max(outputs.data, 1)
total += labels.size(0)
correct += (predicted == labels).sum().item()

print('Accuracy of the model on the test images: {} %'.format(100 * correct / total))

torch.save(model.state_dict(), 'resnet.ckpt')
总结
残差神经网络是很重要的一个网络模型，它的使用场景也非常广泛，如果我们有很深的网络，那就存在难以避免的学习困难和梯度爆炸或者消失的影响，这时候我们就可以使用深度残差神经网络。因为我们可以看到，在本次的例子中，我们残差网络基础有3层，残差块中又有6层（恒等映射或者下采样不算一层）。我们有三个残差结构，每一个残差结构两个残差块，所以我们就有6x2x3=36层。最后我们还有一个平均池化层一个全连接层，所以我们这个例子中就有36+3+1+1=41层网络。因此对于深度神经网络来说ResNet是个不错的选择。


展开全文
• 文章目录CIFAR-10介绍下载数据集处理transforms.Compose简单的卷积池化全连接step1残差网络残差网络介绍ResNet18 CIFAR-10介绍 CIFAR-10是一个包含60000张图片的数据集。其中每张照片为32*32的彩色照片，每个像素点...
• import torch from torch.autograd import Variable from sklearn import datasets from torch import nn digits = datasets.load_digits() X = digits.images y = digits.target ...X_train = X[:1700, :, :] ...
• 本博文为本人学习pytorch系列之——...ResNet是2015年的ImageNet竞赛的冠军，由微软研究院提出，通过引入residual block能够成功地训练高达152层的神经网络。 （paper的链接：https://arxiv.org/pdf/1512.03385.pdf...
• 残差网络是由来自Microsoft Research的4位学者提出的卷积神经网络，在2015年的ImageNet大规模视觉识别竞赛（ImageNet Large Scale Visual Recognition Challenge, ILSVRC）中获得了图像分类和物体识别的优胜。 残差...
• 经典卷积神经网络 ResNet 残差网络 DenseNet 卷积 Kernel_channels 通常指kernel的个数 Stride 指步长 Padding 旁边处空白数量 举个例子： 输入是[b, 3, 28, 28]，则一个kernel为[3, 3, 3]，16个...
• 大学生一枚，最近在学习神经网络，写这篇文章只是记录自己的学习历程，本文参考了Github上fengdu78老师的文章进行学习 ✌ BasicBlock class BasicBlock(nn.Module): # 一层中不同卷积层，卷积核的倍数 # 34层网络...
• 大学生一枚，最近在学习神经网络，写这篇文章只是记录自己的学习历程，本文参考了Github上fengdu78老师的文章进行学习 ✌ ResNet # 总的残差网络模型 class ResNet(nn.Module): def __init__(self,block,block_num...
• 大学生一枚，最近在学习神经网络，写这篇文章只是记录自己的学习历程，本文参考了Github上fengdu78老师的文章进行学习 ✌ Bottleneck # 50、101、152层残差块，三个卷积层，1*1，3*3，1*1 class Bottleneck(nn....
• 卷积神经网络基础1.1二维卷积层1.2填充和步幅1.3多输入通道和多输出通道1.4卷积层与全连接层的对比1.5池化2 经典模型LeNet-5AlexNetVGGGoogLeNet (Inception)ResNet退化问题残差网络的解决办法 1.卷积神经网络基础 ...
• 一、自定义ResNet神经网络-Pytorch【cifar10图片分类数据集】 import torch from torch.utils.data import DataLoader from torchvision import datasets from torchvision import transforms from torch import nn,...
• 我用的是pytorch，所以导入这三个。 2.定义的残差模块结构 残差块有两种设计方式，左边的是用于18,34层的，这样参数多，右面这种设计方式参数少，适用于更深度的 class ResidualBlock(nn.Modu...
• 大学生一枚，最近在学习神经网络，写这篇文章只是记录自己的学习历程，本文参考了Github上fengdu78老师的文章进行学习 源码下载地址 数据下载地址百度云 名称 地址 ResNet残差网络Pytorch实现...
• 深度残差网络（Resnet）是由来自Microsoft Research的4位学者（Kaiming He等人）提出的卷积神经网络，在2015年的ImageNet大规模视觉识别竞赛（ImageNet Large Scale Visual Recognition Challenge, ILSVRC）中获得了...
• 解决方法之一是人为地让神经网络某些层跳过下一层神经元的连接，隔层相连，弱化每层之间的强联系，即跳跃连接(skip connection)。用它可以构建能够训练深度网络的ResNets，这种神经网络被称为Residual Networks...
• 大学生一枚，最近在学习神经网络，写这篇文章只是记录自己的学习历程，本文参考了Github上fengdu78老师的文章进行学习 ✌ 使用ResNet进行对花的种类进行训练 import os import json import torch import torch.nn ...
• 大学生一枚，最近在学习神经网络，写这篇文章只是记录自己的学习历程，本文参考了Github上fengdu78老师的文章进行学习 ✌ 使用ResNet进行对cifar10数据集进行训练 import torchvision import torch from ...
• 大学生一枚，最近在学习神经网络，写这篇文章只是记录自己的学习历程，本文参考了Github上fengdu78老师的文章进行学习 ✌ 使用ResNet进行对cifar10数据集进行预测 import os import json import torch from ...

...