pytorch自定义多分类损失函数怎么反向传播

更新一下

只要自定义的损失函数的计算都是用的torch包内的函数,反向传播时跟平时一样

torchsoftmax函数 torch的concat函数torchsoftmax函数 torch的concat函数


torchsoftmax函数 torch的concat函数


12 db.insert({

loss = customLossFunc(yhat, y)

loss.ba在inference的时候,直接乘img map scale的anchor size就可以了,也就是配置文件里的anchor。ckward()

optimizer.step()

yolov5 代码解读 损失函数 loss.py

如果能培育这样一只AI,即便自己不会下棋,也可以很骄傲吧。

把one-hot label 转换为soft label,一般认为这样更容易work。

在 match 里面比较简单,容易看懂,就是 anchor 和 target 不能的太离谱,误小于阈值就 match。

self.loss_fcn = nn.BCEWithLogitsLoss(reduction='none') # must be nn.BCEWithLogitsLoss()

8 dataloader = DataLoader(dataset, collate_fn=collate_fn,

这里reduction用none因为在forward里返回的时候取mean。

刚开始看这几行非常confused,查了很久。

这个issue里说减少false negative的影响,我觉得应该写错了,是减少false itive的影响。

false negative指gt有框而network没有predict到,这时候的weight应该要比较大才对。

,当 ,即 时,alpha_factor=0,这应该是false itive的情况。

如果采用的话,会减轻pred和gt异过大造成的影响。

设gt是1,pred_prob如果很小,那么就是hard,这样算出来的p_t也会小,modulating_factor大。

对alpha_factor也是类似的。alpha_factor对应于foreground,一般设置为0.25。

这里modulating_factor的算法和QFL论文写的一致。

原本FL用class label,也就是one-hot discrete label来supervise;而QFL将其换成了IoU continuous label。

我们先明确一下p和targets的shape

p,也就是prediction,[num_dec_layer, batch_size, num_anchor, height, width, 85],这里85是80个class和4个offset以及1个confidence。

BCEcls, BCEobj是两个criteria,在scratch的hyp中g=0所以没有用focal loss,是普通的BCEloss

cp 和 cn 是soft label的probability,比如0.95 0.05。

balance控制obj loss的加权系数,autobalance决定加权系数也就是balance是否自动更新,autobalance一般是False。

self.balance = {3: [4.0, 1.0, 0.4]} ,有三个layer的输出,个layer的weight是4,第二个1,以此类推。如果有5个layer的输出才用右边那个weight数组。

gr 是ioatio。

targets就是这个batch里所有的labels,targets(img_idx, cls_idx, x, y, w, h),shape为[nt, 6]。可参考utils/datasets.py line 522, 599。

随便打印几行targets也可以验证我们的分析。

x, y, w, h是归一化后的结果。

先了三份一样的targets,在面加了一维表明anchor idx,本来是6现在变成7。

gain[2:6] = torch.tensor(p[i].shape)[[3, 2, 3, 2]] # xyxy gain t = targets gain 这里是把 grid size 拿出来乘,恢复到特征图的维度。

下一步在扩展 targets,个人认为是 itive examples 太少了,所以根据 center 在 cell 中的相对位置,添加相邻的两个 cell 作为 targets。

举个例子,如果 center 在 cell 的左上角,那么 cell 本身,和 cell 的左边一个位置,还有 cell 的上边一个位置,这三个 cell 都作为 targets。

我个人觉得这里的写法是非常巧妙的,取了 grid xy 和 inverse(类似于 flip)。

(gxy % 1. < g) ,这里的 g 是 0.5,如果仅考虑这个条件, 好像可以 直接判断是否选取左边 cell 和上边 cell。

但是要考虑到边界情况,如果当前已经处于最上方,已经没有上边 cell 可以选择了,这就是 (gxy > 1.) 起到的作用,判断 edge case。

如果本来大于 0.5,那么 inverse 后就小于 0.5 了,所以可以使用相同的逻辑选择右边 cell 和下边 cell ,类似地推理到 edge case。

一点要提的是使用 clamp_ 确保返回的 grid inds 不是非法值,旧版本 code 没用这个检查,不过好像也没什么。

lcls, lbox, lobj 这三个用来存放loss,默认使用pytorch提供的BCE loss。

pxy = ps[:, :2].sigmoid() 2. - 0.5 在learn的时候不需要加cx cy。

Objectness 这里 gr 设置为 1.0,也就意味着直接拿 iou 作为 confidence。

在train的时候,target是在feature map的scale。

动态调整Learning Rate:TORCH.OPTIM.LR_SCHEDULER

6 total_count += nodes[i][1]

GitHub源码

在1.1.0之前,scheduler的更新要在optimizer之前,为了向后兼容,在1.1.0之后scheduler需要放在optimizer更新之后,如果依然放在optimizer更新之前,那么就会跳过设定的LR的个值,如下。

通过设置函数更新LR,lr_lambda可以是一个函数或者函数列表,但是需要和optimizer的参数组数量相同,一个参数一个更新函数,但是有多个参数组的话可以只设定一个更新函数,所有参数组共用这个更新函数。 注意LR更新函数是与Base_lr相乘。

这个规定4 before the last ReLU activation.了一个特殊的LambdaLR方式,每step_size步之后衰减gamma。多个参数组共用Step_size和gamma,同时Step_size固定。

当模型的指标停止增加的时候,可以适当降低LR,在Patience时间内模型没有改进的时候,LR会降低。

上述的方法都是每次epoch之后更新,CyclicLR会在每个batch之后更新,更新频率更快。

Cyclical Learning Rates for Training Neural Networks

一个周期性的余弦下降策略。每经过 次重启一下。

Stochastic Gradient Descent with Warm Restarts

函数图像以及剩下Pytorch中Module,Parameter和Buffer的区别的函数如下表:

torch是什么意思 深入了解torch框架的特点和应用?

至于为什么返回 loss 的时候为什么要乘 bs,还不是很清楚,第二个返回值就是为了打印信息用的。

1. 计算机视觉:torch框架在计算机视觉领域有着广泛的应用,如图像分类、物体检测、图像分割等任务。其中,Facebook的Detectron和Mask R-就是基于torch框架实现的。

代码实现传送门:

2. 易用性:torch框架提供了丰富的模型组件和预训练模型,使得用户可以快速搭建自己的深度学习模型,同时也支持多种优化算法和损失函数的自定义。

2. 自然语言处理:torch框架在自然语言处理领域也有着重要的应用,如文本分类、机器翻译、语音识别等任务。Facebook的fastText和fairseq就是基于torch框架实现的。

3. 高效性:torch框架的底层实现采用了高效的C/C++编写,同时支持GPU加速,可以大幅提升训练和推理的速度。

总之,torch框架是一个功能强大、易用性高、灵活性强的深度学习框架,已经成为了深度学习领域的重要工具pytorch提供的动态调整LR的策略。之一。

总之,torch框架是一个功能强大、易用性高、灵活性强的深度学习框架,已经成为了深度学习领域的重要工具之一。

python原生的range找不到,为什么只能找到pytorch中的torch.range?

直白的说,network觉得这里有一个obj,但是gt说没有,这种情况不应该过多的惩罚。

range函数是python内置函数,肯定支持的

targets [nt, 6]

估计是你的IDE工具环境设置问题,优先按照import路径寻找匹配函数。

range函数用法:

17 result = evaluate(pending_player, best_player)range(stop)

range(start, stop[, step])

torch nn.view参数是怎么计算

4 white_wins = 0

利用input对象计算其对应的output。通常input和output都是Tensor类型的。有时候会有例外例如table layers(Tensor的子类)。Forward之后,outpubbox回归的公式可以参考model/yolo.py line56,15 return True 57。t变量应该被更新为新的值了。

不建议重写这个函数,二是应该去实现updateOutput(input)函数。

自学围棋的AlphaGo Zero,你也可以造一个

8 self.parent = parent

01 遥想当年,AlphaGo的Master版本,在完胜柯洁九段之后不久,就被后辈AlphaGo Zero (简称狗零) 击溃了。

选择落子点

从一只完全不懂围棋的AI,到打败Master,狗零只用了21天。

16 _id += 1

而且,它不需要用人类知识来喂养,成为棋手全靠自学。

于是,来自巴黎的少年Dylan Djian (简称小笛) ,就照着狗零的论文去实现了一下。

他给自己的AI棋手起名SuperGo,也提供了代码 (传送门见文底) 。

除此之外,还有教程——

一个身子两个头

智能体分成三个部分:

一是特征提取器 (Feature Extractor) ,二是策略网络 (Policy Network) ,三是价值网络(Value Network) 。

于是,狗零也被亲切地称为“双头怪”。特征提取器是身子,其他两个网络是脑子。

特征提取器

特征提取模型,是个残网络 (ResNet) ,就是给普通加上了跳层连接 (Skip Connection) , 让梯度的传播更加通畅。

跳跃的样子,写成代码就是:

1class BasicBlock(nn.Module):

2 """

3 Basic residual block with 2 convolutions and a skip connection

5 """

67 def __init__(self, inplanes, planes, stride=1, downsample=None):

8 super(BasicBlock, self).__init__()

0 self.conv1 = nn.Conv2d(inplanes, planes, kernel_size=3,

11 stride=stride, padding=1, bias=False)

12 self.bn1 = nn.BatchNorm2d(planes)

13

14 self.conv2 = nn.Conv2d(planes, planes, kernel_size=3,

15 stride=stride, padding=1, bias=False)

16 self.bn2 = nn.BatchNorm2d(planes)

17

18

19 def forward(self, x):

20 residual = x

21

22 out = self.conv1(x)

23 out = F.relu(self.bn1(out))

24

25 out = self.conv2(out)

26 out = self.bn2(out)

27

28 out += residual

29 out = F.relu(out)

30

31 return out

然后,把它加到特征提取模型里面去:

1class Extractor(nn.Module):

2 def __init__(self, inplanes, outplanes):

3 super(Extractor, self).__init__()

4 self.conv1 = nn.Conv2d(inplanes, outplanes, stride=1,

5 kernel_size=3, padding=1, bias=False)

6 self.bn1 = nn.BatchNorm2d(outplanes)

78 for block in range(BLOCKS):

9 setattr(self, "res{}".format(block),

10 BasicBlock(outplanes, outplanes))

11

12

13 def forward(self, x):

14 x = F.relu(self.bn1(self.conv1(x)))

15 for block in range(BLOCKS - 1):

16 x = getattr(self, "res{}".format(block))(x)

17

18 feature_maps = getattr(self, "res{}".format(BLOCKS - 1))(x)

19 return feature_maps

策略网络

策略网络就是普通的了,里面有个批量标准化 (Batch Normalization) ,还有一个全连接层,输出概率分布。

1class PolicyNet(nn.Module):

2 def __init__(self, inplanes, outplanes):

3 super(PolicyNet, self).__init__()

4 self.outplanes = outplanes

5 self.conv = nn.Conv2d(inplanes, 1, kernel_size=1)

6 self.bn = nn.BatchNorm2d(1)

7 self.logsoftmax = nn.LogSoftmax(dim=1)

8 self.fc = nn.Linear(outplanes - 1, outplanes)

0

11 def forward(self, x):

12 x = F.relu(self.bn(self.conv(x)))

13 x = x.view(-1, self.outplanes - 1)

14 x = self.fc(x)

15 probas = self.logsoftmax(x).exp()

16

17 return probas

价值网络

这个网络稍微复杂一点。除了标配之外,还要再多加一个全连接层。,用双曲正切 (Hyperbolic Tangent) 算出 (-1,1) 之间的数值,来表示当前状态下的赢面多大。

代码长这样——

1class ValueNet(nn.Module):

2 def __init__(self, inplanes, outplanes):

3 super(ValueNet, self).__init__()

4 self.outplanes = outplanes

5 self.conv = nn.Conv2d(inplanes, 1, kernel_size=1)

6 self.bn = nn.BatchNorm2d(1)

7 self.fc1 = nn.Linear(outplanes - 1, 256)

8 self.fc2 = nn.Linear(256, 1)

0

11 def forward(self, x):

12 x = F.relu(self.bn(self.conv(x)))

13 x = x.view(-1, self.outplanes - 1)

14 x = F.relu(self.fc1(x))

15 winning = F.tanh(self.fc2(x))

16 return winning

未雨绸缪的树

狗零,还有一个很重要的组成部分,就是蒙特卡洛树搜索 (MCTS) 。

它可以让AI棋手提前找出,胜率的落子点。

在模拟器里,模拟对方的下一手,以及再下一手,给出应对之策,所以提前的远不止是一步。

(Node)

树上的每一个,都代表一种不同的局势,有不同的统计数据:

每个被经过的次数n,总动作值w,经过这一点的先验概率p,平均动作值q (q=w/n) ,还有从别处来到这个走的那一步,以及从这个出发、所有可能的下一步。

1class Node:

2 def __init__(self, parent=None, proba=None, move=None):

3 self.p = proba

4 self.n = 0

5 self.w = 0

6 self.q = 0

7 self.children = []

9 self.move = move

部署 (Rollout)

步是PUCT (多项式上置信树) 算法,选择能让PUCT函数 (下图) 的某个变体 (Variant) 化,的走法。

写成代码的话——

1def select(nodes, c_puct=C_PUCT):

2 " Optimized version of the selection based of the PUCT formula "

34 total_count = 0

5 for i in range(nodes.shape[0]):

78 action_scores = np.zeros(nodes.shape[0])

9 for i in range(nodes.shape[0]):

10 action_scores[i] = nodes[i][0] + c_puct nodes[i][2]

11 (np.sqrt(total_count) / (1 + nodes[i][1]))

12

13 equals = np.where(action_scores == np.max(action_scores))[0]

14 if equals.shape[0] > 0:

15 return np.random.cho(equals)

16 return equals[0]

结束 (Ending)

选择在不停地进行,直至到达一个叶 (Leaf Node) ,而这个还没有往下生枝。

2 """ Check wher a node is a leaf or not """

34 return len(self.children) == 0

到了叶,那里的一个随机状态就会被评估,得出所有“下一步”的概率。

所有被禁的落子点,概率会变成零,然后重新把总概率归为1。

然后,这个叶就会生出枝节 (都是可以落子的位置,概率不为零的那些) 。代码如下——

2 self.children = [Node(parent=self, move=idx, proba=probas[idx])

3 for idx in range(probas.shape[0]) if probas[idx] > 0]

枝节生好之后,这个叶和它的妈妈们,身上的统计数据都会更新,用的是下面这两串代码。

2 """ Update the node statistics after a rollout """

34 self.w = self.w + v

5 self.q = self.w / self.n if self.n > 0 else 0

1while current_node.parent:

2 current_node.update(v)

3 current_node = current_node.parent

模拟器搭好了,每个可能的“下一步”,都有了自己的统计数据。

按照这些数据,算选择其中一步,真要落子的地方。

选择有两种,一就是选择被模拟的次数最多的点。试用于测试和实战。

另外一种,随机 (Stochastically) 选择,把被经过的次数转换成概率分布,用的是以下代码——

1 total = np.sum(action_scores)

2 probas = action_scores / total

3 move = np.random.cho(action_scores.shape[0], p=probas)

后者适用于训练,让AlphaGo探索更多可能的选择。

三位一体的修炼

狗零的修炼分为三个过程,是异步的。

一是自对弈 (Self-Play) ,用来生成数据。

1def self_play():

2 while True:

3 new_player, checkpoint = load_player()

4 if new_player:

5 player = new_player

67 ## Create the self-play match queue of processes

8 results = create_matches(player, cores=PARALLEL_SELF_PLAY,

9 match_number=SELF_PLAY_MATCH)

10 for _ in range(SELF_PLAY_MATCH):

11 result = results.get()

13 "": result,

14 "id": _id

15 })

二是训练 (Training) ,拿新鲜生成的数据,来改进当前的神经网络。

1def train():

2 criterion = AlphaLoss()

3 dataset = SelfPlayDataset()

4 player, checkpoint = load_player(current_time, loaded_version)

5 optimizer = create_optimizer(player, lr,

6 param=checkpoint['optimizer'])

7 best_player = deepcopy(player)

9 batch_size=BATCH_SIZE, shuffle=True)

10

11 while True:

13

14 ## Evaluate a copy of the current network

15 if total_ite % TRAIN_STEPS == 0:

16 pending_player = deepcopy(player)

18

19 if result:

20 best_player = pending_player

21

22 example = {

24 'winner': winner,

25 'move' : move

26 }

27 optimizer.zero_grad()

28 winner, probas = pending_player.predict(example['state'])

29

30 loss = criterion(winner, example['winner'],

31 probas, example['move'])

32 loss.backward()

33 optimizer.step()

34

35 ## Fetch new s

36 if total_ite % REFRESH_TICK == 0:

37 last_id = fetch_new_s(collection, dataset, last_id)

训练用的损失函数表示如下:

1class AlphaLoss(torch.nn.Module):

2 def __init__(self):

3 super(AlphaLoss, self).__init__()

45 def forward(self, pred_winner, winner, pred_probas, probas):

6 value_error = (winner - pred_winner) 2

7 policy_error = torch.sum((-probas

8 (1e-6 + pred_probas).log()), 1)

9 total_error = (value_error.view(-1) + return total_error

三是评估 (Evaluation) ,看训练过的智能体,比起正在生成数据的智能体,是不是更了 (秀者回到步,继续生成数据) 。

1def evaluate(player, new_player):

2 results = play(player, opponent=new_player)

3 black_wins = 0

56 for result in results:

7 if result[0] == 1:

8 white_wins += 1

9 elif result[0] == 0:

10 black_wins += 1

11

13 ## the current best player depending on the threshold

14 if black_wins >= EVAL_THRESH len(results):

16 return False

第三部分很重要,要不断选出的网络,来不断生成高质量的数据,才能提升AI的棋艺。

三个环节周而复始,才能养成强大的棋手。

有志于AI围棋的各位,也可以试一试这个PyTorch实现。

本来摘自量子位,原作 Dylan Djian。

网页链接

教程原文传送门:

网页链接

AlphaGo Zero论文传送门:

网页链接

torch保存为t7

12 ## Check if the trained player (black) is better than

题主是否想询问“torch怎么保存为t7”?用torch.se()函数。

12 for batch_idx, (state, move, winner) in enumerate(dataloader):

1、先导入了所需的库和模型。

2、然后使用tor23 'state': state,ch.se()函数将模型保存为名为“model.t7”的文件。

3、在实际使用时,需要将上面的示例代码中的模型替换为你自己的模型。

pytorch和sklearn哪个运行快

1def expand(self, probas):

sklearn和pytorc1def update(self, v):h区别

scikit-learn和tensorflow的区别

如何学会快速调用API

Pytorch之CrossEntropyLoss() 与 NLLLoss() 的区别

(原创)sklearn中 F1-micro 与 F1-macro区别和计算原理

pandas 下的 one hot encoder 及 pd.get_dummies() 与 sklearn.preprocessing 下的 OneHotEncoder 的区别

densenet思路 以及和残1def is_leaf(self):网络区别,pytorch实现

Python初探——sklearn库中数据预处理函数fit_transform()和transform()的区别

PyTorch 中,nn 与 nn.functional 有什么区别?

sklearn中的predict与predict_proba的区别(得到各条记录每个标签的概率(支持度))

sklearn中predict()与predict_proba()用法区别

tensorflow和pytorch的区别

sklearn中standardscaler中fit_transform()和transform()有什么区别,应该怎么使用?

pytorch clamp 与clamp_区别

Pytorch本人疑问(1) torch.nn和torch.nn.functional之间的区别

pytorch 中 repeat 和 expend 的功能和区别

sklearn 中fit_tansform 与 transform的区别

sklearn.svm包中的SVC(kernel=”linear“)和LinearSVC的区别

pytorch之Tensor与Variable的区别

PyTorch学习笔记——softmax和log_softmax的区别、CrossEntropyLoss() 与 NLLLoss() 的区别、log似然代价函数

Pytorch: parameters(),children(),modules(),named_区别